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-2013 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: is the host bigendian?  This has to do with float vs double
     53    register accesses on VFP, but it's complex and not properly thought
     54    out. */
     55 static Bool host_is_bigendian;
     56 
     57 /* Pointer to the guest code area. */
     58 static 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(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(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    return False;
    778 }
    779 
    780 static Bool is_Branch_or_Jump_and_Link(UChar * addr)
    781 {
    782    UInt cins = getUInt(addr);
    783 
    784    UInt opcode = get_opcode(cins);
    785    UInt rt = get_rt(cins);
    786    UInt function = get_function(cins);
    787 
    788    /* jal */
    789    if (opcode == 0x02) {
    790       return True;
    791    }
    792 
    793    /* bgezal */
    794    if (opcode == 0x01 && rt == 0x11) {
    795       return True;
    796    }
    797 
    798    /* bltzal */
    799    if (opcode == 0x01 && rt == 0x10) {
    800       return True;
    801    }
    802 
    803    /* jalr */
    804    if (opcode == 0x00 && function == 0x09) {
    805       return True;
    806    }
    807 
    808    return False;
    809 }
    810 
    811 static Bool branch_or_link_likely(UChar * addr)
    812 {
    813    UInt cins = getUInt(addr);
    814    UInt opcode = get_opcode(cins);
    815    UInt rt = get_rt(cins);
    816 
    817    /* bgtzl, blezl, bnel, beql */
    818    if (opcode == 0x17 || opcode == 0x16 || opcode == 0x15 || opcode == 0x14)
    819       return True;
    820 
    821    /* bgezl */
    822    if (opcode == 0x01 && rt == 0x03)
    823       return True;
    824 
    825    /* bgezall */
    826    if (opcode == 0x01 && rt == 0x13)
    827       return True;
    828 
    829    /* bltzall */
    830    if (opcode == 0x01 && rt == 0x12)
    831       return True;
    832 
    833    /* bltzl */
    834    if (opcode == 0x01 && rt == 0x02)
    835       return True;
    836 
    837    return False;
    838 }
    839 
    840 /*------------------------------------------------------------*/
    841 /*--- Helper bits and pieces for creating IR fragments.    ---*/
    842 /*------------------------------------------------------------*/
    843 
    844 static IRExpr *mkU8(UInt i)
    845 {
    846    vassert(i < 256);
    847    return IRExpr_Const(IRConst_U8((UChar) i));
    848 }
    849 
    850 /* Create an expression node for a 16-bit integer constant. */
    851 static IRExpr *mkU16(UInt i)
    852 {
    853    return IRExpr_Const(IRConst_U16(i));
    854 }
    855 
    856 /* Create an expression node for a 32-bit integer constant. */
    857 static IRExpr *mkU32(UInt i)
    858 {
    859    return IRExpr_Const(IRConst_U32(i));
    860 }
    861 
    862 /* Create an expression node for a 64-bit integer constant. */
    863 static IRExpr *mkU64(ULong i)
    864 {
    865    return IRExpr_Const(IRConst_U64(i));
    866 }
    867 
    868 static IRExpr *mkexpr(IRTemp tmp)
    869 {
    870    return IRExpr_RdTmp(tmp);
    871 }
    872 
    873 static IRExpr *unop(IROp op, IRExpr * a)
    874 {
    875    return IRExpr_Unop(op, a);
    876 }
    877 
    878 static IRExpr *binop(IROp op, IRExpr * a1, IRExpr * a2)
    879 {
    880    return IRExpr_Binop(op, a1, a2);
    881 }
    882 
    883 static IRExpr *triop(IROp op, IRExpr * a1, IRExpr * a2, IRExpr * a3)
    884 {
    885    return IRExpr_Triop(op, a1, a2, a3);
    886 }
    887 
    888 static IRExpr *qop ( IROp op, IRExpr * a1, IRExpr * a2, IRExpr * a3,
    889                      IRExpr * a4 )
    890 {
    891    return IRExpr_Qop(op, a1, a2, a3, a4);
    892 }
    893 
    894 static IRExpr *load(IRType ty, IRExpr * addr)
    895 {
    896    IRExpr *load1 = NULL;
    897 #if defined (_MIPSEL)
    898    load1 = IRExpr_Load(Iend_LE, ty, addr);
    899 #elif defined (_MIPSEB)
    900    load1 = IRExpr_Load(Iend_BE, ty, addr);
    901 #endif
    902    return load1;
    903 }
    904 
    905 /* Add a statement to the list held by "irsb". */
    906 static void stmt(IRStmt * st)
    907 {
    908    addStmtToIRSB(irsb, st);
    909 }
    910 
    911 static void assign(IRTemp dst, IRExpr * e)
    912 {
    913    stmt(IRStmt_WrTmp(dst, e));
    914 }
    915 
    916 static void store(IRExpr * addr, IRExpr * data)
    917 {
    918 #if defined (_MIPSEL)
    919    stmt(IRStmt_Store(Iend_LE, addr, data));
    920 #elif defined (_MIPSEB)
    921    stmt(IRStmt_Store(Iend_BE, addr, data));
    922 #endif
    923 }
    924 
    925 /* Generate a new temporary of the given type. */
    926 static IRTemp newTemp(IRType ty)
    927 {
    928    vassert(isPlausibleIRType(ty));
    929    return newIRTemp(irsb->tyenv, ty);
    930 }
    931 
    932 /* Generate an expression for SRC rotated right by ROT. */
    933 static IRExpr *genROR32(IRExpr * src, Int rot)
    934 {
    935    vassert(rot >= 0 && rot < 32);
    936    if (rot == 0)
    937       return src;
    938    return binop(Iop_Or32, binop(Iop_Shl32, src, mkU8(32 - rot)),
    939                           binop(Iop_Shr32, src, mkU8(rot)));
    940 }
    941 
    942 static IRExpr *genRORV32(IRExpr * src, IRExpr * rs)
    943 {
    944    IRTemp t0 = newTemp(Ity_I8);
    945    IRTemp t1 = newTemp(Ity_I8);
    946 
    947    assign(t0, unop(Iop_32to8, binop(Iop_And32, rs, mkU32(0x0000001F))));
    948    assign(t1, binop(Iop_Sub8, mkU8(32), mkexpr(t0)));
    949    return binop(Iop_Or32, binop(Iop_Shl32, src, mkexpr(t1)),
    950                           binop(Iop_Shr32, src, mkexpr(t0)));
    951 }
    952 
    953 static UShort extend_s_10to16(UInt x)
    954 {
    955    return (UShort) ((((Int) x) << 22) >> 22);
    956 }
    957 
    958 static ULong extend_s_10to32(UInt x)
    959 {
    960    return (ULong)((((Long) x) << 22) >> 22);
    961 }
    962 
    963 static ULong extend_s_10to64(UInt x)
    964 {
    965    return (ULong)((((Long) x) << 54) >> 54);
    966 }
    967 
    968 static UInt extend_s_16to32(UInt x)
    969 {
    970    return (UInt) ((((Int) x) << 16) >> 16);
    971 }
    972 
    973 static UInt extend_s_18to32(UInt x)
    974 {
    975    return (UInt) ((((Int) x) << 14) >> 14);
    976 }
    977 
    978 static ULong extend_s_16to64 ( UInt x )
    979 {
    980    return (ULong) ((((Long) x) << 48) >> 48);
    981 }
    982 
    983 static ULong extend_s_18to64 ( UInt x )
    984 {
    985    return (ULong) ((((Long) x) << 46) >> 46);
    986 }
    987 
    988 static ULong extend_s_32to64 ( UInt x )
    989 {
    990    return (ULong) ((((Long) x) << 32) >> 32);
    991 }
    992 
    993 static void jmp_lit32 ( /*MOD*/ DisResult* dres, IRJumpKind kind, Addr32 d32 )
    994 {
    995    vassert(dres->whatNext    == Dis_Continue);
    996    vassert(dres->len         == 0);
    997    vassert(dres->continueAt  == 0);
    998    vassert(dres->jk_StopHere == Ijk_INVALID);
    999    dres->whatNext    = Dis_StopHere;
   1000    dres->jk_StopHere = kind;
   1001    stmt( IRStmt_Put( OFFB_PC, mkU32(d32) ) );
   1002 }
   1003 
   1004 static void jmp_lit64 ( /*MOD*/ DisResult* dres, IRJumpKind kind, Addr64 d64 )
   1005 {
   1006    vassert(dres->whatNext    == Dis_Continue);
   1007    vassert(dres->len         == 0);
   1008    vassert(dres->continueAt  == 0);
   1009    vassert(dres->jk_StopHere == Ijk_INVALID);
   1010    dres->whatNext    = Dis_StopHere;
   1011    dres->jk_StopHere = kind;
   1012    stmt(IRStmt_Put(OFFB_PC, mkU64(d64)));
   1013 }
   1014 
   1015 /* Get value from accumulator (helper function for MIPS32 DSP ASE instructions).
   1016    This function should be called before any other operation if widening
   1017    multiplications are used. */
   1018 static IRExpr *getAcc(UInt acNo)
   1019 {
   1020    vassert(!mode64);
   1021    vassert(acNo <= 3);
   1022    return IRExpr_Get(accumulatorGuestRegOffset(acNo), Ity_I64);
   1023 }
   1024 
   1025 /* Get value from DSPControl register (helper function for MIPS32 DSP ASE
   1026    instructions). */
   1027 static IRExpr *getDSPControl(void)
   1028 {
   1029    vassert(!mode64);
   1030    return IRExpr_Get(offsetof(VexGuestMIPS32State, guest_DSPControl), Ity_I32);
   1031 }
   1032 
   1033 /* Put value to DSPControl register. Expression e is written to DSPControl as
   1034    is. If only certain bits of DSPControl need to be changed, it should be done
   1035    before calling putDSPControl(). It could be done by reading DSPControl and
   1036    ORing it with appropriate mask. */
   1037 static void putDSPControl(IRExpr * e)
   1038 {
   1039    vassert(!mode64);
   1040    stmt(IRStmt_Put(offsetof(VexGuestMIPS32State, guest_DSPControl), e));
   1041 }
   1042 
   1043 /* Fetch a byte from the guest insn stream. */
   1044 static UChar getIByte(Int delta)
   1045 {
   1046    return guest_code[delta];
   1047 }
   1048 
   1049 static IRExpr *getIReg(UInt iregNo)
   1050 {
   1051    if (0 == iregNo) {
   1052       return mode64 ? mkU64(0x0) : mkU32(0x0);
   1053    } else {
   1054       IRType ty = mode64 ? Ity_I64 : Ity_I32;
   1055       vassert(iregNo < 32);
   1056       return IRExpr_Get(integerGuestRegOffset(iregNo), ty);
   1057    }
   1058 }
   1059 
   1060 static IRExpr *getHI(void)
   1061 {
   1062    if (mode64)
   1063       return IRExpr_Get(offsetof(VexGuestMIPS64State, guest_HI), Ity_I64);
   1064    else
   1065       return IRExpr_Get(offsetof(VexGuestMIPS32State, guest_HI), Ity_I32);
   1066 }
   1067 
   1068 static IRExpr *getLO(void)
   1069 {
   1070    if (mode64)
   1071       return IRExpr_Get(offsetof(VexGuestMIPS64State, guest_LO), Ity_I64);
   1072    else
   1073       return IRExpr_Get(offsetof(VexGuestMIPS32State, guest_LO), Ity_I32);
   1074 }
   1075 
   1076 static IRExpr *getFCSR(void)
   1077 {
   1078    if (mode64)
   1079       return IRExpr_Get(offsetof(VexGuestMIPS64State, guest_FCSR), Ity_I32);
   1080    else
   1081       return IRExpr_Get(offsetof(VexGuestMIPS32State, guest_FCSR), Ity_I32);
   1082 }
   1083 
   1084 /* Get byte from register reg, byte pos from 0 to 3 (or 7 for MIPS64) . */
   1085 static IRExpr *getByteFromReg(UInt reg, UInt byte_pos)
   1086 {
   1087   UInt pos = byte_pos * 8;
   1088   if (mode64)
   1089       return unop(Iop_64to8, binop(Iop_And64,
   1090                                    binop(Iop_Shr64, getIReg(reg), mkU8(pos)),
   1091                                    mkU64(0xFF)));
   1092    else
   1093       return unop(Iop_32to8, binop(Iop_And32,
   1094                                    binop(Iop_Shr32, getIReg(reg), mkU8(pos)),
   1095                                    mkU32(0xFF)));
   1096 }
   1097 
   1098 static void putFCSR(IRExpr * e)
   1099 {
   1100    if (mode64)
   1101       stmt(IRStmt_Put(offsetof(VexGuestMIPS64State, guest_FCSR), e));
   1102    else
   1103       stmt(IRStmt_Put(offsetof(VexGuestMIPS32State, guest_FCSR), e));
   1104 }
   1105 
   1106 /* fs   - fpu source register number.
   1107    inst - fpu instruction that needs to be executed.
   1108    sz32 - size of source register.
   1109    opN  - number of operads:
   1110           1 - unary operation.
   1111           2 - binary operation. */
   1112 static void calculateFCSR(UInt fs, UInt ft, UInt inst, Bool sz32, UInt opN)
   1113 {
   1114    IRDirty *d;
   1115    IRTemp fcsr = newTemp(Ity_I32);
   1116    /* IRExpr_BBPTR() => Need to pass pointer to guest state to helper. */
   1117    if (fp_mode64)
   1118       d = unsafeIRDirty_1_N(fcsr, 0,
   1119                             "mips_dirtyhelper_calculate_FCSR_fp64",
   1120                             &mips_dirtyhelper_calculate_FCSR_fp64,
   1121                             mkIRExprVec_4(IRExpr_BBPTR(),
   1122                                           mkU32(fs),
   1123                                           mkU32(ft),
   1124                                           mkU32(inst)));
   1125    else
   1126       d = unsafeIRDirty_1_N(fcsr, 0,
   1127                             "mips_dirtyhelper_calculate_FCSR_fp32",
   1128                             &mips_dirtyhelper_calculate_FCSR_fp32,
   1129                             mkIRExprVec_4(IRExpr_BBPTR(),
   1130                                           mkU32(fs),
   1131                                           mkU32(ft),
   1132                                           mkU32(inst)));
   1133 
   1134    if (opN == 1) {  /* Unary operation. */
   1135       /* Declare we're reading guest state. */
   1136       if (sz32 || fp_mode64)
   1137          d->nFxState = 2;
   1138       else
   1139          d->nFxState = 3;
   1140       vex_bzero(&d->fxState, sizeof(d->fxState));
   1141 
   1142       d->fxState[0].fx     = Ifx_Read;  /* read */
   1143       if (mode64)
   1144          d->fxState[0].offset = offsetof(VexGuestMIPS64State, guest_FCSR);
   1145       else
   1146          d->fxState[0].offset = offsetof(VexGuestMIPS32State, guest_FCSR);
   1147       d->fxState[0].size   = sizeof(UInt);
   1148       d->fxState[1].fx     = Ifx_Read;  /* read */
   1149       d->fxState[1].offset = floatGuestRegOffset(fs);
   1150       d->fxState[1].size   = sizeof(ULong);
   1151 
   1152       if (!(sz32 || fp_mode64)) {
   1153          d->fxState[2].fx     = Ifx_Read;  /* read */
   1154          d->fxState[2].offset = floatGuestRegOffset(fs+1);
   1155          d->fxState[2].size   = sizeof(ULong);
   1156       }
   1157    } else if (opN == 2) {  /* Binary operation. */
   1158       /* Declare we're reading guest state. */
   1159       if (sz32 || fp_mode64)
   1160          d->nFxState = 3;
   1161       else
   1162          d->nFxState = 5;
   1163       vex_bzero(&d->fxState, sizeof(d->fxState));
   1164 
   1165       d->fxState[0].fx     = Ifx_Read;  /* read */
   1166       if (mode64)
   1167          d->fxState[0].offset = offsetof(VexGuestMIPS64State, guest_FCSR);
   1168       else
   1169          d->fxState[0].offset = offsetof(VexGuestMIPS32State, guest_FCSR);
   1170       d->fxState[0].size   = sizeof(UInt);
   1171       d->fxState[1].fx     = Ifx_Read;  /* read */
   1172       d->fxState[1].offset = floatGuestRegOffset(fs);
   1173       d->fxState[1].size   = sizeof(ULong);
   1174       d->fxState[2].fx     = Ifx_Read;  /* read */
   1175       d->fxState[2].offset = floatGuestRegOffset(ft);
   1176       d->fxState[2].size   = sizeof(ULong);
   1177 
   1178       if (!(sz32 || fp_mode64)) {
   1179          d->fxState[3].fx     = Ifx_Read;  /* read */
   1180          d->fxState[3].offset = floatGuestRegOffset(fs+1);
   1181          d->fxState[3].size   = sizeof(ULong);
   1182          d->fxState[4].fx     = Ifx_Read;  /* read */
   1183          d->fxState[4].offset = floatGuestRegOffset(ft+1);
   1184          d->fxState[4].size   = sizeof(ULong);
   1185       }
   1186    }
   1187 
   1188    stmt(IRStmt_Dirty(d));
   1189 
   1190    putFCSR(mkexpr(fcsr));
   1191 }
   1192 
   1193 static IRExpr *getULR(void)
   1194 {
   1195    if (mode64)
   1196       return IRExpr_Get(offsetof(VexGuestMIPS64State, guest_ULR), Ity_I64);
   1197    else
   1198       return IRExpr_Get(offsetof(VexGuestMIPS32State, guest_ULR), Ity_I32);
   1199 }
   1200 
   1201 static void putIReg(UInt archreg, IRExpr * e)
   1202 {
   1203    IRType ty = mode64 ? Ity_I64 : Ity_I32;
   1204    vassert(archreg < 32);
   1205    vassert(typeOfIRExpr(irsb->tyenv, e) == ty);
   1206    if (archreg != 0)
   1207       stmt(IRStmt_Put(integerGuestRegOffset(archreg), e));
   1208 }
   1209 
   1210 static IRExpr *mkNarrowTo32(IRType ty, IRExpr * src)
   1211 {
   1212    vassert(ty == Ity_I32 || ty == Ity_I64);
   1213    return ty == Ity_I64 ? unop(Iop_64to32, src) : src;
   1214 }
   1215 
   1216 static void putLO(IRExpr * e)
   1217 {
   1218    if (mode64) {
   1219       stmt(IRStmt_Put(offsetof(VexGuestMIPS64State, guest_LO), e));
   1220    } else {
   1221       stmt(IRStmt_Put(offsetof(VexGuestMIPS32State, guest_LO), e));
   1222    /* Add value to lower 32 bits of ac0 to maintain compatibility between
   1223       regular MIPS32 instruction set and MIPS DSP ASE. Keep higher 32bits
   1224       unchanged. */
   1225       IRTemp t_lo = newTemp(Ity_I32);
   1226       IRTemp t_hi = newTemp(Ity_I32);
   1227       assign(t_lo, e);
   1228       assign(t_hi, unop(Iop_64HIto32, getAcc(0)));
   1229       stmt(IRStmt_Put(accumulatorGuestRegOffset(0),
   1230            binop(Iop_32HLto64, mkexpr(t_hi), mkexpr(t_lo))));
   1231    }
   1232 }
   1233 
   1234 static void putHI(IRExpr * e)
   1235 {
   1236    if (mode64) {
   1237       stmt(IRStmt_Put(offsetof(VexGuestMIPS64State, guest_HI), e));
   1238    } else {
   1239       stmt(IRStmt_Put(offsetof(VexGuestMIPS32State, guest_HI), e));
   1240    /* Add value to higher 32 bits of ac0 to maintain compatibility between
   1241       regular MIPS32 instruction set and MIPS DSP ASE. Keep lower 32bits
   1242       unchanged. */
   1243       IRTemp t_lo = newTemp(Ity_I32);
   1244       IRTemp t_hi = newTemp(Ity_I32);
   1245       assign(t_hi, e);
   1246       assign(t_lo, unop(Iop_64to32, getAcc(0)));
   1247       stmt(IRStmt_Put(accumulatorGuestRegOffset(0),
   1248            binop(Iop_32HLto64, mkexpr(t_hi), mkexpr(t_lo))));
   1249    }
   1250 }
   1251 
   1252 /* Put value to accumulator(helper function for MIPS32 DSP ASE instructions). */
   1253 static void putAcc(UInt acNo, IRExpr * e)
   1254 {
   1255    vassert(!mode64);
   1256    vassert(acNo <= 3);
   1257    vassert(typeOfIRExpr(irsb->tyenv, e) == Ity_I64);
   1258    stmt(IRStmt_Put(accumulatorGuestRegOffset(acNo), e));
   1259 /* If acNo = 0, split value to HI and LO regs in order to maintain compatibility
   1260    between MIPS32 and MIPS DSP ASE insn sets. */
   1261    if (0 == acNo) {
   1262      putLO(unop(Iop_64to32, e));
   1263      putHI(unop(Iop_64HIto32, e));
   1264    }
   1265 }
   1266 
   1267 static IRExpr *mkNarrowTo8 ( IRType ty, IRExpr * src )
   1268 {
   1269    vassert(ty == Ity_I32 || ty == Ity_I64);
   1270    return ty == Ity_I64 ? unop(Iop_64to8, src) : unop(Iop_32to8, src);
   1271 }
   1272 
   1273 static void putPC(IRExpr * e)
   1274 {
   1275    stmt(IRStmt_Put(OFFB_PC, e));
   1276 }
   1277 
   1278 static IRExpr *mkWidenFrom32(IRType ty, IRExpr * src, Bool sined)
   1279 {
   1280    vassert(ty == Ity_I32 || ty == Ity_I64);
   1281    if (ty == Ity_I32)
   1282       return src;
   1283    return (sined) ? unop(Iop_32Sto64, src) : unop(Iop_32Uto64, src);
   1284 }
   1285 
   1286 /* Narrow 8/16/32 bit int expr to 8/16/32.  Clearly only some
   1287    of these combinations make sense. */
   1288 static IRExpr *narrowTo(IRType dst_ty, IRExpr * e)
   1289 {
   1290    IRType src_ty = typeOfIRExpr(irsb->tyenv, e);
   1291    if (src_ty == dst_ty)
   1292       return e;
   1293    if (src_ty == Ity_I32 && dst_ty == Ity_I16)
   1294       return unop(Iop_32to16, e);
   1295    if (src_ty == Ity_I32 && dst_ty == Ity_I8)
   1296       return unop(Iop_32to8, e);
   1297    if (src_ty == Ity_I64 && dst_ty == Ity_I8) {
   1298       vassert(mode64);
   1299       return unop(Iop_64to8, e);
   1300    }
   1301    if (src_ty == Ity_I64 && dst_ty == Ity_I16) {
   1302       vassert(mode64);
   1303       return unop(Iop_64to16, e);
   1304    }
   1305    vpanic("narrowTo(mips)");
   1306    return 0;
   1307 }
   1308 
   1309 static IRExpr *getLoFromF64(IRType ty, IRExpr * src)
   1310 {
   1311    vassert(ty == Ity_F32 || ty == Ity_F64);
   1312    if (ty == Ity_F64) {
   1313       IRTemp t0, t1;
   1314       t0 = newTemp(Ity_I64);
   1315       t1 = newTemp(Ity_I32);
   1316       assign(t0, unop(Iop_ReinterpF64asI64, src));
   1317       assign(t1, unop(Iop_64to32, mkexpr(t0)));
   1318       return unop(Iop_ReinterpI32asF32, mkexpr(t1));
   1319    } else
   1320       return src;
   1321 }
   1322 
   1323 static IRExpr *mkWidenFromF32(IRType ty, IRExpr * src)
   1324 {
   1325    vassert(ty == Ity_F32 || ty == Ity_F64);
   1326    if (ty == Ity_F64) {
   1327       IRTemp t0 = newTemp(Ity_I32);
   1328       IRTemp t1 = newTemp(Ity_I64);
   1329       assign(t0, unop(Iop_ReinterpF32asI32, src));
   1330       assign(t1, binop(Iop_32HLto64, mkU32(0x0), mkexpr(t0)));
   1331       return unop(Iop_ReinterpI64asF64, mkexpr(t1));
   1332    } else
   1333       return src;
   1334 }
   1335 
   1336 static IRExpr *dis_branch_likely(IRExpr * guard, UInt imm)
   1337 {
   1338    ULong branch_offset;
   1339    IRTemp t0;
   1340 
   1341    /* PC = PC + (SignExtend(signed_immed_24) << 2)
   1342       An 18-bit signed offset (the 16-bit offset field shifted left 2 bits)
   1343       is added to the address of the instruction following
   1344       the branch (not the branch itself), in the branch delay slot, to form
   1345       a PC-relative effective target address. */
   1346    if (mode64)
   1347       branch_offset = extend_s_18to64(imm << 2);
   1348    else
   1349       branch_offset = extend_s_18to32(imm << 2);
   1350 
   1351    t0 = newTemp(Ity_I1);
   1352    assign(t0, guard);
   1353 
   1354    if (mode64)
   1355       stmt(IRStmt_Exit(mkexpr(t0), Ijk_Boring,
   1356                        IRConst_U64(guest_PC_curr_instr + 8), OFFB_PC));
   1357    else
   1358       stmt(IRStmt_Exit(mkexpr(t0), Ijk_Boring,
   1359                        IRConst_U32(guest_PC_curr_instr + 8), OFFB_PC));
   1360 
   1361    irsb->jumpkind = Ijk_Boring;
   1362 
   1363    if (mode64)
   1364       return mkU64(guest_PC_curr_instr + 4 + branch_offset);
   1365    else
   1366       return mkU32(guest_PC_curr_instr + 4 + branch_offset);
   1367 }
   1368 
   1369 static void dis_branch(Bool link, IRExpr * guard, UInt imm, IRStmt ** set)
   1370 {
   1371    ULong branch_offset;
   1372    IRTemp t0;
   1373 
   1374    if (link) {  /* LR (GPR31) = addr of the 2nd instr after branch instr */
   1375       if (mode64)
   1376          putIReg(31, mkU64(guest_PC_curr_instr + 8));
   1377       else
   1378          putIReg(31, mkU32(guest_PC_curr_instr + 8));
   1379    }
   1380 
   1381    /* PC = PC + (SignExtend(signed_immed_24) << 2)
   1382       An 18-bit signed offset (the 16-bit offset field shifted left 2 bits)
   1383       is added to the address of the instruction following
   1384       the branch (not the branch itself), in the branch delay slot, to form
   1385       a PC-relative effective target address. */
   1386 
   1387    if (mode64)
   1388       branch_offset = extend_s_18to64(imm << 2);
   1389    else
   1390       branch_offset = extend_s_18to32(imm << 2);
   1391 
   1392    t0 = newTemp(Ity_I1);
   1393    assign(t0, guard);
   1394    if (mode64)
   1395       *set = IRStmt_Exit(mkexpr(t0), link ? Ijk_Call : Ijk_Boring,
   1396                          IRConst_U64(guest_PC_curr_instr + 4 + branch_offset),
   1397                          OFFB_PC);
   1398    else
   1399       *set = IRStmt_Exit(mkexpr(t0), link ? Ijk_Call : Ijk_Boring,
   1400                          IRConst_U32(guest_PC_curr_instr + 4 +
   1401                                      (UInt) branch_offset), OFFB_PC);
   1402 }
   1403 
   1404 static IRExpr *getFReg(UInt fregNo)
   1405 {
   1406    vassert(fregNo < 32);
   1407    IRType ty = fp_mode64 ? Ity_F64 : Ity_F32;
   1408    return IRExpr_Get(floatGuestRegOffset(fregNo), ty);
   1409 }
   1410 
   1411 static IRExpr *getDReg(UInt dregNo)
   1412 {
   1413    vassert(dregNo < 32);
   1414    if (fp_mode64) {
   1415       return IRExpr_Get(floatGuestRegOffset(dregNo), Ity_F64);
   1416    } else {
   1417       /* Read a floating point register pair and combine their contents into a
   1418          64-bit value */
   1419       IRTemp t0 = newTemp(Ity_F32);
   1420       IRTemp t1 = newTemp(Ity_F32);
   1421       IRTemp t2 = newTemp(Ity_F64);
   1422       IRTemp t3 = newTemp(Ity_I32);
   1423       IRTemp t4 = newTemp(Ity_I32);
   1424       IRTemp t5 = newTemp(Ity_I64);
   1425 
   1426       assign(t0, getFReg(dregNo));
   1427       assign(t1, getFReg(dregNo + 1));
   1428 
   1429       assign(t3, unop(Iop_ReinterpF32asI32, mkexpr(t0)));
   1430       assign(t4, unop(Iop_ReinterpF32asI32, mkexpr(t1)));
   1431       assign(t5, binop(Iop_32HLto64, mkexpr(t4), mkexpr(t3)));
   1432       assign(t2, unop(Iop_ReinterpI64asF64, mkexpr(t5)));
   1433 
   1434       return mkexpr(t2);
   1435    }
   1436 }
   1437 
   1438 static void putFReg(UInt dregNo, IRExpr * e)
   1439 {
   1440    vassert(dregNo < 32);
   1441    IRType ty = fp_mode64 ? Ity_F64 : Ity_F32;
   1442    vassert(typeOfIRExpr(irsb->tyenv, e) == ty);
   1443    stmt(IRStmt_Put(floatGuestRegOffset(dregNo), e));
   1444 }
   1445 
   1446 static void putDReg(UInt dregNo, IRExpr * e)
   1447 {
   1448    if (fp_mode64) {
   1449       vassert(dregNo < 32);
   1450       IRType ty = Ity_F64;
   1451       vassert(typeOfIRExpr(irsb->tyenv, e) == ty);
   1452       stmt(IRStmt_Put(floatGuestRegOffset(dregNo), e));
   1453    } else {
   1454       vassert(dregNo < 32);
   1455       vassert(typeOfIRExpr(irsb->tyenv, e) == Ity_F64);
   1456       IRTemp t1 = newTemp(Ity_F64);
   1457       IRTemp t4 = newTemp(Ity_I32);
   1458       IRTemp t5 = newTemp(Ity_I32);
   1459       IRTemp t6 = newTemp(Ity_I64);
   1460       assign(t1, e);
   1461       assign(t6, unop(Iop_ReinterpF64asI64, mkexpr(t1)));
   1462       assign(t4, unop(Iop_64HIto32, mkexpr(t6)));  /* hi */
   1463       assign(t5, unop(Iop_64to32, mkexpr(t6)));    /* lo */
   1464       putFReg(dregNo, unop(Iop_ReinterpI32asF32, mkexpr(t5)));
   1465       putFReg(dregNo + 1, unop(Iop_ReinterpI32asF32, mkexpr(t4)));
   1466    }
   1467 }
   1468 
   1469 static void setFPUCondCode(IRExpr * e, UInt cc)
   1470 {
   1471    if (cc == 0) {
   1472       putFCSR(binop(Iop_And32, getFCSR(), mkU32(0xFF7FFFFF)));
   1473       putFCSR(binop(Iop_Or32, getFCSR(), binop(Iop_Shl32, e, mkU8(23))));
   1474    } else {
   1475       putFCSR(binop(Iop_And32, getFCSR(), unop(Iop_Not32,
   1476                                binop(Iop_Shl32, mkU32(0x01000000), mkU8(cc)))));
   1477       putFCSR(binop(Iop_Or32, getFCSR(), binop(Iop_Shl32, e, mkU8(24 + cc))));
   1478    }
   1479 }
   1480 
   1481 static IRExpr* get_IR_roundingmode ( void )
   1482 {
   1483 /*
   1484    rounding mode | MIPS | IR
   1485    ------------------------
   1486    to nearest    | 00  | 00
   1487    to zero       | 01  | 11
   1488    to +infinity  | 10  | 10
   1489    to -infinity  | 11  | 01
   1490 */
   1491    IRTemp rm_MIPS = newTemp(Ity_I32);
   1492    /* Last two bits in FCSR are rounding mode. */
   1493 
   1494    if (mode64)
   1495       assign(rm_MIPS, binop(Iop_And32, IRExpr_Get(offsetof(VexGuestMIPS64State,
   1496                                        guest_FCSR), Ity_I32), mkU32(3)));
   1497    else
   1498       assign(rm_MIPS, binop(Iop_And32, IRExpr_Get(offsetof(VexGuestMIPS32State,
   1499                                        guest_FCSR), Ity_I32), mkU32(3)));
   1500 
   1501    /* rm_IR = XOR( rm_MIPS32, (rm_MIPS32 << 1) & 2) */
   1502 
   1503    return binop(Iop_Xor32, mkexpr(rm_MIPS), binop(Iop_And32,
   1504                 binop(Iop_Shl32, mkexpr(rm_MIPS), mkU8(1)), mkU32(2)));
   1505 }
   1506 
   1507 /* sz, ULong -> IRExpr */
   1508 static IRExpr *mkSzImm ( IRType ty, ULong imm64 )
   1509 {
   1510    vassert(ty == Ity_I32 || ty == Ity_I64);
   1511    return ty == Ity_I64 ? mkU64(imm64) : mkU32((UInt) imm64);
   1512 }
   1513 
   1514 static IRConst *mkSzConst ( IRType ty, ULong imm64 )
   1515 {
   1516    vassert(ty == Ity_I32 || ty == Ity_I64);
   1517    return (ty == Ity_I64 ? IRConst_U64(imm64) : IRConst_U32((UInt) imm64));
   1518 }
   1519 
   1520 /* Make sure we get valid 32 and 64bit addresses */
   1521 static Addr64 mkSzAddr ( IRType ty, Addr64 addr )
   1522 {
   1523    vassert(ty == Ity_I32 || ty == Ity_I64);
   1524    return (ty == Ity_I64 ? (Addr64) addr :
   1525                            (Addr64) extend_s_32to64(toUInt(addr)));
   1526 }
   1527 
   1528 /* Shift and Rotate instructions for MIPS64 */
   1529 static Bool dis_instr_shrt ( UInt theInstr )
   1530 {
   1531    UInt opc2 = get_function(theInstr);
   1532    UChar regRs = get_rs(theInstr);
   1533    UChar regRt = get_rt(theInstr);
   1534    UChar regRd = get_rd(theInstr);
   1535    UChar uImmsa = get_sa(theInstr);
   1536    Long sImmsa = extend_s_16to64(uImmsa);
   1537    IRType ty = mode64 ? Ity_I64 : Ity_I32;
   1538    IRTemp tmp = newTemp(ty);
   1539    IRTemp tmpOr = newTemp(ty);
   1540    IRTemp tmpRt = newTemp(ty);
   1541    IRTemp tmpRs = newTemp(ty);
   1542    IRTemp tmpRd = newTemp(ty);
   1543 
   1544    assign(tmpRs, getIReg(regRs));
   1545    assign(tmpRt, getIReg(regRt));
   1546 
   1547    switch (opc2) {
   1548       case 0x3A:
   1549          if ((regRs & 0x01) == 0) {
   1550             /* Doubleword Shift Right Logical - DSRL; MIPS64 */
   1551             DIP("dsrl r%u, r%u, %d", regRd, regRt, (Int)sImmsa);
   1552             assign(tmpRd, binop(Iop_Shr64, mkexpr(tmpRt), mkU8(uImmsa)));
   1553             putIReg(regRd, mkexpr(tmpRd));
   1554          } else if ((regRs & 0x01) == 1) {
   1555             /* Doubleword Rotate Right - DROTR; MIPS64r2 */
   1556             vassert(mode64);
   1557             DIP("drotr r%u, r%u, %d", regRd, regRt, (Int)sImmsa);
   1558             IRTemp tmpL = newTemp(ty);
   1559             IRTemp tmpR = newTemp(ty);
   1560             assign(tmpR, binop(Iop_Shr64, mkexpr(tmpRt), mkU8(uImmsa)));
   1561             assign(tmp, binop(Iop_Shl64, mkexpr(tmpRt), mkU8(63 - uImmsa)));
   1562             assign(tmpL, binop(Iop_Shl64, mkexpr(tmp), mkU8(1)));
   1563             assign(tmpRd, binop(Iop_Or64, mkexpr(tmpL), mkexpr(tmpR)));
   1564             putIReg(regRd, mkexpr(tmpRd));
   1565          } else
   1566             return False;
   1567          break;
   1568 
   1569       case 0x3E:
   1570          if ((regRs & 0x01) == 0) {
   1571             /* Doubleword Shift Right Logical Plus 32 - DSRL32; MIPS64 */
   1572             DIP("dsrl32 r%u, r%u, %d", regRd, regRt, (Int)(sImmsa + 32));
   1573             assign(tmpRd, binop(Iop_Shr64, mkexpr(tmpRt), mkU8(uImmsa + 32)));
   1574             putIReg(regRd, mkexpr(tmpRd));
   1575          } else if ((regRs & 0x01) == 1) {
   1576             /* Doubleword Rotate Right Plus 32 - DROTR32; MIPS64r2 */
   1577             DIP("drotr32 r%u, r%u, %d", regRd, regRt, (Int)sImmsa);
   1578             vassert(mode64);
   1579             IRTemp tmpL = newTemp(ty);
   1580             IRTemp tmpR = newTemp(ty);
   1581             /* (tmpRt >> sa) | (tmpRt << (64 - sa)) */
   1582             assign(tmpR, binop(Iop_Shr64, mkexpr(tmpRt), mkU8(uImmsa + 32)));
   1583             assign(tmp, binop(Iop_Shl64, mkexpr(tmpRt),
   1584                               mkU8(63 - (uImmsa + 32))));
   1585             assign(tmpL, binop(Iop_Shl64, mkexpr(tmp), mkU8(1)));
   1586             assign(tmpRd, binop(Iop_Or64, mkexpr(tmpL), mkexpr(tmpR)));
   1587             putIReg(regRd, mkexpr(tmpRd));
   1588          } else
   1589             return False;
   1590          break;
   1591 
   1592       case 0x16:
   1593          if ((uImmsa & 0x01) == 0) {
   1594             /* Doubleword Shift Right Logical Variable - DSRLV; MIPS64 */
   1595             DIP("dsrlv r%u, r%u, r%u", regRd, regRt, regRs);
   1596             IRTemp tmpRs8 = newTemp(Ity_I8);
   1597             /* s = tmpRs[5..0] */
   1598             assign(tmp, binop(Iop_And64, mkexpr(tmpRs), mkU64(63)));
   1599             assign(tmpRs8, mkNarrowTo8(ty, mkexpr(tmp)));
   1600             assign(tmpRd, binop(Iop_Shr64, mkexpr(tmpRt), mkexpr(tmpRs8)));
   1601             putIReg(regRd, mkexpr(tmpRd));
   1602          } else if ((uImmsa & 0x01) == 1) {
   1603             /* Doubleword Rotate Right Variable - DROTRV; MIPS64r2 */
   1604             DIP("drotrv r%u, r%u, r%u", regRd, regRt, regRs);
   1605             IRTemp tmpL = newTemp(ty);
   1606             IRTemp tmpR = newTemp(ty);
   1607             IRTemp tmpRs8 = newTemp(Ity_I8);
   1608             IRTemp tmpLs8 = newTemp(Ity_I8);
   1609             IRTemp tmp64 = newTemp(ty);
   1610             /* s = tmpRs[5...0]
   1611                m = 64 - s
   1612                (tmpRt << s) | (tmpRt >> m) */
   1613 
   1614             assign(tmp64, binop(Iop_And64, mkexpr(tmpRs), mkSzImm(ty, 63)));
   1615             assign(tmp, binop(Iop_Sub64, mkU64(63), mkexpr(tmp64)));
   1616 
   1617             assign(tmpLs8, mkNarrowTo8(ty, mkexpr(tmp)));
   1618             assign(tmpRs8, mkNarrowTo8(ty, mkexpr(tmp64)));
   1619 
   1620             assign(tmpR, binop(Iop_Shr64, mkexpr(tmpRt), mkexpr(tmpRs8)));
   1621             assign(tmpL, binop(Iop_Shl64, mkexpr(tmpRt), mkexpr(tmpLs8)));
   1622             assign(tmpRd, binop(Iop_Shl64, mkexpr(tmpL), mkU8(1)));
   1623             assign(tmpOr, binop(Iop_Or64, mkexpr(tmpRd), mkexpr(tmpR)));
   1624 
   1625             putIReg(regRd, mkexpr(tmpOr));
   1626          } else
   1627             return False;
   1628          break;
   1629 
   1630       case 0x38:  /* Doubleword Shift Left Logical - DSLL; MIPS64 */
   1631          DIP("dsll r%u, r%u, %d", regRd, regRt, (Int)sImmsa);
   1632          vassert(mode64);
   1633          assign(tmpRd, binop(Iop_Shl64, mkexpr(tmpRt), mkU8(uImmsa)));
   1634          putIReg(regRd, mkexpr(tmpRd));
   1635          break;
   1636 
   1637       case 0x3C:  /* Doubleword Shift Left Logical Plus 32 - DSLL32; MIPS64 */
   1638          DIP("dsll32 r%u, r%u, %d", regRd, regRt, (Int)sImmsa);
   1639          assign(tmpRd, binop(Iop_Shl64, mkexpr(tmpRt), mkU8(uImmsa + 32)));
   1640          putIReg(regRd, mkexpr(tmpRd));
   1641          break;
   1642 
   1643       case 0x14: {  /* Doubleword Shift Left Logical Variable - DSLLV; MIPS64 */
   1644          DIP("dsllv r%u, r%u, r%u", regRd, regRt, regRs);
   1645          IRTemp tmpRs8 = newTemp(Ity_I8);
   1646 
   1647          assign(tmp, binop(Iop_And64, mkexpr(tmpRs), mkSzImm(ty, 63)));
   1648          assign(tmpRs8, mkNarrowTo8(ty, mkexpr(tmp)));
   1649          assign(tmpRd, binop(Iop_Shl64, mkexpr(tmpRt), mkexpr(tmpRs8)));
   1650          putIReg(regRd, mkexpr(tmpRd));
   1651          break;
   1652       }
   1653 
   1654       case 0x3B:  /* Doubleword Shift Right Arithmetic - DSRA; MIPS64 */
   1655          DIP("dsra r%u, r%u, %d", regRd, regRt, (Int)sImmsa);
   1656          assign(tmpRd, binop(Iop_Sar64, mkexpr(tmpRt), mkU8(uImmsa)));
   1657          putIReg(regRd, mkexpr(tmpRd));
   1658          break;
   1659 
   1660       case 0x3F:  /* Doubleword Shift Right Arithmetic Plus 32 - DSRA32;
   1661                      MIPS64 */
   1662          DIP("dsra32 r%u, r%u, %d", regRd, regRt, (Int)sImmsa);
   1663          assign(tmpRd, binop(Iop_Sar64, mkexpr(tmpRt), mkU8(uImmsa + 32)));
   1664          putIReg(regRd, mkexpr(tmpRd));
   1665          break;
   1666 
   1667       case 0x17: {  /* Doubleword Shift Right Arithmetic Variable - DSRAV;
   1668                        MIPS64 */
   1669          DIP("dsrav r%u, r%u, r%u", regRd, regRt, regRs);
   1670          IRTemp tmpRs8 = newTemp(Ity_I8);
   1671          assign(tmp, binop(Iop_And64, mkexpr(tmpRs), mkSzImm(ty, 63)));
   1672          assign(tmpRs8, mkNarrowTo8(ty, mkexpr(tmp)));
   1673          assign(tmpRd, binop(Iop_Sar64, mkexpr(tmpRt), mkexpr(tmpRs8)));
   1674          putIReg(regRd, mkexpr(tmpRd));
   1675          break;
   1676 
   1677       }
   1678 
   1679       default:
   1680          return False;
   1681 
   1682    }
   1683    return True;
   1684 }
   1685 
   1686 static IROp mkSzOp ( IRType ty, IROp op8 )
   1687 {
   1688    Int adj;
   1689    vassert(ty == Ity_I8 || ty == Ity_I16 || ty == Ity_I32 || ty == Ity_I64);
   1690    vassert(op8 == Iop_Add8 || op8 == Iop_Sub8 || op8 == Iop_Mul8
   1691            || op8 == Iop_Or8 || op8 == Iop_And8 || op8 == Iop_Xor8
   1692            || op8 == Iop_Shl8 || op8 == Iop_Shr8 || op8 == Iop_Sar8
   1693            || op8 == Iop_CmpEQ8 || op8 == Iop_CmpNE8 || op8 == Iop_Not8);
   1694    adj = ty == Ity_I8 ? 0 : (ty == Ity_I16 ? 1 : (ty == Ity_I32 ? 2 : 3));
   1695    return adj + op8;
   1696 }
   1697 
   1698 /*********************************************************/
   1699 /*---             Floating Point Compare              ---*/
   1700 /*********************************************************/
   1701 /* Function that returns a string that represent mips cond
   1702    mnemonic for the input code. */
   1703 static const HChar* showCondCode(UInt code) {
   1704    const HChar* ret;
   1705    switch (code) {
   1706       case 0: ret = "f"; break;
   1707       case 1: ret = "un"; break;
   1708       case 2: ret = "eq"; break;
   1709       case 3: ret = "ueq"; break;
   1710       case 4: ret = "olt"; break;
   1711       case 5: ret = "ult"; break;
   1712       case 6: ret = "ole"; break;
   1713       case 7: ret = "ule"; break;
   1714       case 8: ret = "sf"; break;
   1715       case 9: ret = "ngle"; break;
   1716       case 10: ret = "seq"; break;
   1717       case 11: ret = "ngl"; break;
   1718       case 12: ret = "lt"; break;
   1719       case 13: ret = "nge"; break;
   1720       case 14: ret = "le"; break;
   1721       case 15: ret = "ngt"; break;
   1722       default: vpanic("showCondCode"); break;
   1723    }
   1724    return ret;
   1725 }
   1726 
   1727 static Bool dis_instr_CCondFmt ( UInt cins )
   1728 {
   1729    IRTemp t0, t1, t2, t3, tmp5, tmp6;
   1730    IRTemp ccIR = newTemp(Ity_I32);
   1731    IRTemp ccMIPS = newTemp(Ity_I32);
   1732    UInt FC = get_FC(cins);
   1733    UInt fmt = get_fmt(cins);
   1734    UInt fs = get_fs(cins);
   1735    UInt ft = get_ft(cins);
   1736    UInt cond = get_cond(cins);
   1737 
   1738    if (FC == 0x3) {  /* C.cond.fmt */
   1739       UInt fpc_cc = get_fpc_cc(cins);
   1740       switch (fmt) {
   1741          case 0x10: {  /* C.cond.S */
   1742             DIP("c.%s.s %d, f%d, f%d", showCondCode(cond), fpc_cc, fs, ft);
   1743             if (fp_mode64) {
   1744                t0 = newTemp(Ity_I32);
   1745                t1 = newTemp(Ity_I32);
   1746                t2 = newTemp(Ity_I32);
   1747                t3 = newTemp(Ity_I32);
   1748 
   1749                tmp5 = newTemp(Ity_F64);
   1750                tmp6 = newTemp(Ity_F64);
   1751 
   1752                assign(tmp5, unop(Iop_F32toF64, getLoFromF64(Ity_F64,
   1753                                  getFReg(fs))));
   1754                assign(tmp6, unop(Iop_F32toF64, getLoFromF64(Ity_F64,
   1755                                  getFReg(ft))));
   1756 
   1757                assign(ccIR, binop(Iop_CmpF64, mkexpr(tmp5), mkexpr(tmp6)));
   1758                putHI(mkWidenFrom32(mode64 ? Ity_I64: Ity_I32,
   1759                                    mkexpr(ccIR), True));
   1760                /* Map compare result from IR to MIPS
   1761                   FP cmp result | MIPS | IR
   1762                   --------------------------
   1763                   UN            | 0x1 | 0x45
   1764                   EQ            | 0x2 | 0x40
   1765                   GT            | 0x4 | 0x00
   1766                   LT            | 0x8 | 0x01
   1767                 */
   1768 
   1769                /* ccMIPS = Shl(1, (~(ccIR>>5) & 2) | ((ccIR ^ (ccIR>>6)) & 1) */
   1770                assign(ccMIPS, binop(Iop_Shl32, mkU32(1), unop(Iop_32to8,
   1771                               binop(Iop_Or32, binop(Iop_And32, unop(Iop_Not32,
   1772                               binop(Iop_Shr32, mkexpr(ccIR),mkU8(5))),mkU32(2)),
   1773                               binop(Iop_And32, binop(Iop_Xor32, mkexpr(ccIR),
   1774                               binop(Iop_Shr32, mkexpr(ccIR), mkU8(6))),
   1775                               mkU32(1))))));
   1776                putLO(mkWidenFrom32(mode64 ? Ity_I64: Ity_I32,
   1777                                    mkexpr(ccMIPS), True));
   1778 
   1779                /* UN */
   1780                assign(t0, binop(Iop_And32, mkexpr(ccMIPS), mkU32(0x1)));
   1781                /* EQ */
   1782                assign(t1, binop(Iop_And32, binop(Iop_Shr32, mkexpr(ccMIPS),
   1783                                                  mkU8(0x1)), mkU32(0x1)));
   1784                /* NGT */
   1785                assign(t2, binop(Iop_And32, unop(Iop_Not32, binop(Iop_Shr32,
   1786                                  mkexpr(ccMIPS), mkU8(0x2))),mkU32(0x1)));
   1787                /* LT */
   1788                assign(t3, binop(Iop_And32, binop(Iop_Shr32, mkexpr(ccMIPS),
   1789                                                  mkU8(0x3)), mkU32(0x1)));
   1790                switch (cond) {
   1791                   case 0x0:
   1792                      setFPUCondCode(mkU32(0), fpc_cc);
   1793                      break;
   1794                   case 0x1:
   1795                      setFPUCondCode(mkexpr(t0), fpc_cc);
   1796                      break;
   1797                   case 0x2:
   1798                      setFPUCondCode(mkexpr(t1), fpc_cc);
   1799                      break;
   1800                   case 0x3:
   1801                      setFPUCondCode(binop(Iop_Or32, mkexpr(t0), mkexpr(t1)),
   1802                                           fpc_cc);
   1803                      break;
   1804                   case 0x4:
   1805                      setFPUCondCode(mkexpr(t3), fpc_cc);
   1806                      break;
   1807                   case 0x5:
   1808                      setFPUCondCode(binop(Iop_Or32, mkexpr(t0), mkexpr(t3)),
   1809                                           fpc_cc);
   1810                      break;
   1811                   case 0x6:
   1812                      setFPUCondCode(binop(Iop_Or32, mkexpr(t3), mkexpr(t1)),
   1813                                           fpc_cc);
   1814                      break;
   1815                   case 0x7:
   1816                      setFPUCondCode(mkexpr(t2), fpc_cc);
   1817                      break;
   1818                   case 0x8:
   1819                      setFPUCondCode(mkU32(0), fpc_cc);
   1820                      break;
   1821                   case 0x9:
   1822                      setFPUCondCode(mkexpr(t0), fpc_cc);
   1823                      break;
   1824                   case 0xA:
   1825                      setFPUCondCode(mkexpr(t1), fpc_cc);
   1826                      break;
   1827                   case 0xB:
   1828                      setFPUCondCode(binop(Iop_Or32, mkexpr(t0), mkexpr(t1)),
   1829                                           fpc_cc);
   1830                      break;
   1831                   case 0xC:
   1832                      setFPUCondCode(mkexpr(t3), fpc_cc);
   1833                      break;
   1834                   case 0xD:
   1835                      setFPUCondCode(binop(Iop_Or32, mkexpr(t0), mkexpr(t3)),
   1836                                           fpc_cc);
   1837                      break;
   1838                   case 0xE:
   1839                      setFPUCondCode(binop(Iop_Or32, mkexpr(t3), mkexpr(t1)),
   1840                                           fpc_cc);
   1841                      break;
   1842                   case 0xF:
   1843                      setFPUCondCode(mkexpr(t2), fpc_cc);
   1844                      break;
   1845 
   1846                   default:
   1847                      return False;
   1848                }
   1849 
   1850             } else {
   1851                t0 = newTemp(Ity_I32);
   1852                t1 = newTemp(Ity_I32);
   1853                t2 = newTemp(Ity_I32);
   1854                t3 = newTemp(Ity_I32);
   1855 
   1856                assign(ccIR, binop(Iop_CmpF64, unop(Iop_F32toF64, getFReg(fs)),
   1857                                   unop(Iop_F32toF64, getFReg(ft))));
   1858                /* Map compare result from IR to MIPS
   1859                   FP cmp result | MIPS | IR
   1860                   --------------------------
   1861                   UN            | 0x1 | 0x45
   1862                   EQ            | 0x2 | 0x40
   1863                   GT            | 0x4 | 0x00
   1864                   LT            | 0x8 | 0x01
   1865                 */
   1866 
   1867                /* ccMIPS = Shl(1, (~(ccIR>>5) & 2) | ((ccIR ^ (ccIR>>6)) & 1) */
   1868                assign(ccMIPS, binop(Iop_Shl32, mkU32(1), unop(Iop_32to8,
   1869                               binop(Iop_Or32, binop(Iop_And32, unop(Iop_Not32,
   1870                               binop(Iop_Shr32, mkexpr(ccIR), mkU8(5))),
   1871                                     mkU32(2)), binop(Iop_And32,
   1872                               binop(Iop_Xor32, mkexpr(ccIR),
   1873                               binop(Iop_Shr32, mkexpr(ccIR), mkU8(6))),
   1874                               mkU32(1))))));
   1875                /* UN */
   1876                assign(t0, binop(Iop_And32, mkexpr(ccMIPS), mkU32(0x1)));
   1877                /* EQ */
   1878                assign(t1, binop(Iop_And32, binop(Iop_Shr32, mkexpr(ccMIPS),
   1879                       mkU8(0x1)), mkU32(0x1)));
   1880                /* NGT */
   1881                assign(t2, binop(Iop_And32, unop(Iop_Not32, binop(Iop_Shr32,
   1882                       mkexpr(ccMIPS), mkU8(0x2))), mkU32(0x1)));
   1883                /* LT */
   1884                assign(t3, binop(Iop_And32, binop(Iop_Shr32, mkexpr(ccMIPS),
   1885                       mkU8(0x3)), mkU32(0x1)));
   1886 
   1887                switch (cond) {
   1888                   case 0x0:
   1889                      setFPUCondCode(mkU32(0), fpc_cc);
   1890                      break;
   1891                   case 0x1:
   1892                      setFPUCondCode(mkexpr(t0), fpc_cc);
   1893                      break;
   1894                   case 0x2:
   1895                      setFPUCondCode(mkexpr(t1), fpc_cc);
   1896                      break;
   1897                   case 0x3:
   1898                      setFPUCondCode(binop(Iop_Or32, mkexpr(t0), mkexpr(t1)),
   1899                                           fpc_cc);
   1900                      break;
   1901                   case 0x4:
   1902                      setFPUCondCode(mkexpr(t3), fpc_cc);
   1903                      break;
   1904                   case 0x5:
   1905                      setFPUCondCode(binop(Iop_Or32, mkexpr(t0), mkexpr(t3)),
   1906                                           fpc_cc);
   1907                      break;
   1908                   case 0x6:
   1909                      setFPUCondCode(binop(Iop_Or32, mkexpr(t3), mkexpr(t1)),
   1910                                           fpc_cc);
   1911                      break;
   1912                   case 0x7:
   1913                      setFPUCondCode(mkexpr(t2), fpc_cc);
   1914                      break;
   1915                   case 0x8:
   1916                      setFPUCondCode(mkU32(0), fpc_cc);
   1917                      break;
   1918                   case 0x9:
   1919                      setFPUCondCode(mkexpr(t0), fpc_cc);
   1920                      break;
   1921                   case 0xA:
   1922                      setFPUCondCode(mkexpr(t1), fpc_cc);
   1923                      break;
   1924                   case 0xB:
   1925                      setFPUCondCode(binop(Iop_Or32, mkexpr(t0), mkexpr(t1)),
   1926                                           fpc_cc);
   1927                      break;
   1928                   case 0xC:
   1929                      setFPUCondCode(mkexpr(t3), fpc_cc);
   1930                      break;
   1931                   case 0xD:
   1932                      setFPUCondCode(binop(Iop_Or32, mkexpr(t0), mkexpr(t3)),
   1933                                           fpc_cc);
   1934                      break;
   1935                   case 0xE:
   1936                      setFPUCondCode(binop(Iop_Or32, mkexpr(t3), mkexpr(t1)),
   1937                                           fpc_cc);
   1938                      break;
   1939                   case 0xF:
   1940                      setFPUCondCode(mkexpr(t2), fpc_cc);
   1941                      break;
   1942 
   1943                   default:
   1944                      return False;
   1945                }
   1946             }
   1947          }
   1948             break;
   1949 
   1950          case 0x11: {  /* C.cond.D */
   1951             DIP("c.%s.d %d, f%d, f%d", showCondCode(cond), fpc_cc, fs, ft);
   1952             t0 = newTemp(Ity_I32);
   1953             t1 = newTemp(Ity_I32);
   1954             t2 = newTemp(Ity_I32);
   1955             t3 = newTemp(Ity_I32);
   1956             assign(ccIR, binop(Iop_CmpF64, getDReg(fs), getDReg(ft)));
   1957             /* Map compare result from IR to MIPS
   1958                FP cmp result | MIPS | IR
   1959                --------------------------
   1960                UN            | 0x1 | 0x45
   1961                EQ            | 0x2 | 0x40
   1962                GT            | 0x4 | 0x00
   1963                LT            | 0x8 | 0x01
   1964              */
   1965 
   1966             /* ccMIPS = Shl(1, (~(ccIR>>5) & 2) | ((ccIR ^ (ccIR>>6)) & 1) */
   1967             assign(ccMIPS, binop(Iop_Shl32, mkU32(1), unop(Iop_32to8,
   1968                            binop(Iop_Or32, binop(Iop_And32, unop(Iop_Not32,
   1969                            binop(Iop_Shr32, mkexpr(ccIR), mkU8(5))), mkU32(2)),
   1970                            binop(Iop_And32, binop(Iop_Xor32, mkexpr(ccIR),
   1971                            binop(Iop_Shr32, mkexpr(ccIR), mkU8(6))),
   1972                            mkU32(1))))));
   1973 
   1974             /* UN */
   1975             assign(t0, binop(Iop_And32, mkexpr(ccMIPS), mkU32(0x1)));
   1976             /* EQ */
   1977             assign(t1, binop(Iop_And32, binop(Iop_Shr32, mkexpr(ccMIPS),
   1978                    mkU8(0x1)), mkU32(0x1)));
   1979             /* NGT */
   1980             assign(t2, binop(Iop_And32, unop(Iop_Not32, binop(Iop_Shr32,
   1981                    mkexpr(ccMIPS), mkU8(0x2))), mkU32(0x1)));
   1982             /* LT */
   1983             assign(t3, binop(Iop_And32, binop(Iop_Shr32, mkexpr(ccMIPS),
   1984                    mkU8(0x3)), mkU32(0x1)));
   1985 
   1986             switch (cond) {
   1987                case 0x0:
   1988                   setFPUCondCode(mkU32(0), fpc_cc);
   1989                   break;
   1990                case 0x1:
   1991                   setFPUCondCode(mkexpr(t0), fpc_cc);
   1992                   break;
   1993                case 0x2:
   1994                   setFPUCondCode(mkexpr(t1), fpc_cc);
   1995                   break;
   1996                case 0x3:
   1997                   setFPUCondCode(binop(Iop_Or32, mkexpr(t0), mkexpr(t1)),
   1998                                        fpc_cc);
   1999                   break;
   2000                case 0x4:
   2001                   setFPUCondCode(mkexpr(t3), fpc_cc);
   2002                   break;
   2003                case 0x5:
   2004                   setFPUCondCode(binop(Iop_Or32, mkexpr(t0), mkexpr(t3)),
   2005                                        fpc_cc);
   2006                   break;
   2007                case 0x6:
   2008                   setFPUCondCode(binop(Iop_Or32, mkexpr(t3), mkexpr(t1)),
   2009                                        fpc_cc);
   2010                   break;
   2011                case 0x7:
   2012                   setFPUCondCode(mkexpr(t2), fpc_cc);
   2013                   break;
   2014                case 0x8:
   2015                   setFPUCondCode(mkU32(0), fpc_cc);
   2016                   break;
   2017                case 0x9:
   2018                   setFPUCondCode(mkexpr(t0), fpc_cc);
   2019                   break;
   2020                case 0xA:
   2021                   setFPUCondCode(mkexpr(t1), fpc_cc);
   2022                   break;
   2023                case 0xB:
   2024                   setFPUCondCode(binop(Iop_Or32, mkexpr(t0), mkexpr(t1)),
   2025                                        fpc_cc);
   2026                   break;
   2027                case 0xC:
   2028                   setFPUCondCode(mkexpr(t3), fpc_cc);
   2029                   break;
   2030                case 0xD:
   2031                   setFPUCondCode(binop(Iop_Or32, mkexpr(t0), mkexpr(t3)),
   2032                                        fpc_cc);
   2033                   break;
   2034                case 0xE:
   2035                   setFPUCondCode(binop(Iop_Or32, mkexpr(t3), mkexpr(t1)),
   2036                                        fpc_cc);
   2037                   break;
   2038                case 0xF:
   2039                   setFPUCondCode(mkexpr(t2), fpc_cc);
   2040                   break;
   2041                default:
   2042                   return False;
   2043             }
   2044          }
   2045          break;
   2046 
   2047          default:
   2048             return False;
   2049       }
   2050    } else {
   2051       return False;
   2052    }
   2053 
   2054    return True;
   2055 }
   2056 
   2057 /*********************************************************/
   2058 /*---        Branch Instructions for mips64           ---*/
   2059 /*********************************************************/
   2060 static Bool dis_instr_branch ( UInt theInstr, DisResult * dres,
   2061                                Bool(*resteerOkFn) (void *, Addr64),
   2062                                void *callback_opaque, IRStmt ** set )
   2063 {
   2064    UInt jmpKind = 0;
   2065    UChar opc1 = get_opcode(theInstr);
   2066    UChar regRs = get_rs(theInstr);
   2067    UChar regRt = get_rt(theInstr);
   2068    UInt offset = get_imm(theInstr);
   2069    Long sOffset = extend_s_16to64(offset);
   2070    IRType ty = mode64 ? Ity_I64 : Ity_I32;
   2071    IROp opSlt = mode64 ? Iop_CmpLT64S : Iop_CmpLT32S;
   2072 
   2073    IRTemp tmp = newTemp(ty);
   2074    IRTemp tmpRs = newTemp(ty);
   2075    IRTemp tmpRt = newTemp(ty);
   2076    IRTemp tmpLt = newTemp(ty);
   2077    IRTemp tmpReg0 = newTemp(ty);
   2078 
   2079    UChar regLnk = 31;   /* reg 31 is link reg in MIPS */
   2080    Addr64 addrTgt = 0;
   2081    Addr64 cia = guest_PC_curr_instr;
   2082 
   2083    IRExpr *eConst0 = mkSzImm(ty, (UInt) 0);
   2084    IRExpr *eNia = mkSzImm(ty, cia + 8);
   2085    IRExpr *eCond = NULL;
   2086 
   2087    assign(tmpRs, getIReg(regRs));
   2088    assign(tmpRt, getIReg(regRt));
   2089    assign(tmpReg0, getIReg(0));
   2090 
   2091    eCond = binop(mkSzOp(ty, Iop_CmpNE8), mkexpr(tmpReg0), mkexpr(tmpReg0));
   2092 
   2093    switch (opc1) {
   2094       case 0x01:
   2095          switch (regRt) {
   2096             case 0x00: {  /* BLTZ rs, offset */
   2097                addrTgt = mkSzAddr(ty, cia + 4 + (sOffset << 2));
   2098                IRTemp tmpLtRes = newTemp(Ity_I1);
   2099 
   2100                assign(tmp, eConst0);
   2101                assign(tmpLtRes, binop(opSlt, mkexpr(tmpRs), mkexpr(tmp)));
   2102                assign(tmpLt, mode64 ? unop(Iop_1Uto64, mkexpr(tmpLtRes)) :
   2103                       unop(Iop_1Uto32, mkexpr(tmpLtRes)));
   2104 
   2105                eCond = binop(mkSzOp(ty, Iop_CmpNE8), mkexpr(tmpLt),
   2106                              mkexpr(tmpReg0));
   2107 
   2108                jmpKind = Ijk_Call;
   2109                break;
   2110             }
   2111 
   2112             case 0x01: {  /* BGEZ rs, offset */
   2113                IRTemp tmpLtRes = newTemp(Ity_I1);
   2114                addrTgt = mkSzAddr(ty, cia + 4 + (sOffset << 2));
   2115 
   2116                assign(tmp, eConst0);
   2117                assign(tmpLtRes, binop(opSlt, mkexpr(tmpRs), mkexpr(tmp)));
   2118                assign(tmpLt, mode64 ? unop(Iop_1Uto64, mkexpr(tmpLtRes)) :
   2119                                       unop(Iop_1Uto32, mkexpr(tmpLtRes)));
   2120                eCond = binop(mkSzOp(ty, Iop_CmpEQ8), mkexpr(tmpLt),
   2121                                     mkexpr(tmpReg0));
   2122 
   2123                jmpKind = Ijk_Call;
   2124                break;
   2125             }
   2126 
   2127             case 0x11: {  /* BGEZAL rs, offset */
   2128                addrTgt = mkSzAddr(ty, cia + 4 + (sOffset << 2));
   2129                putIReg(regLnk, eNia);
   2130                IRTemp tmpLtRes = newTemp(Ity_I1);
   2131 
   2132                assign(tmpLtRes, binop(opSlt, mkexpr(tmpRs), eConst0));
   2133                assign(tmpLt, mode64 ? unop(Iop_1Uto64, mkexpr(tmpLtRes)) :
   2134                                       unop(Iop_1Uto32, mkexpr(tmpLtRes)));
   2135 
   2136                eCond = binop(mkSzOp(ty, Iop_CmpEQ8), mkexpr(tmpLt),
   2137                                     mkexpr(tmpReg0));
   2138 
   2139                jmpKind = Ijk_Call;
   2140                break;
   2141             }
   2142 
   2143             case 0x10: {  /* BLTZAL rs, offset */
   2144                IRTemp tmpLtRes = newTemp(Ity_I1);
   2145                IRTemp tmpRes = newTemp(ty);
   2146 
   2147                addrTgt = mkSzAddr(ty, cia + 4 + (sOffset << 2));
   2148                putIReg(regLnk, eNia);
   2149 
   2150                assign(tmp, eConst0);
   2151                assign(tmpLtRes, binop(opSlt, mkexpr(tmpRs), mkexpr(tmp)));
   2152                assign(tmpRes, mode64 ? unop(Iop_1Uto64,
   2153                       mkexpr(tmpLtRes)) : unop(Iop_1Uto32, mkexpr(tmpLtRes)));
   2154                eCond = binop(mkSzOp(ty, Iop_CmpNE8), mkexpr(tmpRes),
   2155                                                      mkexpr(tmpReg0));
   2156 
   2157                jmpKind = Ijk_Call;
   2158                break;
   2159             }
   2160 
   2161          }
   2162          break;
   2163       default:
   2164          return False;
   2165       }
   2166    *set = IRStmt_Exit(eCond, jmpKind, mkSzConst(ty, addrTgt), OFFB_PC);
   2167    return True;
   2168 }
   2169 
   2170 /*********************************************************/
   2171 /*---         Cavium Specific Instructions            ---*/
   2172 /*********************************************************/
   2173 static Bool dis_instr_CVM ( UInt theInstr )
   2174 {
   2175    UChar  opc2     = get_function(theInstr);
   2176    UChar  opc1     = get_opcode(theInstr);
   2177    UChar  regRs    = get_rs(theInstr);
   2178    UChar  regRt    = get_rt(theInstr);
   2179    UChar  regRd    = get_rd(theInstr);
   2180    UInt   imm 	   = get_imm(theInstr);
   2181    UChar  lenM1    = get_msb(theInstr);
   2182    UChar  p        = get_lsb(theInstr);
   2183    IRType ty       = mode64? Ity_I64 : Ity_I32;
   2184    IRTemp tmp      = newTemp(ty);
   2185    IRTemp tmpRs    = newTemp(ty);
   2186    IRTemp tmpRt    = newTemp(ty);
   2187    IRTemp t1       = newTemp(ty);
   2188    UInt size;
   2189    assign(tmpRs, getIReg(regRs));
   2190 
   2191    switch(opc1){
   2192       case 0x1C:  {
   2193          switch(opc2) {
   2194             case 0x03: {  /* DMUL rd, rs, rt */
   2195                DIP("dmul r%d, r%d, r%d", regRd, regRs, regRt);
   2196                IRType t0 = newTemp(Ity_I128);
   2197                assign(t0, binop(Iop_MullU64, getIReg(regRs), getIReg(regRt)));
   2198                putIReg(regRd, unop(Iop_128to64, mkexpr(t0)));
   2199                break;
   2200             }
   2201 
   2202             case 0x32:  /* 5. CINS rd, rs, p, lenm1 */
   2203                DIP("cins r%u, r%u, %d, %d\n", regRt, regRs, p, lenM1);
   2204                assign ( tmp  , binop(Iop_Shl64, mkexpr(tmpRs),
   2205                                      mkU8(64-( lenM1+1 ))));
   2206                assign ( tmpRt, binop(Iop_Shr64, mkexpr( tmp ),
   2207                                      mkU8(64-(p+lenM1+1))));
   2208                putIReg( regRt, mkexpr(tmpRt));
   2209                break;
   2210 
   2211             case 0x33:  /* 6. CINS32 rd, rs, p+32, lenm1 */
   2212                DIP("cins32 r%u, r%u, %d, %d\n", regRt, regRs, p+32, lenM1);
   2213                assign ( tmp  , binop(Iop_Shl64, mkexpr(tmpRs),
   2214                                      mkU8(64-( lenM1+1 ))));
   2215                assign ( tmpRt, binop(Iop_Shr64, mkexpr( tmp ),
   2216                                      mkU8(32-(p+lenM1+1))));
   2217                putIReg( regRt, mkexpr(tmpRt));
   2218                break;
   2219 
   2220             case 0x3A:  /* 3. EXTS rt, rs, p len */
   2221                DIP("exts r%u, r%u, %d, %d\n", regRt, regRs, p, lenM1);
   2222                size = lenM1 + 1;  /* lenm1+1 */
   2223                UChar lsAmt = 64 - (p + size);  /* p+lenm1+1 */
   2224                UChar rsAmt = 64 - size;  /* lenm1+1 */
   2225                tmp = newTemp(Ity_I64);
   2226                assign(tmp, binop(Iop_Shl64, mkexpr(tmpRs), mkU8(lsAmt)));
   2227                putIReg(regRt, binop(Iop_Sar64, mkexpr(tmp), mkU8(rsAmt)));
   2228                break;
   2229 
   2230             case 0x3B:  /* 4. EXTS32 rt, rs, p len */
   2231                DIP("exts32 r%u, r%u, %d, %d\n", regRt, regRs, p, lenM1);
   2232                assign ( tmp  , binop(Iop_Shl64, mkexpr(tmpRs),
   2233                                      mkU8(32-(p+lenM1+1))));
   2234                assign ( tmpRt, binop(Iop_Sar64, mkexpr(tmp),
   2235                                      mkU8(64-(lenM1+1))) );
   2236                putIReg( regRt, mkexpr(tmpRt));
   2237                break;
   2238 
   2239             case 0x2B:  /* 20. SNE rd, rs, rt */
   2240                DIP("sne r%d, r%d, r%d", regRd,regRs, regRt);
   2241                if (mode64)
   2242                   putIReg(regRd, unop(Iop_1Uto64, binop(Iop_CmpNE64,
   2243                                                         getIReg(regRs),
   2244                                                         getIReg(regRt))));
   2245                else
   2246                   putIReg(regRd,unop(Iop_1Uto32, binop(Iop_CmpNE32,
   2247                                                        getIReg(regRs),
   2248                                                        getIReg(regRt))));
   2249                break;
   2250 
   2251             case 0x2A:  /* Set Equals - SEQ; Cavium OCTEON */
   2252                DIP("seq r%d, r%d, %d", regRd, regRs, regRt);
   2253                if (mode64)
   2254                   putIReg(regRd, unop(Iop_1Uto64,
   2255                                       binop(Iop_CmpEQ64, getIReg(regRs),
   2256                                             getIReg(regRt))));
   2257                else
   2258                   putIReg(regRd, unop(Iop_1Uto32,
   2259                                       binop(Iop_CmpEQ32, getIReg(regRs),
   2260                                             getIReg(regRt))));
   2261                break;
   2262 
   2263             case 0x2E:  /* Set Equals Immediate - SEQI; Cavium OCTEON */
   2264                DIP("seqi r%d, r%d, %d", regRt, regRs, imm);
   2265                if (mode64)
   2266                   putIReg(regRt, unop(Iop_1Uto64,
   2267                                       binop(Iop_CmpEQ64, getIReg(regRs),
   2268                                             mkU64(extend_s_10to64(imm)))));
   2269                else
   2270                   putIReg(regRt, unop(Iop_1Uto32,
   2271                                       binop(Iop_CmpEQ32, getIReg(regRs),
   2272                                             mkU32(extend_s_10to32(imm)))));
   2273                break;
   2274 
   2275             case 0x2F:  /* Set Not Equals Immediate - SNEI; Cavium OCTEON */
   2276                DIP("snei r%d, r%d, %d", regRt, regRs, imm);
   2277                if (mode64)
   2278                   putIReg(regRt, unop(Iop_1Uto64,
   2279                                    binop(Iop_CmpNE64,
   2280                                          getIReg(regRs),
   2281                                          mkU64(extend_s_10to64(imm)))));
   2282                else
   2283                   putIReg(regRt, unop(Iop_1Uto32,
   2284                                    binop(Iop_CmpNE32,
   2285                                          getIReg(regRs),
   2286                                          mkU32(extend_s_10to32(imm)))));
   2287                break;
   2288 
   2289             default:
   2290                return False;
   2291          }
   2292          break;
   2293       } /* opc1 0x1C ends here*/
   2294       case 0x1F:{
   2295          switch(opc2) {
   2296             case 0x0A: {  // lx - Load indexed instructions
   2297                switch (get_sa(theInstr)) {
   2298                   case 0x00: {  // LWX rd, index(base)
   2299                      DIP("lwx r%d, r%d(r%d)", regRd, regRt, regRs);
   2300                      LOADX_STORE_PATTERN;
   2301                      putIReg(regRd, mkWidenFrom32(ty, load(Ity_I32, mkexpr(t1)),
   2302                                                   True));
   2303                      break;
   2304                   }
   2305                   case 0x08: {  // LDX rd, index(base)
   2306                      DIP("ldx r%d, r%d(r%d)", regRd, regRt, regRs);
   2307                      vassert(mode64); /* Currently Implemented only for n64 */
   2308                      LOADX_STORE_PATTERN;
   2309                      putIReg(regRd, load(Ity_I64, mkexpr(t1)));
   2310                      break;
   2311                   }
   2312                   case 0x06: {  // LBUX rd, index(base)
   2313                      DIP("lbux r%d, r%d(r%d)", regRd, regRt, regRs);
   2314                      LOADX_STORE_PATTERN;
   2315                      if (mode64)
   2316                         putIReg(regRd, unop(Iop_8Uto64, load(Ity_I8,
   2317                                                              mkexpr(t1))));
   2318                      else
   2319                         putIReg(regRd, unop(Iop_8Uto32, load(Ity_I8,
   2320                                                              mkexpr(t1))));
   2321                      break;
   2322                   }
   2323                   case 0x10: {  // LWUX rd, index(base) (Cavium OCTEON)
   2324                      DIP("lwux r%d, r%d(r%d)", regRd, regRt, regRs);
   2325                      LOADX_STORE_PATTERN; /* same for both 32 and 64 modes*/
   2326                      putIReg(regRd, mkWidenFrom32(ty, load(Ity_I32, mkexpr(t1)),
   2327                                                   False));
   2328                      break;
   2329                   }
   2330                   case 0x14: {  // LHUX rd, index(base) (Cavium OCTEON)
   2331                      DIP("lhux r%d, r%d(r%d)", regRd, regRt, regRs);
   2332                      LOADX_STORE_PATTERN;
   2333                      if (mode64)
   2334                         putIReg(regRd,
   2335                                 unop(Iop_16Uto64, load(Ity_I16, mkexpr(t1))));
   2336                      else
   2337                         putIReg(regRd,
   2338                                 unop(Iop_16Uto32, load(Ity_I16, mkexpr(t1))));
   2339                      break;
   2340                   }
   2341                   case 0x16: {  // LBX rd, index(base) (Cavium OCTEON)
   2342                      DIP("lbx r%d, r%d(r%d)", regRd, regRs, regRt);
   2343                      LOADX_STORE_PATTERN;
   2344                      if (mode64)
   2345                         putIReg(regRd,
   2346                                 unop(Iop_8Sto64, load(Ity_I8, mkexpr(t1))));
   2347                      else
   2348                         putIReg(regRd,
   2349                                 unop(Iop_8Sto32, load(Ity_I8, mkexpr(t1))));
   2350                      break;
   2351                   }
   2352                   default:
   2353                      vex_printf("\nUnhandled LX instruction opc3 = %x\n",
   2354                                 get_sa(theInstr));
   2355                      return False;
   2356                }
   2357                break;
   2358             }
   2359          } /* opc1 = 0x1F & opc2 = 0xA (LX) ends here*/
   2360          break;
   2361       } /* opc1 = 0x1F ends here*/
   2362       default:
   2363          return False;
   2364    } /* main opc1 switch ends here */
   2365    return True;
   2366 }
   2367 
   2368 /*------------------------------------------------------------*/
   2369 /*---       Disassemble a single DSP ASE instruction       ---*/
   2370 /*------------------------------------------------------------*/
   2371 
   2372 static UInt disDSPInstr_MIPS_WRK ( UInt cins )
   2373 {
   2374    IRTemp t0, t1 = 0, t2, t3, t4, t5, t6, t7, t8, t9, t10, t11, t12, t13, t14,
   2375           t15, t16, t17;
   2376    UInt opcode, rs, rt, rd, sa, function, ac, ac_mfhilo, rddsp_mask,
   2377         wrdsp_mask, dsp_imm, shift;
   2378 
   2379    opcode = get_opcode(cins);
   2380    rs = get_rs(cins);
   2381    rt = get_rt(cins);
   2382    rd = get_rd(cins);
   2383    sa = get_sa(cins);
   2384    function = get_function(cins);
   2385    ac = get_acNo(cins);
   2386    ac_mfhilo = get_acNo_mfhilo(cins);
   2387    rddsp_mask = get_rddspMask(cins);
   2388    wrdsp_mask = get_wrdspMask(cins);
   2389    dsp_imm = get_dspImm(cins);
   2390    shift = get_shift(cins);
   2391 
   2392    switch (opcode) {
   2393       case 0x00: {  /* Special */
   2394          switch (function) {
   2395             case 0x10: {  /* MFHI */
   2396                DIP("mfhi ac%d r%d", ac_mfhilo, rd);
   2397                putIReg(rd, unop(Iop_64HIto32, getAcc(ac_mfhilo)));
   2398                break;
   2399             }
   2400 
   2401             case 0x11: {  /* MTHI */
   2402                DIP("mthi ac%d r%d", ac, rs);
   2403                t1 = newTemp(Ity_I32);
   2404                assign(t1, unop(Iop_64to32, getAcc(ac)));
   2405                putAcc(ac, binop(Iop_32HLto64, getIReg(rs), mkexpr(t1)));
   2406                break;
   2407             }
   2408 
   2409             case 0x12: {  /* MFLO */
   2410                DIP("mflo ac%d r%d", ac_mfhilo, rd);
   2411                putIReg(rd, unop(Iop_64to32, getAcc(ac_mfhilo)));
   2412                break;
   2413             }
   2414 
   2415             case 0x13: {  /* MTLO */
   2416                DIP("mtlo ac%d r%d", ac, rs);
   2417                t1 = newTemp(Ity_I32);
   2418                assign(t1, unop(Iop_64HIto32, getAcc(ac)));
   2419                putAcc(ac, binop(Iop_32HLto64, mkexpr(t1), getIReg(rs)));
   2420                break;
   2421             }
   2422 
   2423             case 0x18: {  /* MULT */
   2424                DIP("mult ac%d r%d, r%d", ac, rs, rt);
   2425                t1 = newTemp(Ity_I64);
   2426                assign(t1, binop(Iop_MullS32, mkNarrowTo32(Ity_I32, getIReg(rs)),
   2427                                 mkNarrowTo32(Ity_I32, getIReg(rt))));
   2428                putAcc(ac, mkexpr(t1));
   2429                break;
   2430             }
   2431 
   2432             case 0x19: {  /* MULTU */
   2433                DIP("multu ac%d r%d, r%d", ac, rs, rt);
   2434                t1 = newTemp(Ity_I64);
   2435                assign(t1, binop(Iop_MullU32, mkNarrowTo32(Ity_I32, getIReg(rs)),
   2436                                              mkNarrowTo32(Ity_I32,
   2437                                                           getIReg(rt))));
   2438                putAcc(ac, mkexpr(t1));
   2439             break;
   2440             }
   2441          }
   2442          break;
   2443       }
   2444       case 0x1C: {  /* Special2 */
   2445          switch (function) {
   2446             case 0x00: {  /* MADD */
   2447                DIP("madd ac%d, r%d, r%d", ac, rs, rt);
   2448                t1 = newTemp(Ity_I64);
   2449                t2 = newTemp(Ity_I64);
   2450                t3 = newTemp(Ity_I64);
   2451 
   2452                assign(t1, getAcc(ac));
   2453                assign(t2, binop(Iop_MullS32, getIReg(rs), getIReg(rt)));
   2454                assign(t3, binop(Iop_Add64, mkexpr(t1), mkexpr(t2)));
   2455 
   2456                putAcc(ac, mkexpr(t3));
   2457                break;
   2458             }
   2459             case 0x01: {  /* MADDU */
   2460                DIP("maddu ac%d r%d, r%d", ac, rs, rt);
   2461                t1 = newTemp(Ity_I64);
   2462                t2 = newTemp(Ity_I64);
   2463                t3 = newTemp(Ity_I64);
   2464 
   2465                assign(t1, getAcc(ac));
   2466                assign(t2, binop(Iop_MullU32, getIReg(rs), getIReg(rt)));
   2467                assign(t3, binop(Iop_Add64, mkexpr(t2), mkexpr(t1)));
   2468 
   2469                putAcc(ac, mkexpr(t3));
   2470                break;
   2471             }
   2472             case 0x04: {  /* MSUB */
   2473                DIP("msub ac%d r%d, r%d", ac, rs, rt);
   2474                t1 = newTemp(Ity_I64);
   2475                t2 = newTemp(Ity_I64);
   2476                t3 = newTemp(Ity_I64);
   2477 
   2478                assign(t1, getAcc(ac));
   2479                assign(t2, binop(Iop_MullS32, getIReg(rs), getIReg(rt)));
   2480                assign(t3, binop(Iop_Sub64, mkexpr(t1), mkexpr(t2)));
   2481 
   2482                putAcc(ac, mkexpr(t3));
   2483                break;
   2484             }
   2485             case 0x05: {  /* MSUBU */
   2486                DIP("msubu ac%d r%d, r%d", ac, rs, rt);
   2487                t1 = newTemp(Ity_I64);
   2488                t2 = newTemp(Ity_I64);
   2489                t3 = newTemp(Ity_I64);
   2490 
   2491                assign(t1, getAcc(ac));
   2492                assign(t2, binop(Iop_MullU32, getIReg(rs), getIReg(rt)));
   2493                assign(t3, binop(Iop_Sub64, mkexpr(t1), mkexpr(t2)));
   2494 
   2495                putAcc(ac, mkexpr(t3));
   2496                break;
   2497             }
   2498          }
   2499          break;
   2500       }
   2501       case 0x1F: {  /* Special3 */
   2502          switch (function) {
   2503             case 0x12: {  /* ABSQ_S.PH */
   2504                switch (sa) {
   2505                   case 0x1: {  /* ABSQ_S.QB */
   2506                      DIP("absq_s.qb r%d, r%d", rd, rt);
   2507                      vassert(!mode64);
   2508                      t0 = newTemp(Ity_I8);
   2509                      t1 = newTemp(Ity_I1);
   2510                      t2 = newTemp(Ity_I1);
   2511                      t3 = newTemp(Ity_I8);
   2512                      t4 = newTemp(Ity_I8);
   2513                      t5 = newTemp(Ity_I1);
   2514                      t6 = newTemp(Ity_I1);
   2515                      t7 = newTemp(Ity_I8);
   2516                      t8 = newTemp(Ity_I8);
   2517                      t9 = newTemp(Ity_I1);
   2518                      t10 = newTemp(Ity_I1);
   2519                      t11 = newTemp(Ity_I8);
   2520                      t12 = newTemp(Ity_I8);
   2521                      t13 = newTemp(Ity_I1);
   2522                      t14 = newTemp(Ity_I1);
   2523                      t15 = newTemp(Ity_I8);
   2524                      t16 = newTemp(Ity_I32);
   2525                      t17 = newTemp(Ity_I32);
   2526 
   2527                      /* Absolute value of the rightmost byte (bits 7-0). */
   2528                      /* t0 - rightmost byte. */
   2529                      assign(t0, unop(Iop_16to8, unop(Iop_32to16, getIReg(rt))));
   2530                      /* t1 holds 1 if t0 is equal to 0x80, or 0 otherwise. */
   2531                      assign(t1, binop(Iop_CmpEQ32,
   2532                                       unop(Iop_8Uto32, mkexpr(t0)),
   2533                                       mkU32(0x00000080)));
   2534                      /* t2 holds 1 if value in t0 is negative, 0 otherwise. */
   2535                      assign(t2, unop(Iop_32to1,
   2536                                      binop(Iop_Shr32,
   2537                                            binop(Iop_And32,
   2538                                                  getIReg(rt),
   2539                                                  mkU32(0x00000080)),
   2540                                            mkU8(0x7))));
   2541                      /* t3 holds abs(t0). */
   2542                      assign(t3, IRExpr_ITE(mkexpr(t1),
   2543                                            mkU8(0x7F),
   2544                                            IRExpr_ITE(mkexpr(t2),
   2545                                                       binop(Iop_Add8,
   2546                                                             unop(Iop_Not8,
   2547                                                                  mkexpr(t0)),
   2548                                                             mkU8(0x1)),
   2549                                                       mkexpr(t0))));
   2550 
   2551                      /* Absolute value of bits 15-8. */
   2552                      /* t4 - input byte. */
   2553                      assign(t4,
   2554                             unop(Iop_16HIto8, unop(Iop_32to16, getIReg(rt))));
   2555                      /* t5 holds 1 if t4 is equal to 0x80, or 0 otherwise. */
   2556                      assign(t5, binop(Iop_CmpEQ32,
   2557                                       unop(Iop_8Uto32, mkexpr(t4)),
   2558                                       mkU32(0x00000080)));
   2559                      /* t6 holds 1 if value in t4 is negative, 0 otherwise. */
   2560                      assign(t6, unop(Iop_32to1,
   2561                                      binop(Iop_Shr32,
   2562                                            binop(Iop_And32,
   2563                                                  getIReg(rt),
   2564                                                  mkU32(0x00008000)),
   2565                                            mkU8(15))));
   2566                      /* t3 holds abs(t4). */
   2567                      assign(t7, IRExpr_ITE(mkexpr(t5),
   2568                                            mkU8(0x7F),
   2569                                            IRExpr_ITE(mkexpr(t6),
   2570                                                       binop(Iop_Add8,
   2571                                                             unop(Iop_Not8,
   2572                                                                  mkexpr(t4)),
   2573                                                             mkU8(0x1)),
   2574                                                       mkexpr(t4))));
   2575 
   2576                      /* Absolute value of bits 23-15. */
   2577                      /* t8 - input byte. */
   2578                      assign(t8,
   2579                             unop(Iop_16to8, unop(Iop_32HIto16, getIReg(rt))));
   2580                      /* t9 holds 1 if t8 is equal to 0x80, or 0 otherwise. */
   2581                      assign(t9, binop(Iop_CmpEQ32,
   2582                                       unop(Iop_8Uto32, mkexpr(t8)),
   2583                                       mkU32(0x00000080)));
   2584                      /* t6 holds 1 if value in t8 is negative, 0 otherwise. */
   2585                      assign(t10, unop(Iop_32to1,
   2586                                       binop(Iop_Shr32,
   2587                                             binop(Iop_And32,
   2588                                                   getIReg(rt),
   2589                                                   mkU32(0x00800000)),
   2590                                             mkU8(23))));
   2591                      /* t3 holds abs(t8). */
   2592                      assign(t11, IRExpr_ITE(mkexpr(t9),
   2593                                             mkU8(0x7F),
   2594                                             IRExpr_ITE(mkexpr(t10),
   2595                                                        binop(Iop_Add8,
   2596                                                              unop(Iop_Not8,
   2597                                                                   mkexpr(t8)),
   2598                                                              mkU8(0x1)),
   2599                                                        mkexpr(t8))));
   2600 
   2601                      /* Absolute value of bits 31-24. */
   2602                      /* t12 - input byte. */
   2603                      assign(t12,
   2604                             unop(Iop_16HIto8, unop(Iop_32HIto16, getIReg(rt))));
   2605                      /* t13 holds 1 if t12 is equal to 0x80, or 0 otherwise. */
   2606                      assign(t13, binop(Iop_CmpEQ32,
   2607                                        unop(Iop_8Uto32, mkexpr(t12)),
   2608                                        mkU32(0x00000080)));
   2609                      /* t14 holds 1 if value in t12 is negative, 0 otherwise. */
   2610                      assign(t14, unop(Iop_32to1,
   2611                                       binop(Iop_Shr32,
   2612                                             binop(Iop_And32,
   2613                                                   getIReg(rt),
   2614                                                   mkU32(0x80000000)),
   2615                                             mkU8(31))));
   2616                      /* t15 holds abs(t12). */
   2617                      assign(t15, IRExpr_ITE(mkexpr(t13),
   2618                                             mkU8(0x7F),
   2619                                             IRExpr_ITE(mkexpr(t14),
   2620                                                        binop(Iop_Add8,
   2621                                                              unop(Iop_Not8,
   2622                                                                   mkexpr(t12)),
   2623                                                              mkU8(0x1)),
   2624                                                        mkexpr(t12))));
   2625 
   2626                      /* t16 holds !0 if any of input bytes is 0x80 or 0
   2627                         otherwise. */
   2628                      assign(t16,
   2629                             binop(Iop_Or32,
   2630                                   binop(Iop_Or32,
   2631                                         binop(Iop_Or32,
   2632                                               unop(Iop_1Sto32, mkexpr(t13)),
   2633                                               unop(Iop_1Sto32, mkexpr(t9))),
   2634                                         unop(Iop_1Sto32, mkexpr(t5))),
   2635                                   unop(Iop_1Sto32, mkexpr(t1))));
   2636 
   2637                      putDSPControl(IRExpr_ITE(binop(Iop_CmpEQ32,
   2638                                                     mkexpr(t16),
   2639                                                     mkU32(0x0)),
   2640                                               getDSPControl(),
   2641                                               binop(Iop_Or32,
   2642                                                     getDSPControl(),
   2643                                                     mkU32(0x00100000))));
   2644 
   2645                      /* t17 = t15|t11|t7|t3 */
   2646                      assign(t17,
   2647                             binop(Iop_16HLto32,
   2648                                   binop(Iop_8HLto16, mkexpr(t15), mkexpr(t11)),
   2649                                   binop(Iop_8HLto16, mkexpr(t7), mkexpr(t3))));
   2650 
   2651                      putIReg(rd, mkexpr(t17));
   2652                      break;
   2653                   }
   2654                   case 0x2: {  /* REPL.QB */
   2655                      DIP("repl.qb r%d, %d", rd, dsp_imm);
   2656                      vassert(!mode64);
   2657 
   2658                      putIReg(rd, mkU32((dsp_imm << 24) | (dsp_imm << 16) |
   2659                                        (dsp_imm << 8) | (dsp_imm)));
   2660                      break;
   2661                   }
   2662                   case 0x3: {  /* REPLV.QB */
   2663                      DIP("replv.qb r%d, r%d", rd, rt);
   2664                      vassert(!mode64);
   2665                      t0 = newTemp(Ity_I8);
   2666 
   2667                      assign(t0, unop(Iop_32to8,
   2668                                 binop(Iop_And32, getIReg(rt), mkU32(0xff))));
   2669                      putIReg(rd,
   2670                              binop(Iop_16HLto32,
   2671                                    binop(Iop_8HLto16, mkexpr(t0), mkexpr(t0)),
   2672                                    binop(Iop_8HLto16, mkexpr(t0), mkexpr(t0))));
   2673                      break;
   2674                   }
   2675                   case 0x4: {  /* PRECEQU.PH.QBL */
   2676                      DIP("precequ.ph.qbl r%d, r%d", rd, rt);
   2677                      vassert(!mode64);
   2678 
   2679                      putIReg(rd, binop(Iop_Or32,
   2680                                        binop(Iop_Shr32,
   2681                                              binop(Iop_And32,
   2682                                                    getIReg(rt),
   2683                                                    mkU32(0xff000000)),
   2684                                              mkU8(1)),
   2685                                        binop(Iop_Shr32,
   2686                                              binop(Iop_And32,
   2687                                                    getIReg(rt),
   2688                                                    mkU32(0x00ff0000)),
   2689                                              mkU8(9))));
   2690                      break;
   2691                   }
   2692                   case 0x5: {  /* PRECEQU.PH.QBR */
   2693                      DIP("precequ.ph.qbr r%d, r%d", rd, rt);
   2694                      vassert(!mode64);
   2695 
   2696                      putIReg(rd, binop(Iop_Or32,
   2697                                        binop(Iop_Shl32,
   2698                                              binop(Iop_And32,
   2699                                                    getIReg(rt),
   2700                                                    mkU32(0x0000ff00)),
   2701                                              mkU8(15)),
   2702                                        binop(Iop_Shl32,
   2703                                              binop(Iop_And32,
   2704                                                    getIReg(rt),
   2705                                                    mkU32(0x000000ff)),
   2706                                              mkU8(7))));
   2707                      break;
   2708                   }
   2709                   case 0x6: {  /* PRECEQU.PH.QBLA */
   2710                      DIP("precequ.ph.qbla r%d, r%d", rd, rt);
   2711                      vassert(!mode64);
   2712 
   2713                      putIReg(rd, binop(Iop_Or32,
   2714                                        binop(Iop_Shr32,
   2715                                              binop(Iop_And32,
   2716                                                    getIReg(rt),
   2717                                                    mkU32(0xff000000)),
   2718                                              mkU8(1)),
   2719                                        binop(Iop_Shr32,
   2720                                              binop(Iop_And32,
   2721                                                    getIReg(rt),
   2722                                                    mkU32(0x0000ff00)),
   2723                                              mkU8(1))));
   2724                      break;
   2725                   }
   2726                   case 0x7: {  /* PRECEQU.PH.QBRA */
   2727                      DIP("precequ.ph.qbra r%d, r%d", rd, rt);
   2728                      vassert(!mode64);
   2729 
   2730                      putIReg(rd, binop(Iop_Or32,
   2731                                        binop(Iop_Shl32,
   2732                                              binop(Iop_And32,
   2733                                                    getIReg(rt),
   2734                                                    mkU32(0x00ff0000)),
   2735                                              mkU8(7)),
   2736                                        binop(Iop_Shl32,
   2737                                              binop(Iop_And32,
   2738                                                    getIReg(rt),
   2739                                                    mkU32(0x000000ff)),
   2740                                              mkU8(7))));
   2741                      break;
   2742                   }
   2743                   case 0x9: {  /* ABSQ_S.PH */
   2744                      DIP("absq_s.ph r%d, r%d", rd, rt);
   2745                      vassert(!mode64);
   2746                      t0 = newTemp(Ity_I16);
   2747                      t1 = newTemp(Ity_I1);
   2748                      t2 = newTemp(Ity_I1);
   2749                      t3 = newTemp(Ity_I16);
   2750                      t4 = newTemp(Ity_I16);
   2751                      t5 = newTemp(Ity_I1);
   2752                      t6 = newTemp(Ity_I1);
   2753                      t7 = newTemp(Ity_I16);
   2754                      t8 = newTemp(Ity_I32);
   2755                      t9 = newTemp(Ity_I32);
   2756 
   2757                      /* t0 holds lower 16 bits of value in rt. */
   2758                      assign(t0, unop(Iop_32to16, getIReg(rt)));
   2759                      /* t1 holds 1 if t0 is equal to 0x8000. */
   2760                      assign(t1, binop(Iop_CmpEQ32,
   2761                                       unop(Iop_16Uto32, mkexpr(t0)),
   2762                                       mkU32(0x00008000)));
   2763                      /* t2 holds 1 if value in t0 is negative, 0 otherwise. */
   2764                      assign(t2, unop(Iop_32to1,
   2765                                      binop(Iop_Shr32,
   2766                                            binop(Iop_And32,
   2767                                                  getIReg(rt),
   2768                                                  mkU32(0x00008000)),
   2769                                            mkU8(15))));
   2770                      /* t3 holds abs(t0). */
   2771                      assign(t3, IRExpr_ITE(mkexpr(t1),
   2772                                            mkU16(0x7FFF),
   2773                                            IRExpr_ITE(mkexpr(t2),
   2774                                                       binop(Iop_Add16,
   2775                                                             unop(Iop_Not16,
   2776                                                                  mkexpr(t0)),
   2777                                                             mkU16(0x1)),
   2778                                                       mkexpr(t0))));
   2779 
   2780                      /* t4 holds lower 16 bits of value in rt. */
   2781                      assign(t4, unop(Iop_32HIto16, getIReg(rt)));
   2782                      /* t5 holds 1 if t4 is equal to 0x8000. */
   2783                      assign(t5, binop(Iop_CmpEQ32,
   2784                                       unop(Iop_16Uto32, mkexpr(t4)),
   2785                                       mkU32(0x00008000)));
   2786                      /* t6 holds 1 if value in t4 is negative, 0 otherwise. */
   2787                      assign(t6, unop(Iop_32to1,
   2788                                      binop(Iop_Shr32,
   2789                                            binop(Iop_And32,
   2790                                                  getIReg(rt),
   2791                                                  mkU32(0x80000000)),
   2792                                            mkU8(31))));
   2793                      /* t7 holds abs(t4). */
   2794                      assign(t7, IRExpr_ITE(mkexpr(t5),
   2795                                            mkU16(0x7FFF),
   2796                                            IRExpr_ITE(mkexpr(t6),
   2797                                                       binop(Iop_Add16,
   2798                                                             unop(Iop_Not16,
   2799                                                                  mkexpr(t4)),
   2800                                                             mkU16(0x1)),
   2801                                                       mkexpr(t4))));
   2802                      /* If any of the two input halfwords is equal 0x8000,
   2803                         set bit 20 in DSPControl register. */
   2804                      assign(t8, binop(Iop_Or32,
   2805                                       unop(Iop_1Sto32, mkexpr(t5)),
   2806                                       unop(Iop_1Sto32, mkexpr(t1))));
   2807 
   2808                      putDSPControl(IRExpr_ITE(binop(Iop_CmpEQ32,
   2809                                                     mkexpr(t8),
   2810                                                     mkU32(0x0)),
   2811                                               getDSPControl(),
   2812                                               binop(Iop_Or32,
   2813                                                     getDSPControl(),
   2814                                                     mkU32(0x00100000))));
   2815 
   2816                      /* t9 = t7|t3 */
   2817                      assign(t9, binop(Iop_16HLto32, mkexpr(t7), mkexpr(t3)));
   2818 
   2819                      putIReg(rd, mkexpr(t9));
   2820                      break;
   2821                   }
   2822                   case 0xA: {  /* REPL.PH */
   2823                      DIP("repl.ph r%d, %d", rd, dsp_imm);
   2824                      vassert(!mode64);
   2825                      UShort immediate = extend_s_10to16(dsp_imm);
   2826 
   2827                      putIReg(rd, mkU32(immediate << 16 | immediate));
   2828                      break;
   2829                   }
   2830                   case 0xB: {  /* REPLV.PH */
   2831                      DIP("replv.ph r%d, r%d", rd, rt);
   2832                      vassert(!mode64);
   2833 
   2834                      putIReg(rd, binop(Iop_16HLto32,
   2835                                        unop(Iop_32to16, getIReg(rt)),
   2836                                        unop(Iop_32to16, getIReg(rt))));
   2837                      break;
   2838                   }
   2839                   case 0xC: {  /* PRECEQ.W.PHL */
   2840                      DIP("preceq.w.phl r%d, r%d", rd, rt);
   2841                      vassert(!mode64);
   2842                      putIReg(rd, binop(Iop_And32,
   2843                                        getIReg(rt),
   2844                                        mkU32(0xffff0000)));
   2845                      break;
   2846                   }
   2847                   case 0xD: {  /* PRECEQ.W.PHR */
   2848                      DIP("preceq.w.phr r%d, r%d", rd, rt);
   2849                      vassert(!mode64);
   2850                      putIReg(rd, binop(Iop_16HLto32,
   2851                                        unop(Iop_32to16, getIReg(rt)),
   2852                                        mkU16(0x0)));
   2853                      break;
   2854                   }
   2855                   case 0x11: {  /* ABSQ_S.W */
   2856                      DIP("absq_s.w r%d, r%d", rd, rt);
   2857                      vassert(!mode64);
   2858                      t0 = newTemp(Ity_I1);
   2859                      t1 = newTemp(Ity_I1);
   2860                      t2 = newTemp(Ity_I32);
   2861 
   2862                      assign(t0,
   2863                             binop(Iop_CmpEQ32, getIReg(rt), mkU32(0x80000000)));
   2864 
   2865                      putDSPControl(IRExpr_ITE(mkexpr(t0),
   2866                                               binop(Iop_Or32,
   2867                                                     getDSPControl(),
   2868                                                     mkU32(0x00100000)),
   2869                                               getDSPControl()));
   2870 
   2871                      assign(t1, binop(Iop_CmpLT32S, getIReg(rt), mkU32(0x0)));
   2872 
   2873                      assign(t2, IRExpr_ITE(mkexpr(t0),
   2874                                            mkU32(0x7FFFFFFF),
   2875                                            IRExpr_ITE(mkexpr(t1),
   2876                                                       binop(Iop_Add32,
   2877                                                             unop(Iop_Not32,
   2878                                                                  getIReg(rt)),
   2879                                                             mkU32(0x1)),
   2880                                                       getIReg(rt))));
   2881                      putIReg(rd, mkexpr(t2));
   2882                      break;
   2883                   }
   2884                   case 0x1B: {  /* BITREV */
   2885                      DIP("bitrev r%d, r%d", rd, rt);
   2886                      vassert(!mode64);
   2887                      /* 32bit reversal as seen on Bit Twiddling Hacks site
   2888                         http://graphics.stanford.edu/~seander/bithacks.html
   2889                         section ReverseParallel */
   2890                      t1 = newTemp(Ity_I32);
   2891                      t2 = newTemp(Ity_I32);
   2892                      t3 = newTemp(Ity_I32);
   2893                      t4 = newTemp(Ity_I32);
   2894                      t5 = newTemp(Ity_I32);
   2895 
   2896                      assign(t1, binop(Iop_Or32,
   2897                                       binop(Iop_Shr32,
   2898                                             binop(Iop_And32,
   2899                                                   getIReg(rt),
   2900                                                   mkU32(0xaaaaaaaa)),
   2901                                             mkU8(0x1)),
   2902                                       binop(Iop_Shl32,
   2903                                             binop(Iop_And32,
   2904                                                   getIReg(rt),
   2905                                                   mkU32(0x55555555)),
   2906                                             mkU8(0x1))));
   2907                      assign(t2, binop(Iop_Or32,
   2908                                       binop(Iop_Shr32,
   2909                                             binop(Iop_And32,
   2910                                                   mkexpr(t1),
   2911                                                   mkU32(0xcccccccc)),
   2912                                             mkU8(0x2)),
   2913                                       binop(Iop_Shl32,
   2914                                             binop(Iop_And32,
   2915                                                   mkexpr(t1),
   2916                                                   mkU32(0x33333333)),
   2917                                             mkU8(0x2))));
   2918                      assign(t3, binop(Iop_Or32,
   2919                                       binop(Iop_Shr32,
   2920                                             binop(Iop_And32,
   2921                                                   mkexpr(t2),
   2922                                                   mkU32(0xf0f0f0f0)),
   2923                                             mkU8(0x4)),
   2924                                       binop(Iop_Shl32,
   2925                                             binop(Iop_And32,
   2926                                                   mkexpr(t2),
   2927                                                   mkU32(0x0f0f0f0f)),
   2928                                             mkU8(0x4))));
   2929                      assign(t4, binop(Iop_Or32,
   2930                                       binop(Iop_Shr32,
   2931                                             binop(Iop_And32,
   2932                                                   mkexpr(t3),
   2933                                                   mkU32(0xff00ff00)),
   2934                                             mkU8(0x8)),
   2935                                       binop(Iop_Shl32,
   2936                                             binop(Iop_And32,
   2937                                                   mkexpr(t3),
   2938                                                   mkU32(0x00ff00ff)),
   2939                                             mkU8(0x8))));
   2940                      assign(t5, binop(Iop_Or32,
   2941                                       binop(Iop_Shr32,
   2942                                             mkexpr(t4),
   2943                                             mkU8(0x10)),
   2944                                       binop(Iop_Shl32,
   2945                                             mkexpr(t4),
   2946                                             mkU8(0x10))));
   2947                      putIReg(rd, binop(Iop_Shr32,
   2948                                        mkexpr(t5),
   2949                                        mkU8(16)));
   2950                      break;
   2951                   }
   2952                   case 0x1C: {  /* PRECEU.PH.QBL */
   2953                      DIP("preceu.ph.qbl r%d, r%d", rd, rt);
   2954                      vassert(!mode64);
   2955 
   2956                      putIReg(rd, binop(Iop_Or32,
   2957                                        binop(Iop_Shr32,
   2958                                              binop(Iop_And32,
   2959                                                    getIReg(rt),
   2960                                                    mkU32(0xff000000)),
   2961                                              mkU8(8)),
   2962                                        binop(Iop_Shr32,
   2963                                              binop(Iop_And32,
   2964                                                    getIReg(rt),
   2965                                                    mkU32(0x00ff0000)),
   2966                                              mkU8(16))));
   2967                      break;
   2968                   }
   2969                   case 0x1E: {  /* PRECEU.PH.QBLA */
   2970                      DIP("preceu.ph.qbla r%d, r%d", rd, rt);
   2971                      vassert(!mode64);
   2972 
   2973                      putIReg(rd, binop(Iop_Or32,
   2974                                        binop(Iop_Shr32,
   2975                                              binop(Iop_And32,
   2976                                                    getIReg(rt),
   2977                                                    mkU32(0xff000000)),
   2978                                              mkU8(8)),
   2979                                        binop(Iop_Shr32,
   2980                                              binop(Iop_And32,
   2981                                                    getIReg(rt),
   2982                                                    mkU32(0x0000ff00)),
   2983                                              mkU8(8))));
   2984                      break;
   2985                   }
   2986                   case 0x1D: {  /* PRECEU.PH.QBR */
   2987                      DIP("preceu.ph.qbr r%d, r%d", rd, rt);
   2988                      vassert(!mode64);
   2989 
   2990                      putIReg(rd, binop(Iop_Or32,
   2991                                        binop(Iop_Shl32,
   2992                                              binop(Iop_And32,
   2993                                                    getIReg(rt),
   2994                                                    mkU32(0x0000ff00)),
   2995                                              mkU8(8)),
   2996                                        binop(Iop_And32,
   2997                                              getIReg(rt),
   2998                                              mkU32(0x000000ff))));
   2999                      break;
   3000                   }
   3001                   case 0x1F: {  /* PRECEU.PH.QBRA */
   3002                      DIP("preceu.ph.qbra r%d, r%d", rd, rt);
   3003                      vassert(!mode64);
   3004 
   3005                      putIReg(rd, binop(Iop_Or32,
   3006                                        binop(Iop_And32,
   3007                                              getIReg(rt),
   3008                                              mkU32(0x00ff0000)),
   3009                                        binop(Iop_And32,
   3010                                              getIReg(rt),
   3011                                              mkU32(0x000000ff))));
   3012                      break;
   3013                   }
   3014                   default:
   3015                      return -1;
   3016                }
   3017                break;  /* end of ABSQ_S.PH */
   3018             }
   3019             case 0x38: {  /* EXTR.W */
   3020                switch(sa) {
   3021                   case 0x0: {  /* EXTR.W */
   3022                      DIP("extr.w r%d, ac%d, %d", rt, ac, rs);
   3023                      vassert(!mode64);
   3024                      t0 = newTemp(Ity_I64);
   3025                      t1 = newTemp(Ity_I64);
   3026                      t2 = newTemp(Ity_I32);
   3027                      t3 = newTemp(Ity_I1);
   3028                      t4 = newTemp(Ity_I1);
   3029                      t5 = newTemp(Ity_I1);
   3030                      t6 = newTemp(Ity_I1);
   3031                      t7 = newTemp(Ity_I32);
   3032                      t8 = newTemp(Ity_I64);
   3033                      t9 = newTemp(Ity_I64);
   3034                      t10 = newTemp(Ity_I1);
   3035                      t11 = newTemp(Ity_I1);
   3036                      t12 = newTemp(Ity_I1);
   3037                      t13 = newTemp(Ity_I1);
   3038                      t14 = newTemp(Ity_I32);
   3039 
   3040                      assign(t0, getAcc(ac));
   3041                      if (0 == rs) {
   3042                         assign(t1, mkexpr(t0));
   3043                      } else {
   3044                         assign(t1, binop(Iop_Sar64, mkexpr(t0), mkU8(rs)));
   3045                      }
   3046                      /* Check if bits 63..31 of the result in t1 aren't 0. */
   3047                      assign(t3, binop(Iop_CmpNE32,
   3048                                       unop(Iop_64HIto32,
   3049                                            mkexpr(t1)),
   3050                                       mkU32(0)));
   3051                      assign(t4, binop(Iop_CmpNE32,
   3052                                       binop(Iop_And32,
   3053                                             unop(Iop_64to32,
   3054                                                  mkexpr(t1)),
   3055                                             mkU32(0x80000000)),
   3056                                       mkU32(0)));
   3057                      /* Check if bits 63..31 of the result in t1 aren't
   3058                         0x1ffffffff. */
   3059                      assign(t5, binop(Iop_CmpNE32,
   3060                                       unop(Iop_64HIto32,
   3061                                            mkexpr(t1)),
   3062                                       mkU32(0xffffffff)));
   3063                      assign(t6, binop(Iop_CmpNE32,
   3064                                       binop(Iop_And32,
   3065                                             unop(Iop_64to32,
   3066                                                  mkexpr(t1)),
   3067                                             mkU32(0x80000000)),
   3068                                       mkU32(0x80000000)));
   3069                      /* If bits 63..31 aren't 0 nor 0x1ffffffff, set DSP
   3070                         control register. */
   3071                      assign(t7, binop(Iop_And32,
   3072                                       binop(Iop_Or32,
   3073                                             unop(Iop_1Sto32, mkexpr(t3)),
   3074                                             unop(Iop_1Sto32, mkexpr(t4))),
   3075                                       binop(Iop_Or32,
   3076                                             unop(Iop_1Sto32, mkexpr(t5)),
   3077                                             unop(Iop_1Sto32, mkexpr(t6)))));
   3078                      putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32,
   3079                                                     mkexpr(t7),
   3080                                                     mkU32(0)),
   3081                                               binop(Iop_Or32,
   3082                                                     getDSPControl(),
   3083                                                     mkU32(0x00800000)),
   3084                                               getDSPControl()));
   3085 
   3086                      /* If the last discarded bit is 1, there would be carry
   3087                         when rounding, otherwise there wouldn't. We use that
   3088                         fact and just add the value of the last discarded bit
   3089                         to the least sifgnificant bit of the shifted value
   3090                         from acc. */
   3091                      if (0 == rs) {
   3092                         assign(t8, mkU64(0x0ULL));
   3093                      } else {
   3094                         assign(t8, binop(Iop_And64,
   3095                                          binop(Iop_Shr64,
   3096                                                mkexpr(t0),
   3097                                                mkU8(rs-1)),
   3098                                          mkU64(0x1ULL)));
   3099                      }
   3100                      assign(t9, binop(Iop_Add64, mkexpr(t1), mkexpr(t8)));
   3101 
   3102                      /* Repeat previous steps for the rounded value. */
   3103                      assign(t10, binop(Iop_CmpNE32,
   3104                                       unop(Iop_64HIto32,
   3105                                            mkexpr(t9)),
   3106                                       mkU32(0)));
   3107                      assign(t11, binop(Iop_CmpNE32,
   3108                                       binop(Iop_And32,
   3109                                             unop(Iop_64to32,
   3110                                                  mkexpr(t9)),
   3111                                             mkU32(0x80000000)),
   3112                                       mkU32(0)));
   3113 
   3114                      assign(t12, binop(Iop_CmpNE32,
   3115                                       unop(Iop_64HIto32,
   3116                                            mkexpr(t9)),
   3117                                       mkU32(0xffffffff)));
   3118                      assign(t13, binop(Iop_CmpNE32,
   3119                                       binop(Iop_And32,
   3120                                             unop(Iop_64to32,
   3121                                                  mkexpr(t9)),
   3122                                             mkU32(0x80000000)),
   3123                                       mkU32(0x80000000)));
   3124 
   3125                      assign(t14, binop(Iop_And32,
   3126                                       binop(Iop_Or32,
   3127                                             unop(Iop_1Sto32, mkexpr(t10)),
   3128                                             unop(Iop_1Sto32, mkexpr(t11))),
   3129                                       binop(Iop_Or32,
   3130                                             unop(Iop_1Sto32, mkexpr(t12)),
   3131                                             unop(Iop_1Sto32, mkexpr(t13)))));
   3132                      putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32,
   3133                                                     mkexpr(t14),
   3134                                                     mkU32(0)),
   3135                                               binop(Iop_Or32,
   3136                                                     getDSPControl(),
   3137                                                     mkU32(0x00800000)),
   3138                                               getDSPControl()));
   3139                      if (0 == rs) {
   3140                         putIReg(rt, unop(Iop_64to32, mkexpr(t0)));
   3141                      } else {
   3142                         putIReg(rt, unop(Iop_64to32, mkexpr(t1)));
   3143                      }
   3144                      break;
   3145                   }
   3146                   case 0x1: {  /* EXTRV.W */
   3147                      DIP("extrv.w r%d, ac%d, r%d", rt, ac, rs);
   3148                      vassert(!mode64);
   3149                      t0 = newTemp(Ity_I64);
   3150                      t1 = newTemp(Ity_I64);
   3151                      t2 = newTemp(Ity_I32);
   3152                      t3 = newTemp(Ity_I1);
   3153                      t4 = newTemp(Ity_I1);
   3154                      t5 = newTemp(Ity_I1);
   3155                      t6 = newTemp(Ity_I1);
   3156                      t7 = newTemp(Ity_I32);
   3157                      t8 = newTemp(Ity_I64);
   3158                      t9 = newTemp(Ity_I64);
   3159                      t10 = newTemp(Ity_I1);
   3160                      t11 = newTemp(Ity_I1);
   3161                      t12 = newTemp(Ity_I1);
   3162                      t13 = newTemp(Ity_I1);
   3163                      t14 = newTemp(Ity_I32);
   3164                      t15 = newTemp(Ity_I8);
   3165 
   3166                      assign(t15, unop(Iop_32to8,
   3167                                       binop(Iop_And32,
   3168                                             getIReg(rs),
   3169                                             mkU32(0x1f))));
   3170                      assign(t0, getAcc(ac));
   3171                      assign(t1, binop(Iop_Sar64, mkexpr(t0), mkexpr(t15)));
   3172                      putIReg(rt, IRExpr_ITE(binop(Iop_CmpEQ32,
   3173                                                         unop(Iop_8Uto32,
   3174                                                              mkexpr(t15)),
   3175                                                         mkU32(0)),
   3176                                                   unop(Iop_64to32, mkexpr(t0)),
   3177                                                   unop(Iop_64to32, mkexpr(t1))));
   3178 
   3179                      /* Check if bits 63..31 of the result in t1 aren't 0. */
   3180                      assign(t3, binop(Iop_CmpNE32,
   3181                                       unop(Iop_64HIto32,
   3182                                            mkexpr(t1)),
   3183                                       mkU32(0)));
   3184                      assign(t4, binop(Iop_CmpNE32,
   3185                                       binop(Iop_And32,
   3186                                             unop(Iop_64to32,
   3187                                                  mkexpr(t1)),
   3188                                             mkU32(0x80000000)),
   3189                                       mkU32(0)));
   3190                      /* Check if bits 63..31 of the result in t1 aren't
   3191                         0x1ffffffff. */
   3192                      assign(t5, binop(Iop_CmpNE32,
   3193                                       unop(Iop_64HIto32,
   3194                                            mkexpr(t1)),
   3195                                       mkU32(0xffffffff)));
   3196                      assign(t6, binop(Iop_CmpNE32,
   3197                                       binop(Iop_And32,
   3198                                             unop(Iop_64to32,
   3199                                                  mkexpr(t1)),
   3200                                             mkU32(0x80000000)),
   3201                                       mkU32(0x80000000)));
   3202                      /* If bits 63..31 aren't 0 nor 0x1ffffffff, set DSP
   3203                         control register. */
   3204                      assign(t7, binop(Iop_And32,
   3205                                       binop(Iop_Or32,
   3206                                             unop(Iop_1Sto32, mkexpr(t3)),
   3207                                             unop(Iop_1Sto32, mkexpr(t4))),
   3208                                       binop(Iop_Or32,
   3209                                             unop(Iop_1Sto32, mkexpr(t5)),
   3210                                             unop(Iop_1Sto32, mkexpr(t6)))));
   3211                      putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32,
   3212                                                     mkexpr(t7),
   3213                                                     mkU32(0)),
   3214                                               binop(Iop_Or32,
   3215                                                     getDSPControl(),
   3216                                                     mkU32(0x00800000)),
   3217                                               getDSPControl()));
   3218 
   3219                      /* If the last discarded bit is 1, there would be carry
   3220                         when rounding, otherwise there wouldn't. We use that
   3221                         fact and just add the value of the last discarded bit
   3222                         to the least sifgnificant bit of the shifted value
   3223                         from acc. */
   3224                      assign(t8,
   3225                             IRExpr_ITE(binop(Iop_CmpEQ32,
   3226                                              unop(Iop_8Uto32,
   3227                                                   mkexpr(t15)),
   3228                                              mkU32(0)),
   3229                                        mkU64(0x0ULL),
   3230                                        binop(Iop_And64,
   3231                                              binop(Iop_Shr64,
   3232                                                    mkexpr(t0),
   3233                                                    unop(Iop_32to8,
   3234                                                         binop(Iop_Sub32,
   3235                                                               unop(Iop_8Uto32,
   3236                                                                    mkexpr(t15)),
   3237                                                                    mkU32(1)))),
   3238                                              mkU64(0x1ULL))));
   3239 
   3240                      assign(t9, binop(Iop_Add64, mkexpr(t1), mkexpr(t8)));
   3241 
   3242                      /* Repeat previous steps for the rounded value. */
   3243                      assign(t10, binop(Iop_CmpNE32,
   3244                                       unop(Iop_64HIto32,
   3245                                            mkexpr(t9)),
   3246                                       mkU32(0)));
   3247                      assign(t11, binop(Iop_CmpNE32,
   3248                                       binop(Iop_And32,
   3249                                             unop(Iop_64to32,
   3250                                                  mkexpr(t9)),
   3251                                             mkU32(0x80000000)),
   3252                                       mkU32(0)));
   3253 
   3254                      assign(t12, binop(Iop_CmpNE32,
   3255                                       unop(Iop_64HIto32,
   3256                                            mkexpr(t9)),
   3257                                       mkU32(0xffffffff)));
   3258                      assign(t13, binop(Iop_CmpNE32,
   3259                                       binop(Iop_And32,
   3260                                             unop(Iop_64to32,
   3261                                                  mkexpr(t9)),
   3262                                             mkU32(0x80000000)),
   3263                                       mkU32(0x80000000)));
   3264 
   3265                      assign(t14, binop(Iop_And32,
   3266                                       binop(Iop_Or32,
   3267                                             unop(Iop_1Sto32, mkexpr(t10)),
   3268                                             unop(Iop_1Sto32, mkexpr(t11))),
   3269                                       binop(Iop_Or32,
   3270                                             unop(Iop_1Sto32, mkexpr(t12)),
   3271                                             unop(Iop_1Sto32, mkexpr(t13)))));
   3272                      putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32,
   3273                                                     mkexpr(t14),
   3274                                                     mkU32(0)),
   3275                                               binop(Iop_Or32,
   3276                                                     getDSPControl(),
   3277                                                     mkU32(0x00800000)),
   3278                                               getDSPControl()));
   3279                      break;
   3280                   }
   3281                   case 0x2: {  /* EXTP */
   3282                      DIP("extp r%d, ac%d, %d", rt, ac, rs);
   3283                      vassert(!mode64);
   3284                      t0 = newTemp(Ity_I64);
   3285                      t1 = newTemp(Ity_I32);
   3286                      t2 = newTemp(Ity_I1);
   3287                      t3 = newTemp(Ity_I1);
   3288                      t4 = newTemp(Ity_I8);
   3289                      t5 = newTemp(Ity_I64);
   3290                      t6 = newTemp(Ity_I64);
   3291                      t7 = newTemp(Ity_I32);
   3292 
   3293                      assign(t0, getAcc(ac));
   3294                      /* Extract pos field of DSPControl register. */
   3295                      assign(t1, binop(Iop_And32, getDSPControl(), mkU32(0x3f)));
   3296 
   3297                      /* Check if (pos - size) >= 0 [size <= pos]
   3298                         if (pos < size)
   3299                            put 1 to EFI field of DSPControl register
   3300                         else
   3301                            extract bits from acc and put 0 to EFI field of
   3302                            DSPCtrl */
   3303                      assign(t2, binop(Iop_CmpLT32U, mkexpr(t1), mkU32(rs)));
   3304 
   3305                      putDSPControl(IRExpr_ITE(mkexpr(t2),
   3306                                               binop(Iop_Or32,
   3307                                                     binop(Iop_And32,
   3308                                                           getDSPControl(),
   3309                                                           mkU32(0xffffbfff)),
   3310                                                     mkU32(0x4000)),
   3311                                               binop(Iop_And32,
   3312                                                     getDSPControl(),
   3313                                                     mkU32(0xffffbfff))));
   3314 
   3315                      /* If pos <= 31, shift right the value from the acc
   3316                         (pos-size) times and take (size+1) bits from the least
   3317                         significant positions. Otherwise, shift left the value
   3318                         (63-pos) times, take (size+1) bits from the most
   3319                         significant positions and shift right (31-size) times.*/
   3320                      assign(t3, binop(Iop_CmpLE32U, mkexpr(t1), mkU32(31)));
   3321 
   3322                      assign(t4,
   3323                            IRExpr_ITE(mkexpr(t3),
   3324                                       unop(Iop_32to8,
   3325                                            binop(Iop_Sub32,
   3326                                                  mkexpr(t1), mkU32(rs))),
   3327                                       unop(Iop_32to8,
   3328                                            binop(Iop_Sub32,
   3329                                                  mkU32(63), mkexpr(t1)))));
   3330 
   3331                      assign(t5, IRExpr_ITE(mkexpr(t3),
   3332                                            binop(Iop_Shr64,
   3333                                                  mkexpr(t0), mkexpr(t4)),
   3334                                            binop(Iop_Shl64,
   3335                                                  mkexpr(t0), mkexpr(t4))));
   3336 
   3337                      /* t6 holds a mask for bit extraction */
   3338                      assign(t6,
   3339                             IRExpr_ITE(mkexpr(t3),
   3340                                        unop(Iop_Not64,
   3341                                             binop(Iop_Shl64,
   3342                                                   mkU64(0xffffffffffffffffULL),
   3343                                                   mkU8(rs+1))),
   3344                                        unop(Iop_Not64,
   3345                                             binop(Iop_Shr64,
   3346                                                   mkU64(0xffffffffffffffffULL),
   3347                                                   mkU8(rs+1)))));
   3348 
   3349                      assign(t7, IRExpr_ITE(mkexpr(t3),
   3350                                            unop(Iop_64to32,
   3351                                                 binop(Iop_And64,
   3352                                                       mkexpr(t5),
   3353                                                       mkexpr(t6))),
   3354                                            binop(Iop_Shr32,
   3355                                                  unop(Iop_64HIto32,
   3356                                                       binop(Iop_And64,
   3357                                                             mkexpr(t5),
   3358                                                             mkexpr(t6))),
   3359                                                  mkU8(31-rs))));
   3360 
   3361                      putIReg(rt, mkexpr(t7));
   3362                      break;
   3363                   }
   3364                   case 0x3: {  /* EXTPV */
   3365                      DIP("extpv r%d, ac%d, r%d", rt, ac, rs);
   3366                      vassert(!mode64);
   3367                      t0 = newTemp(Ity_I64);
   3368                      t1 = newTemp(Ity_I32);
   3369                      t2 = newTemp(Ity_I1);
   3370                      t3 = newTemp(Ity_I1);
   3371                      t4 = newTemp(Ity_I8);
   3372                      t5 = newTemp(Ity_I64);
   3373                      t6 = newTemp(Ity_I64);
   3374                      t7 = newTemp(Ity_I32);
   3375                      t8 = newTemp(Ity_I32);
   3376 
   3377                      assign(t8, binop(Iop_And32, getIReg(rs), mkU32(0x1f)));
   3378                      assign(t0, getAcc(ac));
   3379                      /* Extract pos field of DSPControl register. */
   3380                      assign(t1, binop(Iop_And32, getDSPControl(), mkU32(0x3f)));
   3381 
   3382                      /* Check if (pos - size) >= 0 [size <= pos]
   3383                         if (pos < size)
   3384                            put 1 to EFI field of DSPControl register
   3385                         else
   3386                            extract bits from acc and put 0 to EFI field of
   3387                            DSPCtrl */
   3388                      assign(t2, binop(Iop_CmpLT32U, mkexpr(t1), mkexpr(t8)));
   3389 
   3390                      putDSPControl(IRExpr_ITE(mkexpr(t2),
   3391                                               binop(Iop_Or32,
   3392                                                     binop(Iop_And32,
   3393                                                           getDSPControl(),
   3394                                                           mkU32(0xffffbfff)),
   3395                                                     mkU32(0x4000)),
   3396                                               binop(Iop_And32,
   3397                                                     getDSPControl(),
   3398                                                     mkU32(0xffffbfff))));
   3399 
   3400                      /* If pos <= 31, shift right the value from the acc
   3401                         (pos-size) times and take (size+1) bits from the least
   3402                         significant positions. Otherwise, shift left the value
   3403                         (63-pos) times, take (size+1) bits from the most
   3404                         significant positions and shift right (31-size)
   3405                         times. */
   3406                      assign(t3, binop(Iop_CmpLE32U, mkexpr(t1), mkU32(31)));
   3407 
   3408                      assign(t4,
   3409                            IRExpr_ITE(mkexpr(t3),
   3410                                       unop(Iop_32to8,
   3411                                            binop(Iop_Sub32,
   3412                                                  mkexpr(t1), mkexpr(t8))),
   3413                                       unop(Iop_32to8,
   3414                                            binop(Iop_Sub32,
   3415                                                  mkU32(63), mkexpr(t1)))));
   3416 
   3417                      assign(t5, IRExpr_ITE(mkexpr(t3),
   3418                                            binop(Iop_Shr64,
   3419                                                  mkexpr(t0), mkexpr(t4)),
   3420                                            binop(Iop_Shl64,
   3421                                                  mkexpr(t0), mkexpr(t4))));
   3422 
   3423                      /* t6 holds a mask for bit extraction. */
   3424                      assign(t6,
   3425                             IRExpr_ITE(mkexpr(t3),
   3426                                        unop(Iop_Not64,
   3427                                             binop(Iop_Shl64,
   3428                                                   mkU64(0xffffffffffffffffULL),
   3429                                                   unop(Iop_32to8,
   3430                                                        binop(Iop_Add32,
   3431                                                              mkexpr(t8),
   3432                                                              mkU32(1))))),
   3433                                        unop(Iop_Not64,
   3434                                             binop(Iop_Shr64,
   3435                                                   mkU64(0xffffffffffffffffULL),
   3436                                                   unop(Iop_32to8,
   3437                                                        binop(Iop_Add32,
   3438                                                              mkexpr(t8),
   3439                                                              mkU32(1)))))));
   3440 
   3441                      assign(t7, IRExpr_ITE(mkexpr(t3),
   3442                                            unop(Iop_64to32,
   3443                                                 binop(Iop_And64,
   3444                                                       mkexpr(t5),
   3445                                                       mkexpr(t6))),
   3446                                            binop(Iop_Shr32,
   3447                                                  unop(Iop_64HIto32,
   3448                                                       binop(Iop_And64,
   3449                                                             mkexpr(t5),
   3450                                                             mkexpr(t6))),
   3451                                                  unop(Iop_32to8,
   3452                                                       binop(Iop_Sub32,
   3453                                                             mkU32(31),
   3454                                                             mkexpr(t8))))));
   3455 
   3456                      putIReg(rt, mkexpr(t7));
   3457                      break;
   3458                   }
   3459                   case 0x4: {  /* EXTR_R.W */
   3460                      DIP("extr_r.w r%d, ac%d, %d", rt, ac, rs);
   3461                      vassert(!mode64);
   3462                      t0 = newTemp(Ity_I64);
   3463                      t1 = newTemp(Ity_I64);
   3464                      t2 = newTemp(Ity_I32);
   3465                      t3 = newTemp(Ity_I1);
   3466                      t4 = newTemp(Ity_I1);
   3467                      t5 = newTemp(Ity_I1);
   3468                      t6 = newTemp(Ity_I1);
   3469                      t7 = newTemp(Ity_I32);
   3470                      t8 = newTemp(Ity_I64);
   3471                      t9 = newTemp(Ity_I64);
   3472                      t10 = newTemp(Ity_I1);
   3473                      t11 = newTemp(Ity_I1);
   3474                      t12 = newTemp(Ity_I1);
   3475                      t13 = newTemp(Ity_I1);
   3476                      t14 = newTemp(Ity_I32);
   3477                      t15 = newTemp(Ity_I64);
   3478                      t16 = newTemp(Ity_I1);
   3479 
   3480                      assign(t0, getAcc(ac));
   3481                      assign(t16, binop(Iop_CmpEQ32,
   3482                                        mkU32(rs),
   3483                                        mkU32(0)));
   3484                      assign(t1, IRExpr_ITE(mkexpr(t16),
   3485                                            mkexpr(t0),
   3486                                            binop(Iop_Sar64,
   3487                                                  mkexpr(t0),
   3488                                                  mkU8(rs))));
   3489                      /* If the last discarded bit is 1, there would be carry
   3490                         when rounding, otherwise there wouldn't. We use that
   3491                         fact and just add the value of the last discarded bit
   3492                         to the least significant bit of the shifted value
   3493                         from acc. */
   3494                      assign(t15, binop(Iop_Shr64,
   3495                                        mkexpr(t0),
   3496                                        unop(Iop_32to8,
   3497                                             binop(Iop_Sub32,
   3498                                                   binop(Iop_And32,
   3499                                                         mkU32(rs),
   3500                                                         mkU32(0x1f)),
   3501                                                   mkU32(1)))));
   3502 
   3503                      assign(t8,
   3504                             IRExpr_ITE(mkexpr(t16),
   3505                                        mkU64(0x0ULL),
   3506                                        binop(Iop_And64,
   3507                                              mkexpr(t15),
   3508                                              mkU64(0x0000000000000001ULL))));
   3509                      assign(t9, binop(Iop_Add64, mkexpr(t1), mkexpr(t8)));
   3510                      putIReg(rt, unop(Iop_64to32, mkexpr(t9)));
   3511 
   3512                      /* Check if bits 63..31 of the result in t1 aren't 0. */
   3513                      assign(t3, binop(Iop_CmpNE32,
   3514                                       unop(Iop_64HIto32,
   3515                                            mkexpr(t1)),
   3516                                       mkU32(0)));
   3517                      assign(t4, binop(Iop_CmpNE32,
   3518                                       binop(Iop_And32,
   3519                                             unop(Iop_64to32,
   3520                                                  mkexpr(t1)),
   3521                                             mkU32(0x80000000)),
   3522                                       mkU32(0)));
   3523 
   3524                      /* Check if bits 63..31 of the result in t1 aren't
   3525                         0x1ffffffff. */
   3526                      assign(t5, binop(Iop_CmpNE32,
   3527                                       unop(Iop_64HIto32,
   3528                                            mkexpr(t1)),
   3529                                       mkU32(0xffffffff)));
   3530                      assign(t6, binop(Iop_CmpNE32,
   3531                                       binop(Iop_And32,
   3532                                             unop(Iop_64to32,
   3533                                                  mkexpr(t1)),
   3534                                             mkU32(0x80000000)),
   3535                                       mkU32(0x80000000)));
   3536                      /* If bits 63..31 aren't 0 nor 0x1ffffffff, set DSP
   3537                         control register. */
   3538                      assign(t7, binop(Iop_And32,
   3539                                       binop(Iop_Or32,
   3540                                             unop(Iop_1Sto32, mkexpr(t3)),
   3541                                             unop(Iop_1Sto32, mkexpr(t4))),
   3542                                       binop(Iop_Or32,
   3543                                             unop(Iop_1Sto32, mkexpr(t5)),
   3544                                             unop(Iop_1Sto32, mkexpr(t6)))));
   3545                      putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32,
   3546                                                     mkexpr(t7),
   3547                                                     mkU32(0)),
   3548                                               binop(Iop_Or32,
   3549                                                     getDSPControl(),
   3550                                                     mkU32(0x00800000)),
   3551                                               getDSPControl()));
   3552 
   3553                      /* Repeat previous steps for the rounded value. */
   3554                      assign(t10, binop(Iop_CmpNE32,
   3555                                       unop(Iop_64HIto32,
   3556                                            mkexpr(t9)),
   3557                                       mkU32(0)));
   3558                      assign(t11, binop(Iop_CmpNE32,
   3559                                       binop(Iop_And32,
   3560                                             unop(Iop_64to32,
   3561                                                  mkexpr(t9)),
   3562                                             mkU32(0x80000000)),
   3563                                       mkU32(0)));
   3564 
   3565                      assign(t12, binop(Iop_CmpNE32,
   3566                                       unop(Iop_64HIto32,
   3567                                            mkexpr(t9)),
   3568                                       mkU32(0xffffffff)));
   3569                      assign(t13, binop(Iop_CmpNE32,
   3570                                       binop(Iop_And32,
   3571                                             unop(Iop_64to32,
   3572                                                  mkexpr(t9)),
   3573                                             mkU32(0x80000000)),
   3574                                       mkU32(0x80000000)));
   3575 
   3576                      assign(t14, binop(Iop_And32,
   3577                                       binop(Iop_Or32,
   3578                                             unop(Iop_1Sto32, mkexpr(t10)),
   3579                                             unop(Iop_1Sto32, mkexpr(t11))),
   3580                                       binop(Iop_Or32,
   3581                                             unop(Iop_1Sto32, mkexpr(t12)),
   3582                                             unop(Iop_1Sto32, mkexpr(t13)))));
   3583                      putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32,
   3584                                                     mkexpr(t14),
   3585                                                     mkU32(0)),
   3586                                               binop(Iop_Or32,
   3587                                                     getDSPControl(),
   3588                                                     mkU32(0x00800000)),
   3589                                               getDSPControl()));
   3590                      break;
   3591                   }
   3592                   case 0x5: {  /* EXTRV_R.W */
   3593                      DIP("extrv_r.w r%d, ac%d, r%d", rt, ac, rs);
   3594                      vassert(!mode64);
   3595                      t0 = newTemp(Ity_I64);
   3596                      t1 = newTemp(Ity_I64);
   3597                      t2 = newTemp(Ity_I32);
   3598                      t3 = newTemp(Ity_I1);
   3599                      t4 = newTemp(Ity_I1);
   3600                      t5 = newTemp(Ity_I1);
   3601                      t6 = newTemp(Ity_I1);
   3602                      t7 = newTemp(Ity_I32);
   3603                      t8 = newTemp(Ity_I64);
   3604                      t9 = newTemp(Ity_I64);
   3605                      t10 = newTemp(Ity_I1);
   3606                      t11 = newTemp(Ity_I1);
   3607                      t12 = newTemp(Ity_I1);
   3608                      t13 = newTemp(Ity_I1);
   3609                      t14 = newTemp(Ity_I32);
   3610                      t15 = newTemp(Ity_I8);
   3611 
   3612                      assign(t15, unop(Iop_32to8,
   3613                                       binop(Iop_And32,
   3614                                             getIReg(rs),
   3615                                             mkU32(0x1f))));
   3616                      assign(t0, getAcc(ac));
   3617                      assign(t1, binop(Iop_Sar64, mkexpr(t0), mkexpr(t15)));
   3618 
   3619                      /* Check if bits 63..31 of the result in t1 aren't 0. */
   3620                      assign(t3, binop(Iop_CmpNE32,
   3621                                       unop(Iop_64HIto32,
   3622                                            mkexpr(t1)),
   3623                                       mkU32(0)));
   3624                      assign(t4, binop(Iop_CmpNE32,
   3625                                       binop(Iop_And32,
   3626                                             unop(Iop_64to32,
   3627                                                  mkexpr(t1)),
   3628                                             mkU32(0x80000000)),
   3629                                       mkU32(0)));
   3630                      /* Check if bits 63..31 of the result in t1 aren't
   3631                         0x1ffffffff. */
   3632                      assign(t5, binop(Iop_CmpNE32,
   3633                                       unop(Iop_64HIto32,
   3634                                            mkexpr(t1)),
   3635                                       mkU32(0xffffffff)));
   3636                      assign(t6, binop(Iop_CmpNE32,
   3637                                       binop(Iop_And32,
   3638                                             unop(Iop_64to32,
   3639                                                  mkexpr(t1)),
   3640                                             mkU32(0x80000000)),
   3641                                       mkU32(0x80000000)));
   3642                      /* If bits 63..31 aren't 0 nor 0x1ffffffff, set DSP
   3643                         control register. */
   3644                      assign(t7, binop(Iop_And32,
   3645                                       binop(Iop_Or32,
   3646                                             unop(Iop_1Sto32, mkexpr(t3)),
   3647                                             unop(Iop_1Sto32, mkexpr(t4))),
   3648                                       binop(Iop_Or32,
   3649                                             unop(Iop_1Sto32, mkexpr(t5)),
   3650                                             unop(Iop_1Sto32, mkexpr(t6)))));
   3651                      putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32,
   3652                                                     mkexpr(t7),
   3653                                                     mkU32(0)),
   3654                                               binop(Iop_Or32,
   3655                                                     getDSPControl(),
   3656                                                     mkU32(0x00800000)),
   3657                                               getDSPControl()));
   3658 
   3659                      /* If the last discarded bit is 1, there would be carry
   3660                         when rounding, otherwise there wouldn't. We use that
   3661                         fact and just add the value of the last discarded bit
   3662                         to the least sifgnificant bit of the shifted value
   3663                         from acc. */
   3664                      assign(t8,
   3665                             IRExpr_ITE(binop(Iop_CmpEQ32,
   3666                                              unop(Iop_8Uto32,
   3667                                                   mkexpr(t15)),
   3668                                              mkU32(0)),
   3669                                        mkU64(0x0ULL),
   3670                                        binop(Iop_And64,
   3671                                              binop(Iop_Shr64,
   3672                                                    mkexpr(t0),
   3673                                                    unop(Iop_32to8,
   3674                                                         binop(Iop_Sub32,
   3675                                                               unop(Iop_8Uto32,
   3676                                                                    mkexpr(t15)),
   3677                                                                    mkU32(1)))),
   3678                                              mkU64(0x1ULL))));
   3679 
   3680                      assign(t9, binop(Iop_Add64, mkexpr(t1), mkexpr(t8)));
   3681                      /* Put rounded value in destination register. */
   3682                      putIReg(rt, unop(Iop_64to32, mkexpr(t9)));
   3683 
   3684                      /* Repeat previous steps for the rounded value. */
   3685                      assign(t10, binop(Iop_CmpNE32,
   3686                                       unop(Iop_64HIto32,
   3687                                            mkexpr(t9)),
   3688                                       mkU32(0)));
   3689                      assign(t11, binop(Iop_CmpNE32,
   3690                                       binop(Iop_And32,
   3691                                             unop(Iop_64to32,
   3692                                                  mkexpr(t9)),
   3693                                             mkU32(0x80000000)),
   3694                                       mkU32(0)));
   3695 
   3696                      assign(t12, binop(Iop_CmpNE32,
   3697                                       unop(Iop_64HIto32,
   3698                                            mkexpr(t9)),
   3699                                       mkU32(0xffffffff)));
   3700                      assign(t13, binop(Iop_CmpNE32,
   3701                                       binop(Iop_And32,
   3702                                             unop(Iop_64to32,
   3703                                                  mkexpr(t9)),
   3704                                             mkU32(0x80000000)),
   3705                                       mkU32(0x80000000)));
   3706 
   3707                      assign(t14, binop(Iop_And32,
   3708                                       binop(Iop_Or32,
   3709                                             unop(Iop_1Sto32, mkexpr(t10)),
   3710                                             unop(Iop_1Sto32, mkexpr(t11))),
   3711                                       binop(Iop_Or32,
   3712                                             unop(Iop_1Sto32, mkexpr(t12)),
   3713                                             unop(Iop_1Sto32, mkexpr(t13)))));
   3714                      putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32,
   3715                                                     mkexpr(t14),
   3716                                                     mkU32(0)),
   3717                                               binop(Iop_Or32,
   3718                                                     getDSPControl(),
   3719                                                     mkU32(0x00800000)),
   3720                                               getDSPControl()));
   3721                      break;
   3722                   }
   3723                   case 0x6: {  /* EXTR_RS.W */
   3724                      DIP("extr_rs.w r%d, ac%d, %d", rt, ac, rs);
   3725                      vassert(!mode64);
   3726                      t0 = newTemp(Ity_I64);
   3727                      t1 = newTemp(Ity_I64);
   3728                      t2 = newTemp(Ity_I32);
   3729                      t3 = newTemp(Ity_I1);
   3730                      t4 = newTemp(Ity_I1);
   3731                      t5 = newTemp(Ity_I1);
   3732                      t6 = newTemp(Ity_I1);
   3733                      t7 = newTemp(Ity_I32);
   3734                      t8 = newTemp(Ity_I64);
   3735                      t9 = newTemp(Ity_I64);
   3736                      t10 = newTemp(Ity_I1);
   3737                      t11 = newTemp(Ity_I1);
   3738                      t12 = newTemp(Ity_I1);
   3739                      t13 = newTemp(Ity_I1);
   3740                      t14 = newTemp(Ity_I32);
   3741                      t16 = newTemp(Ity_I32);
   3742 
   3743                      assign(t0, getAcc(ac));
   3744                      if (0 == rs) {
   3745                         assign(t1, mkexpr(t0));
   3746                      } else {
   3747                         assign(t1, binop(Iop_Sar64, mkexpr(t0), mkU8(rs)));
   3748                      }
   3749 
   3750                      /* Check if bits 63..31 of the result in t1 aren't 0. */
   3751                      assign(t3, binop(Iop_CmpNE32,
   3752                                       unop(Iop_64HIto32,
   3753                                            mkexpr(t1)),
   3754                                       mkU32(0)));
   3755                      assign(t4, binop(Iop_CmpNE32,
   3756                                       binop(Iop_And32,
   3757                                             unop(Iop_64to32,
   3758                                                  mkexpr(t1)),
   3759                                             mkU32(0x80000000)),
   3760                                       mkU32(0)));
   3761                      /* Check if bits 63..31 of the result in t1 aren't
   3762                         0x1ffffffff. */
   3763                      assign(t5, binop(Iop_CmpNE32,
   3764                                       unop(Iop_64HIto32,
   3765                                            mkexpr(t1)),
   3766                                       mkU32(0xffffffff)));
   3767                      assign(t6, binop(Iop_CmpNE32,
   3768                                       binop(Iop_And32,
   3769                                             unop(Iop_64to32,
   3770                                                  mkexpr(t1)),
   3771                                             mkU32(0x80000000)),
   3772                                       mkU32(0x80000000)));
   3773                      /* If bits 63..31 aren't 0 nor 0x1ffffffff, set DSP
   3774                         control register. */
   3775                      assign(t7, binop(Iop_And32,
   3776                                       binop(Iop_Or32,
   3777                                             unop(Iop_1Sto32, mkexpr(t3)),
   3778                                             unop(Iop_1Sto32, mkexpr(t4))),
   3779                                       binop(Iop_Or32,
   3780                                             unop(Iop_1Sto32, mkexpr(t5)),
   3781                                             unop(Iop_1Sto32, mkexpr(t6)))));
   3782                      putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32,
   3783                                                     mkexpr(t7),
   3784                                                     mkU32(0)),
   3785                                               binop(Iop_Or32,
   3786                                                     getDSPControl(),
   3787                                                     mkU32(0x00800000)),
   3788                                               getDSPControl()));
   3789 
   3790                      /* If the last discarded bit is 1, there would be carry
   3791                         when rounding, otherwise there wouldn't. We use that
   3792                         fact and just add the value of the last discarded bit
   3793                         to the least sifgnificant bit of the shifted value
   3794                         from acc. */
   3795                      if (0 == rs) {
   3796                         assign(t8, mkU64(0x0ULL));
   3797                      } else {
   3798                         assign(t8, binop(Iop_And64,
   3799                                          binop(Iop_Shr64,
   3800                                                mkexpr(t0),
   3801                                                mkU8(rs-1)),
   3802                                          mkU64(0x1ULL)));
   3803                      }
   3804 
   3805                      assign(t9, binop(Iop_Add64, mkexpr(t1), mkexpr(t8)));
   3806 
   3807                      /* Repeat previous steps for the rounded value. */
   3808                      assign(t10, binop(Iop_CmpNE32,
   3809                                       unop(Iop_64HIto32,
   3810                                            mkexpr(t9)),
   3811                                       mkU32(0)));
   3812                      assign(t11, binop(Iop_CmpNE32,
   3813                                       binop(Iop_And32,
   3814                                             unop(Iop_64to32,
   3815                                                  mkexpr(t9)),
   3816                                             mkU32(0x80000000)),
   3817                                       mkU32(0)));
   3818 
   3819                      assign(t12, binop(Iop_CmpNE32,
   3820                                       unop(Iop_64HIto32,
   3821                                            mkexpr(t9)),
   3822                                       mkU32(0xffffffff)));
   3823                      assign(t13, binop(Iop_CmpNE32,
   3824                                       binop(Iop_And32,
   3825                                             unop(Iop_64to32,
   3826                                                  mkexpr(t9)),
   3827                                             mkU32(0x80000000)),
   3828                                       mkU32(0x80000000)));
   3829 
   3830                      assign(t14, binop(Iop_And32,
   3831                                       binop(Iop_Or32,
   3832                                             unop(Iop_1Sto32, mkexpr(t10)),
   3833                                             unop(Iop_1Sto32, mkexpr(t11))),
   3834                                       binop(Iop_Or32,
   3835                                             unop(Iop_1Sto32, mkexpr(t12)),
   3836                                             unop(Iop_1Sto32, mkexpr(t13)))));
   3837                      putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32,
   3838                                                     mkexpr(t14),
   3839                                                     mkU32(0)),
   3840                                               binop(Iop_Or32,
   3841                                                     getDSPControl(),
   3842                                                     mkU32(0x00800000)),
   3843                                               getDSPControl()));
   3844 
   3845                      assign(t16, binop(Iop_And32,
   3846                                        unop(Iop_64HIto32,
   3847                                             mkexpr(t9)),
   3848                                        mkU32(0x80000000)));
   3849                      putIReg(rt, IRExpr_ITE(binop(Iop_CmpNE32,
   3850                                                   mkexpr(t14),
   3851                                                   mkU32(0)),
   3852                                             IRExpr_ITE(binop(Iop_CmpEQ32,
   3853                                                              mkexpr(t16),
   3854                                                              mkU32(0)),
   3855                                                        mkU32(0x7fffffff),
   3856                                                        mkU32(0x80000000)),
   3857                                             unop(Iop_64to32, mkexpr(t9))));
   3858                      break;
   3859                   }
   3860                   case 0x7: {  /* EXTRV_RS.W */
   3861                      DIP("extrv_rs.w r%d, ac%d, r%d", rt, ac, rs);
   3862                      vassert(!mode64);
   3863                      t0 = newTemp(Ity_I64);
   3864                      t1 = newTemp(Ity_I64);
   3865                      t2 = newTemp(Ity_I32);
   3866                      t3 = newTemp(Ity_I1);
   3867                      t4 = newTemp(Ity_I1);
   3868                      t5 = newTemp(Ity_I1);
   3869                      t6 = newTemp(Ity_I1);
   3870                      t7 = newTemp(Ity_I32);
   3871                      t8 = newTemp(Ity_I64);
   3872                      t9 = newTemp(Ity_I64);
   3873                      t10 = newTemp(Ity_I1);
   3874                      t11 = newTemp(Ity_I1);
   3875                      t12 = newTemp(Ity_I1);
   3876                      t13 = newTemp(Ity_I1);
   3877                      t14 = newTemp(Ity_I32);
   3878                      t15 = newTemp(Ity_I32);
   3879                      t16 = newTemp(Ity_I32);
   3880                      t17 = newTemp(Ity_I1);
   3881 
   3882                      assign(t15, binop(Iop_And32,
   3883                                        getIReg(rs),
   3884                                        mkU32(0x1f)));
   3885                      assign(t17, binop(Iop_CmpEQ32,
   3886                                        mkexpr(t15),
   3887                                        mkU32(0)));
   3888                      assign(t0, getAcc(ac));
   3889                      assign(t1, IRExpr_ITE(mkexpr(t17),
   3890                                            mkexpr(t0),
   3891                                            binop(Iop_Sar64,
   3892                                                  mkexpr(t0),
   3893                                                  unop(Iop_32to8,
   3894                                                       mkexpr(t15)))));
   3895 
   3896                      /* Check if bits 63..31 of the result in t1 aren't 0. */
   3897                      assign(t3, binop(Iop_CmpNE32,
   3898                                       unop(Iop_64HIto32,
   3899                                            mkexpr(t1)),
   3900                                       mkU32(0)));
   3901                      assign(t4, binop(Iop_CmpNE32,
   3902                                       binop(Iop_And32,
   3903                                             unop(Iop_64to32,
   3904                                                  mkexpr(t1)),
   3905                                             mkU32(0x80000000)),
   3906                                       mkU32(0)));
   3907                      /* Check if bits 63..31 of the result in t1 aren't
   3908                         0x1ffffffff. */
   3909                      assign(t5, binop(Iop_CmpNE32,
   3910                                       unop(Iop_64HIto32,
   3911                                            mkexpr(t1)),
   3912                                       mkU32(0xffffffff)));
   3913                      assign(t6, binop(Iop_CmpNE32,
   3914                                       binop(Iop_And32,
   3915                                             unop(Iop_64to32,
   3916                                                  mkexpr(t1)),
   3917                                             mkU32(0x80000000)),
   3918                                       mkU32(0x80000000)));
   3919                      /* If bits 63..31 aren't 0 nor 0x1ffffffff, set DSP
   3920                         control register. */
   3921                      assign(t7, binop(Iop_And32,
   3922                                       binop(Iop_Or32,
   3923                                             unop(Iop_1Sto32, mkexpr(t3)),
   3924                                             unop(Iop_1Sto32, mkexpr(t4))),
   3925                                       binop(Iop_Or32,
   3926                                             unop(Iop_1Sto32, mkexpr(t5)),
   3927                                             unop(Iop_1Sto32, mkexpr(t6)))));
   3928                      putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32,
   3929                                                     mkexpr(t7),
   3930                                                     mkU32(0)),
   3931                                               binop(Iop_Or32,
   3932                                                     getDSPControl(),
   3933                                                     mkU32(0x00800000)),
   3934                                               getDSPControl()));
   3935 
   3936                      /* If the last discarded bit is 1, there would be carry
   3937                         when rounding, otherwise there wouldn't. We use that
   3938                         fact and just add the value of the last discarded bit
   3939                         to the least sifgnificant bit of the shifted value
   3940                         from acc. */
   3941                      assign(t8,
   3942                             IRExpr_ITE(mkexpr(t17),
   3943                                        mkU64(0x0ULL),
   3944                                        binop(Iop_And64,
   3945                                              binop(Iop_Shr64,
   3946                                                    mkexpr(t0),
   3947                                                    unop(Iop_32to8,
   3948                                                         binop(Iop_Sub32,
   3949                                                               mkexpr(t15),
   3950                                                               mkU32(1)))),
   3951                                              mkU64(0x1ULL))));
   3952 
   3953                      assign(t9, binop(Iop_Add64, mkexpr(t1), mkexpr(t8)));
   3954 
   3955                      /* Repeat previous steps for the rounded value. */
   3956                      assign(t10, binop(Iop_CmpNE32,
   3957                                       unop(Iop_64HIto32,
   3958                                            mkexpr(t9)),
   3959                                       mkU32(0)));
   3960                      assign(t11, binop(Iop_CmpNE32,
   3961                                       binop(Iop_And32,
   3962                                             unop(Iop_64to32,
   3963                                                  mkexpr(t9)),
   3964                                             mkU32(0x80000000)),
   3965                                       mkU32(0)));
   3966 
   3967                      assign(t12, binop(Iop_CmpNE32,
   3968                                       unop(Iop_64HIto32,
   3969                                            mkexpr(t9)),
   3970                                       mkU32(0xffffffff)));
   3971                      assign(t13, binop(Iop_CmpNE32,
   3972                                       binop(Iop_And32,
   3973                                             unop(Iop_64to32,
   3974                                                  mkexpr(t9)),
   3975                                             mkU32(0x80000000)),
   3976                                       mkU32(0x80000000)));
   3977 
   3978                      assign(t14, binop(Iop_And32,
   3979                                       binop(Iop_Or32,
   3980                                             unop(Iop_1Sto32, mkexpr(t10)),
   3981                                             unop(Iop_1Sto32, mkexpr(t11))),
   3982                                       binop(Iop_Or32,
   3983                                             unop(Iop_1Sto32, mkexpr(t12)),
   3984                                             unop(Iop_1Sto32, mkexpr(t13)))));
   3985                      putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32,
   3986                                                     mkexpr(t14),
   3987                                                     mkU32(0)),
   3988                                               binop(Iop_Or32,
   3989                                                     getDSPControl(),
   3990                                                     mkU32(0x00800000)),
   3991                                               getDSPControl()));
   3992 
   3993                      assign(t16, binop(Iop_And32,
   3994                                        unop(Iop_64HIto32,
   3995                                             mkexpr(t9)),
   3996                                        mkU32(0x80000000)));
   3997                      putIReg(rt, IRExpr_ITE(binop(Iop_CmpNE32,
   3998                                                   mkexpr(t14),
   3999                                                   mkU32(0)),
   4000                                             IRExpr_ITE(binop(Iop_CmpEQ32,
   4001                                                              mkexpr(t16),
   4002                                                              mkU32(0)),
   4003                                                        mkU32(0x7fffffff),
   4004                                                        mkU32(0x80000000)),
   4005                                             unop(Iop_64to32, mkexpr(t9))));
   4006                      break;
   4007                   }
   4008                   case 0xA: {  /* EXTPDP */
   4009                      DIP("extpdp r%d, ac%d, %d", rt, ac, rs);
   4010                      vassert(!mode64);
   4011                      t0 = newTemp(Ity_I64);
   4012                      t1 = newTemp(Ity_I32);
   4013                      t2 = newTemp(Ity_I1);
   4014                      t3 = newTemp(Ity_I1);
   4015                      t4 = newTemp(Ity_I8);
   4016                      t5 = newTemp(Ity_I64);
   4017                      t6 = newTemp(Ity_I64);
   4018                      t7 = newTemp(Ity_I32);
   4019                      t8 = newTemp(Ity_I32);
   4020 
   4021                      assign(t0, getAcc(ac));
   4022                      /* Extract pos field of DSPControl register. */
   4023                      assign(t1, binop(Iop_And32, getDSPControl(), mkU32(0x3f)));
   4024 
   4025                      /* Check if (pos - size) >= 0 [size <= pos]
   4026                         if (pos < size)
   4027                            put 1 to EFI field of DSPControl register
   4028                         else
   4029                            extract bits from acc and put 0 to EFI field of
   4030                            DSPCtrl */
   4031                      assign(t2, binop(Iop_CmpLT32U, mkexpr(t1), mkU32(rs)));
   4032 
   4033                      assign(t8, binop(Iop_Or32,
   4034                                       binop(Iop_And32,
   4035                                             getDSPControl(),
   4036                                             mkU32(0xffffbfc0)),
   4037                                       binop(Iop_And32,
   4038                                             binop(Iop_Sub32,
   4039                                                   binop(Iop_And32,
   4040                                                         getDSPControl(),
   4041                                                         mkU32(0x3f)),
   4042                                                   mkU32(rs+1)),
   4043                                             mkU32(0x3f))));
   4044                      putDSPControl(IRExpr_ITE(mkexpr(t2),
   4045                                               binop(Iop_Or32,
   4046                                                      binop(Iop_And32,
   4047                                                            getDSPControl(),
   4048                                                            mkU32(0xffffbfff)),
   4049                                                      mkU32(0x4000)),
   4050                                               mkexpr(t8)));
   4051 
   4052                      /* If pos <= 31, shift right the value from the acc
   4053                         (pos-size) times and take (size+1) bits from the least
   4054                         significant positions. Otherwise, shift left the value
   4055                         (63-pos) times, take (size+1) bits from the most
   4056                         significant positions and shift right (31-size) times.
   4057                      */
   4058                      assign(t3, binop(Iop_CmpLE32U, mkexpr(t1), mkU32(31)));
   4059 
   4060                      assign(t4,
   4061                             IRExpr_ITE(mkexpr(t3),
   4062                                        unop(Iop_32to8,
   4063                                             binop(Iop_Sub32,
   4064                                                   mkexpr(t1), mkU32(rs))),
   4065                                        unop(Iop_32to8,
   4066                                             binop(Iop_Sub32,
   4067                                                   mkU32(63), mkexpr(t1)))));
   4068 
   4069                      assign(t5, IRExpr_ITE(mkexpr(t3),
   4070                                            binop(Iop_Shr64,
   4071                                                  mkexpr(t0), mkexpr(t4)),
   4072                                            binop(Iop_Shl64,
   4073                                                  mkexpr(t0), mkexpr(t4))));
   4074 
   4075                      /* t6 holds a mask for bit extraction. */
   4076                      assign(t6,
   4077                             IRExpr_ITE(mkexpr(t3),
   4078                                        unop(Iop_Not64,
   4079                                             binop(Iop_Shl64,
   4080                                                   mkU64(0xffffffffffffffffULL),
   4081                                                   mkU8(rs+1))),
   4082                                        unop(Iop_Not64,
   4083                                             binop(Iop_Shr64,
   4084                                                   mkU64(0xffffffffffffffffULL),
   4085                                                   mkU8(rs+1)))));
   4086 
   4087                      assign(t7, IRExpr_ITE(mkexpr(t3),
   4088                                            unop(Iop_64to32,
   4089                                                 binop(Iop_And64,
   4090                                                       mkexpr(t5),
   4091                                                       mkexpr(t6))),
   4092                                            binop(Iop_Shr32,
   4093                                                  unop(Iop_64HIto32,
   4094                                                       binop(Iop_And64,
   4095                                                             mkexpr(t5),
   4096                                                             mkexpr(t6))),
   4097                                                  mkU8(31-rs))));
   4098 
   4099                      putIReg(rt, mkexpr(t7));
   4100                      break;
   4101                   }
   4102                   case 0xB: {  /* EXTPDPV */
   4103                      DIP("extpdpv r%d, ac%d, r%d", rt, ac, rs);
   4104                      vassert(!mode64);
   4105                      t0 = newTemp(Ity_I64);
   4106                      t1 = newTemp(Ity_I32);
   4107                      t2 = newTemp(Ity_I1);
   4108                      t3 = newTemp(Ity_I1);
   4109                      t4 = newTemp(Ity_I8);
   4110                      t5 = newTemp(Ity_I64);
   4111                      t6 = newTemp(Ity_I64);
   4112                      t7 = newTemp(Ity_I32);
   4113                      t8 = newTemp(Ity_I32);
   4114                      t9 = newTemp(Ity_I32);
   4115 
   4116                      assign(t8, binop(Iop_And32, getIReg(rs), mkU32(0x1f)));
   4117                      assign(t0, getAcc(ac));
   4118                      /* Extract pos field of DSPControl register. */
   4119                      assign(t1, binop(Iop_And32, getDSPControl(), mkU32(0x3f)));
   4120 
   4121                      /* Check if (pos - size) >= 0 [size <= pos]
   4122                         if (pos < size)
   4123                            put 1 to EFI field of DSPControl register
   4124                         else
   4125                            extract bits from acc and put 0 to EFI field of
   4126                            DSPCtrl */
   4127                      assign(t2, binop(Iop_CmpLT32U, mkexpr(t1), mkexpr(t8)));
   4128 
   4129                      assign(t9, binop(Iop_Or32,
   4130                                       binop(Iop_And32,
   4131                                             getDSPControl(),
   4132                                             mkU32(0xffffbfc0)),
   4133                                       binop(Iop_And32,
   4134                                             binop(Iop_Sub32,
   4135                                                   binop(Iop_And32,
   4136                                                         getDSPControl(),
   4137                                                         mkU32(0x3f)),
   4138                                                   binop(Iop_Add32,
   4139                                                         mkexpr(t8),
   4140                                                         mkU32(0x1))),
   4141                                             mkU32(0x3f))));
   4142                      putDSPControl(IRExpr_ITE(mkexpr(t2),
   4143                                               binop(Iop_Or32,
   4144                                                     binop(Iop_And32,
   4145                                                           getDSPControl(),
   4146                                                           mkU32(0xffffbfff)),
   4147                                                     mkU32(0x4000)),
   4148                                               mkexpr(t9)));
   4149 
   4150                      /* If pos <= 31, shift right the value from the acc
   4151                         (pos-size) times and take (size+1) bits from the least
   4152                         significant positions. Otherwise, shift left the value
   4153                         (63-pos) times, take (size+1) bits from the most
   4154                         significant positions and shift right (31-size) times.
   4155                      */
   4156                      assign(t3, binop(Iop_CmpLE32U, mkexpr(t1), mkU32(31)));
   4157 
   4158                      assign(t4,
   4159                             IRExpr_ITE(mkexpr(t3),
   4160                                       unop(Iop_32to8,
   4161                                            binop(Iop_Sub32,
   4162                                                  mkexpr(t1), mkexpr(t8))),
   4163                                       unop(Iop_32to8,
   4164                                            binop(Iop_Sub32,
   4165                                                  mkU32(63), mkexpr(t1)))));
   4166 
   4167                      assign(t5, IRExpr_ITE(mkexpr(t3),
   4168                                            binop(Iop_Shr64,
   4169                                                  mkexpr(t0), mkexpr(t4)),
   4170                                            binop(Iop_Shl64,
   4171                                                  mkexpr(t0), mkexpr(t4))));
   4172 
   4173                      /* t6 holds a mask for bit extraction. */
   4174                      assign(t6,
   4175                             IRExpr_ITE(mkexpr(t3),
   4176                                        unop(Iop_Not64,
   4177                                             binop(Iop_Shl64,
   4178                                                   mkU64(0xffffffffffffffffULL),
   4179                                                   unop(Iop_32to8,
   4180                                                        binop(Iop_Add32,
   4181                                                              mkexpr(t8),
   4182                                                              mkU32(1))))),
   4183                                        unop(Iop_Not64,
   4184                                             binop(Iop_Shr64,
   4185                                                   mkU64(0xffffffffffffffffULL),
   4186                                                   unop(Iop_32to8,
   4187                                                        binop(Iop_Add32,
   4188                                                              mkexpr(t8),
   4189                                                              mkU32(1)))))));
   4190 
   4191                      assign(t7, IRExpr_ITE(mkexpr(t3),
   4192                                            unop(Iop_64to32,
   4193                                                 binop(Iop_And64,
   4194                                                       mkexpr(t5),
   4195                                                       mkexpr(t6))),
   4196                                            binop(Iop_Shr32,
   4197                                                  unop(Iop_64HIto32,
   4198                                                       binop(Iop_And64,
   4199                                                             mkexpr(t5),
   4200                                                             mkexpr(t6))),
   4201                                                  unop(Iop_32to8,
   4202                                                       binop(Iop_Sub32,
   4203                                                             mkU32(31),
   4204                                                             mkexpr(t8))))));
   4205 
   4206                      putIReg(rt, mkexpr(t7));
   4207                      break;
   4208                   }
   4209                   case 0xE: {  /* EXTR_S.H */
   4210                      DIP("extr_s.h r%d, ac%d, %d", rt, ac, rs);
   4211                      vassert(!mode64);
   4212                      t0 = newTemp(Ity_I64);
   4213                      t1 = newTemp(Ity_I64);
   4214                      t2 = newTemp(Ity_I32);
   4215                      t3 = newTemp(Ity_I64);
   4216                      t4 = newTemp(Ity_I32);
   4217                      t5 = newTemp(Ity_I32);
   4218                      t6 = newTemp(Ity_I64);
   4219                      t7 = newTemp(Ity_I32);
   4220                      t9 = newTemp(Ity_I32);
   4221 
   4222                      assign(t0, getAcc(ac));
   4223 
   4224                      assign(t1, binop(Iop_Sar64, mkexpr(t0), mkU8(rs)));
   4225 
   4226                      assign(t2, binop(Iop_Or32,
   4227                                       getDSPControl(), mkU32(0x00800000)));
   4228 
   4229                      assign(t9, binop(Iop_And32,
   4230                                       unop(Iop_64to32,
   4231                                            mkexpr(t1)),
   4232                                       mkU32(0x80000000)));
   4233                      putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32,
   4234                                                     mkexpr(t9),
   4235                                                     binop(Iop_And32,
   4236                                                           unop(Iop_64HIto32,
   4237                                                                mkexpr(t0)),
   4238                                                           mkU32(0x80000000))),
   4239                                               mkexpr(t2),
   4240                                               getDSPControl()));
   4241 
   4242                      /* Check if t1 > 0x7fff ((t1 - 0x7fff) > 0)
   4243                         1. subtract 0x7fff from t1
   4244                         2. if the resulting number is positive (sign bit = 0)
   4245                            and any of the other bits is 1, the value is > 0. */
   4246                      assign(t3, binop(Iop_Sub64,
   4247                                       mkexpr(t1),
   4248                                       mkU64(0x0000000000007fffULL)));
   4249                      assign(t4, binop(Iop_And32,
   4250                                        binop(Iop_Or32,
   4251                                             unop(Iop_1Sto32,
   4252                                                  binop(Iop_CmpNE32,
   4253                                                        mkU32(0),
   4254                                                        binop(Iop_And32,
   4255                                                              unop(Iop_64HIto32,
   4256                                                                   mkexpr(t3)),
   4257                                                              mkU32(0x7fffffff)))),
   4258                                             unop(Iop_1Sto32,
   4259                                                  binop(Iop_CmpNE32,
   4260                                                        mkU32(0),
   4261                                                        unop(Iop_64to32,
   4262                                                             mkexpr(t3))))),
   4263                                        unop(Iop_1Sto32,
   4264                                             binop(Iop_CmpEQ32,
   4265                                                   binop(Iop_And32,
   4266                                                         unop(Iop_64HIto32,
   4267                                                                   mkexpr(t3)),
   4268                                                              mkU32(0x80000000)),
   4269                                                   mkU32(0)))));
   4270                      putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32,
   4271                                                     mkU32(0),
   4272                                                     mkexpr(t4)),
   4273                                               binop(Iop_Or32,
   4274                                                     getDSPControl(),
   4275                                                     mkU32(0x00800000)),
   4276                                               getDSPControl()));
   4277                      /* Check if t1<0xffffffffffff8000 (0xffffffffffff8000-t1)>0
   4278                         1. subtract t1 from 0xffffffffffff8000
   4279                         2. if the resulting number is positive (sign bit = 0)
   4280                             and any of the other bits is 1, the value is > 0 */
   4281                      assign(t6, binop(Iop_Sub64,
   4282                                        mkU64(0xffffffffffff8000ULL),
   4283                                        mkexpr(t1)));
   4284                      assign(t7, binop(Iop_And32,
   4285                                       binop(Iop_Or32,
   4286                                             unop(Iop_1Sto32,
   4287                                                  binop(Iop_CmpNE32,
   4288                                                        mkU32(0),
   4289                                                        binop(Iop_And32,
   4290                                                              unop(Iop_64HIto32,
   4291                                                                   mkexpr(t6)),
   4292                                                              mkU32(0x7fffffff)))),
   4293                                             unop(Iop_1Sto32,
   4294                                                  binop(Iop_CmpNE32,
   4295                                                        mkU32(0),
   4296                                                        unop(Iop_64to32,
   4297                                                             mkexpr(t6))))),
   4298                                       unop(Iop_1Sto32,
   4299                                             binop(Iop_CmpEQ32,
   4300                                                   binop(Iop_And32,
   4301                                                         unop(Iop_64HIto32,
   4302                                                                   mkexpr(t6)),
   4303                                                              mkU32(0x80000000)),
   4304                                                   mkU32(0)))));
   4305                      putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32,
   4306                                                     mkU32(0),
   4307                                                     mkexpr(t7)),
   4308                                               binop(Iop_Or32,
   4309                                                     getDSPControl(),
   4310                                                     mkU32(0x00800000)),
   4311                                               getDSPControl()));
   4312                      putIReg(rt, IRExpr_ITE(binop(Iop_CmpNE32,
   4313                                                     mkU32(0),
   4314                                                     mkexpr(t4)),
   4315                                             mkU32(0x00007fff),
   4316                                             IRExpr_ITE(binop(Iop_CmpNE32,
   4317                                                              mkU32(0),
   4318                                                              mkexpr(t7)),
   4319                                                        mkU32(0xffff8000),
   4320                                                        unop(Iop_64to32,
   4321                                                             mkexpr(t1)))));
   4322                      break;
   4323                   }
   4324                   case 0xF: {  /* EXTRV_S.H */
   4325                      DIP("extrv_s.h r%d, ac%d, %d", rt, ac, rs);
   4326                      vassert(!mode64);
   4327                      t0 = newTemp(Ity_I64);
   4328                      t1 = newTemp(Ity_I64);
   4329                      t2 = newTemp(Ity_I32);
   4330                      t3 = newTemp(Ity_I64);
   4331                      t4 = newTemp(Ity_I32);
   4332                      t5 = newTemp(Ity_I32);
   4333                      t6 = newTemp(Ity_I64);
   4334                      t7 = newTemp(Ity_I32);
   4335                      t9 = newTemp(Ity_I32);
   4336 
   4337                      assign(t0, getAcc(ac));
   4338 
   4339                      assign(t1, binop(Iop_Sar64,
   4340                                       mkexpr(t0),
   4341                                       unop(Iop_32to8,
   4342                                            binop(Iop_And32,
   4343                                                  getIReg(rs),
   4344                                                  mkU32(0x1f)))));
   4345 
   4346                      assign(t2, binop(Iop_Or32,
   4347                                       getDSPControl(), mkU32(0x00800000)));
   4348 
   4349                      assign(t9, binop(Iop_And32,
   4350                                       unop(Iop_64to32,
   4351                                            mkexpr(t1)),
   4352                                       mkU32(0x80000000)));
   4353                      putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32,
   4354                                                     mkexpr(t9),
   4355                                                     binop(Iop_And32,
   4356                                                           unop(Iop_64HIto32,
   4357                                                                mkexpr(t0)),
   4358                                                           mkU32(0x80000000))),
   4359                                               mkexpr(t2),
   4360                                               getDSPControl()));
   4361 
   4362                      /* Check if t1 > 0x7fff ((t1 - 0x7fff) > 0)
   4363                         1. subtract 0x7fff from t1
   4364                         2. if the resulting number is positive (sign bit = 0)
   4365                            and any of the other bits is 1, the value is > 0. */
   4366                      assign(t3, binop(Iop_Sub64,
   4367                                       mkexpr(t1),
   4368                                       mkU64(0x0000000000007fffULL)));
   4369                      assign(t4, binop(Iop_And32,
   4370                                        binop(Iop_Or32,
   4371                                             unop(Iop_1Sto32,
   4372                                                  binop(Iop_CmpNE32,
   4373                                                        mkU32(0),
   4374                                                        binop(Iop_And32,
   4375                                                              unop(Iop_64HIto32,
   4376                                                                   mkexpr(t3)),
   4377                                                              mkU32(0x7fffffff)))),
   4378                                             unop(Iop_1Sto32,
   4379                                                  binop(Iop_CmpNE32,
   4380                                                        mkU32(0),
   4381                                                        unop(Iop_64to32,
   4382                                                             mkexpr(t3))))),
   4383                                        unop(Iop_1Sto32,
   4384                                             binop(Iop_CmpEQ32,
   4385                                                   binop(Iop_And32,
   4386                                                         unop(Iop_64HIto32,
   4387                                                                   mkexpr(t3)),
   4388                                                              mkU32(0x80000000)),
   4389                                                   mkU32(0)))));
   4390                      putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32,
   4391                                                     mkU32(0),
   4392                                                     mkexpr(t4)),
   4393                                               binop(Iop_Or32,
   4394                                                     getDSPControl(),
   4395                                                     mkU32(0x00800000)),
   4396                                               getDSPControl()));
   4397                      /* Check if t1<0xffffffffffff8000 (0xffffffffffff8000-t1)>0
   4398                         1. subtract t1 from 0xffffffffffff8000
   4399                         2. if the resulting number is positive (sign bit = 0)
   4400                             and any of the other bits is 1, the value is > 0 */
   4401                      assign(t6, binop(Iop_Sub64,
   4402                                        mkU64(0xffffffffffff8000ULL),
   4403                                        mkexpr(t1)));
   4404                      assign(t7, binop(Iop_And32,
   4405                                       binop(Iop_Or32,
   4406                                             unop(Iop_1Sto32,
   4407                                                  binop(Iop_CmpNE32,
   4408                                                        mkU32(0),
   4409                                                        binop(Iop_And32,
   4410                                                              unop(Iop_64HIto32,
   4411                                                                   mkexpr(t6)),
   4412                                                              mkU32(0x7fffffff)))),
   4413                                             unop(Iop_1Sto32,
   4414                                                  binop(Iop_CmpNE32,
   4415                                                        mkU32(0),
   4416                                                        unop(Iop_64to32,
   4417                                                             mkexpr(t6))))),
   4418                                       unop(Iop_1Sto32,
   4419                                             binop(Iop_CmpEQ32,
   4420                                                   binop(Iop_And32,
   4421                                                         unop(Iop_64HIto32,
   4422                                                                   mkexpr(t6)),
   4423                                                              mkU32(0x80000000)),
   4424                                                   mkU32(0)))));
   4425                      putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32,
   4426                                                     mkU32(0),
   4427                                                     mkexpr(t7)),
   4428                                               binop(Iop_Or32,
   4429                                                     getDSPControl(),
   4430                                                     mkU32(0x00800000)),
   4431                                               getDSPControl()));
   4432                      putIReg(rt, IRExpr_ITE(binop(Iop_CmpNE32,
   4433                                                     mkU32(0),
   4434                                                     mkexpr(t4)),
   4435                                             mkU32(0x00007fff),
   4436                                             IRExpr_ITE(binop(Iop_CmpNE32,
   4437                                                              mkU32(0),
   4438                                                              mkexpr(t7)),
   4439                                                        mkU32(0xffff8000),
   4440                                                        unop(Iop_64to32,
   4441                                                             mkexpr(t1)))));
   4442                      break;
   4443                   }
   4444                   case 0x12: {  /* RDDSP*/
   4445                      DIP("rddsp r%d, mask 0x%x", rd, rddsp_mask);
   4446                      vassert(!mode64);
   4447 
   4448                      putIReg(rd, mkU32(0x0));
   4449 
   4450                      if ((rddsp_mask & 0x1) == 0x1) {
   4451                         /* Read pos field (bits 5-0) of DSPControl register. */
   4452                         putIReg(rd, binop(Iop_Or32,
   4453                                           getIReg(rd),
   4454                                           binop(Iop_And32,
   4455                                                 getDSPControl(),
   4456                                                 mkU32(0x0000003F))));
   4457                      }
   4458 
   4459                      if ((rddsp_mask & 0x2) == 0x2) {
   4460                         /* Read scount field (bits 12-7) of DSPControl
   4461                            register. */
   4462                         putIReg(rd, binop(Iop_Or32,
   4463                                           getIReg(rd),
   4464                                           binop(Iop_And32,
   4465                                                 getDSPControl(),
   4466                                                 mkU32(0x00001F80))));
   4467                      }
   4468 
   4469                      if ((rddsp_mask & 0x4) == 0x4) {
   4470                         /* Read C field (bit 13) of DSPControl register. */
   4471                         putIReg(rd, binop(Iop_Or32,
   4472                                           getIReg(rd),
   4473                                           binop(Iop_And32,
   4474                                                 getDSPControl(),
   4475                                                 mkU32(0x00002000))));
   4476                      }
   4477 
   4478                      if ((rddsp_mask & 0x8) == 0x8) {
   4479                         /* Read outflag field (bit s 23-16) of DSPControl
   4480                            register. */
   4481                         putIReg(rd, binop(Iop_Or32,
   4482                                           getIReg(rd),
   4483                                           binop(Iop_And32,
   4484                                                 getDSPControl(),
   4485                                                 mkU32(0x00FF0000))));
   4486                      }
   4487 
   4488                      if ((rddsp_mask & 0x10) == 0x10) {
   4489                         /* Read ccond field (bits 31-24) of DSPControl
   4490                            register. */
   4491                         putIReg(rd, binop(Iop_Or32,
   4492                                           getIReg(rd),
   4493                                           binop(Iop_And32,
   4494                                                 getDSPControl(),
   4495                                                 mkU32(0xFF000000))));
   4496                      }
   4497 
   4498                      if ((rddsp_mask & 0x20) == 0x20) {
   4499                         /* Read EFI field (bit 14) of DSPControl register. */
   4500                         putIReg(rd, binop(Iop_Or32,
   4501                                           getIReg(rd),
   4502                                           binop(Iop_And32,
   4503                                                 getDSPControl(),
   4504                                                 mkU32(0x00004000))));
   4505                      }
   4506 
   4507                      if ((rddsp_mask & 0x3f) == 0x3f) {
   4508                         /* Read all fields of DSPControl register. */
   4509                         putIReg(rd, getDSPControl());
   4510                      }
   4511                      break;
   4512                   }
   4513                   case 0x13: {  /* WRDSP */
   4514                      DIP("wrdsp r%d, mask 0x%x", rs, wrdsp_mask);
   4515                      vassert(!mode64);
   4516 
   4517                      if ((wrdsp_mask & 0x3f) == 0x3f) {
   4518                         /* If mips64 put all fields of rs, except bit 15 and bit
   4519                            6, to DSPControl register, otherwise put all except
   4520                            bits 15, 6 and bits 31..28. */
   4521                         putDSPControl(mode64 ?
   4522                                       binop(Iop_And32,
   4523                                             getIReg(rs),
   4524                                             mkU32(0xffff7fbf)) :
   4525                                       binop(Iop_And32,
   4526                                             getIReg(rs),
   4527                                             mkU32(0x0fff7fbf)));
   4528                      } else {
   4529                         if ((wrdsp_mask & 0x1) == 0x1) {
   4530                            /* Put bits 5-0 of rs to DSPControl register pos
   4531                               field. */
   4532                            putDSPControl(binop(Iop_Or32,
   4533                                                binop(Iop_And32,
   4534                                                      getDSPControl(),
   4535                                                      mkU32(0xFFFF7F40)),
   4536                                                binop(Iop_And32,
   4537                                                      getIReg(rs),
   4538                                                      mkU32(0x0000003F))));
   4539                         }
   4540 
   4541                         if ((wrdsp_mask & 0x2) == 0x2) {
   4542                            /* Put bits 12-7 of rs to DSPControl scount field. */
   4543                            putDSPControl(binop(Iop_Or32,
   4544                                                binop(Iop_And32,
   4545                                                      getDSPControl(),
   4546                                                      mkU32(0xFFFFE03F)),
   4547                                                binop(Iop_And32,
   4548                                                      getIReg(rs),
   4549                                                      mkU32(0x00001F80))));
   4550                         }
   4551 
   4552                         if ((wrdsp_mask & 0x4) == 0x4) {
   4553                            /* Put bit 13 of rs to DSPControl register C
   4554                               field. */
   4555                            putDSPControl(binop(Iop_Or32,
   4556                                                binop(Iop_And32,
   4557                                                      getDSPControl(),
   4558                                                      mkU32(0xFFFF5FBF)),
   4559                                                binop(Iop_And32,
   4560                                                      getIReg(rs),
   4561                                                      mkU32(0x00002000))));
   4562                         }
   4563 
   4564                         if ((wrdsp_mask & 0x8) == 0x8) {
   4565                            /* Put bits 23-16 of rs to DSPControl reg outflag
   4566                               field. */
   4567                            putDSPControl(binop(Iop_Or32,
   4568                                                binop(Iop_And32,
   4569                                                      getDSPControl(),
   4570                                                      mkU32(0xFF007FBF)),
   4571                                                binop(Iop_And32,
   4572                                                      getIReg(rs),
   4573                                                      mkU32(0x00FF0000))));
   4574                         }
   4575 
   4576                         if ((wrdsp_mask & 0x10) == 0x10) {
   4577                            /* Put bits 31-24 of rs to DSPControl reg ccond
   4578                               field. */
   4579                            putDSPControl(binop(Iop_Or32,
   4580                                                binop(Iop_And32,
   4581                                                      getDSPControl(),
   4582                                                      mkU32(0x00FF7FBF)),
   4583                                                binop(Iop_And32,
   4584                                                      getIReg(rs),
   4585                                                      mode64 ? mkU32(0xFF000000)
   4586                                                             : mkU32(0x0F000000))
   4587                                                )
   4588                                         );
   4589                         }
   4590 
   4591                         if ((wrdsp_mask & 0x20) == 0x20) {
   4592                            /* Put bit 14 of rs to DSPControl register EFI
   4593                               field. */
   4594                            putDSPControl(binop(Iop_Or32,
   4595                                                binop(Iop_And32,
   4596                                                      getDSPControl(),
   4597                                                      mkU32(0xFFFF3FBF)),
   4598                                                binop(Iop_And32,
   4599                                                      getIReg(rs),
   4600                                                      mkU32(0x00004000))));
   4601                         }
   4602                      }
   4603                      break;
   4604                   }
   4605                   case 0x1A: {  /* SHILO */
   4606                      DIP("shilo ac%d, %d", ac, shift);
   4607                      vassert(!mode64);
   4608                      t0 = newTemp(Ity_I64);
   4609                      t1 = newTemp(Ity_I64);
   4610 
   4611                      assign(t0, getAcc(ac));
   4612 
   4613                      putAcc(ac, mkexpr(t0));
   4614 
   4615                      if (0x20 == (shift & 0x3f)) {
   4616                         putAcc(ac, binop(Iop_32HLto64,
   4617                                          unop(Iop_64to32, mkexpr(t0)),
   4618                                          mkU32(0x0)));
   4619                      } else if (0x20 == (shift & 0x20)) {
   4620                         assign(t1, binop(Iop_Shl64,
   4621                                          mkexpr(t0),
   4622                                          unop(Iop_32to8,
   4623                                               binop(Iop_Add32,
   4624                                                     unop(Iop_Not32,
   4625                                                          mkU32(shift)),
   4626                                                     mkU32(0x1)))));
   4627 
   4628                         putAcc(ac, mkexpr(t1));
   4629                      } else {
   4630                         assign(t1, binop(Iop_Shr64, mkexpr(t0), mkU8(shift)));
   4631 
   4632                         putAcc(ac, mkexpr(t1));
   4633                      }
   4634                      break;
   4635                   }
   4636                   case 0x1B: {  /* SHILOV */
   4637                      DIP("shilov ac%d, r%d", ac, rs);
   4638                      vassert(!mode64);
   4639                      t0 = newTemp(Ity_I64);
   4640                      t1 = newTemp(Ity_I32);
   4641                      t2 = newTemp(Ity_I1);
   4642                      t3 = newTemp(Ity_I64);
   4643                      t4 = newTemp(Ity_I64);
   4644 
   4645                      assign(t0, getAcc(ac));
   4646                      assign(t1, binop(Iop_And32, getIReg(rs), mkU32(0x3f)));
   4647                      assign(t2, binop(Iop_CmpEQ32, mkexpr(t1), mkU32(0x20)));
   4648                      assign(t3, binop(Iop_Shl64,
   4649                                       mkexpr(t0),
   4650                                       unop(Iop_32to8,
   4651                                            binop(Iop_Add32,
   4652                                                  unop(Iop_Not32,
   4653                                                       mkexpr(t1)),
   4654                                                  mkU32(0x1)))));
   4655                      assign(t4, binop(Iop_Shr64,
   4656                                       mkexpr(t0),
   4657                                       unop(Iop_32to8,
   4658                                            mkexpr(t1))));
   4659 
   4660                      putAcc(ac,
   4661                             IRExpr_ITE(mkexpr(t2),
   4662                                        binop(Iop_32HLto64,
   4663                                              unop(Iop_64to32, mkexpr(t0)),
   4664                                              mkU32(0x0)),
   4665                                        IRExpr_ITE(binop(Iop_CmpEQ32,
   4666                                                         binop(Iop_And32,
   4667                                                               mkexpr(t1),
   4668                                                               mkU32(0x20)),
   4669                                                         mkU32(0x20)),
   4670                                                   mkexpr(t3),
   4671                                                   mkexpr(t4))));
   4672                      break;
   4673                   }
   4674                   case 0x1F: {  /* MTHLIP */
   4675                      DIP("mthlip r%d, ac%d", rs, ac);
   4676                      vassert(!mode64);
   4677                      t0 = newTemp(Ity_I64);
   4678                      t1 = newTemp(Ity_I32);
   4679                      t2 = newTemp(Ity_I32);
   4680                      t3 = newTemp(Ity_I1);
   4681 
   4682                      assign(t0, getAcc(ac));
   4683                      putAcc(ac, binop(Iop_32HLto64,
   4684                                       unop(Iop_64to32, mkexpr(t0)),
   4685                                       getIReg(rs)));
   4686                      assign(t1, binop(Iop_And32, getDSPControl(), mkU32(0x3f)));
   4687                      putDSPControl(IRExpr_ITE(binop(Iop_CmpLE32U,
   4688                                                     mkU32(32),
   4689                                                     mkexpr(t1)),
   4690                                               binop(Iop_Or32,
   4691                                                     binop(Iop_Sub32,
   4692                                                           mkexpr(t1),
   4693                                                           mkU32(32)),
   4694                                                    binop(Iop_And32,
   4695                                                          getDSPControl(),
   4696                                                          mkU32(0xffffffc0))),
   4697                                               binop(Iop_Or32,
   4698                                                     binop(Iop_Add32,
   4699                                                           mkexpr(t1),
   4700                                                           mkU32(32)),
   4701                                                     binop(Iop_And32,
   4702                                                           getDSPControl(),
   4703                                                           mkU32(0xffffffc0)))));
   4704                      break;
   4705                   }
   4706                   default:
   4707                      return -1;
   4708                }
   4709                break;  /* end of EXTR.W */
   4710             }
   4711             case 0xA: {  /* LX */
   4712                switch(sa) {
   4713                   case 0x0: {  /* LWX */
   4714                      DIP("lwx r%d, r%d(r%d)", rd, rt, rs);
   4715                      vassert(!mode64);
   4716                      t0 = newTemp(Ity_I32);
   4717 
   4718                      assign(t0, binop(Iop_Add32, getIReg(rt), getIReg(rs)));
   4719 
   4720                      putIReg(rd, load(Ity_I32, mkexpr(t0)));
   4721                      break;
   4722                   }
   4723                   case 0x4: {  /* LHX */
   4724                      DIP("lhx r%d, r%d(r%d)", rd, rt, rs);
   4725                      vassert(!mode64);
   4726                      t0 = newTemp(Ity_I32);
   4727 
   4728                      assign(t0, binop(Iop_Add32, getIReg(rt), getIReg(rs)));
   4729 
   4730                      putIReg(rd, unop(Iop_16Sto32, load(Ity_I16, mkexpr(t0))));
   4731                      break;
   4732                   }
   4733                   case 0x6: {  /* LBUX */
   4734                      DIP("lbux r%d, r%d(r%d)", rd, rt, rs);
   4735                      vassert(!mode64);
   4736                      t0 = newTemp(Ity_I32);
   4737 
   4738                      assign(t0, binop(Iop_Add32, getIReg(rt), getIReg(rs)));
   4739 
   4740                      putIReg(rd, unop(Iop_8Uto32, load(Ity_I8, mkexpr(t0))));
   4741                      break;
   4742                   }
   4743                   default:
   4744                      return -1;
   4745                }
   4746                break;  /* end of LX */
   4747             }
   4748             case 0xC: {  /* INSV */
   4749                switch(sa) {
   4750                   case 0x0: {  /* INSV */
   4751                      DIP("insv r%d, r%d", rt, rs);
   4752                      vassert(!mode64);
   4753 
   4754                      t0 = newTemp(Ity_I32);
   4755                      t1 = newTemp(Ity_I32);
   4756                      t2 = newTemp(Ity_I8);
   4757                      t3 = newTemp(Ity_I8);
   4758                      t4 = newTemp(Ity_I32);
   4759                      t5 = newTemp(Ity_I1);
   4760                      t6 = newTemp(Ity_I32);
   4761                      t7 = newTemp(Ity_I32);
   4762                      t8 = newTemp(Ity_I32);
   4763                      t9 = newTemp(Ity_I32);
   4764 
   4765                      /* t0 <- pos field of DSPControl register. */
   4766                      assign(t0, binop(Iop_And32, getDSPControl(), mkU32(0x3f)));
   4767                      /* t1 <- scount field of DSPControl register. */
   4768                      assign(t1, binop(Iop_Shr32,
   4769                                       binop(Iop_And32,
   4770                                             getDSPControl(),
   4771                                             mkU32(0x1f80)),
   4772                                       mkU8(7)));
   4773 
   4774                      assign(t2, unop(Iop_32to8,
   4775                                      binop(Iop_Add32,
   4776                                            mkexpr(t1),
   4777                                            mkexpr(t0))));
   4778 
   4779                      /* 32-(pos+size) most significant bits of rt. */
   4780                      assign(t6, binop(Iop_Shl32,
   4781                                       binop(Iop_Shr32,
   4782                                             getIReg(rt),
   4783                                             mkexpr(t2)),
   4784                                       mkexpr(t2)));
   4785 
   4786                      assign(t3, unop(Iop_32to8,
   4787                                      binop(Iop_Sub32,
   4788                                            mkU32(32),
   4789                                            mkexpr(t0))));
   4790                      /* Pos least significant bits of rt. */
   4791                      assign(t7, binop(Iop_Shr32,
   4792                                       binop(Iop_Shl32,
   4793                                             getIReg(rt),
   4794                                             mkexpr(t3)),
   4795                                       mkexpr(t3)));
   4796 
   4797                      /* Size least significant bits of rs,
   4798                         shifted to appropriate position. */
   4799                      assign(t8, binop(Iop_Shl32,
   4800                                       binop(Iop_And32,
   4801                                             getIReg(rs),
   4802                                             unop(Iop_Not32,
   4803                                                  binop(Iop_Shl32,
   4804                                                        mkU32(0xffffffff),
   4805                                                        unop(Iop_32to8,
   4806                                                             mkexpr(t1))))),
   4807                                       unop(Iop_32to8,
   4808                                            mkexpr(t0))));
   4809 
   4810                      putIReg(rt, IRExpr_ITE(binop(Iop_CmpEQ32,
   4811                                                   mkexpr(t0),
   4812                                                   mkU32(0)),
   4813                                             IRExpr_ITE(binop(Iop_CmpEQ32,
   4814                                                              mkexpr(t1),
   4815                                                              mkU32(32)),
   4816                                                        getIReg(rs),
   4817                                                        binop(Iop_Or32,
   4818                                                              mkexpr(t6),
   4819                                                              mkexpr(t8))),
   4820                                             IRExpr_ITE(binop(Iop_CmpEQ32,
   4821                                                              unop(Iop_8Uto32,
   4822                                                                   mkexpr(t2)),
   4823                                                              mkU32(32)),
   4824                                                        binop(Iop_Or32,
   4825                                                              mkexpr(t7),
   4826                                                              mkexpr(t8)),
   4827                                                        binop(Iop_Or32,
   4828                                                              binop(Iop_Or32,
   4829                                                                    mkexpr(t6),
   4830                                                                    mkexpr(t7)),
   4831                                                              mkexpr(t8)))));
   4832                      break;
   4833                   }
   4834                   default:
   4835                      return -1;
   4836                }
   4837                break;  /* enf of INSV */
   4838             }
   4839             case 0x10: {  /* ADDU.QB */
   4840                switch(sa) {
   4841                   case 0x00: {  /* ADDU.QB */
   4842                      DIP("addu.qb r%d, r%d, r%d", rd, rs, rt);
   4843                      vassert(!mode64);
   4844                      t0 = newTemp(Ity_I32);
   4845                      t1 = newTemp(Ity_I1);
   4846                      t2 = newTemp(Ity_I32);
   4847                      t3 = newTemp(Ity_I1);
   4848                      t4 = newTemp(Ity_I32);
   4849                      t5 = newTemp(Ity_I1);
   4850                      t6 = newTemp(Ity_I32);
   4851                      t7 = newTemp(Ity_I1);
   4852                      t8 = newTemp(Ity_I32);
   4853 
   4854                      /* Add rightmost bytes of rs and rt. */
   4855                      assign(t0,
   4856                             binop(Iop_Add32,
   4857                                   unop(Iop_8Uto32,
   4858                                        unop(Iop_16to8,
   4859                                             unop(Iop_32to16, getIReg(rs)))),
   4860                                   unop(Iop_8Uto32,
   4861                                        unop(Iop_16to8,
   4862                                             unop(Iop_32to16, getIReg(rt))))));
   4863                      /* t1 will be 1 if there is overflow, 0 otherwise. */
   4864                      assign(t1, binop(Iop_CmpEQ32,
   4865                                       binop(Iop_And32,
   4866                                             mkexpr(t0),
   4867                                             mkU32(0x00000100)),
   4868                                       mkU32(0x00000100)));
   4869 
   4870                      /* Add bits 15-8 of rs and rt. */
   4871                      assign(t2,
   4872                             binop(Iop_Add32,
   4873                                   unop(Iop_8Uto32,
   4874                                        unop(Iop_16HIto8,
   4875                                             unop(Iop_32to16, getIReg(rs)))),
   4876                                   unop(Iop_8Uto32,
   4877                                        unop(Iop_16HIto8,
   4878                                             unop(Iop_32to16, getIReg(rt))))));
   4879                      /* t3 will be 1 if there is overflow, 0 otherwise. */
   4880                      assign(t3, binop(Iop_CmpEQ32,
   4881                                       binop(Iop_And32,
   4882                                             mkexpr(t2),
   4883                                             mkU32(0x00000100)),
   4884                                       mkU32(0x00000100)));
   4885 
   4886                      /* Add bits 15-8 of rs and rt. */
   4887                      assign(t4,
   4888                             binop(Iop_Add32,
   4889                                   unop(Iop_8Uto32,
   4890                                        unop(Iop_16to8,
   4891                                             unop(Iop_32HIto16, getIReg(rs)))),
   4892                                   unop(Iop_8Uto32,
   4893                                        unop(Iop_16to8,
   4894                                             unop(Iop_32HIto16, getIReg(rt))))));
   4895                      /* t5 will be 1 if there is overflow, 0 otherwise. */
   4896                      assign(t5, binop(Iop_CmpEQ32,
   4897                                       binop(Iop_And32,
   4898                                             mkexpr(t4),
   4899                                             mkU32(0x00000100)),
   4900                                       mkU32(0x00000100)));
   4901 
   4902                      /* Add bits 15-8 of rs and rt. */
   4903                      assign(t6,
   4904                             binop(Iop_Add32,
   4905                                   unop(Iop_8Uto32,
   4906                                        unop(Iop_16HIto8,
   4907                                             unop(Iop_32HIto16, getIReg(rs)))),
   4908                                   unop(Iop_8Uto32,
   4909                                        unop(Iop_16HIto8,
   4910                                             unop(Iop_32HIto16, getIReg(rt))))));
   4911                      /* t7 will be 1 if there is overflow, 0 otherwise. */
   4912                      assign(t7, binop(Iop_CmpEQ32,
   4913                                       binop(Iop_And32,
   4914                                             mkexpr(t6),
   4915                                             mkU32(0x00000100)),
   4916                                       mkU32(0x00000100)));
   4917 
   4918                      assign(t8,
   4919                             binop(Iop_Or32,
   4920                                   binop(Iop_Or32,
   4921                                         binop(Iop_Or32,
   4922                                               unop(Iop_1Sto32, mkexpr(t7)),
   4923                                               unop(Iop_1Sto32,  mkexpr(t5))),
   4924                                         unop(Iop_1Sto32, mkexpr(t3))),
   4925                                   unop(Iop_1Sto32, mkexpr(t1))));
   4926 
   4927                      putDSPControl(IRExpr_ITE(binop(Iop_CmpEQ32,
   4928                                                     mkexpr(t8),
   4929                                                     mkU32(0x0)),
   4930                                               getDSPControl(),
   4931                                               binop(Iop_Or32,
   4932                                                     getDSPControl(),
   4933                                                     mkU32(0x00100000))));
   4934 
   4935                      putIReg(rd, binop(Iop_16HLto32,
   4936                                        binop(Iop_8HLto16,
   4937                                              unop(Iop_32to8, mkexpr(t6)),
   4938                                              unop(Iop_32to8, mkexpr(t4))),
   4939                                        binop(Iop_8HLto16,
   4940                                              unop(Iop_32to8, mkexpr(t2)),
   4941                                              unop(Iop_32to8, mkexpr(t0)))));
   4942                      break;
   4943                   }
   4944                   case 0x1: {  /* SUBU.QB */
   4945                      DIP("subu.qb r%d, r%d, r%d", rd, rs, rt);
   4946                      vassert(!mode64);
   4947                      t0 = newTemp(Ity_I32);
   4948                      t1 = newTemp(Ity_I1);
   4949                      t2 = newTemp(Ity_I32);
   4950                      t3 = newTemp(Ity_I1);
   4951                      t4 = newTemp(Ity_I32);
   4952                      t5 = newTemp(Ity_I1);
   4953                      t6 = newTemp(Ity_I32);
   4954                      t7 = newTemp(Ity_I1);
   4955                      t8 = newTemp(Ity_I32);
   4956 
   4957                      /* Subtract rightmost bytes of rs and rt. */
   4958                      assign(t0,
   4959                             binop(Iop_Sub32,
   4960                                   unop(Iop_8Uto32,
   4961                                        unop(Iop_16to8,
   4962                                             unop(Iop_32to16, getIReg(rs)))),
   4963                                   unop(Iop_8Uto32,
   4964                                        unop(Iop_16to8,
   4965                                             unop(Iop_32to16, getIReg(rt))))));
   4966                      /* t1 will be 1 if there is overflow, 0 otherwise. */
   4967                      assign(t1, binop(Iop_CmpEQ32,
   4968                                       binop(Iop_And32,
   4969                                             mkexpr(t0),
   4970                                             mkU32(0x00000100)),
   4971                                       mkU32(0x00000100)));
   4972 
   4973                      /* Subtract bits 15-8 of rs and rt. */
   4974                      assign(t2,
   4975                             binop(Iop_Sub32,
   4976                                   unop(Iop_8Uto32,
   4977                                        unop(Iop_16HIto8,
   4978                                             unop(Iop_32to16, getIReg(rs)))),
   4979                                   unop(Iop_8Uto32,
   4980                                        unop(Iop_16HIto8,
   4981                                             unop(Iop_32to16, getIReg(rt))))));
   4982                      /* t3 will be 1 if there is overflow, 0 otherwise. */
   4983                      assign(t3, binop(Iop_CmpEQ32,
   4984                                       binop(Iop_And32,
   4985                                             mkexpr(t2),
   4986                                             mkU32(0x00000100)),
   4987                                       mkU32(0x00000100)));
   4988 
   4989                      /* Subtract bits 15-8 of rs and rt. */
   4990                      assign(t4,
   4991                             binop(Iop_Sub32,
   4992                                   unop(Iop_8Uto32,
   4993                                        unop(Iop_16to8,
   4994                                             unop(Iop_32HIto16, getIReg(rs)))),
   4995                                   unop(Iop_8Uto32,
   4996                                        unop(Iop_16to8,
   4997                                             unop(Iop_32HIto16, getIReg(rt))))));
   4998                      /* t5 will be 1 if there is overflow, 0 otherwise. */
   4999                      assign(t5, binop(Iop_CmpEQ32,
   5000                                       binop(Iop_And32,
   5001                                             mkexpr(t4),
   5002                                             mkU32(0x00000100)),
   5003                                       mkU32(0x00000100)));
   5004 
   5005                      /* Subtract bits 15-8 of rs and rt. */
   5006                      assign(t6,
   5007                             binop(Iop_Sub32,
   5008                                   unop(Iop_8Uto32,
   5009                                        unop(Iop_16HIto8,
   5010                                             unop(Iop_32HIto16, getIReg(rs)))),
   5011                                   unop(Iop_8Uto32,
   5012                                        unop(Iop_16HIto8,
   5013                                             unop(Iop_32HIto16, getIReg(rt))))));
   5014                      /* t7 will be 1 if there is overflow, 0 otherwise. */
   5015                      assign(t7, binop(Iop_CmpEQ32,
   5016                                       binop(Iop_And32,
   5017                                             mkexpr(t6),
   5018                                             mkU32(0x00000100)),
   5019                                       mkU32(0x00000100)));
   5020 
   5021                      assign(t8, binop(Iop_Or32,
   5022                                       binop(Iop_Or32,
   5023                                             binop(Iop_Or32,
   5024                                                   unop(Iop_1Sto32, mkexpr(t7)),
   5025                                                   unop(Iop_1Sto32, mkexpr(t5))),
   5026                                             unop(Iop_1Sto32, mkexpr(t3))),
   5027                                       unop(Iop_1Sto32, mkexpr(t1))));
   5028 
   5029                      putDSPControl(IRExpr_ITE(binop(Iop_CmpEQ32,
   5030                                                      mkexpr(t8),
   5031                                                      mkU32(0x0)),
   5032                                               getDSPControl(),
   5033                                               binop(Iop_Or32,
   5034                                                     getDSPControl(),
   5035                                                     mkU32(0x00100000))));
   5036 
   5037                      putIReg(rd, binop(Iop_16HLto32,
   5038                                        binop(Iop_8HLto16,
   5039                                              unop(Iop_32to8, mkexpr(t6)),
   5040                                              unop(Iop_32to8, mkexpr(t4))),
   5041                                        binop(Iop_8HLto16,
   5042                                              unop(Iop_32to8, mkexpr(t2)),
   5043                                              unop(Iop_32to8, mkexpr(t0)))));
   5044                      break;
   5045                   }
   5046                   case 0x04: {  /* ADDU_S.QB */
   5047                      DIP("addu_s.qb r%d, r%d, r%d", rd, rs, rt);
   5048                      vassert(!mode64);
   5049                      t0 = newTemp(Ity_I32);
   5050                      t1 = newTemp(Ity_I1);
   5051                      t2 = newTemp(Ity_I8);
   5052                      t3 = newTemp(Ity_I32);
   5053                      t4 = newTemp(Ity_I1);
   5054                      t5 = newTemp(Ity_I8);
   5055                      t6 = newTemp(Ity_I32);
   5056                      t7 = newTemp(Ity_I1);
   5057                      t8 = newTemp(Ity_I8);
   5058                      t9 = newTemp(Ity_I32);
   5059                      t10 = newTemp(Ity_I1);
   5060                      t11 = newTemp(Ity_I8);
   5061                      t12 = newTemp(Ity_I32);
   5062 
   5063                      /* Add rightmost bytes of rs and rt. */
   5064                      assign(t0,
   5065                             binop(Iop_Add32,
   5066                                   unop(Iop_8Uto32,
   5067                                        unop(Iop_16to8,
   5068                                             unop(Iop_32to16, getIReg(rs)))),
   5069                                   unop(Iop_8Uto32,
   5070                                        unop(Iop_16to8,
   5071                                             unop(Iop_32to16, getIReg(rt))))));
   5072                      /* t1 will be 1 if there is overflow, 0 otherwise. */
   5073                      assign(t1, binop(Iop_CmpEQ32,
   5074                                       binop(Iop_And32,
   5075                                             mkexpr(t0),
   5076                                             mkU32(0x00000100)),
   5077                                       mkU32(0x00000100)));
   5078                      /* Saturate if necessary. */
   5079                      assign(t2, IRExpr_ITE(mkexpr(t1),
   5080                                            mkU8(0xff),
   5081                                            unop(Iop_32to8, mkexpr(t0))));
   5082 
   5083                      /* Add bits 15-8 of rs and rt. */
   5084                      assign(t3,
   5085                             binop(Iop_Add32,
   5086                                   unop(Iop_8Uto32,
   5087                                        unop(Iop_16HIto8,
   5088                                             unop(Iop_32to16, getIReg(rs)))),
   5089                                   unop(Iop_8Uto32,
   5090                                        unop(Iop_16HIto8,
   5091                                             unop(Iop_32to16, getIReg(rt))))));
   5092                      /* t4 will be 1 if there is overflow, 0 otherwise. */
   5093                      assign(t4, binop(Iop_CmpEQ32,
   5094                                       binop(Iop_And32,
   5095                                             mkexpr(t3),
   5096                                             mkU32(0x00000100)),
   5097                                       mkU32(0x00000100)));
   5098                      /* Saturate if necessary. */
   5099                      assign(t5, IRExpr_ITE(mkexpr(t4),
   5100                                            mkU8(0xff),
   5101                                            unop(Iop_32to8, mkexpr(t3))));
   5102 
   5103                      /* Add bits 15-8 of rs and rt. */
   5104                      assign(t6,
   5105                             binop(Iop_Add32,
   5106                                   unop(Iop_8Uto32,
   5107                                        unop(Iop_16to8,
   5108                                             unop(Iop_32HIto16, getIReg(rs)))),
   5109                                   unop(Iop_8Uto32,
   5110                                        unop(Iop_16to8,
   5111                                             unop(Iop_32HIto16, getIReg(rt))))));
   5112                      /* t7 will be 1 if there is overflow, 0 otherwise. */
   5113                      assign(t7, binop(Iop_CmpEQ32,
   5114                                       binop(Iop_And32,
   5115                                             mkexpr(t6),
   5116                                             mkU32(0x00000100)),
   5117                                       mkU32(0x00000100)));
   5118                      /* Saturate if necessary. */
   5119                      assign(t8, IRExpr_ITE(mkexpr(t7),
   5120                                            mkU8(0xff),
   5121                                            unop(Iop_32to8, mkexpr(t6))));
   5122 
   5123                      /* Add bits 15-8 of rs and rt. */
   5124                      assign(t9,
   5125                             binop(Iop_Add32,
   5126                                   unop(Iop_8Uto32,
   5127                                        unop(Iop_16HIto8,
   5128                                             unop(Iop_32HIto16, getIReg(rs)))),
   5129                                   unop(Iop_8Uto32,
   5130                                        unop(Iop_16HIto8,
   5131                                             unop(Iop_32HIto16, getIReg(rt))))));
   5132                      /* t10 will be 1 if there is overflow, 0 otherwise. */
   5133                      assign(t10, binop(Iop_CmpEQ32,
   5134                                        binop(Iop_And32,
   5135                                              mkexpr(t9),
   5136                                              mkU32(0x00000100)),
   5137                                        mkU32(0x00000100)));
   5138                      /* Saturate if necessary. */
   5139                      assign(t11, IRExpr_ITE(mkexpr(t10),
   5140                                             mkU8(0xff),
   5141                                             unop(Iop_32to8, mkexpr(t9))));
   5142 
   5143                      assign(t12,
   5144                             binop(Iop_Or32,
   5145                                   binop(Iop_Or32,
   5146                                         binop(Iop_Or32,
   5147                                               unop(Iop_1Sto32, mkexpr(t10)),
   5148                                               unop(Iop_1Sto32, mkexpr(t7))),
   5149                                         unop(Iop_1Sto32, mkexpr(t4))),
   5150                                   unop(Iop_1Sto32, mkexpr(t1))));
   5151 
   5152                      putDSPControl(IRExpr_ITE(binop(Iop_CmpEQ32,
   5153                                                     mkexpr(t12),
   5154                                                     mkU32(0x0)),
   5155                                               getDSPControl(),
   5156                                               binop(Iop_Or32,
   5157                                                     getDSPControl(),
   5158                                                     mkU32(0x00100000))));
   5159 
   5160                      putIReg(rd,
   5161                              binop(Iop_16HLto32,
   5162                                    binop(Iop_8HLto16, mkexpr(t11), mkexpr(t8)),
   5163                                    binop(Iop_8HLto16, mkexpr(t5), mkexpr(t2))));
   5164                      break;
   5165                   }
   5166                   case 0x05: {  /* SUBU_S.QB */
   5167                      DIP("subu_s.qb r%d, r%d, r%d", rd, rs, rt);
   5168                      vassert(!mode64);
   5169                      t1 = newTemp(Ity_I32);
   5170                      t2 = newTemp(Ity_I1);
   5171                      t3 = newTemp(Ity_I1);
   5172                      t4 = newTemp(Ity_I1);
   5173                      t5 = newTemp(Ity_I1);
   5174                      t6 = newTemp(Ity_I32);
   5175                      t7 = newTemp(Ity_I32);
   5176                      t8 = newTemp(Ity_I32);
   5177                      t9 = newTemp(Ity_I32);
   5178 
   5179                      /* Use C function to easily calculate the result
   5180                         and write it in the register more conveniently
   5181                         Underflow is checked using step by step subtraction. */
   5182                      assign(t1, binop(Iop_QSub8Ux4, getIReg(rs), getIReg(rt)));
   5183 
   5184                      /* Subtract each byte of rs and rt. */
   5185                      assign(t6,
   5186                             binop(Iop_Sub32,
   5187                                   unop(Iop_8Uto32,
   5188                                        unop(Iop_16to8,
   5189                                             unop(Iop_32to16, getIReg(rs)))),
   5190                                   unop(Iop_8Uto32,
   5191                                        unop(Iop_16to8,
   5192                                             unop(Iop_32to16, getIReg(rt))))));
   5193                      assign(t7,
   5194                             binop(Iop_Sub32,
   5195                                   unop(Iop_8Uto32,
   5196                                        unop(Iop_16HIto8,
   5197                                             unop(Iop_32to16, getIReg(rs)))),
   5198                                   unop(Iop_8Uto32,
   5199                                        unop(Iop_16HIto8,
   5200                                             unop(Iop_32to16, getIReg(rt))))));
   5201                      assign(t8,
   5202                             binop(Iop_Sub32,
   5203                                   unop(Iop_8Uto32,
   5204                                        unop(Iop_16to8,
   5205                                             unop(Iop_32HIto16, getIReg(rs)))),
   5206                                   unop(Iop_8Uto32,
   5207                                        unop(Iop_16to8,
   5208                                             unop(Iop_32HIto16, getIReg(rt))))));
   5209                      assign(t9,
   5210                             binop(Iop_Sub32,
   5211                                   unop(Iop_8Uto32,
   5212                                        unop(Iop_16HIto8,
   5213                                             unop(Iop_32HIto16, getIReg(rs)))),
   5214                                   unop(Iop_8Uto32,
   5215                                        unop(Iop_16HIto8,
   5216                                             unop(Iop_32HIto16, getIReg(rt))))));
   5217 
   5218                      /* Put 1 to bit 20 in DSPControl if there is underflow
   5219                         in either byte. */
   5220                      assign(t2, binop(Iop_CmpEQ32,
   5221                                       binop(Iop_And32,
   5222                                             mkexpr(t6),
   5223                                             mkU32(0x00000100)),
   5224                                       mkU32(0x00000100)));
   5225                      putDSPControl(IRExpr_ITE(mkexpr(t2),
   5226                                               binop(Iop_Or32,
   5227                                                     getDSPControl(),
   5228                                                     mkU32(0x00100000)),
   5229                                               getDSPControl()));
   5230                      assign(t3, binop(Iop_CmpEQ32,
   5231                                       binop(Iop_And32,
   5232                                             mkexpr(t7),
   5233                                             mkU32(0x00000100)),
   5234                                       mkU32(0x00000100)));
   5235                      putDSPControl(IRExpr_ITE(mkexpr(t3),
   5236                                               binop(Iop_Or32,
   5237                                                     getDSPControl(),
   5238                                                     mkU32(0x00100000)),
   5239                                               getDSPControl()));
   5240                      assign(t4, binop(Iop_CmpEQ32,
   5241                                       binop(Iop_And32,
   5242                                             mkexpr(t8),
   5243                                             mkU32(0x00000100)),
   5244                                       mkU32(0x00000100)));
   5245                      putDSPControl(IRExpr_ITE(mkexpr(t4),
   5246                                               binop(Iop_Or32,
   5247                                                     getDSPControl(),
   5248                                                     mkU32(0x00100000)),
   5249                                               getDSPControl()));
   5250                      assign(t5, binop(Iop_CmpEQ32,
   5251                                       binop(Iop_And32,
   5252                                             mkexpr(t9),
   5253                                             mkU32(0x00000100)),
   5254                                       mkU32(0x00000100)));
   5255                      putDSPControl(IRExpr_ITE(mkexpr(t5),
   5256                                               binop(Iop_Or32,
   5257                                                     getDSPControl(),
   5258                                                     mkU32(0x00100000)),
   5259                                               getDSPControl()));
   5260                      putIReg(rd, mkexpr(t1));
   5261                      break;
   5262                   }
   5263                   case 0x6: {  /* MULEU_S.PH.QBL */
   5264                      DIP("muleu_s.ph.qbl r%d, r%d, r%d", rd, rs, rt);
   5265                      vassert(!mode64);
   5266                      t0 = newTemp(Ity_I32);
   5267                      t1 = newTemp(Ity_I32);
   5268                      t2 = newTemp(Ity_I1);
   5269                      t3 = newTemp(Ity_I1);
   5270 
   5271                      assign(t0,
   5272                             unop(Iop_64to32,
   5273                                  binop(Iop_MullU32,
   5274                                        unop(Iop_8Uto32,
   5275                                             unop(Iop_16HIto8,
   5276                                                  unop(Iop_32HIto16,
   5277                                                       getIReg(rs)))),
   5278                                        unop(Iop_16Uto32,
   5279                                             unop(Iop_32HIto16, getIReg(rt))))));
   5280                      assign(t1,
   5281                             unop(Iop_64to32,
   5282                                  binop(Iop_MullU32,
   5283                                        unop(Iop_8Uto32,
   5284                                             unop(Iop_16to8,
   5285                                                  unop(Iop_32HIto16,
   5286                                                       getIReg(rs)))),
   5287                                        unop(Iop_16Uto32,
   5288                                             unop(Iop_32to16, getIReg(rt))))));
   5289 
   5290                      assign(t2, binop(Iop_CmpNE32,
   5291                                       mkU32(0x0),
   5292                                       binop(Iop_And32,
   5293                                             mkexpr(t0),
   5294                                             mkU32(0x03ff0000))));
   5295                      assign(t3, binop(Iop_CmpNE32,
   5296                                       mkU32(0x0),
   5297                                       binop(Iop_And32,
   5298                                             mkexpr(t1),
   5299                                             mkU32(0x03ff0000))));
   5300                      putDSPControl(IRExpr_ITE(mkexpr(t2),
   5301                                               binop(Iop_Or32,
   5302                                                     getDSPControl(),
   5303                                                     mkU32(0x200000)),
   5304                                               IRExpr_ITE(mkexpr(t3),
   5305                                                          binop(Iop_Or32,
   5306                                                                getDSPControl(),
   5307                                                                mkU32(0x200000)),
   5308                                                          getDSPControl())));
   5309                      putIReg(rd,
   5310                              binop(Iop_16HLto32,
   5311                                    IRExpr_ITE(mkexpr(t2),
   5312                                               mkU16(0xffff),
   5313                                               unop(Iop_32to16, mkexpr(t0))),
   5314                                    IRExpr_ITE(mkexpr(t3),
   5315                                               mkU16(0xffff),
   5316                                               unop(Iop_32to16, mkexpr(t1)))));
   5317                      break;
   5318                   }
   5319                   case 0x7: {  /* MULEU_S.PH.QBR */
   5320                      DIP("muleu_s.ph.qbr r%d, r%d, r%d", rd, rs, rt);
   5321                      vassert(!mode64);
   5322                      t0 = newTemp(Ity_I32);
   5323                      t1 = newTemp(Ity_I32);
   5324                      t2 = newTemp(Ity_I1);
   5325                      t3 = newTemp(Ity_I1);
   5326 
   5327                      assign(t0, unop(Iop_64to32,
   5328                                      binop(Iop_MullU32,
   5329                                            unop(Iop_8Uto32,
   5330                                                 unop(Iop_16HIto8,
   5331                                                      unop(Iop_32to16,
   5332                                                           getIReg(rs)))),
   5333                                            unop(Iop_16Uto32,
   5334                                                 unop(Iop_32HIto16,
   5335                                                      getIReg(rt))))));
   5336                      assign(t1, unop(Iop_64to32,
   5337                                      binop(Iop_MullU32,
   5338                                            unop(Iop_8Uto32,
   5339                                                 unop(Iop_16to8,
   5340                                                      unop(Iop_32to16,
   5341                                                           getIReg(rs)))),
   5342                                            unop(Iop_16Uto32,
   5343                                                 unop(Iop_32to16,
   5344                                                      getIReg(rt))))));
   5345 
   5346                      assign(t2, binop(Iop_CmpNE32,
   5347                                       mkU32(0x0),
   5348                                       binop(Iop_And32,
   5349                                             mkexpr(t0),
   5350                                             mkU32(0x03ff0000))));
   5351                      assign(t3, binop(Iop_CmpNE32,
   5352                                       mkU32(0x0),
   5353                                       binop(Iop_And32,
   5354                                             mkexpr(t1),
   5355                                             mkU32(0x03ff0000))));
   5356                      putDSPControl(IRExpr_ITE(mkexpr(t2),
   5357                                               binop(Iop_Or32,
   5358                                                     getDSPControl(),
   5359                                                     mkU32(0x200000)),
   5360                                               IRExpr_ITE(mkexpr(t3),
   5361                                                          binop(Iop_Or32,
   5362                                                                getDSPControl(),
   5363                                                                mkU32(0x200000)),
   5364                                                          getDSPControl())));
   5365                      putIReg(rd, binop(Iop_16HLto32,
   5366                                        IRExpr_ITE(mkexpr(t2),
   5367                                                   mkU16(0xffff),
   5368                                                   unop(Iop_32to16,
   5369                                                        mkexpr(t0))),
   5370                                        IRExpr_ITE(mkexpr(t3),
   5371                                                   mkU16(0xffff),
   5372                                                   unop(Iop_32to16,
   5373                                                        mkexpr(t1)))));
   5374                      break;
   5375                   }
   5376                   case 0x08: {  /* ADDU.PH */
   5377                      DIP("addu.ph r%d, r%d, r%d", rd, rs, rt);
   5378                      vassert(!mode64);
   5379                      t0 = newTemp(Ity_I32);
   5380                      t1 = newTemp(Ity_I1);
   5381                      t2 = newTemp(Ity_I32);
   5382                      t3 = newTemp(Ity_I1);
   5383 
   5384                      /* Add lower halves. */
   5385                      assign(t0, binop(Iop_Add32,
   5386                                       unop(Iop_16Uto32,
   5387                                            unop(Iop_32to16, getIReg(rs))),
   5388                                       unop(Iop_16Uto32,
   5389                                            unop(Iop_32to16, getIReg(rt)))));
   5390 
   5391                      /* Detect overflow. */
   5392                      assign(t1, binop(Iop_CmpLT32U,
   5393                                       unop(Iop_16Uto32,
   5394                                            unop(Iop_32to16, mkexpr(t0))),
   5395                                       unop(Iop_16Uto32,
   5396                                            unop(Iop_32to16, getIReg(rs)))));
   5397 
   5398                      putDSPControl(IRExpr_ITE(mkexpr(t1),
   5399                                               binop(Iop_Or32,
   5400                                                     getDSPControl(),
   5401                                                     mkU32(0x00100000)),
   5402                                               getDSPControl()));
   5403 
   5404                      /* Add higher halves. */
   5405                      assign(t2, binop(Iop_Add32,
   5406                                       unop(Iop_16Uto32,
   5407                                            unop(Iop_32HIto16, getIReg(rs))),
   5408                                       unop(Iop_16Uto32,
   5409                                            unop(Iop_32HIto16, getIReg(rt)))));
   5410 
   5411                      /* Detect overflow. */
   5412                      assign(t3, binop(Iop_CmpLT32U,
   5413                                       unop(Iop_16Uto32,
   5414                                            unop(Iop_32to16, mkexpr(t2))),
   5415                                       unop(Iop_16Uto32,
   5416                                            unop(Iop_32HIto16,
   5417                                                 getIReg(rs)))));
   5418 
   5419                      putDSPControl(IRExpr_ITE(mkexpr(t3),
   5420                                               binop(Iop_Or32,
   5421                                                     getDSPControl(),
   5422                                                     mkU32(0x00100000)),
   5423                                               getDSPControl()));
   5424 
   5425                      putIReg(rd, binop(Iop_16HLto32,
   5426                                        unop(Iop_32to16, mkexpr(t2)),
   5427                                        unop(Iop_32to16, mkexpr(t0))));
   5428                      break;
   5429                   }
   5430                   case 0x9: {  /* SUBU.PH */
   5431                      DIP("subu.ph r%d, r%d, r%d", rd, rs, rt);
   5432                      vassert(!mode64);
   5433                      t0 = newTemp(Ity_I32);
   5434                      t1 = newTemp(Ity_I1);
   5435                      t2 = newTemp(Ity_I32);
   5436                      t3 = newTemp(Ity_I1);
   5437 
   5438                      /* Substract lower halves. */
   5439                      assign(t0, binop(Iop_Sub32,
   5440                                       unop(Iop_16Uto32,
   5441                                            unop(Iop_32to16, getIReg(rs))),
   5442                                       unop(Iop_16Uto32,
   5443                                            unop(Iop_32to16, getIReg(rt)))));
   5444 
   5445                      /* Detect underflow. */
   5446                      assign(t1, binop(Iop_CmpNE32,
   5447                                       binop(Iop_And32,
   5448                                             mkexpr(t0),
   5449                                             mkU32(0x00010000)),
   5450                                       mkU32(0x0)));
   5451 
   5452                      putDSPControl(IRExpr_ITE(mkexpr(t1),
   5453                                               binop(Iop_Or32,
   5454                                                     getDSPControl(),
   5455                                                     mkU32(0x00100000)),
   5456                                               getDSPControl()));
   5457 
   5458                      /* Subtract higher halves. */
   5459                      assign(t2, binop(Iop_Sub32,
   5460                                       unop(Iop_16Uto32,
   5461                                            unop(Iop_32HIto16, getIReg(rs))),
   5462                                       unop(Iop_16Uto32,
   5463                                            unop(Iop_32HIto16, getIReg(rt)))));
   5464 
   5465                      /* Detect underflow. */
   5466                      assign(t3, binop(Iop_CmpNE32,
   5467                                       binop(Iop_And32,
   5468                                             mkexpr(t2),
   5469                                             mkU32(0x00010000)),
   5470                                       mkU32(0x0)));
   5471 
   5472                      putDSPControl(IRExpr_ITE(mkexpr(t3),
   5473                                               binop(Iop_Or32,
   5474                                                     getDSPControl(),
   5475                                                     mkU32(0x00100000)),
   5476                                               getDSPControl()));
   5477 
   5478                      putIReg(rd, binop(Iop_16HLto32,
   5479                                        unop(Iop_32to16, mkexpr(t2)),
   5480                                        unop(Iop_32to16, mkexpr(t0))));
   5481                      break;
   5482                   }
   5483                   case 0xA: {  /* ADDQ.PH */
   5484                      DIP("addq.ph r%d, r%d, r%d", rd, rs, rt);
   5485                      vassert(!mode64);
   5486                      t0 = newTemp(Ity_I32);
   5487                      t1 = newTemp(Ity_I1);
   5488                      t2 = newTemp(Ity_I32);
   5489                      t3 = newTemp(Ity_I1);
   5490                      t6 = newTemp(Ity_I32);
   5491                      t7 = newTemp(Ity_I32);
   5492 
   5493                      /* Add lower halves. */
   5494                      assign(t0, binop(Iop_Add32,
   5495                                       unop(Iop_16Sto32,
   5496                                            unop(Iop_32to16, getIReg(rs))),
   5497                                       unop(Iop_16Sto32,
   5498                                            unop(Iop_32to16, getIReg(rt)))));
   5499 
   5500                      /* Bit 16 of the result. */
   5501                      assign(t6, binop(Iop_And32,
   5502                                       unop(Iop_16Uto32,
   5503                                            unop(Iop_32HIto16, mkexpr(t0))),
   5504                                       mkU32(0x1)));
   5505                      /* Detect overflow. */
   5506                      assign(t1, binop(Iop_CmpNE32,
   5507                                       binop(Iop_Shr32,
   5508                                             binop(Iop_And32,
   5509                                                   mkexpr(t0),
   5510                                                   mkU32(0x8000)),
   5511                                             mkU8(15)),
   5512                                       mkexpr(t6)));
   5513 
   5514                      putDSPControl(IRExpr_ITE(mkexpr(t1),
   5515                                               binop(Iop_Or32,
   5516                                                     getDSPControl(),
   5517                                                     mkU32(0x00100000)),
   5518                                               getDSPControl()));
   5519 
   5520                      /* Add higher halves. */
   5521                      assign(t2, binop(Iop_Add32,
   5522                                       unop(Iop_16Sto32,
   5523                                            unop(Iop_32HIto16, getIReg(rs))),
   5524                                       unop(Iop_16Sto32,
   5525                                            unop(Iop_32HIto16, getIReg(rt)))));
   5526 
   5527                      /* Bit 16 of the result. */
   5528                      assign(t7, binop(Iop_And32,
   5529                                       unop(Iop_16Uto32,
   5530                                            unop(Iop_32HIto16, mkexpr(t2))),
   5531                                       mkU32(0x1)));
   5532                      /* Detect overflow. */
   5533                      assign(t3, binop(Iop_CmpNE32,
   5534                                       binop(Iop_Shr32,
   5535                                             binop(Iop_And32,
   5536                                                   mkexpr(t2),
   5537                                                   mkU32(0x00008000)),
   5538                                             mkU8(15)),
   5539                                       mkexpr(t7)));
   5540 
   5541                      putDSPControl(IRExpr_ITE(mkexpr(t3),
   5542                                               binop(Iop_Or32,
   5543                                                     getDSPControl(),
   5544                                                     mkU32(0x00100000)),
   5545                                               getDSPControl()));
   5546 
   5547                      putIReg(rd, binop(Iop_16HLto32,
   5548                                        unop(Iop_32to16, mkexpr(t2)),
   5549                                        unop(Iop_32to16, mkexpr(t0))));
   5550                      break;
   5551                   }
   5552                   case 0xB: {  /* SUBQ.PH */
   5553                      DIP("subq.ph r%d, r%d, r%d", rd, rs, rt);
   5554                      vassert(!mode64);
   5555                      t0 = newTemp(Ity_I32);
   5556                      t1 = newTemp(Ity_I1);
   5557                      t2 = newTemp(Ity_I32);
   5558                      t3 = newTemp(Ity_I1);
   5559                      t6 = newTemp(Ity_I32);
   5560                      t7 = newTemp(Ity_I32);
   5561 
   5562                      /* Subtract lower halves. */
   5563                      assign(t0, binop(Iop_Sub32,
   5564                                       unop(Iop_16Sto32,
   5565                                            unop(Iop_32to16, getIReg(rs))),
   5566                                       unop(Iop_16Sto32,
   5567                                            unop(Iop_32to16, getIReg(rt)))));
   5568 
   5569                      /* Bit 16 of the result. */
   5570                      assign(t6, binop(Iop_And32,
   5571                                       unop(Iop_16Uto32,
   5572                                            unop(Iop_32HIto16, mkexpr(t0))),
   5573                                       mkU32(0x1)));
   5574                      /* Compare the signs of input value and the result. */
   5575                      assign(t1, binop(Iop_CmpNE32,
   5576                                       binop(Iop_Shr32,
   5577                                             binop(Iop_And32,
   5578                                                   mkexpr(t0),
   5579                                                   mkU32(0x8000)),
   5580                                             mkU8(15)),
   5581                                       mkexpr(t6)));
   5582 
   5583                      putDSPControl(IRExpr_ITE(mkexpr(t1),
   5584                                               binop(Iop_Or32,
   5585                                                     getDSPControl(),
   5586                                                     mkU32(0x00100000)),
   5587                                               getDSPControl()));
   5588 
   5589                      /* Subtract higher halves. */
   5590                      assign(t2, binop(Iop_Sub32,
   5591                                       unop(Iop_16Sto32,
   5592                                            unop(Iop_32HIto16, getIReg(rs))),
   5593                                       unop(Iop_16Sto32,
   5594                                            unop(Iop_32HIto16, getIReg(rt)))));
   5595 
   5596                      /* Bit 16 of the result. */
   5597                      assign(t7, binop(Iop_And32,
   5598                                       unop(Iop_16Uto32,
   5599                                            unop(Iop_32HIto16, mkexpr(t2))),
   5600                                       mkU32(0x1)));
   5601                      /* Compare the signs of input value and the result. */
   5602                      assign(t3, binop(Iop_CmpNE32,
   5603                                       binop(Iop_Shr32,
   5604                                             binop(Iop_And32,
   5605                                                   mkexpr(t2),
   5606                                                   mkU32(0x00008000)),
   5607                                             mkU8(15)),
   5608                                       mkexpr(t7)));
   5609 
   5610                      putDSPControl(IRExpr_ITE(mkexpr(t3),
   5611                                               binop(Iop_Or32,
   5612                                                     getDSPControl(),
   5613                                                     mkU32(0x00100000)),
   5614                                               getDSPControl()));
   5615 
   5616                      putIReg(rd, binop(Iop_16HLto32,
   5617                                        unop(Iop_32to16, mkexpr(t2)),
   5618                                        unop(Iop_32to16, mkexpr(t0))));
   5619                      break;
   5620                   }
   5621                   case 0xC: {  /* ADDU_S.PH */
   5622                      DIP("addu_s.ph r%d, r%d, r%d", rd, rs, rt);
   5623                      vassert(!mode64);
   5624                      t0 = newTemp(Ity_I32);
   5625                      t1 = newTemp(Ity_I1);
   5626                      t2 = newTemp(Ity_I32);
   5627                      t3 = newTemp(Ity_I1);
   5628 
   5629                      /* Add lower halves. */
   5630                      assign(t0, binop(Iop_Add32,
   5631                                       unop(Iop_16Uto32,
   5632                                            unop(Iop_32to16, getIReg(rs))),
   5633                                       unop(Iop_16Uto32,
   5634                                            unop(Iop_32to16, getIReg(rt)))));
   5635 
   5636                      /* Detect overflow. */
   5637                      assign(t1, binop(Iop_CmpLT32U,
   5638                                       unop(Iop_16Uto32,
   5639                                            unop(Iop_32to16, mkexpr(t0))),
   5640                                       unop(Iop_16Uto32,
   5641                                            unop(Iop_32to16, getIReg(rs)))));
   5642 
   5643                      putDSPControl(IRExpr_ITE(mkexpr(t1),
   5644                                               binop(Iop_Or32,
   5645                                                     getDSPControl(),
   5646                                                     mkU32(0x00100000)),
   5647                                               getDSPControl()));
   5648 
   5649                      /* Add higher halves. */
   5650                      assign(t2, binop(Iop_Add32,
   5651                                       unop(Iop_16Uto32,
   5652                                            unop(Iop_32HIto16, getIReg(rs))),
   5653                                       unop(Iop_16Uto32,
   5654                                            unop(Iop_32HIto16, getIReg(rt)))));
   5655 
   5656                      /* Detect overflow. */
   5657                      assign(t3, binop(Iop_CmpLT32U,
   5658                                       unop(Iop_16Uto32,
   5659                                            unop(Iop_32to16, mkexpr(t2))),
   5660                                       unop(Iop_16Uto32,
   5661                                            unop(Iop_32HIto16, getIReg(rs)))));
   5662 
   5663                      putDSPControl(IRExpr_ITE(mkexpr(t3),
   5664                                               binop(Iop_Or32,
   5665                                                     getDSPControl(),
   5666                                                     mkU32(0x00100000)),
   5667                                               getDSPControl()));
   5668 
   5669                      putIReg(rd, binop(Iop_16HLto32,
   5670                                        IRExpr_ITE(mkexpr(t3),
   5671                                                   mkU16(0xffff),
   5672                                                   unop(Iop_32to16,
   5673                                                        mkexpr(t2))),
   5674                                        IRExpr_ITE(mkexpr(t1),
   5675                                                   mkU16(0xffff),
   5676                                                   unop(Iop_32to16,
   5677                                                        mkexpr(t0)))));
   5678                      break;
   5679                   }
   5680                   case 0xD: {  /* SUBU_S.PH */
   5681                      DIP("subu_s.ph r%d, r%d, r%d", rd, rs, rt);
   5682                      vassert(!mode64);
   5683                      t0 = newTemp(Ity_I32);
   5684                      t1 = newTemp(Ity_I1);
   5685                      t2 = newTemp(Ity_I32);
   5686                      t3 = newTemp(Ity_I1);
   5687 
   5688                      /* Subtract lower halves. */
   5689                      assign(t0, binop(Iop_Sub32,
   5690                                       unop(Iop_16Uto32,
   5691                                            unop(Iop_32to16, getIReg(rs))),
   5692                                       unop(Iop_16Uto32,
   5693                                            unop(Iop_32to16, getIReg(rt)))));
   5694 
   5695                      /* Detect underflow. */
   5696                      assign(t1, binop(Iop_CmpNE32,
   5697                                       binop(Iop_And32,
   5698                                             mkexpr(t0), mkU32(0x00010000)),
   5699                                       mkU32(0x0)));
   5700 
   5701                      putDSPControl(IRExpr_ITE(mkexpr(t1),
   5702                                               binop(Iop_Or32,
   5703                                                     getDSPControl(),
   5704                                                     mkU32(0x00100000)),
   5705                                               getDSPControl()));
   5706 
   5707                      /* Subtract higher halves. */
   5708                      assign(t2, binop(Iop_Sub32,
   5709                                       unop(Iop_16Uto32,
   5710                                            unop(Iop_32HIto16, getIReg(rs))),
   5711                                       unop(Iop_16Uto32,
   5712                                            unop(Iop_32HIto16, getIReg(rt)))));
   5713 
   5714                      /* Detect underflow. */
   5715                      assign(t3, binop(Iop_CmpNE32,
   5716                                       binop(Iop_And32,
   5717                                             mkexpr(t2), mkU32(0x00010000)),
   5718                                       mkU32(0x0)));
   5719 
   5720                      putDSPControl(IRExpr_ITE(mkexpr(t3),
   5721                                               binop(Iop_Or32,
   5722                                                     getDSPControl(),
   5723                                                     mkU32(0x00100000)),
   5724                                               getDSPControl()));
   5725 
   5726                      putIReg(rd,
   5727                              binop(Iop_16HLto32,
   5728                                    IRExpr_ITE(mkexpr(t3),
   5729                                               mkU16(0x0000),
   5730                                               unop(Iop_32to16, mkexpr(t2))),
   5731                                    IRExpr_ITE(mkexpr(t1),
   5732                                               mkU16(0x0000),
   5733                                               unop(Iop_32to16, mkexpr(t0)))));
   5734                      break;
   5735                   }
   5736                   case 0xE: {  /* ADDQ_S.PH */
   5737                      DIP("addq_s.ph r%d r%d, r%d", rd, rs, rt);
   5738                      vassert(!mode64);
   5739                      t0 = newTemp(Ity_I32);
   5740                      t1 = newTemp(Ity_I1);
   5741                      t2 = newTemp(Ity_I32);
   5742                      t3 = newTemp(Ity_I1);
   5743                      t4 = newTemp(Ity_I16);
   5744                      t5 = newTemp(Ity_I16);
   5745                      t6 = newTemp(Ity_I32);
   5746                      t7 = newTemp(Ity_I32);
   5747 
   5748                      /* Add lower halves. */
   5749                      assign(t0, binop(Iop_Add32,
   5750                                       unop(Iop_16Sto32,
   5751                                            unop(Iop_32to16, getIReg(rs))),
   5752                                       unop(Iop_16Sto32,
   5753                                            unop(Iop_32to16, getIReg(rt)))));
   5754 
   5755                      /* Bit 16 of the result. */
   5756                      assign(t6, binop(Iop_And32,
   5757                                       unop(Iop_16Uto32,
   5758                                            unop(Iop_32HIto16, mkexpr(t0))),
   5759                                       mkU32(0x1)));
   5760                      /* Detect overflow. */
   5761                      assign(t1, binop(Iop_CmpNE32,
   5762                                       binop(Iop_Shr32,
   5763                                             binop(Iop_And32,
   5764                                                   mkexpr(t0),
   5765                                                   mkU32(0x8000)),
   5766                                             mkU8(15)),
   5767                                       mkexpr(t6)));
   5768 
   5769                      putDSPControl(IRExpr_ITE(mkexpr(t1),
   5770                                               binop(Iop_Or32,
   5771                                                     getDSPControl(),
   5772                                                     mkU32(0x00100000)),
   5773                                               getDSPControl()));
   5774                      /* Saturate if needed. */
   5775                      assign(t4, IRExpr_ITE(mkexpr(t1),
   5776                                            IRExpr_ITE(binop(Iop_CmpEQ32,
   5777                                                             mkexpr(t6),
   5778                                                             mkU32(0x0)),
   5779                                                       mkU16(0x7fff),
   5780                                                       mkU16(0x8000)),
   5781                                            unop(Iop_32to16, mkexpr(t0))));
   5782 
   5783                      /* Add higher halves. */
   5784                      assign(t2, binop(Iop_Add32,
   5785                                       unop(Iop_16Sto32,
   5786                                            unop(Iop_32HIto16, getIReg(rs))),
   5787                                       unop(Iop_16Sto32,
   5788                                            unop(Iop_32HIto16, getIReg(rt)))));
   5789 
   5790                      /* Bit 16 of the result. */
   5791                      assign(t7, binop(Iop_And32,
   5792                                       unop(Iop_16Uto32,
   5793                                            unop(Iop_32HIto16, mkexpr(t2))),
   5794                                       mkU32(0x1)));
   5795                      /* Detect overflow. */
   5796                      assign(t3, binop(Iop_CmpNE32,
   5797                                       binop(Iop_Shr32,
   5798                                             binop(Iop_And32,
   5799                                                   mkexpr(t2),
   5800                                                   mkU32(0x00008000)),
   5801                                             mkU8(15)),
   5802                                       mkexpr(t7)));
   5803 
   5804                      putDSPControl(IRExpr_ITE(mkexpr(t3),
   5805                                               binop(Iop_Or32,
   5806                                                     getDSPControl(),
   5807                                                     mkU32(0x00100000)),
   5808                                               getDSPControl()));
   5809                      /* Saturate if needed. */
   5810                      assign(t5, IRExpr_ITE(mkexpr(t3),
   5811                                            IRExpr_ITE(binop(Iop_CmpEQ32,
   5812                                                             mkexpr(t7),
   5813                                                             mkU32(0x0)),
   5814                                                       mkU16(0x7fff),
   5815                                                       mkU16(0x8000)),
   5816                                            unop(Iop_32to16, mkexpr(t2))));
   5817 
   5818                      putIReg(rd, binop(Iop_16HLto32, mkexpr(t5), mkexpr(t4)));
   5819                      break;
   5820                   }
   5821                   case 0xF: {  /* SUBQ_S.PH */
   5822                      DIP("subq_s.ph r%d r%d, r%d", rd, rs, rt);
   5823                      vassert(!mode64);
   5824                      t0 = newTemp(Ity_I32);
   5825                      t1 = newTemp(Ity_I1);
   5826                      t2 = newTemp(Ity_I32);
   5827                      t3 = newTemp(Ity_I1);
   5828                      t4 = newTemp(Ity_I16);
   5829                      t5 = newTemp(Ity_I16);
   5830                      t6 = newTemp(Ity_I32);
   5831                      t7 = newTemp(Ity_I32);
   5832 
   5833                      /* Subtract lower halves. */
   5834                      assign(t0, binop(Iop_Sub32,
   5835                                       unop(Iop_16Sto32,
   5836                                            unop(Iop_32to16, getIReg(rs))),
   5837                                       unop(Iop_16Sto32,
   5838                                            unop(Iop_32to16, getIReg(rt)))));
   5839 
   5840                      /* Bit 16 of the result. */
   5841                      assign(t6, binop(Iop_And32,
   5842                                       unop(Iop_16Uto32,
   5843                                            unop(Iop_32HIto16, mkexpr(t0))),
   5844                                       mkU32(0x1)));
   5845                      /* Detect overflow or underflow. */
   5846                      assign(t1, binop(Iop_CmpNE32,
   5847                                       binop(Iop_Shr32,
   5848                                             binop(Iop_And32,
   5849                                                   mkexpr(t0),
   5850                                                   mkU32(0x8000)),
   5851                                             mkU8(15)),
   5852                                       mkexpr(t6)));
   5853 
   5854                      putDSPControl(IRExpr_ITE(mkexpr(t1),
   5855                                               binop(Iop_Or32,
   5856                                                     getDSPControl(),
   5857                                                     mkU32(0x00100000)),
   5858                                               getDSPControl()));
   5859                      /* Saturate if needed. */
   5860                      assign(t4, IRExpr_ITE(mkexpr(t1),
   5861                                            IRExpr_ITE(binop(Iop_CmpEQ32,
   5862                                                             mkexpr(t6),
   5863                                                             mkU32(0x0)),
   5864                                                       mkU16(0x7fff),
   5865                                                       mkU16(0x8000)),
   5866                                            unop(Iop_32to16, mkexpr(t0))));
   5867 
   5868                      /* Subtract higher halves. */
   5869                      assign(t2, binop(Iop_Sub32,
   5870                                       unop(Iop_16Sto32,
   5871                                            unop(Iop_32HIto16, getIReg(rs))),
   5872                                       unop(Iop_16Sto32,
   5873                                            unop(Iop_32HIto16, getIReg(rt)))));
   5874 
   5875                      /* Bit 16 of the result. */
   5876                      assign(t7, binop(Iop_And32,
   5877                                       unop(Iop_16Uto32,
   5878                                            unop(Iop_32HIto16, mkexpr(t2))),
   5879                                       mkU32(0x1)));
   5880                      /* Detect overflow or underflow. */
   5881                      assign(t3, binop(Iop_CmpNE32,
   5882                                       binop(Iop_Shr32,
   5883                                             binop(Iop_And32,
   5884                                                   mkexpr(t2),
   5885                                                   mkU32(0x00008000)),
   5886                                             mkU8(15)),
   5887                                       mkexpr(t7)));
   5888 
   5889                      putDSPControl(IRExpr_ITE(mkexpr(t3),
   5890                                               binop(Iop_Or32,
   5891                                                     getDSPControl(),
   5892                                                     mkU32(0x00100000)),
   5893                                               getDSPControl()));
   5894                      /* Saturate if needed. */
   5895                      assign(t5, IRExpr_ITE(mkexpr(t3),
   5896                                            IRExpr_ITE(binop(Iop_CmpEQ32,
   5897                                                             mkexpr(t7),
   5898                                                             mkU32(0x0)),
   5899                                                       mkU16(0x7fff),
   5900                                                       mkU16(0x8000)),
   5901                                            unop(Iop_32to16, mkexpr(t2))));
   5902 
   5903                      putIReg(rd, binop(Iop_16HLto32, mkexpr(t5), mkexpr(t4)));
   5904                      break;
   5905                   }
   5906                   case 0x10: {  /* ADDSC */
   5907                      DIP("addsc r%d, r%d, r%d", rd, rs, rt);
   5908                      vassert(!mode64);
   5909                      t0 = newTemp(Ity_I64);
   5910                      t1 = newTemp(Ity_I1);
   5911 
   5912                      /* The carry bit result out of the addition operation is
   5913                         written to bit 13(the c field) of the DSPControl reg. */
   5914                      assign(t0, binop(Iop_Add64,
   5915                                       unop(Iop_32Uto64, getIReg(rs)),
   5916                                       unop(Iop_32Uto64, getIReg(rt))));
   5917 
   5918                      assign(t1, binop(Iop_CmpEQ32,
   5919                                       binop(Iop_And32,
   5920                                             unop(Iop_64HIto32, mkexpr(t0)),
   5921                                             mkU32(0x1)),
   5922                                       mkU32(0x1)));
   5923                      putDSPControl(IRExpr_ITE(mkexpr(t1),
   5924                                               binop(Iop_Or32,
   5925                                                     getDSPControl(),
   5926                                                     mkU32(0x2000)),
   5927                                               binop(Iop_And32,
   5928                                                     getDSPControl(),
   5929                                                     mkU32(0xffffdfff))));
   5930 
   5931                      putIReg(rd, unop(Iop_64to32, mkexpr(t0)));
   5932                      break;
   5933                   }
   5934                   case 0x11: {  /* ADDWC */
   5935                      DIP("addwc r%d, r%d, r%d", rd, rs, rt);
   5936                      vassert(!mode64);
   5937                      t0 = newTemp(Ity_I32);
   5938                      t1 = newTemp(Ity_I64);
   5939                      t2 = newTemp(Ity_I32);
   5940                      t3 = newTemp(Ity_I32);
   5941                      t4 = newTemp(Ity_I1);
   5942 
   5943                      /* Get carry bit from DSPControl register. */
   5944                      assign(t0, binop(Iop_Shr32,
   5945                                        binop(Iop_And32,
   5946                                              getDSPControl(),
   5947                                              mkU32(0x2000)),
   5948                                        mkU8(0xd)));
   5949                      assign(t1, binop(Iop_Add64,
   5950                                       unop(Iop_32Sto64, getIReg(rs)),
   5951                                       unop(Iop_32Sto64,
   5952                                            binop(Iop_Add32,
   5953                                                  getIReg(rt),
   5954                                                  mkexpr(t0)))));
   5955 
   5956                      /* Extract bits 32 and 31. */
   5957                      assign(t2, binop(Iop_And32,
   5958                                       unop(Iop_64HIto32, mkexpr(t1)),
   5959                                       mkU32(0x1)));
   5960                      assign(t3, binop(Iop_Shr32,
   5961                                       binop(Iop_And32,
   5962                                             unop(Iop_64to32, mkexpr(t1)),
   5963                                             mkU32(0x80000000)),
   5964                                       mkU8(31)));
   5965                      assign(t4, binop(Iop_CmpNE32, mkexpr(t2), mkexpr(t3)));
   5966 
   5967                      putDSPControl(IRExpr_ITE(mkexpr(t4),
   5968                                               binop(Iop_Or32,
   5969                                                     getDSPControl(),
   5970                                                     mkU32(0x00100000)),
   5971                                               getDSPControl()));
   5972                      putIReg(rd, unop(Iop_64to32, mkexpr(t1)));
   5973                      break;
   5974                   }
   5975                   case 0x12: {  /* MODSUB */
   5976                      DIP("modsub r%d, r%d, r%d", rd, rs, rt);
   5977                      vassert(!mode64);
   5978                      t0 = newTemp(Ity_I32);
   5979                      t1 = newTemp(Ity_I32);
   5980                      t2 = newTemp(Ity_I32);
   5981 
   5982                      /* decr_7..0 */
   5983                      assign(t0,
   5984                             unop(Iop_8Uto32,
   5985                                  unop(Iop_16to8,
   5986                                       unop(Iop_32to16, getIReg(rt)))));
   5987 
   5988                      /* lastindex_15..0 */
   5989                      assign(t1,
   5990                             unop(Iop_16Uto32,
   5991                                  binop(Iop_8HLto16,
   5992                                        unop(Iop_16to8,
   5993                                             unop(Iop_32HIto16, getIReg(rt))),
   5994                                        unop(Iop_16HIto8,
   5995                                             unop(Iop_32to16, getIReg(rt))))));
   5996                      /* temp_15..0 */
   5997                      assign(t2,
   5998                             IRExpr_ITE(binop(Iop_CmpEQ32,
   5999                                              getIReg(rs),
   6000                                              mkU32(0x00000000)),
   6001                                        mkexpr(t1),
   6002                                        binop(Iop_Sub32,
   6003                                              getIReg(rs), mkexpr(t0))));
   6004                      putIReg(rd, mkexpr(t2));
   6005                      break;
   6006                   }
   6007                   case 0x14: {  /* RADDU.W.QB */
   6008                      DIP("raddu.w.qb r%d, r%d", rd, rs);
   6009                      vassert(!mode64);
   6010                      putIReg(rd, binop(Iop_Add32,
   6011                                        binop(Iop_Add32,
   6012                                              unop(Iop_8Uto32,
   6013                                                   unop(Iop_16to8,
   6014                                                        unop(Iop_32to16,
   6015                                                             getIReg(rs)))),
   6016                                              unop(Iop_8Uto32,
   6017                                                   unop(Iop_16HIto8,
   6018                                                        unop(Iop_32to16,
   6019                                                             getIReg(rs))))),
   6020                                        binop(Iop_Add32,
   6021                                              unop(Iop_8Uto32,
   6022                                                   unop(Iop_16to8,
   6023                                                        unop(Iop_32HIto16,
   6024                                                             getIReg(rs)))),
   6025                                              unop(Iop_8Uto32,
   6026                                                   unop(Iop_16HIto8,
   6027                                                        unop(Iop_32HIto16,
   6028                                                             getIReg(rs)))))));
   6029                      break;
   6030                   }
   6031                   case 0x16: {  /* ADDQ_S.W */
   6032                      DIP("addq_s.w r%d, r%d, r%d", rd, rs, rt);
   6033                      vassert(!mode64);
   6034                      t0 = newTemp(Ity_I64);
   6035                      t1 = newTemp(Ity_I1);
   6036                      t2 = newTemp(Ity_I32);
   6037                      t3 = newTemp(Ity_I32);
   6038 
   6039                      assign(t0, binop(Iop_Add64,
   6040                                       unop(Iop_32Sto64, getIReg(rs)),
   6041                                       unop(Iop_32Sto64, getIReg(rt))));
   6042 
   6043                      assign(t3, binop(Iop_And32,
   6044                                       unop(Iop_64HIto32, mkexpr(t0)),
   6045                                       mkU32(0x1)));
   6046                      assign(t1, binop(Iop_CmpNE32,
   6047                                       binop(Iop_Shr32,
   6048                                             binop(Iop_And32,
   6049                                                   unop(Iop_64to32, mkexpr(t0)),
   6050                                                   mkU32(0x80000000)),
   6051                                             mkU8(31)),
   6052                                       mkexpr(t3)));
   6053 
   6054                      putDSPControl(IRExpr_ITE(mkexpr(t1),
   6055                                               binop(Iop_Or32,
   6056                                                     getDSPControl(),
   6057                                                     mkU32(0x00100000)),
   6058                                               getDSPControl()));
   6059 
   6060                      putIReg(rd, IRExpr_ITE(mkexpr(t1),
   6061                                             IRExpr_ITE(binop(Iop_CmpEQ32,
   6062                                                              mkexpr(t3),
   6063                                                              mkU32(0x0)),
   6064                                                        mkU32(0x7fffffff),
   6065                                                        mkU32(0x80000000)),
   6066                                             unop(Iop_64to32, mkexpr(t0))));
   6067                      break;
   6068                   }
   6069                   case 0x17: {  /* SUBQ_S.W */
   6070                      DIP("subq_s.w r%d, r%d, r%d", rd, rs, rt);
   6071                      vassert(!mode64);
   6072                      t0 = newTemp(Ity_I64);
   6073                      t1 = newTemp(Ity_I1);
   6074                      t2 = newTemp(Ity_I32);
   6075                      t3 = newTemp(Ity_I32);
   6076 
   6077                      assign(t0, binop(Iop_Sub64,
   6078                                       unop(Iop_32Sto64, getIReg(rs)),
   6079                                       unop(Iop_32Sto64, getIReg(rt))));
   6080 
   6081                      assign(t3, binop(Iop_And32,
   6082                                       unop(Iop_64HIto32, mkexpr(t0)),
   6083                                       mkU32(0x1)));
   6084                      assign(t1, binop(Iop_CmpNE32,
   6085                                       binop(Iop_Shr32,
   6086                                             binop(Iop_And32,
   6087                                                   unop(Iop_64to32, mkexpr(t0)),
   6088                                                   mkU32(0x80000000)),
   6089                                             mkU8(31)),
   6090                                       mkexpr(t3)));
   6091 
   6092                      putDSPControl(IRExpr_ITE(mkexpr(t1),
   6093                                               binop(Iop_Or32,
   6094                                                     getDSPControl(),
   6095                                                     mkU32(0x00100000)),
   6096                                               getDSPControl()));
   6097 
   6098                      putIReg(rd, IRExpr_ITE(mkexpr(t1),
   6099                                             IRExpr_ITE(binop(Iop_CmpEQ32,
   6100                                                              mkexpr(t3),
   6101                                                              mkU32(0x0)),
   6102                                                        mkU32(0x7fffffff),
   6103                                                        mkU32(0x80000000)),
   6104                                             unop(Iop_64to32, mkexpr(t0))));
   6105                      break;
   6106                   }
   6107                   case 0x1C: {  /* MULEQ_S.W.PHL */
   6108                      DIP("muleq_s.w.phl r%d, r%d, r%d", rd, rs, rt);
   6109                      vassert(!mode64);
   6110                      t0 = newTemp(Ity_I32);
   6111                      t1 = newTemp(Ity_I1);
   6112                      t2 = newTemp(Ity_I1);
   6113                      t3 = newTemp(Ity_I32);
   6114 
   6115                      assign(t0,
   6116                             binop(Iop_Shl32,
   6117                                   binop(Iop_Mul32,
   6118                                         unop(Iop_16Sto32,
   6119                                              unop(Iop_32HIto16, getIReg(rt))),
   6120                                         unop(Iop_16Sto32,
   6121                                              unop(Iop_32HIto16, getIReg(rs)))),
   6122                                   mkU8(0x1)));
   6123                      assign(t1, binop(Iop_CmpEQ32,
   6124                                       binop(Iop_And32,
   6125                                             getIReg(rt),
   6126                                             mkU32(0xffff0000)),
   6127                                       mkU32(0x80000000)));
   6128                      assign(t2, binop(Iop_CmpEQ32,
   6129                                       binop(Iop_And32,
   6130                                             getIReg(rs),
   6131                                             mkU32(0xffff0000)),
   6132                                       mkU32(0x80000000)));
   6133                      assign(t3, IRExpr_ITE(mkexpr(t1),
   6134                                            IRExpr_ITE(mkexpr(t2),
   6135                                                       binop(Iop_Or32,
   6136                                                             getDSPControl(),
   6137                                                             mkU32(0x00200000)),
   6138                                                       getDSPControl()),
   6139                                            getDSPControl()));
   6140                      putDSPControl(mkexpr(t3));
   6141 
   6142                      putIReg(rd, IRExpr_ITE(mkexpr(t1),
   6143                                             IRExpr_ITE(mkexpr(t2),
   6144                                                        mkU32(0x7fffffff),
   6145                                                        mkexpr(t0)),
   6146                                             mkexpr(t0)));
   6147                      break;
   6148                   }
   6149                   case 0x1D: {  /* MULEQ_S.W.PHR */
   6150                      DIP("muleq_s.w.phr r%d, r%d, r%d", rd, rs, rt);
   6151                      vassert(!mode64);
   6152                      t0 = newTemp(Ity_I32);
   6153                      t1 = newTemp(Ity_I1);
   6154                      t2 = newTemp(Ity_I1);
   6155 
   6156                      assign(t0,
   6157                             binop(Iop_Shl32,
   6158                                   binop(Iop_Mul32,
   6159                                         unop(Iop_16Sto32,
   6160                                              unop(Iop_32to16, getIReg(rt))),
   6161                                         unop(Iop_16Sto32,
   6162                                              unop(Iop_32to16, getIReg(rs)))),
   6163                                   mkU8(0x1)));
   6164                      assign(t1, binop(Iop_CmpEQ32,
   6165                                       binop(Iop_And32,
   6166                                             getIReg(rt),
   6167                                             mkU32(0xffff)),
   6168                                       mkU32(0x8000)));
   6169                      assign(t2, binop(Iop_CmpEQ32,
   6170                                       binop(Iop_And32,
   6171                                             getIReg(rs),
   6172                                             mkU32(0xffff)),
   6173                                       mkU32(0x8000)));
   6174                      putDSPControl(IRExpr_ITE(mkexpr(t1),
   6175                                               IRExpr_ITE(mkexpr(t2),
   6176                                                          binop(Iop_Or32,
   6177                                                                getDSPControl(),
   6178                                                                mkU32(0x00200000)
   6179                                                               ),
   6180                                                          getDSPControl()),
   6181                                               getDSPControl()));
   6182                      putIReg(rd, IRExpr_ITE(mkexpr(t1),
   6183                                             IRExpr_ITE(mkexpr(t2),
   6184                                                        mkU32(0x7fffffff),
   6185                                                        mkexpr(t0)),
   6186                                             mkexpr(t0)));
   6187                      break;
   6188                   }
   6189                   case 0x1E: {  /* MULQ_S.PH */
   6190                      DIP("mulq_s.ph r%d, r%d, r%d", rd, rs, rt);
   6191                      vassert(!mode64);
   6192                      t0 = newTemp(Ity_I32);
   6193                      t1 = newTemp(Ity_I32);
   6194                      t2 = newTemp(Ity_I16);
   6195                      t3 = newTemp(Ity_I16);
   6196                      t5 = newTemp(Ity_I32);
   6197                      t6 = newTemp(Ity_I32);
   6198                      t7 = newTemp(Ity_I32);
   6199                      t8 = newTemp(Ity_I32);
   6200 
   6201                      assign(t5,
   6202                             unop(Iop_16Sto32, unop(Iop_32to16, getIReg(rs))));
   6203                      assign(t6,
   6204                             unop(Iop_16Sto32, unop(Iop_32to16, getIReg(rt))));
   6205 
   6206                      assign(t7,
   6207                             unop(Iop_16Sto32, unop(Iop_32HIto16, getIReg(rs))));
   6208                      assign(t8,
   6209                             unop(Iop_16Sto32, unop(Iop_32HIto16, getIReg(rt))));
   6210 
   6211                      assign(t0, binop(Iop_And32,
   6212                                       unop(Iop_1Sto32,
   6213                                            binop(Iop_CmpEQ32,
   6214                                                  binop(Iop_And32,
   6215                                                        mkexpr(t5),
   6216                                                        mkU32(0xffff)),
   6217                                                  mkU32(0x8000))),
   6218                                       unop(Iop_1Sto32,
   6219                                            binop(Iop_CmpEQ32,
   6220                                                  binop(Iop_And32,
   6221                                                        mkexpr(t6),
   6222                                                        mkU32(0xffff)),
   6223                                                  mkU32(0x8000)))));
   6224                      assign(t1, binop(Iop_And32,
   6225                                       unop(Iop_1Sto32,
   6226                                            binop(Iop_CmpEQ32,
   6227                                                  binop(Iop_And32,
   6228                                                        mkexpr(t7),
   6229                                                        mkU32(0xffff)),
   6230                                                  mkU32(0x8000))),
   6231                                       unop(Iop_1Sto32,
   6232                                            binop(Iop_CmpEQ32,
   6233                                                  binop(Iop_And32,
   6234                                                        mkexpr(t8),
   6235                                                        mkU32(0xffff)),
   6236                                                  mkU32(0x8000)))));
   6237 
   6238                      putDSPControl(IRExpr_ITE(binop(Iop_CmpEQ32,
   6239                                                     binop(Iop_Or32,
   6240                                                           mkexpr(t0),
   6241                                                           mkexpr(t1)),
   6242                                                     mkU32(0x0)),
   6243                                               getDSPControl(),
   6244                                               binop(Iop_Or32,
   6245                                                     getDSPControl(),
   6246                                                     mkU32(0x200000))));
   6247 
   6248                      assign(t2, unop(Iop_32HIto16,
   6249                                      binop(Iop_Shl32,
   6250                                            unop(Iop_64to32,
   6251                                                 binop(Iop_MullS32,
   6252                                                       mkexpr(t7),
   6253                                                       mkexpr(t8))),
   6254                                            mkU8(0x1))));
   6255                      assign(t3, unop(Iop_32HIto16,
   6256                                      binop(Iop_Shl32,
   6257                                            unop(Iop_64to32,
   6258                                                 binop(Iop_MullS32,
   6259                                                       mkexpr(t5),
   6260                                                       mkexpr(t6))),
   6261                                            mkU8(0x1))));
   6262                      putIReg(rd, binop(Iop_16HLto32,
   6263                                        IRExpr_ITE(binop(Iop_CmpEQ32,
   6264                                                         mkexpr(t1),
   6265                                                         mkU32(0x0)),
   6266                                                   mkexpr(t2),
   6267                                                   mkU16(0x7fff)),
   6268                                        IRExpr_ITE(binop(Iop_CmpEQ32,
   6269                                                         mkexpr(t0),
   6270                                                         mkU32(0x0)),
   6271                                                   mkexpr(t3),
   6272                                                   mkU16(0x7fff))));
   6273                      break;
   6274                   }
   6275                   case 0x1F: {  /* MULQ_RS.PH */
   6276                      DIP("mulq_rs.ph r%d, r%d, r%d", rd, rs, rt);
   6277                      vassert(!mode64);
   6278                      t0 = newTemp(Ity_I32);
   6279                      t1 = newTemp(Ity_I1);
   6280                      t2 = newTemp(Ity_I1);
   6281                      t3 = newTemp(Ity_I16);
   6282                      t4 = newTemp(Ity_I32);
   6283                      t5 = newTemp(Ity_I1);
   6284                      t6 = newTemp(Ity_I1);
   6285                      t7 = newTemp(Ity_I16);
   6286 
   6287                      /* Multiply and round lower halfwords. */
   6288                      assign(t0, binop(Iop_Add32,
   6289                                       binop(Iop_Shl32,
   6290                                             binop(Iop_Mul32,
   6291                                                   unop(Iop_16Sto32,
   6292                                                        unop(Iop_32to16,
   6293                                                             getIReg(rt))),
   6294                                                   unop(Iop_16Sto32,
   6295                                                        unop(Iop_32to16,
   6296                                                             getIReg(rs)))),
   6297                                             mkU8(0x1)),
   6298                                       mkU32(0x00008000)));
   6299                      assign(t1, binop(Iop_CmpEQ32,
   6300                                       binop(Iop_And32,
   6301                                             getIReg(rt), mkU32(0xffff)),
   6302                                       mkU32(0x8000)));
   6303                      assign(t2, binop(Iop_CmpEQ32,
   6304                                       binop(Iop_And32,
   6305                                             getIReg(rs), mkU32(0xffff)),
   6306                                       mkU32(0x8000)));
   6307                      putDSPControl(IRExpr_ITE(mkexpr(t1),
   6308                                               IRExpr_ITE(mkexpr(t2),
   6309                                                          binop(Iop_Or32,
   6310                                                                getDSPControl(),
   6311                                                                mkU32(0x00200000)
   6312                                                               ),
   6313                                                          getDSPControl()),
   6314                                               getDSPControl()));
   6315                      assign(t3, IRExpr_ITE(mkexpr(t1),
   6316                                            IRExpr_ITE(mkexpr(t2),
   6317                                                       mkU16(0x7fff),
   6318                                                       unop(Iop_32HIto16,
   6319                                                            mkexpr(t0))),
   6320                                            unop(Iop_32HIto16, mkexpr(t0))));
   6321 
   6322                      /* Multiply and round higher halfwords. */
   6323                      assign(t4, binop(Iop_Add32,
   6324                                       binop(Iop_Shl32,
   6325                                             binop(Iop_Mul32,
   6326                                                   unop(Iop_16Sto32,
   6327                                                        unop(Iop_32HIto16,
   6328                                                             getIReg(rt))),
   6329                                                   unop(Iop_16Sto32,
   6330                                                        unop(Iop_32HIto16,
   6331                                                             getIReg(rs)))),
   6332                                             mkU8(0x1)),
   6333                                       mkU32(0x00008000)));
   6334                      assign(t5, binop(Iop_CmpEQ32,
   6335                                       binop(Iop_And32,
   6336                                             getIReg(rt),
   6337                                             mkU32(0xffff0000)),
   6338                                       mkU32(0x80000000)));
   6339                      assign(t6, binop(Iop_CmpEQ32,
   6340                                       binop(Iop_And32,
   6341                                             getIReg(rs),
   6342                                             mkU32(0xffff0000)),
   6343                                       mkU32(0x80000000)));
   6344                      putDSPControl(IRExpr_ITE(mkexpr(t5),
   6345                                              IRExpr_ITE(mkexpr(t6),
   6346                                                         binop(Iop_Or32,
   6347                                                              getDSPControl(),
   6348                                                              mkU32(0x00200000)),
   6349                                                         getDSPControl()),
   6350                                              getDSPControl()));
   6351                      assign(t7, IRExpr_ITE(mkexpr(t5),
   6352                                            IRExpr_ITE(mkexpr(t6),
   6353                                                       mkU16(0x7fff),
   6354                                                       unop(Iop_32HIto16,
   6355                                                            mkexpr(t4))),
   6356                                            unop(Iop_32HIto16, mkexpr(t4))));
   6357 
   6358                      putIReg(rd, binop(Iop_16HLto32, mkexpr(t7), mkexpr(t3)));
   6359                      break;
   6360                   }
   6361                   default:
   6362                      return -1;
   6363                }
   6364                break;  /* end of ADDU.QB */
   6365             }
   6366             case 0x11: {  /* CMPU.EQ.QB */
   6367                switch(sa) {
   6368                   case 0x0: {  /* CMPU.EQ.QB */
   6369                      DIP("cmpu.eq.qb r%d, r%d", rs, rt);
   6370                      vassert(!mode64);
   6371                      t1 = newTemp(Ity_I1);
   6372                      t2 = newTemp(Ity_I1);
   6373                      t3 = newTemp(Ity_I1);
   6374                      t4 = newTemp(Ity_I1);
   6375 
   6376                      assign(t1,
   6377                             binop(Iop_CmpEQ32,
   6378                                   binop(Iop_And32, getIReg(rs), mkU32(0xff)),
   6379                                   binop(Iop_And32, getIReg(rt), mkU32(0xff))));
   6380                      putDSPControl(IRExpr_ITE(mkexpr(t1),
   6381                                               binop(Iop_Or32,
   6382                                                     getDSPControl(),
   6383                                                     mkU32(0x01000000)),
   6384                                               binop(Iop_And32,
   6385                                                     getDSPControl(),
   6386                                                     mkU32(0xfeffffff))));
   6387 
   6388                      assign(t2, binop(Iop_CmpEQ32,
   6389                                       unop(Iop_8Uto32,
   6390                                            unop(Iop_16HIto8,
   6391                                                 unop(Iop_32to16,
   6392                                                      getIReg(rs)))),
   6393                                       unop(Iop_8Uto32,
   6394                                            unop(Iop_16HIto8,
   6395                                                 unop(Iop_32to16,
   6396                                                      getIReg(rt))))));
   6397                      putDSPControl(IRExpr_ITE(mkexpr(t2),
   6398                                               binop(Iop_Or32,
   6399                                                     getDSPControl(),
   6400                                                     mkU32(0x02000000)),
   6401                                               binop(Iop_And32,
   6402                                                     getDSPControl(),
   6403                                                     mkU32(0xfdffffff))));
   6404 
   6405                      assign(t3, binop(Iop_CmpEQ32,
   6406                                       unop(Iop_8Uto32,
   6407                                            unop(Iop_16to8,
   6408                                                 unop(Iop_32HIto16,
   6409                                                      getIReg(rs)))),
   6410                                       unop(Iop_8Uto32,
   6411                                            unop(Iop_16to8,
   6412                                                 unop(Iop_32HIto16,
   6413                                                      getIReg(rt))))));
   6414                      putDSPControl(IRExpr_ITE(mkexpr(t3),
   6415                                               binop(Iop_Or32,
   6416                                                     getDSPControl(),
   6417                                                     mkU32(0x04000000)),
   6418                                               binop(Iop_And32,
   6419                                                     getDSPControl(),
   6420                                                     mkU32(0xfbffffff))));
   6421 
   6422                      assign(t4, binop(Iop_CmpEQ32,
   6423                                       unop(Iop_8Uto32,
   6424                                            unop(Iop_16HIto8,
   6425                                                 unop(Iop_32HIto16,
   6426                                                      getIReg(rs)))),
   6427                                       unop(Iop_8Uto32,
   6428                                            unop(Iop_16HIto8,
   6429                                                 unop(Iop_32HIto16,
   6430                                                      getIReg(rt))))));
   6431                      putDSPControl(IRExpr_ITE(mkexpr(t4),
   6432                                               binop(Iop_Or32,
   6433                                                     getDSPControl(),
   6434                                                     mkU32(0x08000000)),
   6435                                               binop(Iop_And32,
   6436                                                     getDSPControl(),
   6437                                                     mkU32(0xf7ffffff))));
   6438                      break;
   6439                   }
   6440                   case 0x1: {  /* CMPU.LT.QB */
   6441                      DIP("cmpu.lt.qb r%d, r%d", rs, rt);
   6442                      vassert(!mode64);
   6443                      t1 = newTemp(Ity_I1);
   6444                      t2 = newTemp(Ity_I1);
   6445                      t3 = newTemp(Ity_I1);
   6446                      t4 = newTemp(Ity_I1);
   6447 
   6448                      assign(t1, binop(Iop_CmpLT32U,
   6449                                       unop(Iop_8Uto32,
   6450                                            unop(Iop_16to8,
   6451                                                 unop(Iop_32to16,
   6452                                                      getIReg(rs)))),
   6453                                       unop(Iop_8Uto32,
   6454                                            unop(Iop_16to8,
   6455                                                 unop(Iop_32to16,
   6456                                                      getIReg(rt))))));
   6457                      putDSPControl(IRExpr_ITE(mkexpr(t1),
   6458                                               binop(Iop_Or32,
   6459                                                     getDSPControl(),
   6460                                                     mkU32(0x01000000)),
   6461                                               binop(Iop_And32,
   6462                                                     getDSPControl(),
   6463                                                     mkU32(0xfeffffff))));
   6464 
   6465                      assign(t2, binop(Iop_CmpLT32U,
   6466                                       unop(Iop_8Uto32,
   6467                                            unop(Iop_16HIto8,
   6468                                                 unop(Iop_32to16,
   6469                                                      getIReg(rs)))),
   6470                                       unop(Iop_8Uto32,
   6471                                            unop(Iop_16HIto8,
   6472                                                 unop(Iop_32to16,
   6473                                                      getIReg(rt))))));
   6474                      putDSPControl(IRExpr_ITE(mkexpr(t2),
   6475                                               binop(Iop_Or32,
   6476                                                     getDSPControl(),
   6477                                                     mkU32(0x02000000)),
   6478                                               binop(Iop_And32,
   6479                                                     getDSPControl(),
   6480                                                     mkU32(0xfdffffff))));
   6481 
   6482                      assign(t3, binop(Iop_CmpLT32U,
   6483                                       unop(Iop_8Uto32,
   6484                                            unop(Iop_16to8,
   6485                                                 unop(Iop_32HIto16,
   6486                                                      getIReg(rs)))),
   6487                                       unop(Iop_8Uto32,
   6488                                            unop(Iop_16to8,
   6489                                                 unop(Iop_32HIto16,
   6490                                                      getIReg(rt))))));
   6491                      putDSPControl(IRExpr_ITE(mkexpr(t3),
   6492                                               binop(Iop_Or32,
   6493                                                     getDSPControl(),
   6494                                                     mkU32(0x04000000)),
   6495                                               binop(Iop_And32,
   6496                                                     getDSPControl(),
   6497                                                     mkU32(0xfbffffff))));
   6498 
   6499                      assign(t4, binop(Iop_CmpLT32U,
   6500                                       unop(Iop_8Uto32,
   6501                                            unop(Iop_16HIto8,
   6502                                                 unop(Iop_32HIto16,
   6503                                                      getIReg(rs)))),
   6504                                       unop(Iop_8Uto32,
   6505                                            unop(Iop_16HIto8,
   6506                                                 unop(Iop_32HIto16,
   6507                                                      getIReg(rt))))));
   6508                      putDSPControl(IRExpr_ITE(mkexpr(t4),
   6509                                               binop(Iop_Or32,
   6510                                                     getDSPControl(),
   6511                                                     mkU32(0x08000000)),
   6512                                               binop(Iop_And32,
   6513                                                     getDSPControl(),
   6514                                                     mkU32(0xf7ffffff))));
   6515                      break;
   6516                   }
   6517                   case 0x2: {  /* CMPU.LE.QB */
   6518                      DIP("cmpu.le.qb r%d, r%d", rs, rt);
   6519                      vassert(!mode64);
   6520                      t1 = newTemp(Ity_I1);
   6521                      t2 = newTemp(Ity_I1);
   6522                      t3 = newTemp(Ity_I1);
   6523                      t4 = newTemp(Ity_I1);
   6524 
   6525                      assign(t1, binop(Iop_CmpLE32U,
   6526                                       unop(Iop_8Uto32,
   6527                                            unop(Iop_16to8,
   6528                                                 unop(Iop_32to16,
   6529                                                      getIReg(rs)))),
   6530                                       unop(Iop_8Uto32,
   6531                                            unop(Iop_16to8,
   6532                                                 unop(Iop_32to16,
   6533                                                      getIReg(rt))))));
   6534                      putDSPControl(IRExpr_ITE(mkexpr(t1),
   6535                                               binop(Iop_Or32,
   6536                                                     getDSPControl(),
   6537                                                     mkU32(0x01000000)),
   6538                                               binop(Iop_And32,
   6539                                                     getDSPControl(),
   6540                                                     mkU32(0xfeffffff))));
   6541 
   6542                      assign(t2, binop(Iop_CmpLE32U,
   6543                                       unop(Iop_8Uto32,
   6544                                            unop(Iop_16HIto8,
   6545                                                 unop(Iop_32to16,
   6546                                                      getIReg(rs)))),
   6547                                       unop(Iop_8Uto32,
   6548                                            unop(Iop_16HIto8,
   6549                                                 unop(Iop_32to16,
   6550                                                      getIReg(rt))))));
   6551                      putDSPControl(IRExpr_ITE(mkexpr(t2),
   6552                                               binop(Iop_Or32,
   6553                                                     getDSPControl(),
   6554                                                     mkU32(0x02000000)),
   6555                                               binop(Iop_And32,
   6556                                                     getDSPControl(),
   6557                                                     mkU32(0xfdffffff))));
   6558 
   6559                      assign(t3, binop(Iop_CmpLE32U,
   6560                                       unop(Iop_8Uto32,
   6561                                            unop(Iop_16to8,
   6562                                                 unop(Iop_32HIto16,
   6563                                                      getIReg(rs)))),
   6564                                       unop(Iop_8Uto32,
   6565                                            unop(Iop_16to8,
   6566                                                 unop(Iop_32HIto16,
   6567                                                      getIReg(rt))))));
   6568                      putDSPControl(IRExpr_ITE(mkexpr(t3),
   6569                                               binop(Iop_Or32,
   6570                                                     getDSPControl(),
   6571                                                     mkU32(0x04000000)),
   6572                                               binop(Iop_And32,
   6573                                                     getDSPControl(),
   6574                                                     mkU32(0xfbffffff))));
   6575 
   6576                      assign(t4, binop(Iop_CmpLE32U,
   6577                                       unop(Iop_8Uto32,
   6578                                            unop(Iop_16HIto8,
   6579                                                 unop(Iop_32HIto16,
   6580                                                      getIReg(rs)))),
   6581                                       unop(Iop_8Uto32,
   6582                                            unop(Iop_16HIto8,
   6583                                                 unop(Iop_32HIto16,
   6584                                                      getIReg(rt))))));
   6585                      putDSPControl(IRExpr_ITE(mkexpr(t4),
   6586                                               binop(Iop_Or32,
   6587                                                     getDSPControl(),
   6588                                                     mkU32(0x08000000)),
   6589                                               binop(Iop_And32,
   6590                                                     getDSPControl(),
   6591                                                     mkU32(0xf7ffffff))));
   6592                      break;
   6593                   }
   6594                   case 0x3: {  /* PICK.QB */
   6595                      DIP("pick.qb r%d, r%d, r%d", rd, rs, rt);
   6596                      vassert(!mode64);
   6597                      t0 = newTemp(Ity_I32);
   6598                      t1 = newTemp(Ity_I8);
   6599                      t2 = newTemp(Ity_I8);
   6600                      t3 = newTemp(Ity_I8);
   6601                      t4 = newTemp(Ity_I8);
   6602 
   6603                      assign(t0, getDSPControl());
   6604                      assign(t1, IRExpr_ITE(binop(Iop_CmpNE32,
   6605                                                  binop(Iop_And32,
   6606                                                        mkexpr(t0),
   6607                                                        mkU32(0x01000000)),
   6608                                                  mkU32(0x0)),
   6609                                            unop(Iop_16to8,
   6610                                                  unop(Iop_32to16,
   6611                                                       getIReg(rs))),
   6612                                            unop(Iop_16to8,
   6613                                                 unop(Iop_32to16,
   6614                                                      getIReg(rt)))));
   6615                      assign(t2, IRExpr_ITE(binop(Iop_CmpNE32,
   6616                                                  binop(Iop_And32,
   6617                                                        mkexpr(t0),
   6618                                                        mkU32(0x02000000)),
   6619                                                  mkU32(0x0)),
   6620                                            unop(Iop_16HIto8,
   6621                                                 unop(Iop_32to16, getIReg(rs))),
   6622                                            unop(Iop_16HIto8,
   6623                                                 unop(Iop_32to16,
   6624                                                      getIReg(rt)))));
   6625                      assign(t3, IRExpr_ITE(binop(Iop_CmpNE32,
   6626                                                  binop(Iop_And32,
   6627                                                        mkexpr(t0),
   6628                                                        mkU32(0x04000000)),
   6629                                                  mkU32(0x0)),
   6630                                            unop(Iop_16to8,
   6631                                                 unop(Iop_32HIto16,
   6632                                                      getIReg(rs))),
   6633                                            unop(Iop_16to8,
   6634                                                 unop(Iop_32HIto16,
   6635                                                      getIReg(rt)))));
   6636                      assign(t4, IRExpr_ITE(binop(Iop_CmpNE32,
   6637                                                  binop(Iop_And32,
   6638                                                        mkexpr(t0),
   6639                                                        mkU32(0x08000000)),
   6640                                                  mkU32(0x0)),
   6641                                            unop(Iop_16HIto8,
   6642                                                 unop(Iop_32HIto16,
   6643                                                      getIReg(rs))),
   6644                                            unop(Iop_16HIto8,
   6645                                                 unop(Iop_32HIto16,
   6646                                                      getIReg(rt)))));
   6647                      putIReg(rd,
   6648                              binop(Iop_16HLto32,
   6649                                    binop(Iop_8HLto16, mkexpr(t4), mkexpr(t3)),
   6650                                    binop(Iop_8HLto16, mkexpr(t2), mkexpr(t1))));
   6651                      break;
   6652                   }
   6653                   case 0x4: {  /* CMPGU.EQ.QB */
   6654                      DIP("cmpgu.eq.qb r%d, r%d, r%d", rd, rs, rt);
   6655                      vassert(!mode64);
   6656                      t1 = newTemp(Ity_I1);
   6657                      t2 = newTemp(Ity_I1);
   6658                      t3 = newTemp(Ity_I1);
   6659                      t4 = newTemp(Ity_I1);
   6660                      t5 = newTemp(Ity_I32);
   6661                      t6 = newTemp(Ity_I32);
   6662                      t7 = newTemp(Ity_I32);
   6663                      t8 = newTemp(Ity_I32);
   6664 
   6665                      assign(t1, binop(Iop_CmpEQ32,
   6666                                       unop(Iop_8Uto32,
   6667                                            unop(Iop_16to8,
   6668                                                 unop(Iop_32to16, getIReg(rs)))),
   6669                                       unop(Iop_8Uto32,
   6670                                            unop(Iop_16to8,
   6671                                                 unop(Iop_32to16,
   6672                                                      getIReg(rt))))));
   6673                      assign(t5, IRExpr_ITE(mkexpr(t1),
   6674                                            mkU32(0x00000001), mkU32(0)));
   6675 
   6676                      assign(t2, binop(Iop_CmpEQ32,
   6677                                       unop(Iop_8Uto32,
   6678                                            unop(Iop_16HIto8,
   6679                                                 unop(Iop_32to16, getIReg(rs)))),
   6680                                       unop(Iop_8Uto32,
   6681                                            unop(Iop_16HIto8,
   6682                                                 unop(Iop_32to16,
   6683                                                      getIReg(rt))))));
   6684                      assign(t6, IRExpr_ITE(mkexpr(t2),
   6685                                            mkU32(0x00000002), mkU32(0)));
   6686 
   6687                      assign(t3, binop(Iop_CmpEQ32,
   6688                                       unop(Iop_8Uto32,
   6689                                            unop(Iop_16to8,
   6690                                                 unop(Iop_32HIto16,
   6691                                                      getIReg(rs)))),
   6692                                       unop(Iop_8Uto32,
   6693                                            unop(Iop_16to8,
   6694                                                 unop(Iop_32HIto16,
   6695                                                      getIReg(rt))))));
   6696                      assign(t7, IRExpr_ITE(mkexpr(t3),
   6697                                            mkU32(0x00000004), mkU32(0)));
   6698 
   6699                      assign(t4, binop(Iop_CmpEQ32,
   6700                                       unop(Iop_8Uto32,
   6701                                            unop(Iop_16HIto8,
   6702                                                 unop(Iop_32HIto16,
   6703                                                      getIReg(rs)))),
   6704                                       unop(Iop_8Uto32,
   6705                                            unop(Iop_16HIto8,
   6706                                                 unop(Iop_32HIto16,
   6707                                                      getIReg(rt))))));
   6708                      assign(t8, IRExpr_ITE(mkexpr(t4),
   6709                                            mkU32(0x00000008), mkU32(0)));
   6710 
   6711                      putIReg(rd, binop(Iop_Or32,
   6712                                        binop(Iop_Or32,
   6713                                              binop(Iop_Or32,
   6714                                                    mkexpr(t5), mkexpr(t6)),
   6715                                              mkexpr(t7)),
   6716                                        mkexpr(t8)));
   6717                      break;
   6718                   }
   6719                   case 0x5: {  /* CMPGU.LT.QB */
   6720                      DIP("cmpgu.lt.qb r%d, r%d, r%d", rd, rs, rt);
   6721                      vassert(!mode64);
   6722                      t1 = newTemp(Ity_I1);
   6723                      t2 = newTemp(Ity_I1);
   6724                      t3 = newTemp(Ity_I1);
   6725                      t4 = newTemp(Ity_I1);
   6726                      t5 = newTemp(Ity_I32);
   6727                      t6 = newTemp(Ity_I32);
   6728                      t7 = newTemp(Ity_I32);
   6729                      t8 = newTemp(Ity_I32);
   6730 
   6731                      assign(t1, binop(Iop_CmpLT32U,
   6732                                       unop(Iop_8Uto32,
   6733                                            unop(Iop_16to8,
   6734                                                 unop(Iop_32to16, getIReg(rs)))),
   6735                                       unop(Iop_8Uto32,
   6736                                            unop(Iop_16to8,
   6737                                                 unop(Iop_32to16,
   6738                                                      getIReg(rt))))));
   6739                      assign(t5, IRExpr_ITE(mkexpr(t1),
   6740                                            mkU32(0x00000001), mkU32(0)));
   6741 
   6742                      assign(t2, binop(Iop_CmpLT32U,
   6743                                       unop(Iop_8Uto32,
   6744                                            unop(Iop_16HIto8,
   6745                                                 unop(Iop_32to16, getIReg(rs)))),
   6746                                       unop(Iop_8Uto32,
   6747                                            unop(Iop_16HIto8,
   6748                                                 unop(Iop_32to16,
   6749                                                      getIReg(rt))))));
   6750                      assign(t6, IRExpr_ITE(mkexpr(t2),
   6751                                            mkU32(0x00000002), mkU32(0)));
   6752 
   6753                      assign(t3, binop(Iop_CmpLT32U,
   6754                                       unop(Iop_8Uto32,
   6755                                            unop(Iop_16to8,
   6756                                                 unop(Iop_32HIto16,
   6757                                                      getIReg(rs)))),
   6758                                       unop(Iop_8Uto32,
   6759                                            unop(Iop_16to8,
   6760                                                 unop(Iop_32HIto16,
   6761                                                      getIReg(rt))))));
   6762                      assign(t7, IRExpr_ITE(mkexpr(t3),
   6763                                            mkU32(0x00000004), mkU32(0)));
   6764 
   6765                      assign(t4, binop(Iop_CmpLT32U,
   6766                                       unop(Iop_8Uto32,
   6767                                            unop(Iop_16HIto8,
   6768                                                 unop(Iop_32HIto16,
   6769                                                      getIReg(rs)))),
   6770                                       unop(Iop_8Uto32,
   6771                                            unop(Iop_16HIto8,
   6772                                                 unop(Iop_32HIto16,
   6773                                                      getIReg(rt))))));
   6774                      assign(t8, IRExpr_ITE(mkexpr(t4),
   6775                                            mkU32(0x00000008), mkU32(0)));
   6776                      putIReg(rd, binop(Iop_Or32,
   6777                                        binop(Iop_Or32,
   6778                                              binop(Iop_Or32,
   6779                                                    mkexpr(t5), mkexpr(t6)),
   6780                                              mkexpr(t7)),
   6781                                        mkexpr(t8)));
   6782                      break;
   6783                   }
   6784                   case 0x6: {  /* CMPGU.LE.QB */
   6785                      DIP("cmpgu.le.qb r%d, r%d, r%d", rd, rs, rt);
   6786                      vassert(!mode64);
   6787                      t1 = newTemp(Ity_I1);
   6788                      t2 = newTemp(Ity_I1);
   6789                      t3 = newTemp(Ity_I1);
   6790                      t4 = newTemp(Ity_I1);
   6791                      t5 = newTemp(Ity_I32);
   6792                      t6 = newTemp(Ity_I32);
   6793                      t7 = newTemp(Ity_I32);
   6794                      t8 = newTemp(Ity_I32);
   6795 
   6796                      assign(t1, binop(Iop_CmpLE32U,
   6797                                       unop(Iop_8Uto32,
   6798                                            unop(Iop_16to8,
   6799                                                 unop(Iop_32to16, getIReg(rs)))),
   6800                                       unop(Iop_8Uto32,
   6801                                            unop(Iop_16to8,
   6802                                                 unop(Iop_32to16,
   6803                                                      getIReg(rt))))));
   6804                      assign(t5, IRExpr_ITE(mkexpr(t1),
   6805                                            mkU32(0x00000001), mkU32(0)));
   6806 
   6807                      assign(t2, binop(Iop_CmpLE32U,
   6808                                       unop(Iop_8Uto32,
   6809                                            unop(Iop_16HIto8,
   6810                                                 unop(Iop_32to16, getIReg(rs)))),
   6811                                       unop(Iop_8Uto32,
   6812                                            unop(Iop_16HIto8,
   6813                                                 unop(Iop_32to16,
   6814                                                      getIReg(rt))))));
   6815                      assign(t6, IRExpr_ITE(mkexpr(t2),
   6816                                            mkU32(0x00000002), mkU32(0)));
   6817 
   6818                      assign(t3, binop(Iop_CmpLE32U,
   6819                                       unop(Iop_8Uto32,
   6820                                            unop(Iop_16to8,
   6821                                                 unop(Iop_32HIto16,
   6822                                                      getIReg(rs)))),
   6823                                       unop(Iop_8Uto32,
   6824                                            unop(Iop_16to8,
   6825                                                 unop(Iop_32HIto16,
   6826                                                      getIReg(rt))))));
   6827                      assign(t7, IRExpr_ITE(mkexpr(t3),
   6828                                            mkU32(0x00000004), mkU32(0)));
   6829 
   6830                      assign(t4, binop(Iop_CmpLE32U,
   6831                                       unop(Iop_8Uto32,
   6832                                            unop(Iop_16HIto8,
   6833                                                 unop(Iop_32HIto16,
   6834                                                      getIReg(rs)))),
   6835                                       unop(Iop_8Uto32,
   6836                                            unop(Iop_16HIto8,
   6837                                                 unop(Iop_32HIto16,
   6838                                                      getIReg(rt))))));
   6839                      assign(t8, IRExpr_ITE(mkexpr(t4),
   6840                                            mkU32(0x00000008), mkU32(0)));
   6841                      putIReg(rd, binop(Iop_Or32,
   6842                                        binop(Iop_Or32,
   6843                                              binop(Iop_Or32,
   6844                                                    mkexpr(t5), mkexpr(t6)),
   6845                                              mkexpr(t7)),
   6846                                        mkexpr(t8)));
   6847                      break;
   6848                   }
   6849                   case 0x8: {  /* CMP.EQ.PH */
   6850                      DIP("cmp.eq.ph r%d, r%d", rs, rt);
   6851                      vassert(!mode64);
   6852                      t1 = newTemp(Ity_I1);
   6853                      t2 = newTemp(Ity_I1);
   6854 
   6855                      assign(t1, binop(Iop_CmpEQ16,
   6856                                       unop(Iop_32to16, getIReg(rs)),
   6857                                       unop(Iop_32to16, getIReg(rt))));
   6858                      putDSPControl(IRExpr_ITE(mkexpr(t1),
   6859                                               binop(Iop_Or32,
   6860                                                     getDSPControl(),
   6861                                                     mkU32(0x01000000)),
   6862                                               binop(Iop_And32,
   6863                                                     getDSPControl(),
   6864                                                     mkU32(0xfeffffff))));
   6865                      assign(t2, binop(Iop_CmpEQ16,
   6866                                       unop(Iop_32HIto16, getIReg(rs)),
   6867                                       unop(Iop_32HIto16, getIReg(rt))));
   6868                      putDSPControl(IRExpr_ITE(mkexpr(t2),
   6869                                               binop(Iop_Or32,
   6870                                                     getDSPControl(),
   6871                                                     mkU32(0x02000000)),
   6872                                               binop(Iop_And32,
   6873                                                     getDSPControl(),
   6874                                                     mkU32(0xfdffffff))));
   6875                      break;
   6876                   }
   6877                   case 0x9: {  /* CMP.LT.PH */
   6878                      DIP("cmp.lt.ph r%d, r%d", rs, rt);
   6879                      vassert(!mode64);
   6880                      t1 = newTemp(Ity_I1);
   6881                      t2 = newTemp(Ity_I1);
   6882 
   6883                      assign(t1, binop(Iop_CmpLT32S,
   6884                                       unop(Iop_16Sto32,
   6885                                            unop(Iop_32to16, getIReg(rs))),
   6886                                       unop(Iop_16Sto32,
   6887                                            unop(Iop_32to16, getIReg(rt)))));
   6888                      putDSPControl(IRExpr_ITE(mkexpr(t1),
   6889                                               binop(Iop_Or32,
   6890                                                     getDSPControl(),
   6891                                                     mkU32(0x01000000)),
   6892                                               binop(Iop_And32,
   6893                                                     getDSPControl(),
   6894                                                     mkU32(0xfeffffff))));
   6895 
   6896                      assign(t2, binop(Iop_CmpLT32S,
   6897                                       unop(Iop_16Sto32,
   6898                                            unop(Iop_32HIto16, getIReg(rs))),
   6899                                       unop(Iop_16Sto32,
   6900                                            unop(Iop_32HIto16, getIReg(rt)))));
   6901                      putDSPControl(IRExpr_ITE(mkexpr(t2),
   6902                                               binop(Iop_Or32,
   6903                                                     getDSPControl(),
   6904                                                     mkU32(0x02000000)),
   6905                                               binop(Iop_And32,
   6906                                                     getDSPControl(),
   6907                                                     mkU32(0xfdffffff))));
   6908                      break;
   6909                   }
   6910                   case 0xA: {  /* CMP.LE.PH */
   6911                      DIP("cmp.le.ph r%d, r%d", rs, rt);
   6912                      vassert(!mode64);
   6913                      t1 = newTemp(Ity_I1);
   6914                      t2 = newTemp(Ity_I1);
   6915 
   6916                      assign(t1, binop(Iop_CmpLE32S,
   6917                                       unop(Iop_16Sto32,
   6918                                            unop(Iop_32to16, getIReg(rs))),
   6919                                       unop(Iop_16Sto32,
   6920                                            unop(Iop_32to16, getIReg(rt)))));
   6921                      putDSPControl(IRExpr_ITE(mkexpr(t1),
   6922                                               binop(Iop_Or32,
   6923                                                     getDSPControl(),
   6924                                                     mkU32(0x01000000)),
   6925                                               binop(Iop_And32,
   6926                                                     getDSPControl(),
   6927                                                     mkU32(0xfeffffff))));
   6928 
   6929                      assign(t2, binop(Iop_CmpLE32S,
   6930                                       unop(Iop_16Sto32,
   6931                                            unop(Iop_32HIto16, getIReg(rs))),
   6932                                       unop(Iop_16Sto32,
   6933                                            unop(Iop_32HIto16, getIReg(rt)))));
   6934                      putDSPControl(IRExpr_ITE(mkexpr(t2),
   6935                                               binop(Iop_Or32,
   6936                                                     getDSPControl(),
   6937                                                     mkU32(0x02000000)),
   6938                                               binop(Iop_And32,
   6939                                                     getDSPControl(),
   6940                                                     mkU32(0xfdffffff))));
   6941                      break;
   6942                   }
   6943                   case 0xB: {  /* PICK.PH */
   6944                      DIP("pick.qb r%d, r%d, r%d", rd, rs, rt);
   6945                      vassert(!mode64);
   6946                      t0 = newTemp(Ity_I32);
   6947                      t1 = newTemp(Ity_I16);
   6948                      t2 = newTemp(Ity_I16);
   6949 
   6950                      assign(t0, getDSPControl());
   6951 
   6952                      assign(t1, IRExpr_ITE(binop(Iop_CmpNE32,
   6953                                                  binop(Iop_And32,
   6954                                                        mkexpr(t0),
   6955                                                        mkU32(0x01000000)),
   6956                                                  mkU32(0x0)),
   6957                                            unop(Iop_32to16, getIReg(rs)),
   6958                                            unop(Iop_32to16, getIReg(rt))));
   6959 
   6960                      assign(t2, IRExpr_ITE(binop(Iop_CmpNE32,
   6961                                                  binop(Iop_And32,
   6962                                                        mkexpr(t0),
   6963                                                        mkU32(0x02000000)),
   6964                                                  mkU32(0x0)),
   6965                                            unop(Iop_32HIto16, getIReg(rs)),
   6966                                            unop(Iop_32HIto16, getIReg(rt))));
   6967 
   6968                      putIReg(rd, binop(Iop_16HLto32, mkexpr(t2), mkexpr(t1)));
   6969                      break;
   6970                   }
   6971                   case 0xC: {  /* PRECRQ.QB.PH */
   6972                      DIP("precrq.qb.ph r%d, r%d, %d", rd, rs, rt);
   6973                      vassert(!mode64);
   6974                      putIReg(rd,
   6975                              binop(Iop_16HLto32,
   6976                                    binop(Iop_8HLto16,
   6977                                          unop(Iop_16HIto8,
   6978                                               unop(Iop_32HIto16, getIReg(rs))),
   6979                                          unop(Iop_16HIto8,
   6980                                               unop(Iop_32to16, getIReg(rs)))),
   6981                                    binop(Iop_8HLto16,
   6982                                          unop(Iop_16HIto8,
   6983                                               unop(Iop_32HIto16, getIReg(rt))),
   6984                                          unop(Iop_16HIto8,
   6985                                               unop(Iop_32to16, getIReg(rt))))));
   6986                      break;
   6987                   }
   6988                   case 0xD: {  /* PRECR.QB.PH */
   6989                      DIP("precr.qb.ph r%d, r%d, r%d", rd, rs, rt);
   6990                      vassert(!mode64);
   6991 
   6992                      putIReg(rd,
   6993                              binop(Iop_16HLto32,
   6994                                    binop(Iop_8HLto16,
   6995                                          unop(Iop_16to8,
   6996                                               unop(Iop_32HIto16, getIReg(rs))),
   6997                                          unop(Iop_16to8,
   6998                                               unop(Iop_32to16, getIReg(rs)))),
   6999                                    binop(Iop_8HLto16,
   7000                                          unop(Iop_16to8,
   7001                                               unop(Iop_32HIto16, getIReg(rt))),
   7002                                          unop(Iop_16to8,
   7003                                               unop(Iop_32to16, getIReg(rt))))));
   7004                      break;
   7005                   }
   7006                   case 0xF: {  /* PRECRQU_S.QB.PH */
   7007                      DIP("precrqu_s.qb.ph r%d, r%d, %d", rd, rs, rt);
   7008                      vassert(!mode64);
   7009                      t0 = newTemp(Ity_I8);
   7010                      t1 = newTemp(Ity_I8);
   7011                      t2 = newTemp(Ity_I8);
   7012                      t3 = newTemp(Ity_I8);
   7013                      t4 = newTemp(Ity_I8);
   7014                      t5 = newTemp(Ity_I32);
   7015                      t6 = newTemp(Ity_I1);
   7016                      t7 = newTemp(Ity_I8);
   7017                      t8 = newTemp(Ity_I1);
   7018                      t9 = newTemp(Ity_I32);
   7019                      t10 = newTemp(Ity_I8);
   7020                      t11 = newTemp(Ity_I1);
   7021                      t12 = newTemp(Ity_I32);
   7022                      t13 = newTemp(Ity_I8);
   7023                      t14 = newTemp(Ity_I1);
   7024                      t15 = newTemp(Ity_I32);
   7025 
   7026                      assign(t4, IRExpr_ITE(binop(Iop_CmpLT32U,
   7027                                                  mkU32(0x7f80),
   7028                                                  binop(Iop_And32,
   7029                                                        unop(Iop_16Uto32,
   7030                                                             unop(Iop_32to16,
   7031                                                             getIReg(rs))),
   7032                                                        mkU32(0x7fff))),
   7033                                            mkU8(0xff),
   7034                                            unop(Iop_16HIto8,
   7035                                                 unop(Iop_32to16,
   7036                                                      binop(Iop_Shl32,
   7037                                                            getIReg(rs),
   7038                                                            mkU8(1))))));
   7039                      assign(t0, IRExpr_ITE(binop(Iop_CmpEQ32,
   7040                                                  binop(Iop_And32,
   7041                                                        unop(Iop_16Uto32,
   7042                                                             unop(Iop_32to16,
   7043                                                                  getIReg(rs))),
   7044                                                        mkU32(0x00008000)),
   7045                                                  mkU32(0x0)),
   7046                                            mkexpr(t4),
   7047                                            mkU8(0x0)));
   7048                      assign(t5, binop(Iop_And32,
   7049                                       unop(Iop_16Uto32,
   7050                                             unop(Iop_32to16,
   7051                                                  getIReg(rs))),
   7052                                       mkU32(0x00008000)));
   7053                      assign(t6, binop(Iop_CmpLT32U,
   7054                                       mkU32(0x7f80),
   7055                                       binop(Iop_And32,
   7056                                             unop(Iop_16Uto32,
   7057                                                  unop(Iop_32to16,
   7058                                                  getIReg(rs))),
   7059                                             mkU32(0x7fff))));
   7060                      putDSPControl(IRExpr_ITE(binop(Iop_CmpEQ32,
   7061                                                     mkexpr(t5),
   7062                                                     mkU32(0x0)),
   7063                                               IRExpr_ITE(mkexpr(t6),
   7064                                                          binop(Iop_Or32,
   7065                                                                getDSPControl(),
   7066                                                                mkU32(0x00400000)
   7067                                                               ),
   7068                                                          getDSPControl()),
   7069                                               binop(Iop_Or32,
   7070                                                     getDSPControl(),
   7071                                                     mkU32(0x00400000))));
   7072 
   7073                      assign(t7, IRExpr_ITE(binop(Iop_CmpLT32U,
   7074                                                  mkU32(0x7f80),
   7075                                                  binop(Iop_And32,
   7076                                                        unop(Iop_16Uto32,
   7077                                                             unop(Iop_32HIto16,
   7078                                                                  getIReg(rs))),
   7079                                                        mkU32(0x7fff))),
   7080                                            mkU8(0xff),
   7081                                            unop(Iop_16HIto8,
   7082                                                 unop(Iop_32HIto16,
   7083                                                      binop(Iop_Shl32,
   7084                                                            getIReg(rs),
   7085                                                            mkU8(1))))));
   7086                      assign(t1, IRExpr_ITE(binop(Iop_CmpEQ32,
   7087                                                  binop(Iop_And32,
   7088                                                        unop(Iop_16Uto32,
   7089                                                             unop(Iop_32HIto16,
   7090                                                                  getIReg(rs))),
   7091                                                        mkU32(0x00008000)),
   7092                                                  mkU32(0x0)),
   7093                                            mkexpr(t7),
   7094                                            mkU8(0x0)));
   7095                      assign(t8, binop(Iop_CmpEQ32,
   7096                                       binop(Iop_And32,
   7097                                             unop(Iop_16Uto32,
   7098                                                  unop(Iop_32HIto16,
   7099                                                       getIReg(rs))),
   7100                                             mkU32(0x00008000)),
   7101                                       mkU32(0x0)));
   7102                      assign(t9, IRExpr_ITE(binop(Iop_CmpLT32U,
   7103                                                  mkU32(0x7f80),
   7104                                                  binop(Iop_And32,
   7105                                                        unop(Iop_16Uto32,
   7106                                                             unop(Iop_32HIto16,
   7107                                                                  getIReg(rs))),
   7108                                                        mkU32(0x7fff))),
   7109                                            binop(Iop_Or32,
   7110                                                  getDSPControl(),
   7111                                                  mkU32(0x00400000)),
   7112                                            getDSPControl()));
   7113                      putDSPControl(IRExpr_ITE(mkexpr(t8),
   7114                                               mkexpr(t9),
   7115                                               binop(Iop_Or32,
   7116                                                     getDSPControl(),
   7117                                                     mkU32(0x00400000))));
   7118 
   7119                      assign(t10, IRExpr_ITE(binop(Iop_CmpLT32U,
   7120                                                   mkU32(0x7f80),
   7121                                                   binop(Iop_And32,
   7122                                                         unop(Iop_16Uto32,
   7123                                                              unop(Iop_32to16,
   7124                                                              getIReg(rt))),
   7125                                                         mkU32(0x7fff))),
   7126                                             mkU8(0xff),
   7127                                             unop(Iop_16HIto8,
   7128                                                  unop(Iop_32to16,
   7129                                                       binop(Iop_Shl32,
   7130                                                             getIReg(rt),
   7131                                                             mkU8(1))))));
   7132                      assign(t2, IRExpr_ITE(binop(Iop_CmpEQ32,
   7133                                                  binop(Iop_And32,
   7134                                                        unop(Iop_16Uto32,
   7135                                                             unop(Iop_32to16,
   7136                                                                  getIReg(rt))),
   7137                                                        mkU32(0x00008000)),
   7138                                                  mkU32(0x0)),
   7139                                            mkexpr(t10),
   7140                                            mkU8(0x0)));
   7141                      assign(t11, binop(Iop_CmpEQ32,
   7142                                        binop(Iop_And32,
   7143                                              unop(Iop_16Uto32,
   7144                                                   unop(Iop_32to16,
   7145                                                        getIReg(rt))),
   7146                                              mkU32(0x00008000)),
   7147                                        mkU32(0x0)));
   7148                      assign(t12, IRExpr_ITE(binop(Iop_CmpLT32U,
   7149                                                   mkU32(0x7f80),
   7150                                                   binop(Iop_And32,
   7151                                                         unop(Iop_16Uto32,
   7152                                                              unop(Iop_32to16,
   7153                                                              getIReg(rt))),
   7154                                                         mkU32(0x7fff))),
   7155                                             binop(Iop_Or32,
   7156                                                   getDSPControl(),
   7157                                                   mkU32(0x00400000)),
   7158                                             getDSPControl()));
   7159                      putDSPControl(IRExpr_ITE(mkexpr(t11),
   7160                                               mkexpr(t12),
   7161                                               binop(Iop_Or32,
   7162                                                     getDSPControl(),
   7163                                                     mkU32(0x00400000))));
   7164 
   7165                      assign(t13, IRExpr_ITE(binop(Iop_CmpLT32U,
   7166                                                   mkU32(0x7f80),
   7167                                                   binop(Iop_And32,
   7168                                                         unop(Iop_16Uto32,
   7169                                                              unop(Iop_32HIto16,
   7170                                                                   getIReg(rt))),
   7171                                                         mkU32(0x7fff))),
   7172                                             mkU8(0xff),
   7173                                             unop(Iop_16HIto8,
   7174                                                  unop(Iop_32HIto16,
   7175                                                       binop(Iop_Shl32,
   7176                                                             getIReg(rt),
   7177                                                             mkU8(1))))));
   7178                      assign(t3, IRExpr_ITE(binop(Iop_CmpEQ32,
   7179                                                  binop(Iop_And32,
   7180                                                        unop(Iop_16Uto32,
   7181                                                             unop(Iop_32HIto16,
   7182                                                                  getIReg(rt))),
   7183                                                        mkU32(0x00008000)),
   7184                                                  mkU32(0x0)),
   7185                                            mkexpr(t13),
   7186                                            mkU8(0x0)));
   7187                      assign(t14, binop(Iop_CmpEQ32,
   7188                                        binop(Iop_And32,
   7189                                              unop(Iop_16Uto32,
   7190                                                   unop(Iop_32HIto16,
   7191                                                        getIReg(rt))),
   7192                                              mkU32(0x00008000)),
   7193                                        mkU32(0x0)));
   7194                      assign(t15, IRExpr_ITE(binop(Iop_CmpLT32U,
   7195                                                   mkU32(0x7f80),
   7196                                                   binop(Iop_And32,
   7197                                                         unop(Iop_16Uto32,
   7198                                                              unop(Iop_32HIto16,
   7199                                                                   getIReg(rt))),
   7200                                                         mkU32(0x7fff))),
   7201                                             binop(Iop_Or32,
   7202                                                   getDSPControl(),
   7203                                                   mkU32(0x00400000)),
   7204                                             getDSPControl()));
   7205                      putDSPControl(IRExpr_ITE(mkexpr(t14),
   7206                                               mkexpr(t15),
   7207                                               binop(Iop_Or32,
   7208                                                     getDSPControl(),
   7209                                                     mkU32(0x00400000))));
   7210 
   7211                      putIReg(rd, binop(Iop_16HLto32,
   7212                                        binop(Iop_8HLto16,
   7213                                              mkexpr(t1), mkexpr(t0)),
   7214                                        binop(Iop_8HLto16,
   7215                                              mkexpr(t3), mkexpr(t2))));
   7216                      break;
   7217                   }
   7218                   case 0x14: {  /* PRECRQ.PH.W */
   7219                      DIP("precrq.ph.w r%d, r%d, %d", rd, rs, rt);
   7220                      vassert(!mode64);
   7221                      putIReg(rd, binop(Iop_16HLto32,
   7222                                        unop(Iop_32HIto16, getIReg(rs)),
   7223                                        unop(Iop_32HIto16, getIReg(rt))));
   7224                      break;
   7225                   }
   7226                   case 0x15: {  /* PRECRQ_RS.PH.W */
   7227                      DIP("precrq_rs.ph.w r%d, r%d, %d", rd, rs, rt);
   7228                      vassert(!mode64);
   7229                      t0 = newTemp(Ity_I64);
   7230                      t1 = newTemp(Ity_I1);
   7231                      t2 = newTemp(Ity_I32);
   7232                      t3 = newTemp(Ity_I64);
   7233                      t4 = newTemp(Ity_I1);
   7234                      t5 = newTemp(Ity_I32);
   7235 
   7236                      assign(t0, binop(Iop_Add64,
   7237                                       binop(Iop_32HLto64,
   7238                                             binop(Iop_Shr32,
   7239                                                   binop(Iop_And32,
   7240                                                         getIReg(rs),
   7241                                                         mkU32(0x80000000)),
   7242                                                   mkU8(31)),
   7243                                             getIReg(rs)),
   7244                                       mkU64(0x0000000000008000ULL)));
   7245                      assign(t1, binop(Iop_CmpNE32,
   7246                                       binop(Iop_And32,
   7247                                             unop(Iop_64HIto32, mkexpr(t0)),
   7248                                             mkU32(0x1)),
   7249                                       binop(Iop_And32,
   7250                                             binop(Iop_Shr32,
   7251                                                   unop(Iop_64to32, mkexpr(t0)),
   7252                                                   mkU8(31)),
   7253                                             mkU32(0x1))));
   7254                      assign(t2, IRExpr_ITE(mkexpr(t1),
   7255                                            mkU32(0x7fffffff),
   7256                                            unop(Iop_64to32, mkexpr(t0))));
   7257                      putDSPControl(IRExpr_ITE(mkexpr(t1),
   7258                                               binop(Iop_Or32,
   7259                                                     getDSPControl(),
   7260                                                     mkU32(0x400000)),
   7261                                               getDSPControl()));
   7262                      assign(t3, binop(Iop_Add64,
   7263                                       binop(Iop_32HLto64,
   7264                                             binop(Iop_Shr32,
   7265                                                   binop(Iop_And32,
   7266                                                         getIReg(rt),
   7267                                                         mkU32(0x80000000)),
   7268                                                   mkU8(31)),
   7269                                             getIReg(rt)),
   7270                                       mkU64(0x0000000000008000ULL)));
   7271                      assign(t4, binop(Iop_CmpNE32,
   7272                                       binop(Iop_And32,
   7273                                             unop(Iop_64HIto32, mkexpr(t3)),
   7274                                             mkU32(0x1)),
   7275                                       binop(Iop_And32,
   7276                                             binop(Iop_Shr32,
   7277                                                   unop(Iop_64to32, mkexpr(t3)),
   7278                                                   mkU8(31)),
   7279                                             mkU32(0x1))));
   7280                      assign(t5, IRExpr_ITE(mkexpr(t4),
   7281                                            mkU32(0x7fffffff),
   7282                                            unop(Iop_64to32, mkexpr(t3))));
   7283                      putDSPControl(IRExpr_ITE(mkexpr(t4),
   7284                                               binop(Iop_Or32,
   7285                                                     getDSPControl(),
   7286                                                     mkU32(0x400000)),
   7287                                               getDSPControl()));
   7288                      putIReg(rd, binop(Iop_16HLto32,
   7289                                        unop(Iop_32HIto16, mkexpr(t2)),
   7290                                        unop(Iop_32HIto16, mkexpr(t5))));
   7291                      break;
   7292                   }
   7293                   case 0x1E: {  /* PRECR_SRA.PH.W */
   7294                      DIP("precr_sra.ph.w r%d, r%d, %d", rt, rs, rd);
   7295                      vassert(!mode64);
   7296 
   7297                      if (0 == rd) {
   7298                         putIReg(rt, binop(Iop_16HLto32,
   7299                                           unop(Iop_32to16, getIReg(rt)),
   7300                                           unop(Iop_32to16, getIReg(rs))));
   7301                      } else {
   7302                         putIReg(rt, binop(Iop_16HLto32,
   7303                                           unop(Iop_32to16, binop(Iop_Sar32,
   7304                                                                  getIReg(rt),
   7305                                                                  mkU8(rd))),
   7306                                           unop(Iop_32to16, binop(Iop_Sar32,
   7307                                                                  getIReg(rs),
   7308                                                                  mkU8(rd)))));
   7309                      }
   7310                      break;
   7311                   }
   7312                   case 0x1F: {  /* PRECR_SRA_R.PH.W */
   7313                      DIP("precr_sra_r.ph.w r%d, r%d, %d", rt, rs, rd);
   7314                      vassert(!mode64);
   7315 
   7316                      t0 = newTemp(Ity_I32);
   7317                      t1 = newTemp(Ity_I32);
   7318 
   7319                      if (0 == rd) {
   7320                         putIReg(rt, binop(Iop_16HLto32,
   7321                                           unop(Iop_32to16, getIReg(rt)),
   7322                                           unop(Iop_32to16, getIReg(rs))));
   7323                      } else {
   7324                         assign(t0, binop(Iop_Shr32,
   7325                                          binop(Iop_Add32,
   7326                                                binop(Iop_Sar32,
   7327                                                      getIReg(rt),
   7328                                                      mkU8(rd-1)),
   7329                                                mkU32(0x1)),
   7330                                          mkU8(0x1)));
   7331                         assign(t1, binop(Iop_Shr32,
   7332                                          binop(Iop_Add32,
   7333                                                binop(Iop_Sar32,
   7334                                                      getIReg(rs),
   7335                                                      mkU8(rd-1)),
   7336                                                mkU32(0x1)),
   7337                                          mkU8(0x1)));
   7338                         putIReg(rt, binop(Iop_16HLto32,
   7339                                           unop(Iop_32to16, mkexpr(t0)),
   7340                                           unop(Iop_32to16, mkexpr(t1))));
   7341                      };
   7342                      break;
   7343                   }
   7344                   case 0xE: {  /* PACKRL.PH */
   7345                      DIP("packrl.ph r%d, r%d, r%d", rd, rs, rt);
   7346                      vassert(!mode64);
   7347 
   7348                      putIReg(rd, binop(Iop_16HLto32,
   7349                                        unop(Iop_32to16, getIReg(rs)),
   7350                                        unop(Iop_32HIto16, getIReg(rt))));
   7351                      break;
   7352                   }
   7353                   case 0x18: {  /* CMPGDU.EQ.QB */
   7354                      DIP("cmpgdu.eq.qb r%d, r%d, r%d", rd, rs, rt);
   7355                      vassert(!mode64);
   7356                      t1 = newTemp(Ity_I1);
   7357                      t2 = newTemp(Ity_I1);
   7358                      t3 = newTemp(Ity_I1);
   7359                      t4 = newTemp(Ity_I1);
   7360                      t5 = newTemp(Ity_I32);
   7361                      t6 = newTemp(Ity_I32);
   7362                      t7 = newTemp(Ity_I32);
   7363                      t8 = newTemp(Ity_I32);
   7364 
   7365                      assign(t1,
   7366                             binop(Iop_CmpEQ32,
   7367                                   unop(Iop_8Uto32,
   7368                                        unop(Iop_16to8,
   7369                                             unop(Iop_32to16, getIReg(rs)))),
   7370                                   unop(Iop_8Uto32,
   7371                                        unop(Iop_16to8,
   7372                                             unop(Iop_32to16, getIReg(rt))))));
   7373                      assign(t5, IRExpr_ITE(mkexpr(t1),
   7374                                            mkU32(0x00000001), mkU32(0)));
   7375                      putDSPControl(IRExpr_ITE(mkexpr(t1),
   7376                                               binop(Iop_Or32,
   7377                                                     getDSPControl(),
   7378                                                     mkU32(0x01000000)),
   7379                                               binop(Iop_And32,
   7380                                                     getDSPControl(),
   7381                                                     mkU32(0xfeffffff))));
   7382 
   7383                      assign(t2, binop(Iop_CmpEQ32,
   7384                                       unop(Iop_8Uto32,
   7385                                            unop(Iop_16HIto8,
   7386                                                 unop(Iop_32to16, getIReg(rs)))),
   7387                                       unop(Iop_8Uto32,
   7388                                            unop(Iop_16HIto8,
   7389                                                 unop(Iop_32to16,
   7390                                                      getIReg(rt))))));
   7391                      assign(t6, IRExpr_ITE(mkexpr(t2),
   7392                                            mkU32(0x00000002), mkU32(0)));
   7393                      putDSPControl(IRExpr_ITE(mkexpr(t2),
   7394                                               binop(Iop_Or32,
   7395                                                     getDSPControl(),
   7396                                                     mkU32(0x02000000)),
   7397                                               binop(Iop_And32,
   7398                                                     getDSPControl(),
   7399                                                     mkU32(0xfdffffff))));
   7400 
   7401                      assign(t3, binop(Iop_CmpEQ32,
   7402                                       unop(Iop_8Uto32,
   7403                                            unop(Iop_16to8,
   7404                                                 unop(Iop_32HIto16,
   7405                                                      getIReg(rs)))),
   7406                                       unop(Iop_8Uto32,
   7407                                            unop(Iop_16to8,
   7408                                                 unop(Iop_32HIto16,
   7409                                                      getIReg(rt))))));
   7410                      assign(t7, IRExpr_ITE(mkexpr(t3),
   7411                                            mkU32(0x00000004), mkU32(0)));
   7412                      putDSPControl(IRExpr_ITE(mkexpr(t3),
   7413                                               binop(Iop_Or32,
   7414                                                     getDSPControl(),
   7415                                                     mkU32(0x04000000)),
   7416                                               binop(Iop_And32,
   7417                                                     getDSPControl(),
   7418                                                     mkU32(0xfbffffff))));
   7419 
   7420                      assign(t4, binop(Iop_CmpEQ32,
   7421                                       unop(Iop_8Uto32,
   7422                                            unop(Iop_16HIto8,
   7423                                                 unop(Iop_32HIto16,
   7424                                                      getIReg(rs)))),
   7425                                       unop(Iop_8Uto32,
   7426                                            unop(Iop_16HIto8,
   7427                                                 unop(Iop_32HIto16,
   7428                                                      getIReg(rt))))));
   7429                      assign(t8, IRExpr_ITE(mkexpr(t4),
   7430                                            mkU32(0x00000008), mkU32(0)));
   7431                      putDSPControl(IRExpr_ITE(mkexpr(t4),
   7432                                               binop(Iop_Or32,
   7433                                                     getDSPControl(),
   7434                                                     mkU32(0x08000000)),
   7435                                               binop(Iop_And32,
   7436                                                     getDSPControl(),
   7437                                                     mkU32(0xf7ffffff))));
   7438 
   7439                      putIReg(rd, binop(Iop_Or32,
   7440                                        binop(Iop_Or32,
   7441                                              binop(Iop_Or32,
   7442                                                    mkexpr(t5), mkexpr(t6)),
   7443                                              mkexpr(t7)),
   7444                                        mkexpr(t8)));
   7445                      break;
   7446                   }
   7447                   case 0x19: {  /* CMPGDU.LT.QB */
   7448                      DIP("cmpgdu.lt.qb r%d, r%d, r%d", rd, rs, rt);
   7449                      vassert(!mode64);
   7450                      t1 = newTemp(Ity_I1);
   7451                      t2 = newTemp(Ity_I1);
   7452                      t3 = newTemp(Ity_I1);
   7453                      t4 = newTemp(Ity_I1);
   7454                      t5 = newTemp(Ity_I32);
   7455                      t6 = newTemp(Ity_I32);
   7456                      t7 = newTemp(Ity_I32);
   7457                      t8 = newTemp(Ity_I32);
   7458 
   7459                      assign(t1, binop(Iop_CmpLT32U,
   7460                                       unop(Iop_8Uto32,
   7461                                            unop(Iop_16to8,
   7462                                                 unop(Iop_32to16, getIReg(rs)))),
   7463                                       unop(Iop_8Uto32,
   7464                                            unop(Iop_16to8,
   7465                                                 unop(Iop_32to16,
   7466                                                      getIReg(rt))))));
   7467                      assign(t5, IRExpr_ITE(mkexpr(t1),
   7468                                            mkU32(0x00000001), mkU32(0)));
   7469                      putDSPControl(IRExpr_ITE(mkexpr(t1),
   7470                                               binop(Iop_Or32,
   7471                                                     getDSPControl(),
   7472                                                     mkU32(0x01000000)),
   7473                                               binop(Iop_And32,
   7474                                                     getDSPControl(),
   7475                                                     mkU32(0xfeffffff))));
   7476 
   7477                      assign(t2, binop(Iop_CmpLT32U,
   7478                                       unop(Iop_8Uto32,
   7479                                            unop(Iop_16HIto8,
   7480                                                 unop(Iop_32to16, getIReg(rs)))),
   7481                                       unop(Iop_8Uto32,
   7482                                            unop(Iop_16HIto8,
   7483                                                 unop(Iop_32to16,
   7484                                                      getIReg(rt))))));
   7485                      assign(t6, IRExpr_ITE(mkexpr(t2),
   7486                                            mkU32(0x00000002), mkU32(0)));
   7487                      putDSPControl(IRExpr_ITE(mkexpr(t2),
   7488                                               binop(Iop_Or32,
   7489                                                     getDSPControl(),
   7490                                                     mkU32(0x02000000)),
   7491                                               binop(Iop_And32,
   7492                                                     getDSPControl(),
   7493                                                     mkU32(0xfdffffff))));
   7494 
   7495                      assign(t3, binop(Iop_CmpLT32U,
   7496                                       unop(Iop_8Uto32,
   7497                                            unop(Iop_16to8,
   7498                                                 unop(Iop_32HIto16,
   7499                                                      getIReg(rs)))),
   7500                                       unop(Iop_8Uto32,
   7501                                            unop(Iop_16to8,
   7502                                                 unop(Iop_32HIto16,
   7503                                                      getIReg(rt))))));
   7504                      assign(t7, IRExpr_ITE(mkexpr(t3),
   7505                                            mkU32(0x00000004), mkU32(0)));
   7506                      putDSPControl(IRExpr_ITE(mkexpr(t3),
   7507                                               binop(Iop_Or32,
   7508                                                     getDSPControl(),
   7509                                                     mkU32(0x04000000)),
   7510                                               binop(Iop_And32,
   7511                                                     getDSPControl(),
   7512                                                     mkU32(0xfbffffff))));
   7513 
   7514                      assign(t4, binop(Iop_CmpLT32U,
   7515                                       unop(Iop_8Uto32,
   7516                                            unop(Iop_16HIto8,
   7517                                                 unop(Iop_32HIto16,
   7518                                                      getIReg(rs)))),
   7519                                       unop(Iop_8Uto32,
   7520                                            unop(Iop_16HIto8,
   7521                                                 unop(Iop_32HIto16,
   7522                                                      getIReg(rt))))));
   7523                      assign(t8, IRExpr_ITE(mkexpr(t4),
   7524                                            mkU32(0x00000008), mkU32(0)));
   7525                      putDSPControl(IRExpr_ITE(mkexpr(t4),
   7526                                               binop(Iop_Or32,
   7527                                                     getDSPControl(),
   7528                                                     mkU32(0x08000000)),
   7529                                               binop(Iop_And32,
   7530                                                     getDSPControl(),
   7531                                                     mkU32(0xf7ffffff))));
   7532 
   7533                      putIReg(rd, binop(Iop_Or32,
   7534                                        binop(Iop_Or32,
   7535                                              binop(Iop_Or32,
   7536                                                    mkexpr(t5), mkexpr(t6)),
   7537                                              mkexpr(t7)),
   7538                                        mkexpr(t8)));
   7539                      break;
   7540                   }
   7541                   case 0x1A: {  /* CMPGDU.LE.QB */
   7542                      DIP("cmpgdu.le.qb r%d, r%d, r%d", rd, rs, rt);
   7543                      vassert(!mode64);
   7544                      t1 = newTemp(Ity_I1);
   7545                      t2 = newTemp(Ity_I1);
   7546                      t3 = newTemp(Ity_I1);
   7547                      t4 = newTemp(Ity_I1);
   7548                      t5 = newTemp(Ity_I32);
   7549                      t6 = newTemp(Ity_I32);
   7550                      t7 = newTemp(Ity_I32);
   7551                      t8 = newTemp(Ity_I32);
   7552 
   7553                      assign(t1, binop(Iop_CmpLE32U,
   7554                                       unop(Iop_8Uto32,
   7555                                            unop(Iop_16to8,
   7556                                                 unop(Iop_32to16, getIReg(rs)))),
   7557                                       unop(Iop_8Uto32,
   7558                                            unop(Iop_16to8,
   7559                                                 unop(Iop_32to16,
   7560                                                      getIReg(rt))))));
   7561                      assign(t5, IRExpr_ITE(mkexpr(t1),
   7562                                            mkU32(0x00000001),
   7563                                            mkU32(0)));
   7564                      putDSPControl(IRExpr_ITE(mkexpr(t1),
   7565                                               binop(Iop_Or32,
   7566                                                     getDSPControl(),
   7567                                                     mkU32(0x01000000)),
   7568                                               binop(Iop_And32,
   7569                                                     getDSPControl(),
   7570                                                     mkU32(0xfeffffff))));
   7571 
   7572                      assign(t2, binop(Iop_CmpLE32U,
   7573                                       unop(Iop_8Uto32,
   7574                                            unop(Iop_16HIto8,
   7575                                                 unop(Iop_32to16, getIReg(rs)))),
   7576                                       unop(Iop_8Uto32,
   7577                                            unop(Iop_16HIto8,
   7578                                                 unop(Iop_32to16,
   7579                                                      getIReg(rt))))));
   7580                      assign(t6, IRExpr_ITE(mkexpr(t2),
   7581                                            mkU32(0x00000002), mkU32(0)));
   7582                      putDSPControl(IRExpr_ITE(mkexpr(t2),
   7583                                               binop(Iop_Or32,
   7584                                                     getDSPControl(),
   7585                                                     mkU32(0x02000000)),
   7586                                               binop(Iop_And32,
   7587                                                     getDSPControl(),
   7588                                                     mkU32(0xfdffffff))));
   7589 
   7590                      assign(t3, binop(Iop_CmpLE32U,
   7591                                       unop(Iop_8Uto32,
   7592                                            unop(Iop_16to8,
   7593                                                 unop(Iop_32HIto16,
   7594                                                      getIReg(rs)))),
   7595                                       unop(Iop_8Uto32,
   7596                                            unop(Iop_16to8,
   7597                                                 unop(Iop_32HIto16,
   7598                                                      getIReg(rt))))));
   7599                      assign(t7, IRExpr_ITE(mkexpr(t3),
   7600                                            mkU32(0x00000004), mkU32(0)));
   7601                      putDSPControl(IRExpr_ITE(mkexpr(t3),
   7602                                               binop(Iop_Or32,
   7603                                                     getDSPControl(),
   7604                                                     mkU32(0x04000000)),
   7605                                               binop(Iop_And32,
   7606                                                     getDSPControl(),
   7607                                                     mkU32(0xfbffffff))));
   7608 
   7609                      assign(t4, binop(Iop_CmpLE32U,
   7610                                       unop(Iop_8Uto32,
   7611                                            unop(Iop_16HIto8,
   7612                                                 unop(Iop_32HIto16,
   7613                                                      getIReg(rs)))),
   7614                                       unop(Iop_8Uto32,
   7615                                            unop(Iop_16HIto8,
   7616                                                 unop(Iop_32HIto16,
   7617                                                      getIReg(rt))))));
   7618                      assign(t8, IRExpr_ITE(mkexpr(t4),
   7619                                            mkU32(0x00000008), mkU32(0)));
   7620                      putDSPControl(IRExpr_ITE(mkexpr(t4),
   7621                                               binop(Iop_Or32,
   7622                                                     getDSPControl(),
   7623                                                     mkU32(0x08000000)),
   7624                                               binop(Iop_And32,
   7625                                                     getDSPControl(),
   7626                                                     mkU32(0xf7ffffff))));
   7627 
   7628                      putIReg(rd, binop(Iop_Or32,
   7629                                        binop(Iop_Or32,
   7630                                              binop(Iop_Or32,
   7631                                                    mkexpr(t5), mkexpr(t6)),
   7632                                              mkexpr(t7)),
   7633                                        mkexpr(t8)));
   7634                      break;
   7635                   }
   7636                   default:
   7637                      return -1;
   7638                }
   7639                break;  /* end of CMPU.EQ.QB */
   7640             }
   7641             case 0x13: {  /* SHLL.QB */
   7642                switch(sa) {
   7643                   case 0x0: {  /* SHLL.QB */
   7644                      DIP("shll.qb r%d, r%d, %d", rd, rt, rs);
   7645                      vassert(!mode64);
   7646                      t0 = newTemp(Ity_I32);
   7647                      t1 = newTemp(Ity_I1);
   7648                      t2 = newTemp(Ity_I1);
   7649                      t3 = newTemp(Ity_I32);
   7650                      t4 = newTemp(Ity_I1);
   7651                      t5 = newTemp(Ity_I1);
   7652                      t6 = newTemp(Ity_I32);
   7653                      t7 = newTemp(Ity_I1);
   7654                      t8 = newTemp(Ity_I1);
   7655                      t9 = newTemp(Ity_I1);
   7656                      t10 = newTemp(Ity_I1);
   7657 
   7658                      if (0 == rs) {
   7659                         putIReg(rd, getIReg(rt));
   7660                      } else {
   7661                         /* Shift bits 7..0 and 23..16. */
   7662                         assign(t0, binop(Iop_Shl32,
   7663                                          binop(Iop_And32,
   7664                                                getIReg(rt),
   7665                                                mkU32(0x00ff00ff)),
   7666                                          mkU8(rs)));
   7667                         assign(t1, binop(Iop_CmpNE32,
   7668                                         binop(Iop_And32,
   7669                                               mkexpr(t0),
   7670                                               mkU32(0xff000000)),
   7671                                         mkU32(0x00000000)));
   7672                         assign(t2, binop(Iop_CmpNE32,
   7673                                         binop(Iop_And32,
   7674                                               mkexpr(t0),
   7675                                               mkU32(0xff000000)),
   7676                                         mkU32(0xff000000)));
   7677                         assign(t7, binop(Iop_CmpNE32,
   7678                                         binop(Iop_And32,
   7679                                               mkexpr(t0),
   7680                                               mkU32(0x0000ff00)),
   7681                                         mkU32(0x00000000)));
   7682                         assign(t8, binop(Iop_CmpNE32,
   7683                                         binop(Iop_And32,
   7684                                               mkexpr(t0),
   7685                                               mkU32(0x0000ff00)),
   7686                                         mkU32(0x000ff00)));
   7687                         /* Shift bits 15..8 and 31..24. */
   7688                         assign(t3, binop(Iop_Shl32,
   7689                                          binop(Iop_Shr32,
   7690                                                binop(Iop_And32,
   7691                                                      getIReg(rt),
   7692                                                      mkU32(0xff00ff00)),
   7693                                                mkU8(8)),
   7694                                          mkU8(rs)));
   7695                         assign(t4, binop(Iop_CmpNE32,
   7696                                         binop(Iop_And32,
   7697                                               mkexpr(t3),
   7698                                               mkU32(0xff000000)),
   7699                                         mkU32(0x00000000)));
   7700                         assign(t5, binop(Iop_CmpNE32,
   7701                                         binop(Iop_And32,
   7702                                               mkexpr(t3),
   7703                                               mkU32(0xff000000)),
   7704                                         mkU32(0xff000000)));
   7705                         assign(t9, binop(Iop_CmpNE32,
   7706                                         binop(Iop_And32,
   7707                                               mkexpr(t3),
   7708                                               mkU32(0x0000ff00)),
   7709                                         mkU32(0x00000000)));
   7710                         assign(t10, binop(Iop_CmpNE32,
   7711                                         binop(Iop_And32,
   7712                                               mkexpr(t3),
   7713                                               mkU32(0x0000ff00)),
   7714                                         mkU32(0x0000ff00)));
   7715 
   7716                         assign(t6, binop(Iop_Or32,
   7717                                          binop(Iop_Or32,
   7718                                                binop(Iop_And32,
   7719                                                      unop(Iop_1Uto32,
   7720                                                           mkexpr(t1)),
   7721                                                      unop(Iop_1Uto32,
   7722                                                           mkexpr(t2))),
   7723                                                binop(Iop_And32,
   7724                                                      unop(Iop_1Uto32,
   7725                                                           mkexpr(t7)),
   7726                                                      unop(Iop_1Uto32,
   7727                                                           mkexpr(t8)))),
   7728                                          binop(Iop_Or32,
   7729                                                binop(Iop_And32,
   7730                                                      unop(Iop_1Uto32,
   7731                                                           mkexpr(t4)),
   7732                                                      unop(Iop_1Uto32,
   7733                                                           mkexpr(t5))),
   7734                                                binop(Iop_And32,
   7735                                                      unop(Iop_1Uto32,
   7736                                                           mkexpr(t9)),
   7737                                                      unop(Iop_1Uto32,
   7738                                                           mkexpr(t10))))));
   7739 
   7740                         putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32,
   7741                                                        mkexpr(t6),
   7742                                                        mkU32(0x0)),
   7743                                                  binop(Iop_Or32,
   7744                                                        getDSPControl(),
   7745                                                        mkU32(0x400000)),
   7746                                                  getDSPControl()));
   7747                         putIReg(rd, binop(Iop_Or32,
   7748                                           binop(Iop_Shl32,
   7749                                                 binop(Iop_And32,
   7750                                                       mkexpr(t3),
   7751                                                       mkU32(0x00ff00ff)),
   7752                                                 mkU8(8)),
   7753                                           binop(Iop_And32,
   7754                                                 mkexpr(t0),
   7755                                                 mkU32(0x00ff00ff))));
   7756                      }
   7757                      break;
   7758                   }
   7759                   case 0x3: {  /* SHRL.QB */
   7760                      DIP("shrl.qb r%d, r%d, %d", rd, rt, rs);
   7761                      vassert(!mode64);
   7762                      t0 = newTemp(Ity_I32);
   7763                      t1 = newTemp(Ity_I8);
   7764                      t2 = newTemp(Ity_I32);
   7765                      t3 = newTemp(Ity_I8);
   7766                      t4 = newTemp(Ity_I32);
   7767                      t5 = newTemp(Ity_I8);
   7768                      t6 = newTemp(Ity_I32);
   7769                      t7 = newTemp(Ity_I8);
   7770                      t9 = newTemp(Ity_I32);
   7771 
   7772                      assign(t9, binop(Iop_And32, getIReg(rs), mkU32(0x7)));
   7773                      assign(t0, unop(Iop_8Uto32,
   7774                                      unop(Iop_16to8,
   7775                                           unop(Iop_32to16, getIReg(rt)))));
   7776                      assign(t1, unop(Iop_32to8,
   7777                                      binop(Iop_Shr32,
   7778                                            mkexpr(t0),
   7779                                            unop(Iop_32to8, mkexpr(t9)))));
   7780 
   7781                      assign(t2, unop(Iop_8Uto32,
   7782                                      unop(Iop_16HIto8,
   7783                                           unop(Iop_32to16, getIReg(rt)))));
   7784                      assign(t3, unop(Iop_32to8,
   7785                                      binop(Iop_Shr32,
   7786                                            mkexpr(t2),
   7787                                            unop(Iop_32to8, mkexpr(t9)))));
   7788 
   7789                      assign(t4, unop(Iop_8Uto32,
   7790                                      unop(Iop_16to8,
   7791                                           unop(Iop_32HIto16, getIReg(rt)))));
   7792                      assign(t5, unop(Iop_32to8,
   7793                                      binop(Iop_Shr32,
   7794                                            mkexpr(t4),
   7795                                            unop(Iop_32to8, mkexpr(t9)))));
   7796 
   7797                      assign(t6, unop(Iop_8Uto32,
   7798                                      unop(Iop_16HIto8,
   7799                                           unop(Iop_32HIto16, getIReg(rt)))));
   7800                      assign(t7, unop(Iop_32to8,
   7801                                      binop(Iop_Shr32,
   7802                                            mkexpr(t6),
   7803                                            unop(Iop_32to8, mkexpr(t9)))));
   7804                      putIReg(rd, IRExpr_ITE(binop(Iop_CmpEQ32,
   7805                                                   mkexpr(t9),
   7806                                                   mkU32(0x0)),
   7807                                             getIReg(rt),
   7808                                             binop(Iop_16HLto32,
   7809                                                   binop(Iop_8HLto16,
   7810                                                         mkexpr(t7),
   7811                                                         mkexpr(t5)),
   7812                                                   binop(Iop_8HLto16,
   7813                                                         mkexpr(t3),
   7814                                                         mkexpr(t1)))));
   7815                      break;
   7816                   }
   7817                   case 0x2: {  /* SHLLV.QB */
   7818                      DIP("shllv.qb r%d, r%d, r%d", rd, rt, rs);
   7819                      vassert(!mode64);
   7820                      t0 = newTemp(Ity_I32);
   7821                      t1 = newTemp(Ity_I1);
   7822                      t2 = newTemp(Ity_I1);
   7823                      t3 = newTemp(Ity_I32);
   7824                      t4 = newTemp(Ity_I1);
   7825                      t5 = newTemp(Ity_I1);
   7826                      t6 = newTemp(Ity_I32);
   7827                      t7 = newTemp(Ity_I1);
   7828                      t8 = newTemp(Ity_I1);
   7829                      t9 = newTemp(Ity_I1);
   7830                      t10 = newTemp(Ity_I1);
   7831                      t11 = newTemp(Ity_I8);
   7832 
   7833                      assign(t11, unop(Iop_32to8,
   7834                                       binop(Iop_And32,
   7835                                             getIReg(rs),
   7836                                             mkU32(0x7))));
   7837                      /* Shift bits 7..0 and 23..16. */
   7838                      assign(t0, binop(Iop_Shl32,
   7839                                       binop(Iop_And32,
   7840                                             getIReg(rt),
   7841                                             mkU32(0x00ff00ff)),
   7842                                       mkexpr(t11)));
   7843                      assign(t1, binop(Iop_CmpNE32,
   7844                                      binop(Iop_And32,
   7845                                            mkexpr(t0),
   7846                                            mkU32(0xff000000)),
   7847                                      mkU32(0x00000000)));
   7848                      assign(t2, binop(Iop_CmpNE32,
   7849                                      binop(Iop_And32,
   7850                                            mkexpr(t0),
   7851                                            mkU32(0xff000000)),
   7852                                      mkU32(0xff000000)));
   7853                      assign(t7, binop(Iop_CmpNE32,
   7854                                      binop(Iop_And32,
   7855                                            mkexpr(t0),
   7856                                            mkU32(0x0000ff00)),
   7857                                      mkU32(0x00000000)));
   7858                      assign(t8, binop(Iop_CmpNE32,
   7859                                      binop(Iop_And32,
   7860                                            mkexpr(t0),
   7861                                            mkU32(0x0000ff00)),
   7862                                      mkU32(0x000ff00)));
   7863                      /* Shift bits 15..8 and 31..24. */
   7864                      assign(t3, binop(Iop_Shl32,
   7865                                       binop(Iop_Shr32,
   7866                                             binop(Iop_And32,
   7867                                                   getIReg(rt),
   7868                                                   mkU32(0xff00ff00)),
   7869                                             mkU8(8)),
   7870                                       mkexpr(t11)));
   7871                      assign(t4, binop(Iop_CmpNE32,
   7872                                      binop(Iop_And32,
   7873                                            mkexpr(t3),
   7874                                            mkU32(0xff000000)),
   7875                                      mkU32(0x00000000)));
   7876                      assign(t5, binop(Iop_CmpNE32,
   7877                                      binop(Iop_And32,
   7878                                            mkexpr(t3),
   7879                                            mkU32(0xff000000)),
   7880                                      mkU32(0xff000000)));
   7881                      assign(t9, binop(Iop_CmpNE32,
   7882                                      binop(Iop_And32,
   7883                                            mkexpr(t3),
   7884                                            mkU32(0x0000ff00)),
   7885                                      mkU32(0x00000000)));
   7886                      assign(t10, binop(Iop_CmpNE32,
   7887                                      binop(Iop_And32,
   7888                                            mkexpr(t3),
   7889                                            mkU32(0x0000ff00)),
   7890                                      mkU32(0x0000ff00)));
   7891 
   7892                      assign(t6, binop(Iop_Or32,
   7893                                       binop(Iop_Or32,
   7894                                             binop(Iop_And32,
   7895                                                   unop(Iop_1Uto32,
   7896                                                        mkexpr(t1)),
   7897                                                   unop(Iop_1Uto32,
   7898                                                        mkexpr(t2))),
   7899                                             binop(Iop_And32,
   7900                                                   unop(Iop_1Uto32,
   7901                                                        mkexpr(t7)),
   7902                                                   unop(Iop_1Uto32,
   7903                                                        mkexpr(t8)))),
   7904                                       binop(Iop_Or32,
   7905                                             binop(Iop_And32,
   7906                                                   unop(Iop_1Uto32,
   7907                                                        mkexpr(t4)),
   7908                                                   unop(Iop_1Uto32,
   7909                                                        mkexpr(t5))),
   7910                                             binop(Iop_And32,
   7911                                                   unop(Iop_1Uto32,
   7912                                                        mkexpr(t9)),
   7913                                                   unop(Iop_1Uto32,
   7914                                                        mkexpr(t10))))));
   7915 
   7916                      putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32,
   7917                                                     mkexpr(t6),
   7918                                                     mkU32(0x0)),
   7919                                               binop(Iop_Or32,
   7920                                                     getDSPControl(),
   7921                                                     mkU32(0x400000)),
   7922                                               getDSPControl()));
   7923                      putIReg(rd, IRExpr_ITE(binop(Iop_CmpEQ32,
   7924                                                   unop(Iop_8Uto32, mkexpr(t11)),
   7925                                                   mkU32(0)),
   7926                                             getIReg(rt),
   7927                                             binop(Iop_Or32,
   7928                                                   binop(Iop_Shl32,
   7929                                                         binop(Iop_And32,
   7930                                                               mkexpr(t3),
   7931                                                               mkU32(0xff00ff)),
   7932                                                         mkU8(8)),
   7933                                                   binop(Iop_And32,
   7934                                                         mkexpr(t0),
   7935                                                         mkU32(0x00ff00ff)))));
   7936                      break;
   7937                   }
   7938                   case 0x1: {  /* SHRLV.QB */
   7939                      DIP("shrlv.qb r%d, r%d, r%d", rd, rt, rs);
   7940                      vassert(!mode64);
   7941                      t0 = newTemp(Ity_I8);
   7942                      t1 = newTemp(Ity_I8);
   7943                      t2 = newTemp(Ity_I8);
   7944                      t3 = newTemp(Ity_I8);
   7945 
   7946                      assign(t0, unop(Iop_32to8,
   7947                                      binop(Iop_Shr32,
   7948                                            unop(Iop_8Uto32,
   7949                                                 unop(Iop_32to8, getIReg(rt))),
   7950                                            mkU8(rs))));
   7951                      assign(t1, unop(Iop_32to8,
   7952                                      binop(Iop_Shr32,
   7953                                            unop(Iop_8Uto32,
   7954                                                 unop(Iop_16HIto8,
   7955                                                      unop(Iop_32to16,
   7956                                                           getIReg(rt)))),
   7957                                            mkU8(rs))));
   7958                      assign(t2, unop(Iop_32to8,
   7959                                       binop(Iop_Shr32,
   7960                                             unop(Iop_8Uto32,
   7961                                                  unop(Iop_16to8,
   7962                                                       unop(Iop_32HIto16,
   7963                                                            getIReg(rt)))),
   7964                                             mkU8(rs))));
   7965                      assign(t3, unop(Iop_32to8,
   7966                                      binop(Iop_Shr32,
   7967                                            unop(Iop_8Uto32,
   7968                                                 unop(Iop_16HIto8,
   7969                                                      unop(Iop_32HIto16,
   7970                                                           getIReg(rt)))),
   7971                                            mkU8(rs))));
   7972                      putIReg(rd,
   7973                              binop(Iop_16HLto32,
   7974                                    binop(Iop_8HLto16, mkexpr(t3), mkexpr(t2)),
   7975                                    binop(Iop_8HLto16, mkexpr(t1), mkexpr(t0))));
   7976                      break;
   7977                   }
   7978                   case 0x4: {  /* SHRA.QB */
   7979                      DIP("shra.qb r%d, r%d, %d", rd, rt, rs);
   7980                      vassert(!mode64);
   7981                      t0 = newTemp(Ity_I32);
   7982                      t1 = newTemp(Ity_I32);
   7983                      t2 = newTemp(Ity_I32);
   7984                      t3 = newTemp(Ity_I32);
   7985                      t4 = newTemp(Ity_I32);
   7986                      t5 = newTemp(Ity_I32);
   7987                      t6 = newTemp(Ity_I32);
   7988                      t7 = newTemp(Ity_I32);
   7989                      t8 = newTemp(Ity_I32);
   7990                      t9 = newTemp(Ity_I32);
   7991                      t10 = newTemp(Ity_I32);
   7992                      t11 = newTemp(Ity_I32);
   7993 
   7994                      /* ========== GPR[rt]_31..24 ========== */
   7995                      assign(t1,
   7996                             unop(Iop_8Uto32,
   7997                                  unop(Iop_16HIto8,
   7998                                       unop(Iop_32HIto16, getIReg(rt)))));
   7999                      assign(t2,
   8000                             binop(Iop_Shr32, mkexpr(t1), mkU8(rs)));
   8001                      /* tempD_7..0 */
   8002                      assign(t0,
   8003                             binop(Iop_Or32,
   8004                                   mkexpr(t2),
   8005                                   binop(Iop_Shl32,
   8006                                         IRExpr_ITE(binop(Iop_CmpEQ32,
   8007                                                          binop(Iop_And32,
   8008                                                                mkexpr(t1),
   8009                                                                mkU32(0x00000080)
   8010                                                               ),
   8011                                                          mkU32(0x00000080)),
   8012                                                    mkU32(0xFFFFFFFF),
   8013                                                    mkU32(0x00000000)),
   8014                                         binop(Iop_Sub8, mkU8(0x8), mkU8(rs)))));
   8015 
   8016                      /* ========== GPR[rt]_23..16 ========== */
   8017                      assign(t4,
   8018                             unop(Iop_8Uto32,
   8019                                  unop(Iop_16to8,
   8020                                       unop(Iop_32HIto16, getIReg(rt)))));
   8021                      assign(t5, binop(Iop_Shr32, mkexpr(t4), mkU8(rs)));
   8022                      /* tempC_7..0 */
   8023                      assign(t3,
   8024                             binop(Iop_Or32,
   8025                                   mkexpr(t5),
   8026                                   binop(Iop_Shl32,
   8027                                         IRExpr_ITE(binop(Iop_CmpEQ32,
   8028                                                          binop(Iop_And32,
   8029                                                                mkexpr(t4),
   8030                                                                mkU32(0x00000080)
   8031                                                               ),
   8032                                                          mkU32(0x00000080)),
   8033                                                    mkU32(0xFFFFFFFF),
   8034                                                    mkU32(0x00000000)),
   8035                                         binop(Iop_Sub8, mkU8(0x8), mkU8(rs)))));
   8036 
   8037                      /* ========== GPR[rt]_15..8 ========== */
   8038                      assign(t7,
   8039                             unop(Iop_8Uto32,
   8040                                  unop(Iop_16HIto8,
   8041                                       unop(Iop_32to16, getIReg(rt)))));
   8042                      assign(t8, binop(Iop_Shr32, mkexpr(t7), mkU8(rs)));
   8043                      /* tempB_7..0 */
   8044                      assign(t6,
   8045                             binop(Iop_Or32,
   8046                                   mkexpr(t8),
   8047                                   binop(Iop_Shl32,
   8048                                         IRExpr_ITE(binop(Iop_CmpEQ32,
   8049                                                          binop(Iop_And32,
   8050                                                                mkexpr(t7),
   8051                                                                mkU32(0x00000080)
   8052                                                               ),
   8053                                                          mkU32(0x00000080)),
   8054                                                    mkU32(0xFFFFFFFF),
   8055                                                    mkU32(0x00000000)),
   8056                                         binop(Iop_Sub8, mkU8(0x8), mkU8(rs)))));
   8057 
   8058                      /* ========== GPR[rt]_7..0 ========== */
   8059                      assign(t10,
   8060                             unop(Iop_8Uto32,
   8061                                  unop(Iop_16to8,
   8062                                       unop(Iop_32to16, getIReg(rt)))));
   8063                      assign(t11, binop(Iop_Shr32, mkexpr(t10), mkU8(rs)));
   8064                      /* tempB_7..0 */
   8065                      assign(t9,
   8066                             binop(Iop_Or32,
   8067                                   mkexpr(t11),
   8068                                   binop(Iop_Shl32,
   8069                                         IRExpr_ITE(binop(Iop_CmpEQ32,
   8070                                                          binop(Iop_And32,
   8071                                                                mkexpr(t10),
   8072                                                                mkU32(0x00000080)
   8073                                                               ),
   8074                                                          mkU32(0x00000080)),
   8075                                                    mkU32(0xFFFFFFFF),
   8076                                                    mkU32(0x00000000)),
   8077                                         binop(Iop_Sub8, mkU8(0x8), mkU8(rs)))));
   8078 
   8079                      putIReg(rd,
   8080                              binop(Iop_16HLto32,
   8081                                    binop(Iop_8HLto16,
   8082                                          unop(Iop_32to8, mkexpr(t0)),
   8083                                          unop(Iop_32to8, mkexpr(t3))),
   8084                                    binop(Iop_8HLto16,
   8085                                          unop(Iop_32to8, mkexpr(t6)),
   8086                                          unop(Iop_32to8, mkexpr(t9)))));
   8087                      break;
   8088                   }
   8089                   case 0x5: {  /* SHRA_R.QB */
   8090                      DIP("shra_r.qb r%d, r%d, %d", rd, rt, rs);
   8091                      vassert(!mode64);
   8092                      t0 = newTemp(Ity_I32);
   8093                      t1 = newTemp(Ity_I8);
   8094                      t2 = newTemp(Ity_I32);
   8095                      t3 = newTemp(Ity_I8);
   8096                      t4 = newTemp(Ity_I32);
   8097                      t5 = newTemp(Ity_I8);
   8098                      t6 = newTemp(Ity_I32);
   8099                      t7 = newTemp(Ity_I8);
   8100 
   8101                      if (0 == rs) {
   8102                         putIReg(rd, getIReg(rt));
   8103                      } else {
   8104                         assign(t0, unop(Iop_8Sto32,
   8105                                         unop(Iop_16to8,
   8106                                              unop(Iop_32to16, getIReg(rt)))));
   8107                         assign(t1, unop(Iop_32to8,
   8108                                         binop(Iop_Sar32,
   8109                                               binop(Iop_Add32,
   8110                                                     mkexpr(t0),
   8111                                                     binop(Iop_Shl32,
   8112                                                           mkU32(0x1),
   8113                                                           mkU8(rs-1))),
   8114                                               mkU8(rs))));
   8115 
   8116                         assign(t2, unop(Iop_8Sto32,
   8117                                         unop(Iop_16HIto8,
   8118                                              unop(Iop_32to16, getIReg(rt)))));
   8119                         assign(t3, unop(Iop_32to8,
   8120                                         binop(Iop_Sar32,
   8121                                               binop(Iop_Add32,
   8122                                                     mkexpr(t2),
   8123                                                     binop(Iop_Shl32,
   8124                                                           mkU32(0x1),
   8125                                                           mkU8(rs-1))),
   8126                                               mkU8(rs))));
   8127 
   8128                         assign(t4, unop(Iop_8Sto32,
   8129                                         unop(Iop_16to8,
   8130                                              unop(Iop_32HIto16, getIReg(rt)))));
   8131                         assign(t5, unop(Iop_32to8,
   8132                                         binop(Iop_Sar32,
   8133                                               binop(Iop_Add32,
   8134                                                     mkexpr(t4),
   8135                                                     binop(Iop_Shl32,
   8136                                                           mkU32(0x1),
   8137                                                           mkU8(rs-1))),
   8138                                               mkU8(rs))));
   8139 
   8140                         assign(t6, unop(Iop_8Sto32,
   8141                                         unop(Iop_16HIto8,
   8142                                              unop(Iop_32HIto16, getIReg(rt)))));
   8143                         assign(t7, unop(Iop_32to8,
   8144                                         binop(Iop_Sar32,
   8145                                               binop(Iop_Add32,
   8146                                                     mkexpr(t6),
   8147                                                     binop(Iop_Shl32,
   8148                                                           mkU32(0x1),
   8149                                                           mkU8(rs-1))),
   8150                                               mkU8(rs))));
   8151                         putIReg(rd, binop(Iop_16HLto32,
   8152                                          binop(Iop_8HLto16,
   8153                                                mkexpr(t7), mkexpr(t5)),
   8154                                          binop(Iop_8HLto16,
   8155                                                mkexpr(t3), mkexpr(t1))));
   8156                      }
   8157                      break;
   8158                   }
   8159                   case 0x6: {  /* SHRAV.QB */
   8160                      DIP("shrav.qb r%d, r%d, %d", rd, rt, rs);
   8161                      vassert(!mode64);
   8162 
   8163                      t0 = newTemp(Ity_I32);
   8164                      t1 = newTemp(Ity_I32);
   8165                      t2 = newTemp(Ity_I32);
   8166 
   8167                      t3 = newTemp(Ity_I32);
   8168                      t4 = newTemp(Ity_I32);
   8169                      t5 = newTemp(Ity_I32);
   8170 
   8171                      t6 = newTemp(Ity_I32);
   8172                      t7 = newTemp(Ity_I32);
   8173                      t8 = newTemp(Ity_I32);
   8174 
   8175                      t9 = newTemp(Ity_I32);
   8176                      t10 = newTemp(Ity_I32);
   8177                      t11 = newTemp(Ity_I32);
   8178 
   8179                      /* ========== GPR[rt]_31..24 ========== */
   8180                      assign(t1,
   8181                             unop(Iop_8Uto32,
   8182                                  unop(Iop_16HIto8,
   8183                                       unop(Iop_32HIto16, getIReg(rt)))));
   8184                      assign(t2,
   8185                             binop(Iop_Shr32,
   8186                                   mkexpr(t1),
   8187                                   unop(Iop_32to8, binop(Iop_And32,
   8188                                                         getIReg(rs),
   8189                                                         mkU32(0x7)))));
   8190                      /* tempD_7..0 */
   8191                      assign(t0,
   8192                             binop(Iop_Or32,
   8193                                   mkexpr(t2),
   8194                                   binop(Iop_Shl32,
   8195                                         IRExpr_ITE(binop(Iop_CmpEQ32,
   8196                                                          binop(Iop_And32,
   8197                                                                mkexpr(t1),
   8198                                                                mkU32(0x00000080)
   8199                                                               ),
   8200                                                          mkU32(0x00000080)),
   8201                                                    mkU32(0xFFFFFFFF),
   8202                                                    mkU32(0x00000000)),
   8203                                         binop(Iop_Sub8,
   8204                                               mkU8(0x8),
   8205                                               unop(Iop_32to8, binop(Iop_And32,
   8206                                                                     getIReg(rs),
   8207                                                                     mkU32(0x7)))
   8208                                               ))));
   8209 
   8210                      /* ========== GPR[rt]_23..16 ========== */
   8211                      assign(t4,
   8212                             unop(Iop_8Uto32,
   8213                                  unop(Iop_16to8,
   8214                                       unop(Iop_32HIto16, getIReg(rt)))));
   8215                      assign(t5,
   8216                             binop(Iop_Shr32,
   8217                                   mkexpr(t4),
   8218                                   unop(Iop_32to8, binop(Iop_And32,
   8219                                                         getIReg(rs),
   8220                                                         mkU32(0x7)))));
   8221                      /* tempC_7..0 */
   8222                      assign(t3,
   8223                             binop(Iop_Or32,
   8224                                   mkexpr(t5),
   8225                                   binop(Iop_Shl32,
   8226                                         IRExpr_ITE(binop(Iop_CmpEQ32,
   8227                                                          binop(Iop_And32,
   8228                                                                mkexpr(t4),
   8229                                                                mkU32(0x00000080)
   8230                                                               ),
   8231                                                          mkU32(0x00000080)),
   8232                                                    mkU32(0xFFFFFFFF),
   8233                                                    mkU32(0x00000000)),
   8234                                         binop(Iop_Sub8,
   8235                                               mkU8(0x8),
   8236                                               unop(Iop_32to8, binop(Iop_And32,
   8237                                                                     getIReg(rs),
   8238                                                                     mkU32(0x7)))
   8239                                               ))));
   8240 
   8241                      /* ========== GPR[rt]_15..8 ========== */
   8242                      assign(t7,
   8243                             unop(Iop_8Uto32,
   8244                                  unop(Iop_16HIto8,
   8245                                       unop(Iop_32to16, getIReg(rt)))));
   8246                      assign(t8,
   8247                             binop(Iop_Shr32,
   8248                                   mkexpr(t7),
   8249                                   unop(Iop_32to8, binop(Iop_And32,
   8250                                                         getIReg(rs),
   8251                                                         mkU32(0x7)))));
   8252                      /* tempB_7..0 */
   8253                      assign(t6,
   8254                             binop(Iop_Or32,
   8255                                   mkexpr(t8),
   8256                                   binop(Iop_Shl32,
   8257                                         IRExpr_ITE(binop(Iop_CmpEQ32,
   8258                                                          binop(Iop_And32,
   8259                                                                mkexpr(t7),
   8260                                                                mkU32(0x00000080)
   8261                                                               ),
   8262                                                          mkU32(0x00000080)),
   8263                                                    mkU32(0xFFFFFFFF),
   8264                                                    mkU32(0x00000000)),
   8265                                         binop(Iop_Sub8,
   8266                                               mkU8(0x8),
   8267                                               unop(Iop_32to8, binop(Iop_And32,
   8268                                                                     getIReg(rs),
   8269                                                                     mkU32(0x7)))
   8270                                               ))));
   8271 
   8272                      /* ========== GPR[rt]_7..0 ========== */
   8273                      assign(t10,
   8274                             unop(Iop_8Uto32,
   8275                                  unop(Iop_16to8,
   8276                                       unop(Iop_32to16, getIReg(rt)))));
   8277                      assign(t11,
   8278                             binop(Iop_Shr32,
   8279                                   mkexpr(t10),
   8280                                   unop(Iop_32to8, binop(Iop_And32,
   8281                                                         getIReg(rs),
   8282                                                         mkU32(0x7)))));
   8283                      /* tempB_7..0 */
   8284                      assign(t9,
   8285                             binop(Iop_Or32,
   8286                                   mkexpr(t11),
   8287                                   binop(Iop_Shl32,
   8288                                         IRExpr_ITE(binop(Iop_CmpEQ32,
   8289                                                          binop(Iop_And32,
   8290                                                                mkexpr(t10),
   8291                                                                mkU32(0x00000080)
   8292                                                               ),
   8293                                                          mkU32(0x00000080)),
   8294                                                    mkU32(0xFFFFFFFF),
   8295                                                    mkU32(0x00000000)),
   8296                                         binop(Iop_Sub8,
   8297                                               mkU8(0x8),
   8298                                               unop(Iop_32to8, binop(Iop_And32,
   8299                                                                     getIReg(rs),
   8300                                                                     mkU32(0x7)))
   8301                                               ))));
   8302 
   8303                      putIReg(rd,
   8304                              binop(Iop_16HLto32,
   8305                                    binop(Iop_8HLto16,
   8306                                          unop(Iop_32to8,
   8307                                               IRExpr_ITE(binop(Iop_CmpEQ32,
   8308                                                                binop(Iop_And32,
   8309                                                                      mkU32(rs),
   8310                                                                      mkU32(0x7)
   8311                                                                     ),
   8312                                                                mkU32(0x0)),
   8313                                                          mkexpr(t1),
   8314                                                          mkexpr(t0))),
   8315                                          unop(Iop_32to8,
   8316                                               IRExpr_ITE(binop(Iop_CmpEQ32,
   8317                                                                binop(Iop_And32,
   8318                                                                      mkU32(rs),
   8319                                                                      mkU32(0x7)
   8320                                                                     ),
   8321                                                                mkU32(0x0)),
   8322                                                          mkexpr(t2),
   8323                                                          mkexpr(t3)))),
   8324                                    binop(Iop_8HLto16,
   8325                                          unop(Iop_32to8,
   8326                                               IRExpr_ITE(binop(Iop_CmpEQ32,
   8327                                                                binop(Iop_And32,
   8328                                                                      mkU32(rs),
   8329                                                                      mkU32(0x7)
   8330                                                                     ),
   8331                                                                mkU32(0x0)),
   8332                                                          mkexpr(t5),
   8333                                                          mkexpr(t6))),
   8334                                          unop(Iop_32to8,
   8335                                               IRExpr_ITE(binop(Iop_CmpEQ32,
   8336                                                                binop(Iop_And32,
   8337                                                                      mkU32(rs),
   8338                                                                      mkU32(0x7)
   8339                                                                     ),
   8340                                                                mkU32(0x0)),
   8341                                                          mkexpr(t8),
   8342                                                          mkexpr(t9))))));
   8343                      break;
   8344                   }
   8345                   case 0x7: {  /* SHRAV_R.QB */
   8346                      DIP("shrav_r.qb r%d, r%d, r%d", rd, rt, rs);
   8347                      vassert(!mode64);
   8348                      t0 = newTemp(Ity_I32);
   8349                      t1 = newTemp(Ity_I8);
   8350                      t2 = newTemp(Ity_I32);
   8351                      t3 = newTemp(Ity_I8);
   8352                      t4 = newTemp(Ity_I32);
   8353                      t5 = newTemp(Ity_I8);
   8354                      t6 = newTemp(Ity_I32);
   8355                      t7 = newTemp(Ity_I8);
   8356                      t8 = newTemp(Ity_I8);
   8357                      t9 = newTemp(Ity_I32);
   8358 
   8359                      assign(t9, binop(Iop_And32, getIReg(rs), mkU32(0x7)));
   8360                      assign(t8, unop(Iop_32to8,
   8361                                      binop(Iop_Sub32, mkexpr(t9), mkU32(0x1))));
   8362                      assign(t0, unop(Iop_8Sto32,
   8363                                      unop(Iop_16to8,
   8364                                           unop(Iop_32to16, getIReg(rt)))));
   8365                      assign(t1, unop(Iop_32to8,
   8366                                      binop(Iop_Sar32,
   8367                                            binop(Iop_Add32,
   8368                                                  mkexpr(t0),
   8369                                                  binop(Iop_Shl32,
   8370                                                        mkU32(0x1),
   8371                                                        mkexpr(t8))),
   8372                                            unop(Iop_32to8,
   8373                                                 mkexpr(t9)))));
   8374 
   8375                      assign(t2, unop(Iop_8Sto32,
   8376                                      unop(Iop_16HIto8,
   8377                                           unop(Iop_32to16, getIReg(rt)))));
   8378                      assign(t3, unop(Iop_32to8,
   8379                                      binop(Iop_Sar32,
   8380                                            binop(Iop_Add32,
   8381                                                  mkexpr(t2),
   8382                                                  binop(Iop_Shl32,
   8383                                                        mkU32(0x1),
   8384                                                        mkexpr(t8))),
   8385                                            unop(Iop_32to8, mkexpr(t9)))));
   8386 
   8387                      assign(t4, unop(Iop_8Sto32,
   8388                                      unop(Iop_16to8,
   8389                                           unop(Iop_32HIto16, getIReg(rt)))));
   8390                      assign(t5, unop(Iop_32to8,
   8391                                      binop(Iop_Sar32,
   8392                                            binop(Iop_Add32,
   8393                                                  mkexpr(t4),
   8394                                                  binop(Iop_Shl32,
   8395                                                        mkU32(0x1),
   8396                                                        mkexpr(t8))),
   8397                                            unop(Iop_32to8, mkexpr(t9)))));
   8398 
   8399                      assign(t6, unop(Iop_8Sto32,
   8400                                      unop(Iop_16HIto8,
   8401                                           unop(Iop_32HIto16, getIReg(rt)))));
   8402                      assign(t7, unop(Iop_32to8,
   8403                                      binop(Iop_Sar32,
   8404                                            binop(Iop_Add32,
   8405                                                  mkexpr(t6),
   8406                                                  binop(Iop_Shl32,
   8407                                                        mkU32(0x1),
   8408                                                        mkexpr(t8))),
   8409                                            unop(Iop_32to8, mkexpr(t9)))));
   8410                      putIReg(rd, IRExpr_ITE(binop(Iop_CmpEQ32,
   8411                                                   mkexpr(t9),
   8412                                                   mkU32(0x0)),
   8413                                             getIReg(rt),
   8414                                             binop(Iop_16HLto32,
   8415                                                   binop(Iop_8HLto16,
   8416                                                         mkexpr(t7),
   8417                                                         mkexpr(t5)),
   8418                                                   binop(Iop_8HLto16,
   8419                                                         mkexpr(t3),
   8420                                                         mkexpr(t1)))));
   8421                      break;
   8422                   }
   8423                   case 0x8: {  /* SHLL.PH */
   8424                      DIP("shll.ph r%d, r%d, %d", rd, rt, rs);
   8425                      vassert(!mode64);
   8426                      t0 = newTemp(Ity_I32);
   8427                      t1 = newTemp(Ity_I32);
   8428                      t2 = newTemp(Ity_I32);
   8429                      t3 = newTemp(Ity_I32);
   8430                      t4 = newTemp(Ity_I32);
   8431                      t5 = newTemp(Ity_I32);
   8432                      t6 = newTemp(Ity_I32);
   8433                      t7 = newTemp(Ity_I32);
   8434 
   8435                      if (0 == rs) {
   8436                         putIReg(rd, getIReg(rt));
   8437                      } else {
   8438                         /* Shift lower 16 bits. */
   8439                         assign(t0, binop(Iop_Shl32,
   8440                                          unop(Iop_16Sto32,
   8441                                               unop(Iop_32to16, getIReg(rt))),
   8442                                          mkU8(rs)));
   8443 
   8444                         assign(t1, unop(Iop_1Uto32,
   8445                                         binop(Iop_CmpNE32,
   8446                                                binop(Iop_Sar32,
   8447                                                      mkexpr(t0),
   8448                                                      mkU8(16)),
   8449                                                mkU32(0))));
   8450                         assign(t2, unop(Iop_1Uto32,
   8451                                         binop(Iop_CmpNE32,
   8452                                               binop(Iop_Sar32,
   8453                                                     mkexpr(t0),
   8454                                                     mkU8(16)),
   8455                                               mkU32(0xffffffff))));
   8456                         assign(t3, binop(Iop_And32,
   8457                                          mkexpr(t1),
   8458                                          mkexpr(t2)));
   8459                         putDSPControl(IRExpr_ITE(binop(Iop_CmpEQ32,
   8460                                                        mkexpr(t3),
   8461                                                        mkU32(0x1)),
   8462                                                  binop(Iop_Or32,
   8463                                                        getDSPControl(),
   8464                                                        mkU32(0x400000)),
   8465                                                  getDSPControl()));
   8466                         putDSPControl(IRExpr_ITE(binop(Iop_CmpEQ32,
   8467                                                        binop(Iop_And32,
   8468                                                              getIReg(rt),
   8469                                                              mkU32(0x00008000)),
   8470                                                        binop(Iop_And32,
   8471                                                              mkexpr(t0),
   8472                                                              mkU32(0x00008000))
   8473                                                       ),
   8474                                                  getDSPControl(),
   8475                                                  binop(Iop_Or32,
   8476                                                        getDSPControl(),
   8477                                                        mkU32(0x400000))));
   8478                         /* Shift higher 16 bits. */
   8479                         assign(t4, binop(Iop_Shl32,
   8480                                          unop(Iop_16Sto32,
   8481                                               unop(Iop_32HIto16, getIReg(rt))),
   8482                                          mkU8(rs)));
   8483 
   8484                         assign(t5, unop(Iop_1Uto32,
   8485                                         binop(Iop_CmpNE32,
   8486                                                binop(Iop_Sar32,
   8487                                                      mkexpr(t4),
   8488                                                      mkU8(16)),
   8489                                                mkU32(0))));
   8490                         assign(t6, unop(Iop_1Uto32,
   8491                                         binop(Iop_CmpNE32,
   8492                                               binop(Iop_Sar32,
   8493                                                     mkexpr(t4),
   8494                                                     mkU8(16)),
   8495                                               mkU32(0xffffffff))));
   8496                         assign(t7, binop(Iop_And32,
   8497                                          mkexpr(t5),
   8498                                          mkexpr(t6)));
   8499                         putDSPControl(IRExpr_ITE(binop(Iop_CmpEQ32,
   8500                                                        mkexpr(t7),
   8501                                                        mkU32(0x1)),
   8502                                                  binop(Iop_Or32,
   8503                                                        getDSPControl(),
   8504                                                        mkU32(0x400000)),
   8505                                                  getDSPControl()));
   8506                         putDSPControl(IRExpr_ITE(binop(Iop_CmpEQ32,
   8507                                                        mkexpr(t7),
   8508                                                        mkU32(0x1)),
   8509                                                  binop(Iop_Or32,
   8510                                                        getDSPControl(),
   8511                                                        mkU32(0x400000)),
   8512                                                  getDSPControl()));
   8513                         putDSPControl(IRExpr_ITE(binop(Iop_CmpEQ32,
   8514                                                        binop(Iop_And32,
   8515                                                              getIReg(rt),
   8516                                                              mkU32(0x80000000)),
   8517                                                        binop(Iop_Shl32,
   8518                                                              binop(Iop_And32,
   8519                                                                    mkexpr(t4),
   8520                                                                    mkU32(0x00008000)),
   8521                                                              mkU8(16))
   8522                                                       ),
   8523                                                  getDSPControl(),
   8524                                                  binop(Iop_Or32,
   8525                                                        getDSPControl(),
   8526                                                        mkU32(0x400000))));
   8527                         putIReg(rd, binop(Iop_16HLto32,
   8528                                           unop(Iop_32to16, mkexpr(t4)),
   8529                                           unop(Iop_32to16, mkexpr(t0))));
   8530                      }
   8531                      break;
   8532                   }
   8533                   case 0x9: {  /* SHRA.PH */
   8534                      DIP("shra.ph r%d, r%d, %d", rd, rt, rs);
   8535                      vassert(!mode64);
   8536                      t0 = newTemp(Ity_I32);
   8537                      t1 = newTemp(Ity_I32);
   8538                      if (0 == rs) {
   8539                         putIReg(rd, getIReg(rt));
   8540                      } else {
   8541                         assign(t0, binop(Iop_Sar32,
   8542                                          unop(Iop_16Sto32,
   8543                                               unop(Iop_32to16, getIReg(rt))),
   8544                                          mkU8(rs)));
   8545                         assign(t1, binop(Iop_Sar32,
   8546                                          unop(Iop_16Sto32,
   8547                                               unop(Iop_32HIto16, getIReg(rt))),
   8548                                          mkU8(rs)));
   8549                         putIReg(rd, binop(Iop_16HLto32,
   8550                                           unop(Iop_32to16, mkexpr(t1)),
   8551                                           unop(Iop_32to16, mkexpr(t0))));
   8552                      }
   8553                      break;
   8554                   }
   8555                   case 0xA: {  /* SHLLV.PH */
   8556                      DIP("shllv.ph r%d, r%d, r%d", rd, rt, rs);
   8557                      vassert(!mode64);
   8558                      t0 = newTemp(Ity_I32);
   8559                      t2 = newTemp(Ity_I32);
   8560                      t3 = newTemp(Ity_I1);
   8561                      t4 = newTemp(Ity_I1);
   8562                      t5 = newTemp(Ity_I32);
   8563                      t6 = newTemp(Ity_I32);
   8564                      t7 = newTemp(Ity_I1);
   8565                      t8 = newTemp(Ity_I1);
   8566                      t9 = newTemp(Ity_I32);
   8567                      t10 = newTemp(Ity_I32);
   8568                      t11 = newTemp(Ity_I32);
   8569                      t12 = newTemp(Ity_I1);
   8570                      t13 = newTemp(Ity_I1);
   8571 
   8572                      assign(t0, binop(Iop_And32, getIReg(rs), mkU32(0x0f)));
   8573 
   8574                      /* Shift lower 16 bits. */
   8575                      assign(t2, binop(Iop_Shl32,
   8576                                       unop(Iop_16Sto32,
   8577                                            unop(Iop_32to16, getIReg(rt))),
   8578                                       unop(Iop_32to8, mkexpr(t0))));
   8579 
   8580                      assign(t3, binop(Iop_CmpNE32,
   8581                                       unop(Iop_16Sto32,
   8582                                            unop(Iop_32HIto16, mkexpr(t2))),
   8583                                       mkU32(0x00000000)));
   8584                      assign(t4, binop(Iop_CmpNE32,
   8585                                       unop(Iop_16Sto32,
   8586                                            unop(Iop_32HIto16, mkexpr(t2))),
   8587                                       mkU32(0xffffffff)));
   8588                      assign(t10, binop(Iop_And32,
   8589                                        unop(Iop_1Sto32, mkexpr(t3)),
   8590                                        unop(Iop_1Sto32, mkexpr(t4))));
   8591                      assign(t5, binop(Iop_Shr32,
   8592                                       binop(Iop_And32,
   8593                                             getIReg(rt),
   8594                                             mkU32(0x00008000)),
   8595                                       mkU8(15)));
   8596                      assign(t12, binop(Iop_CmpEQ32,
   8597                                        mkexpr(t5),
   8598                                        binop(Iop_Shr32,
   8599                                              binop(Iop_And32,
   8600                                                    mkexpr(t2),
   8601                                                    mkU32(0x00008000)),
   8602                                              mkU8(15))));
   8603 
   8604                      putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32,
   8605                                                     mkexpr(t10),
   8606                                                     mkU32(0x0)),
   8607                                               binop(Iop_Or32,
   8608                                                     getDSPControl(),
   8609                                                     mkU32(0x400000)),
   8610                                               IRExpr_ITE(mkexpr(t12),
   8611                                                          getDSPControl(),
   8612                                                          binop(Iop_Or32,
   8613                                                                getDSPControl(),
   8614                                                                mkU32(0x400000)))
   8615                                              ));
   8616                      /* Shift higher 16 bits. */
   8617                      assign(t6, binop(Iop_Shl32,
   8618                                       unop(Iop_16Sto32,
   8619                                            unop(Iop_32HIto16, getIReg(rt))),
   8620                                       unop(Iop_32to8, mkexpr(t0))));
   8621 
   8622                      assign(t7, binop(Iop_CmpNE32,
   8623                                       unop(Iop_16Sto32,
   8624                                            unop(Iop_32HIto16, mkexpr(t6))),
   8625                                       mkU32(0x00000000)));
   8626                      assign(t8, binop(Iop_CmpNE32,
   8627                                       unop(Iop_16Sto32,
   8628                                            unop(Iop_32HIto16, mkexpr(t6))),
   8629                                       mkU32(0xffffffff)));
   8630                      assign(t11, binop(Iop_And32,
   8631                                        unop(Iop_1Sto32, mkexpr(t7)),
   8632                                        unop(Iop_1Sto32, mkexpr(t8))));
   8633 
   8634                      assign(t9, binop(Iop_Shr32,
   8635                                       binop(Iop_And32,
   8636                                             getIReg(rt),
   8637                                             mkU32(0x80000000)),
   8638                                       mkU8(31)));
   8639                      assign(t13, binop(Iop_CmpEQ32,
   8640                                        mkexpr(t9),
   8641                                        binop(Iop_Shr32,
   8642                                              binop(Iop_And32,
   8643                                                    mkexpr(t6),
   8644                                                    mkU32(0x00008000)),
   8645                                              mkU8(15))));
   8646 
   8647                      putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32,
   8648                                                     mkexpr(t11),
   8649                                                     mkU32(0x0)),
   8650                                               binop(Iop_Or32,
   8651                                                     getDSPControl(),
   8652                                                     mkU32(0x400000)),
   8653                                               IRExpr_ITE(mkexpr(t13),
   8654                                                          getDSPControl(),
   8655                                                          binop(Iop_Or32,
   8656                                                                getDSPControl(),
   8657                                                                mkU32(0x400000)))
   8658                                              ));
   8659 
   8660                      putIReg(rd, binop(Iop_16HLto32,
   8661                                        unop(Iop_32to16, mkexpr(t6)),
   8662                                        unop(Iop_32to16, mkexpr(t2))));
   8663                      break;
   8664                   }
   8665                   case 0xB: {  /* SHRAV.PH */
   8666                      DIP("shrav.ph r%d, r%d, r%d", rd, rt, rs);
   8667                      vassert(!mode64);
   8668                      t0 = newTemp(Ity_I32);
   8669                      t1 = newTemp(Ity_I1);
   8670                      t2 = newTemp(Ity_I32);
   8671                      t3 = newTemp(Ity_I32);
   8672 
   8673                      assign(t0, binop(Iop_And32, getIReg(rs), mkU32(0x0f)));
   8674                      assign(t1, binop(Iop_CmpEQ32, mkexpr(t0), mkU32(0x0)));
   8675                      assign(t2, binop(Iop_Sar32,
   8676                                       unop(Iop_16Sto32,
   8677                                            unop(Iop_32to16, getIReg(rt))),
   8678                                       unop(Iop_32to8, mkexpr(t0))));
   8679                      assign(t3, binop(Iop_Sar32,
   8680                                       unop(Iop_16Sto32,
   8681                                            unop(Iop_32HIto16, getIReg(rt))),
   8682                                       unop(Iop_32to8, mkexpr(t0))));
   8683                      putIReg(rd,
   8684                              binop(Iop_16HLto32,
   8685                                    IRExpr_ITE(mkexpr(t1),
   8686                                               unop(Iop_32HIto16, getIReg(rt)),
   8687                                               unop(Iop_32to16, mkexpr(t3))),
   8688                                    IRExpr_ITE(mkexpr(t1),
   8689                                               unop(Iop_32to16, getIReg(rt)),
   8690                                               unop(Iop_32to16, mkexpr(t2)))));
   8691                      break;
   8692                   }
   8693                   case 0xC: {  /* SHLL_S.PH */
   8694                      DIP("shll_s.ph r%d, r%d, %d", rd, rt, rs);
   8695                      vassert(!mode64);
   8696                      t0 = newTemp(Ity_I32);
   8697                      t1 = newTemp(Ity_I32);
   8698                      t2 = newTemp(Ity_I32);
   8699                      t3 = newTemp(Ity_I32);
   8700                      t4 = newTemp(Ity_I32);
   8701                      t5 = newTemp(Ity_I32);
   8702                      t6 = newTemp(Ity_I32);
   8703                      t7 = newTemp(Ity_I32);
   8704                      t8 = newTemp(Ity_I32);
   8705                      t9 = newTemp(Ity_I32);
   8706                      t10 = newTemp(Ity_I32);
   8707                      t11 = newTemp(Ity_I32);
   8708                      t12 = newTemp(Ity_I32);
   8709                      t13 = newTemp(Ity_I32);
   8710                      t14 = newTemp(Ity_I32);
   8711 
   8712                      if (0 == rs) {
   8713                         putIReg(rd, getIReg(rt));
   8714                      } else {
   8715                         /* Shift lower 16 bits. */
   8716                         assign(t0, binop(Iop_Shl32,
   8717                                          unop(Iop_16Sto32,
   8718                                               unop(Iop_32to16, getIReg(rt))),
   8719                                          mkU8(rs)));
   8720 
   8721                         assign(t1, unop(Iop_1Uto32,
   8722                                         binop(Iop_CmpNE32,
   8723                                                binop(Iop_Sar32,
   8724                                                      mkexpr(t0),
   8725                                                      mkU8(16)),
   8726                                                mkU32(0))));
   8727                         assign(t2, unop(Iop_1Uto32,
   8728                                         binop(Iop_CmpNE32,
   8729                                               binop(Iop_Sar32,
   8730                                                     mkexpr(t0),
   8731                                                     mkU8(16)),
   8732                                               mkU32(0xffffffff))));
   8733                         assign(t3, binop(Iop_And32,
   8734                                          mkexpr(t1),
   8735                                          mkexpr(t2)));
   8736                         putDSPControl(IRExpr_ITE(binop(Iop_CmpEQ32,
   8737                                                        mkexpr(t3),
   8738                                                        mkU32(0x1)),
   8739                                                  binop(Iop_Or32,
   8740                                                        getDSPControl(),
   8741                                                        mkU32(0x400000)),
   8742                                                  getDSPControl()));
   8743                         putDSPControl(IRExpr_ITE(binop(Iop_CmpEQ32,
   8744                                                        binop(Iop_And32,
   8745                                                              getIReg(rt),
   8746                                                              mkU32(0x00008000)),
   8747                                                        binop(Iop_And32,
   8748                                                              mkexpr(t0),
   8749                                                              mkU32(0x00008000))
   8750                                                       ),
   8751                                                  getDSPControl(),
   8752                                                  binop(Iop_Or32,
   8753                                                        getDSPControl(),
   8754                                                        mkU32(0x400000))));
   8755                         assign(t8,
   8756                                IRExpr_ITE(binop(Iop_CmpEQ32,
   8757                                                 mkexpr(t3),
   8758                                                 mkU32(0x1)),
   8759                                           IRExpr_ITE(binop(Iop_CmpEQ32,
   8760                                                            binop(Iop_And32,
   8761                                                                  getIReg(rt),
   8762                                                                  mkU32(0x8000)),
   8763                                                            mkU32(0)),
   8764                                                      mkU32(0x00007fff),
   8765                                                      mkU32(0x00008000)),
   8766                                           binop(Iop_And32,
   8767                                                 mkexpr(t0),
   8768                                                 mkU32(0x0000ffff))));
   8769                         assign(t10,
   8770                                IRExpr_ITE(binop(Iop_CmpEQ32,
   8771                                                 binop(Iop_And32,
   8772                                                       getIReg(rt),
   8773                                                       mkU32(0x00008000)),
   8774                                                 binop(Iop_And32,
   8775                                                       mkexpr(t0),
   8776                                                       mkU32(0x00008000))),
   8777                                           mkexpr(t8),
   8778                                           IRExpr_ITE(binop(Iop_CmpEQ32,
   8779                                                            binop(Iop_And32,
   8780                                                                  getIReg(rt),
   8781                                                                  mkU32(0x8000)),
   8782                                                            mkU32(0)),
   8783                                                      mkU32(0x00007fff),
   8784                                                      mkU32(0x00008000))));
   8785                         /* Shift higher 16 bits. */
   8786                         assign(t4, binop(Iop_Shl32,
   8787                                          unop(Iop_16Sto32,
   8788                                               unop(Iop_32HIto16, getIReg(rt))),
   8789                                          mkU8(rs)));
   8790 
   8791                         assign(t5, unop(Iop_1Uto32,
   8792                                         binop(Iop_CmpNE32,
   8793                                                binop(Iop_Sar32,
   8794                                                      mkexpr(t4),
   8795                                                      mkU8(16)),
   8796                                                mkU32(0))));
   8797                         assign(t6, unop(Iop_1Uto32,
   8798                                         binop(Iop_CmpNE32,
   8799                                               binop(Iop_Sar32,
   8800                                                     mkexpr(t4),
   8801                                                     mkU8(16)),
   8802                                               mkU32(0xffffffff))));
   8803                         assign(t7, binop(Iop_And32,
   8804                                          mkexpr(t5),
   8805                                          mkexpr(t6)));
   8806                         putDSPControl(IRExpr_ITE(binop(Iop_CmpEQ32,
   8807                                                        mkexpr(t7),
   8808                                                        mkU32(0x1)),
   8809                                                  binop(Iop_Or32,
   8810                                                        getDSPControl(),
   8811                                                        mkU32(0x400000)),
   8812                                                  getDSPControl()));
   8813                         putDSPControl(IRExpr_ITE(binop(Iop_CmpEQ32,
   8814                                                        mkexpr(t7),
   8815                                                        mkU32(0x1)),
   8816                                                  binop(Iop_Or32,
   8817                                                        getDSPControl(),
   8818                                                        mkU32(0x400000)),
   8819                                                  getDSPControl()));
   8820                         assign(t12, binop(Iop_Shl32,
   8821                                           binop(Iop_And32,
   8822                                                 mkexpr(t4),
   8823                                                 mkU32(0x8000)),
   8824                                           mkU8(16)));
   8825                         putDSPControl(IRExpr_ITE(binop(Iop_CmpEQ32,
   8826                                                        binop(Iop_And32,
   8827                                                              getIReg(rt),
   8828                                                              mkU32(0x80000000)),
   8829                                                        mkexpr(t12)),
   8830                                                  getDSPControl(),
   8831                                                  binop(Iop_Or32,
   8832                                                        getDSPControl(),
   8833                                                        mkU32(0x400000))));
   8834                         assign(t13, IRExpr_ITE(binop(Iop_CmpEQ32,
   8835                                                      binop(Iop_And32,
   8836                                                            getIReg(rt),
   8837                                                            mkU32(0x80000000)),
   8838                                                      mkU32(0)),
   8839                                                mkU32(0x7fff0000),
   8840                                                mkU32(0x80000000)));
   8841                         assign(t9,
   8842                                IRExpr_ITE(binop(Iop_CmpEQ32,
   8843                                                 mkexpr(t7),
   8844                                                 mkU32(0x1)),
   8845                                           mkexpr(t13),
   8846                                           binop(Iop_Shl32,
   8847                                                 binop(Iop_And32,
   8848                                                       mkexpr(t4),
   8849                                                       mkU32(0x0000ffff)),
   8850                                                 mkU8(16))));
   8851                         assign(t14, IRExpr_ITE(binop(Iop_CmpEQ32,
   8852                                                      binop(Iop_And32,
   8853                                                            getIReg(rt),
   8854                                                            mkU32(0x80000000)),
   8855                                                      mkU32(0)),
   8856                                                mkU32(0x7fff0000),
   8857                                                mkU32(0x80000000)));
   8858                         assign(t11,
   8859                                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                                           mkexpr(t9),
   8869                                           mkexpr(t14)));
   8870                         putIReg(rd, binop(Iop_Or32,
   8871                                           mkexpr(t10),
   8872                                           mkexpr(t11)));
   8873                      }
   8874                      break;
   8875                   }
   8876                   case 0xD: {  /* SHRA_R.PH */
   8877                      DIP("shra.ph r%d, r%d, %d", rd, rt, rs);
   8878                      vassert(!mode64);
   8879                      t0 = newTemp(Ity_I32);
   8880                      t1 = newTemp(Ity_I32);
   8881                      if (0 == rs) {
   8882                         putIReg(rd, getIReg(rt));
   8883                      } else {
   8884                         assign(t0, binop(Iop_Sar32,
   8885                                          binop(Iop_Add32,
   8886                                                unop(Iop_16Sto32,
   8887                                                     unop(Iop_32to16,
   8888                                                          getIReg(rt))),
   8889                                                binop(Iop_Shl32,
   8890                                                      mkU32(0x1),
   8891                                                      mkU8(rs-1))),
   8892                                          mkU8(rs)));
   8893                         assign(t1, binop(Iop_Sar32,
   8894                                          binop(Iop_Add32,
   8895                                                unop(Iop_16Sto32,
   8896                                                     unop(Iop_32HIto16,
   8897                                                          getIReg(rt))),
   8898                                                binop(Iop_Shl32,
   8899                                                      mkU32(0x1),
   8900                                                      mkU8(rs-1))),
   8901                                          mkU8(rs)));
   8902                         putIReg(rd, binop(Iop_16HLto32,
   8903                                           unop(Iop_32to16, mkexpr(t1)),
   8904                                           unop(Iop_32to16, mkexpr(t0))));
   8905                      }
   8906                      break;
   8907                   }
   8908                   case 0xE: {  /* SHLLV_S.PH */
   8909                      DIP("shllv_s.ph r%d, r%d, r%d", rd, rt, rs);
   8910                      vassert(!mode64);
   8911                      t0 = newTemp(Ity_I32);
   8912                      t2 = newTemp(Ity_I32);
   8913                      t3 = newTemp(Ity_I1);
   8914                      t4 = newTemp(Ity_I1);
   8915                      t5 = newTemp(Ity_I32);
   8916                      t6 = newTemp(Ity_I32);
   8917                      t7 = newTemp(Ity_I1);
   8918                      t8 = newTemp(Ity_I1);
   8919                      t9 = newTemp(Ity_I32);
   8920                      t10 = newTemp(Ity_I32);
   8921                      t11 = newTemp(Ity_I32);
   8922                      t12 = newTemp(Ity_I1);
   8923                      t13 = newTemp(Ity_I1);
   8924                      t14 = newTemp(Ity_I16);
   8925                      t15 = newTemp(Ity_I16);
   8926                      t16 = newTemp(Ity_I16);
   8927                      t17 = newTemp(Ity_I16);
   8928 
   8929                      assign(t0, binop(Iop_And32, getIReg(rs), mkU32(0x0f)));
   8930 
   8931                      /* Shift lower 16 bits. */
   8932                      assign(t2, binop(Iop_Shl32,
   8933                                       unop(Iop_16Sto32,
   8934                                            unop(Iop_32to16, getIReg(rt))),
   8935                                       unop(Iop_32to8, mkexpr(t0))));
   8936 
   8937                      assign(t3, binop(Iop_CmpNE32,
   8938                                       unop(Iop_16Sto32,
   8939                                            unop(Iop_32HIto16, mkexpr(t2))),
   8940                                       mkU32(0x00000000)));
   8941                      assign(t4, binop(Iop_CmpNE32,
   8942                                       unop(Iop_16Sto32,
   8943                                            unop(Iop_32HIto16, mkexpr(t2))),
   8944                                       mkU32(0xffffffff)));
   8945                      assign(t10, binop(Iop_And32,
   8946                                        unop(Iop_1Sto32, mkexpr(t3)),
   8947                                        unop(Iop_1Sto32, mkexpr(t4))));
   8948                      assign(t5, binop(Iop_Shr32,
   8949                                        binop(Iop_And32,
   8950                                              getIReg(rt),
   8951                                              mkU32(0x00008000)),
   8952                                        mkU8(15)));
   8953                      assign(t12, binop(Iop_CmpEQ32,
   8954                                        mkexpr(t5),
   8955                                        binop(Iop_Shr32,
   8956                                              binop(Iop_And32,
   8957                                                    mkexpr(t2),
   8958                                                    mkU32(0x00008000)),
   8959                                              mkU8(15))));
   8960 
   8961                      putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32,
   8962                                                     mkexpr(t10),
   8963                                                     mkU32(0x0)),
   8964                                               binop(Iop_Or32,
   8965                                                     getDSPControl(),
   8966                                                     mkU32(0x400000)),
   8967                                               IRExpr_ITE(mkexpr(t12),
   8968                                                          getDSPControl(),
   8969                                                          binop(Iop_Or32,
   8970                                                                getDSPControl(),
   8971                                                                mkU32(0x400000)))
   8972                                              ));
   8973                      assign(t14, IRExpr_ITE(binop(Iop_CmpNE32,
   8974                                                   mkexpr(t5),
   8975                                                   mkU32(0x0)),
   8976                                             mkU16(0x8000),
   8977                                             mkU16(0x7fff)));
   8978                      assign(t15, IRExpr_ITE(binop(Iop_CmpNE32,
   8979                                                   mkexpr(t10),
   8980                                                   mkU32(0x0)),
   8981                                             mkexpr(t14),
   8982                                             IRExpr_ITE(mkexpr(t12),
   8983                                                        unop(Iop_32to16,
   8984                                                             mkexpr(t2)),
   8985                                                        mkexpr(t14))));
   8986                      /* Shift higher 16 bits. */
   8987                      assign(t6, binop(Iop_Shl32,
   8988                                       unop(Iop_16Sto32,
   8989                                            unop(Iop_32HIto16, getIReg(rt))),
   8990                                       unop(Iop_32to8, mkexpr(t0))));
   8991 
   8992                      assign(t7, binop(Iop_CmpNE32,
   8993                                       unop(Iop_16Sto32,
   8994                                            unop(Iop_32HIto16, mkexpr(t6))),
   8995                                       mkU32(0x00000000)));
   8996                      assign(t8, binop(Iop_CmpNE32,
   8997                                       unop(Iop_16Sto32,
   8998                                            unop(Iop_32HIto16, mkexpr(t6))),
   8999                                       mkU32(0xffffffff)));
   9000                      assign(t11, binop(Iop_And32,
   9001                                        unop(Iop_1Sto32, mkexpr(t7)),
   9002                                        unop(Iop_1Sto32, mkexpr(t8))));
   9003 
   9004                      assign(t9, binop(Iop_Shr32,
   9005                                       binop(Iop_And32,
   9006                                             getIReg(rt),
   9007                                             mkU32(0x80000000)),
   9008                                       mkU8(31)));
   9009                      assign(t13, binop(Iop_CmpEQ32,
   9010                                        mkexpr(t9),
   9011                                        binop(Iop_Shr32,
   9012                                              binop(Iop_And32,
   9013                                                    mkexpr(t6),
   9014                                                    mkU32(0x00008000)),
   9015                                              mkU8(15))));
   9016 
   9017                      putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32,
   9018                                                     mkexpr(t11),
   9019                                                     mkU32(0x0)),
   9020                                               binop(Iop_Or32,
   9021                                                     getDSPControl(),
   9022                                                     mkU32(0x400000)),
   9023                                               IRExpr_ITE(mkexpr(t13),
   9024                                                          getDSPControl(),
   9025                                                          binop(Iop_Or32,
   9026                                                                getDSPControl(),
   9027                                                                mkU32(0x400000)))
   9028                                              ));
   9029 
   9030                      assign(t16, IRExpr_ITE(binop(Iop_CmpNE32,
   9031                                                   mkexpr(t9),
   9032                                                   mkU32(0x0)),
   9033                                             mkU16(0x8000),
   9034                                             mkU16(0x7fff)));
   9035                      assign(t17, IRExpr_ITE(binop(Iop_CmpNE32,
   9036                                                   mkexpr(t11),
   9037                                                   mkU32(0x0)),
   9038                                             mkexpr(t16),
   9039                                             IRExpr_ITE(mkexpr(t13),
   9040                                                        unop(Iop_32to16,
   9041                                                             mkexpr(t6)),
   9042                                                        mkexpr(t16))));
   9043 
   9044                      putIReg(rd, binop(Iop_16HLto32, mkexpr(t17), mkexpr(t15)));
   9045                      break;
   9046                   }
   9047                   case 0xF: {  /* SHRAV_R.PH */
   9048                      DIP("shrav_r.ph r%d, r%d, r%d", rd, rt, rs);
   9049                      vassert(!mode64);
   9050                      t0 = newTemp(Ity_I32);
   9051                      t1 = newTemp(Ity_I1);
   9052                      t2 = newTemp(Ity_I8);
   9053                      t3 = newTemp(Ity_I32);
   9054                      t4 = newTemp(Ity_I32);
   9055 
   9056                      assign(t0, binop(Iop_And32, getIReg(rs), mkU32(0x0f)));
   9057                      assign(t1, binop(Iop_CmpEQ32, mkexpr(t0), mkU32(0x0)));
   9058                      assign(t2, unop(Iop_32to8,
   9059                                      binop(Iop_Sub32, mkexpr(t0), mkU32(1))));
   9060 
   9061                      assign(t3, binop(Iop_Sar32,
   9062                                       binop(Iop_Add32,
   9063                                             unop(Iop_16Sto32,
   9064                                                  unop(Iop_32to16, getIReg(rt))),
   9065                                             binop(Iop_Shl32,
   9066                                                   mkU32(0x1),
   9067                                                   mkexpr(t2))),
   9068                                       unop(Iop_32to8, mkexpr(t0))));
   9069                      assign(t4, binop(Iop_Sar32,
   9070                                       binop(Iop_Add32,
   9071                                             unop(Iop_16Sto32,
   9072                                                  unop(Iop_32HIto16,
   9073                                                       getIReg(rt))),
   9074                                             binop(Iop_Shl32,
   9075                                                   mkU32(0x1),
   9076                                                   mkexpr(t2))),
   9077                                       unop(Iop_32to8, mkexpr(t0))));
   9078 
   9079                      putIReg(rd, binop(Iop_16HLto32,
   9080                                        IRExpr_ITE(mkexpr(t1),
   9081                                                   unop(Iop_32HIto16,
   9082                                                        getIReg(rt)),
   9083                                                   unop(Iop_32to16,
   9084                                                        mkexpr(t4))),
   9085                                        IRExpr_ITE(mkexpr(t1),
   9086                                                   unop(Iop_32to16, getIReg(rt)),
   9087                                                   unop(Iop_32to16,
   9088                                                        mkexpr(t3)))));
   9089                      break;
   9090                   }
   9091                   case 0x14: {  /* SHLL_S.W */
   9092                      DIP("shll_s.w r%d, r%d, %d", rd, rt, rs);
   9093                      vassert(!mode64);
   9094                      t0 = newTemp(Ity_I32);
   9095                      t1 = newTemp(Ity_I32);
   9096                      t2 = newTemp(Ity_I32);
   9097                      t3 = newTemp(Ity_I32);
   9098                      t4 = newTemp(Ity_I32);
   9099                      t5 = newTemp(Ity_I32);
   9100 
   9101                      if (0 == rs) {
   9102                         putIReg(rd, getIReg(rt));
   9103                      } else {
   9104                         /* t0-bits that will be discarded, sign extended to
   9105                            32bits. */
   9106                         assign(t0, binop(Iop_Sar32,
   9107                                          binop(Iop_And32,
   9108                                                getIReg(rt),
   9109                                                binop(Iop_Sar32,
   9110                                                      mkU32(0x80000000),
   9111                                                      mkU8(rs-1))),
   9112                                          mkU8(32-rs)));
   9113 
   9114                         assign(t1, IRExpr_ITE(binop(Iop_CmpEQ32,
   9115                                                     binop(Iop_And32,
   9116                                                           getIReg(rt),
   9117                                                           mkU32(0x80000000)),
   9118                                                     mkU32(0x0)),
   9119                                               mkU32(0x7fffffff),
   9120                                               mkU32(0x80000000)));
   9121 
   9122                         assign(t2, binop(Iop_Shl32, getIReg(rt), mkU8(rs)));
   9123                         assign(t3, IRExpr_ITE(binop(Iop_CmpEQ32,
   9124                                                     binop(Iop_And32,
   9125                                                           getIReg(rt),
   9126                                                           mkU32(0x80000000)),
   9127                                                     binop(Iop_And32,
   9128                                                           mkexpr(t2),
   9129                                                           mkU32(0x80000000))),
   9130                                               mkexpr(t2),
   9131                                               mkexpr(t1)));
   9132 
   9133                         assign(t4, IRExpr_ITE(binop(Iop_CmpNE32,
   9134                                                     mkexpr(t0),
   9135                                                     mkU32(0x0)),
   9136                                               IRExpr_ITE(binop(Iop_CmpNE32,
   9137                                                                mkexpr(t0),
   9138                                                                mkU32(0xffffffff)
   9139                                                               ),
   9140                                                          mkexpr(t1),
   9141                                                          mkexpr(t3)),
   9142                                               mkexpr(t3)));
   9143                         assign(t5, IRExpr_ITE(binop(Iop_CmpNE32,
   9144                                                     mkexpr(t0),
   9145                                                     mkU32(0xffffffff)),
   9146                                               binop(Iop_Or32,
   9147                                                     getDSPControl(),
   9148                                                     mkU32(0x400000)),
   9149                                               getDSPControl()));
   9150                         putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32,
   9151                                                        mkexpr(t0),
   9152                                                        mkU32(0x0)),
   9153                                                  mkexpr(t5),
   9154                                                  getDSPControl()));
   9155                         putDSPControl(IRExpr_ITE(binop(Iop_CmpEQ32,
   9156                                                        binop(Iop_And32,
   9157                                                              getIReg(rt),
   9158                                                              mkU32(0x80000000)),
   9159                                                        binop(Iop_And32,
   9160                                                              mkexpr(t2),
   9161                                                              mkU32(0x80000000))
   9162                                                             ),
   9163                                                  getDSPControl(),
   9164                                                  binop(Iop_Or32,
   9165                                                        getDSPControl(),
   9166                                                        mkU32(0x400000))));
   9167                         putIReg(rd, mkexpr(t4));
   9168                      }
   9169                      break;
   9170                   }
   9171                   case 0x15: {  /* SHRA_R.W */
   9172                      DIP("shra_r.w r%d, r%d, %d", rd, rt, rs);
   9173                      vassert(!mode64);
   9174                      if (0 == rs) {
   9175                         putIReg(rd, getIReg(rt));
   9176                      } else {
   9177                         putIReg(rd, binop(Iop_Add32,
   9178                                           binop(Iop_Sar32,
   9179                                                 getIReg(rt), mkU8(rs)),
   9180                                           binop(Iop_Shr32,
   9181                                                 binop(Iop_And32,
   9182                                                       getIReg(rt),
   9183                                                       binop(Iop_Shl32,
   9184                                                             mkU32(0x1),
   9185                                                             mkU8(rs-1))),
   9186                                                 mkU8(rs-1))));
   9187                      }
   9188                      break;
   9189                   }
   9190                   case 0x16: {  /* SHLLV_S.W */
   9191                      DIP("shllv_s.w r%d, r%d, r%d", rd, rt, rs);
   9192                      vassert(!mode64);
   9193                      t0 = newTemp(Ity_I32);
   9194                      t1 = newTemp(Ity_I1);
   9195                      t2 = newTemp(Ity_I32);
   9196                      t3 = newTemp(Ity_I64);
   9197                      t4 = newTemp(Ity_I1);
   9198                      t5 = newTemp(Ity_I1);
   9199                      t6 = newTemp(Ity_I32);
   9200                      t7 = newTemp(Ity_I1);
   9201                      t8 = newTemp(Ity_I32);
   9202 
   9203                      /* Check if shift amount is zero. */
   9204                      assign(t0, binop(Iop_And32, getIReg(rs), mkU32(0x1f)));
   9205                      assign(t1, binop(Iop_CmpEQ32, mkexpr(t0), mkU32(0x0)));
   9206 
   9207                      /* t2 = sign of the input value. */
   9208                      assign(t2, binop(Iop_Shr32,
   9209                                       binop(Iop_And32,
   9210                                             getIReg(rt),
   9211                                             mkU32(0x80000000)),
   9212                                       mkU8(31)));
   9213                      /* Shift left input value and check for overflow. */
   9214                      assign(t3, binop(Iop_Shl64,
   9215                                       unop(Iop_32Sto64, getIReg(rt)),
   9216                                       unop(Iop_32to8, mkexpr(t0))));
   9217                      assign(t4, binop(Iop_CmpNE32,
   9218                                       unop(Iop_64HIto32, mkexpr(t3)),
   9219                                       mkU32(0x00000000)));
   9220                      assign(t5, binop(Iop_CmpNE32,
   9221                                       unop(Iop_64HIto32, mkexpr(t3)),
   9222                                       mkU32(0xffffffff)));
   9223                      assign(t6, binop(Iop_And32,
   9224                                       unop(Iop_1Uto32, mkexpr(t4)),
   9225                                       unop(Iop_1Uto32, mkexpr(t5))));
   9226                      assign(t7, binop(Iop_CmpEQ32,
   9227                                       binop(Iop_Shr32,
   9228                                             binop(Iop_And32,
   9229                                                   getIReg(rt),
   9230                                                   mkU32(0x80000000)),
   9231                                             mkU8(31)),
   9232                                       binop(Iop_Shr32,
   9233                                             binop(Iop_And32,
   9234                                                   unop(Iop_64to32, mkexpr(t3)),
   9235                                                   mkU32(0x80000000)),
   9236                                             mkU8(31))));
   9237 
   9238                      putDSPControl(IRExpr_ITE(unop(Iop_32to1, mkexpr(t6)),
   9239                                                    binop(Iop_Or32,
   9240                                                          getDSPControl(),
   9241                                                          mkU32(0x400000)),
   9242                                               IRExpr_ITE(mkexpr(t7),
   9243                                                          getDSPControl(),
   9244                                                          binop(Iop_Or32,
   9245                                                                getDSPControl(),
   9246                                                                mkU32(0x400000)))
   9247                                              ));
   9248 
   9249                      assign(t8, IRExpr_ITE(unop(Iop_32to1,
   9250                                                 mkexpr(t2)),
   9251                                            mkU32(0x80000000),
   9252                                            mkU32(0x7fffffff)));
   9253                      putIReg(rd, IRExpr_ITE(unop(Iop_32to1, mkexpr(t6)),
   9254                                             IRExpr_ITE(unop(Iop_32to1,
   9255                                                             mkexpr(t2)),
   9256                                                        mkU32(0x80000000),
   9257                                                        mkU32(0x7fffffff)),
   9258                                             IRExpr_ITE(mkexpr(t7),
   9259                                                        unop(Iop_64to32,
   9260                                                             mkexpr(t3)),
   9261                                                        mkexpr(t8))));
   9262                      break;
   9263                   }
   9264                   case 0x17: {  /* SHRAV_R.W */
   9265                      DIP("shrav_r.w r%d, r%d, r%d", rd, rt, rs);
   9266                      vassert(!mode64);
   9267                      t0 = newTemp(Ity_I32);
   9268                      t1 = newTemp(Ity_I1);
   9269                      t2 = newTemp(Ity_I8);
   9270                      t3 = newTemp(Ity_I32);
   9271 
   9272                      assign(t0, binop(Iop_And32, getIReg(rs), mkU32(0x1f)));
   9273                      assign(t1, binop(Iop_CmpEQ32, mkexpr(t0), mkU32(0x0)));
   9274                      assign(t2, unop(Iop_32to8,
   9275                                      binop(Iop_Sub32, mkexpr(t0), mkU32(1))));
   9276 
   9277                      putIReg(rd, IRExpr_ITE(mkexpr(t1),
   9278                                             getIReg(rt),
   9279                                             binop(Iop_Sar32,
   9280                                                   binop(Iop_Add32,
   9281                                                         binop(Iop_Sar32,
   9282                                                               getIReg(rt),
   9283                                                               mkexpr(t2)),
   9284                                                         mkU32(0x1)),
   9285                                                   mkU8(1))));
   9286                      break;
   9287                   }
   9288                   case 0x19: {  /* SHRL.PH */
   9289                      DIP("shrl.ph r%d, r%d, %d", rd, rt, rs);
   9290                      vassert(!mode64);
   9291                      t0 = newTemp(Ity_I32);
   9292                      t1 = newTemp(Ity_I32);
   9293                      assign(t0, binop(Iop_Shr32,
   9294                                       unop(Iop_16Uto32,
   9295                                            unop(Iop_32to16, getIReg(rt))),
   9296                                       mkU8(rs)));
   9297                      assign(t1, binop(Iop_Shr32,
   9298                                       unop(Iop_16Uto32,
   9299                                            unop(Iop_32HIto16, getIReg(rt))),
   9300                                       mkU8(rs)));
   9301                      putIReg(rd, binop(Iop_16HLto32,
   9302                                        unop(Iop_32to16, mkexpr(t1)),
   9303                                        unop(Iop_32to16, mkexpr(t0))));
   9304                      break;
   9305                   }
   9306                   case 0x1B: {  /* SHRLV.PH */
   9307                      DIP("shrlv.ph r%d, r%d, r%d", rd, rt, rs);
   9308                      vassert(!mode64);
   9309                      t0 = newTemp(Ity_I32);
   9310                      t1 = newTemp(Ity_I1);
   9311                      t2 = newTemp(Ity_I32);
   9312                      t3 = newTemp(Ity_I32);
   9313                      t4 = newTemp(Ity_I16);
   9314                      t5 = newTemp(Ity_I16);
   9315 
   9316                      /* Get shift amount from lower 5 bits of rs
   9317                         and check if it is zero. */
   9318                      assign(t0, binop(Iop_And32, getIReg(rs), mkU32(0x0f)));
   9319                      assign(t1, binop(Iop_CmpEQ32, mkexpr(t0), mkU32(0x0)));
   9320 
   9321                      assign(t2, binop(Iop_Shr32,
   9322                                       unop(Iop_16Uto32,
   9323                                            unop(Iop_32to16, getIReg(rt))),
   9324                                       unop(Iop_32to8, mkexpr(t0))));
   9325                      assign(t3, binop(Iop_Shr32,
   9326                                       unop(Iop_16Uto32,
   9327                                            unop(Iop_32HIto16, getIReg(rt))),
   9328                                       unop(Iop_32to8, mkexpr(t0))));
   9329 
   9330                      assign(t4, IRExpr_ITE(mkexpr(t1),
   9331                                            unop(Iop_32HIto16, getIReg(rt)),
   9332                                            unop(Iop_32to16, mkexpr(t3))));
   9333                      assign(t5, IRExpr_ITE(mkexpr(t1),
   9334                                            unop(Iop_32to16, getIReg(rt)),
   9335                                            unop(Iop_32to16, mkexpr(t2))));
   9336                      putIReg(rd, binop(Iop_16HLto32, mkexpr(t4), mkexpr(t5)));
   9337                      break;
   9338                   }
   9339                   default:
   9340                      return -1;
   9341                }
   9342                break;  /* end of SHLL.QB */
   9343             }
   9344             case 0x18: {  /* ADDUH.QB/MUL.PH */
   9345                switch(sa) {
   9346                   case 0x00: {  /* ADDUH.QB */
   9347                      DIP("adduh.qb r%d, r%d, r%d", rd, rs, rt);
   9348                      vassert(!mode64);
   9349                      t0 = newTemp(Ity_I32);
   9350 
   9351                      assign(t0, binop(Iop_HAdd8Ux4, getIReg(rs), getIReg(rt)));
   9352 
   9353                      putIReg(rd, mkexpr(t0));
   9354                      break;
   9355                   }
   9356                   case 0x1: {  /* SUBUH.QB */
   9357                      DIP("subuh.qb r%d, r%d, r%d", rd, rs, rt);
   9358                      vassert(!mode64);
   9359                      t0 = newTemp(Ity_I32);
   9360 
   9361                      assign(t0, binop(Iop_HSub8Ux4, getIReg(rs), getIReg(rt)));
   9362 
   9363                      putIReg(rd, mkexpr(t0));
   9364                      break;
   9365                   }
   9366                   case 0x02: {  /* ADDUH_R.QB */
   9367                      DIP("adduh_r.qb r%d, r%d, r%d", rd, rs, rt);
   9368                      vassert(!mode64);
   9369                      t0 = newTemp(Ity_I32);
   9370                      t1 = newTemp(Ity_I32);
   9371                      t2 = newTemp(Ity_I8);
   9372                      t3 = newTemp(Ity_I32);
   9373                      t4 = newTemp(Ity_I32);
   9374                      t5 = newTemp(Ity_I8);
   9375                      t6 = newTemp(Ity_I32);
   9376                      t7 = newTemp(Ity_I32);
   9377                      t8 = newTemp(Ity_I8);
   9378                      t9 = newTemp(Ity_I32);
   9379                      t10 = newTemp(Ity_I32);
   9380                      t11 = newTemp(Ity_I8);
   9381 
   9382                      /* Extract input bytes, add values, add 1 and half the
   9383                         result. */
   9384                      assign(t0, unop(Iop_8Uto32,
   9385                                      unop(Iop_16to8,
   9386                                           unop(Iop_32to16, getIReg(rs)))));
   9387                      assign(t1, unop(Iop_8Uto32,
   9388                                      unop(Iop_16to8,
   9389                                           unop(Iop_32to16, getIReg(rt)))));
   9390                      assign(t2, unop(Iop_16to8,
   9391                                      unop(Iop_32to16,
   9392                                           binop(Iop_Shr32,
   9393                                                 binop(Iop_Add32,
   9394                                                       binop(Iop_Add32,
   9395                                                             mkexpr(t0),
   9396                                                             mkexpr(t1)),
   9397                                                       mkU32(0x00000001)),
   9398                                                 mkU8(0x01)))));
   9399 
   9400                      assign(t3, unop(Iop_8Uto32,
   9401                                      unop(Iop_16HIto8,
   9402                                           unop(Iop_32to16, getIReg(rs)))));
   9403                      assign(t4, unop(Iop_8Uto32,
   9404                                      unop(Iop_16HIto8,
   9405                                           unop(Iop_32to16, getIReg(rt)))));
   9406                      assign(t5, unop(Iop_16to8,
   9407                                      unop(Iop_32to16,
   9408                                           binop(Iop_Shr32,
   9409                                                 binop(Iop_Add32,
   9410                                                       binop(Iop_Add32,
   9411                                                             mkexpr(t3),
   9412                                                             mkexpr(t4)),
   9413                                                       mkU32(0x00000001)),
   9414                                                 mkU8(0x01)))));
   9415 
   9416                      assign(t6, unop(Iop_8Uto32,
   9417                                      unop(Iop_16to8,
   9418                                           unop(Iop_32HIto16, getIReg(rs)))));
   9419                      assign(t7, unop(Iop_8Uto32,
   9420                                      unop(Iop_16to8,
   9421                                           unop(Iop_32HIto16, getIReg(rt)))));
   9422                      assign(t8, unop(Iop_16to8,
   9423                                      unop(Iop_32to16,
   9424                                           binop(Iop_Shr32,
   9425                                                 binop(Iop_Add32,
   9426                                                       binop(Iop_Add32,
   9427                                                             mkexpr(t7),
   9428                                                             mkexpr(t6)),
   9429                                                       mkU32(0x00000001)),
   9430                                                 mkU8(0x01)))));
   9431 
   9432                      assign(t9, unop(Iop_8Uto32,
   9433                                      unop(Iop_16HIto8,
   9434                                           unop(Iop_32HIto16, getIReg(rs)))));
   9435                      assign(t10, unop(Iop_8Uto32,
   9436                                       unop(Iop_16HIto8,
   9437                                            unop(Iop_32HIto16, getIReg(rt)))));
   9438                      assign(t11, unop(Iop_16to8,
   9439                                       unop(Iop_32to16,
   9440                                            binop(Iop_Shr32,
   9441                                                  binop(Iop_Add32,
   9442                                                        binop(Iop_Add32,
   9443                                                              mkexpr(t9),
   9444                                                              mkexpr(t10)),
   9445                                                        mkU32(0x00000001)),
   9446                                                  mkU8(0x01)))));
   9447 
   9448                      putIReg(rd, binop(Iop_16HLto32,
   9449                                        binop(Iop_8HLto16,
   9450                                              mkexpr(t11), mkexpr(t8)),
   9451                                        binop(Iop_8HLto16,
   9452                                              mkexpr(t5), mkexpr(t2))));
   9453                      break;
   9454                   }
   9455                   case 0x3: {  /* SUBUH_R.QB */
   9456                      DIP("subuh_r.qb r%d, r%d, r%d", rd, rs, rt);
   9457                      vassert(!mode64);
   9458                      t1 = newTemp(Ity_I32);
   9459                      t2 = newTemp(Ity_I32);
   9460                      t3 = newTemp(Ity_I32);
   9461                      t4 = newTemp(Ity_I32);
   9462                      t5 = newTemp(Ity_I32);
   9463                      t6 = newTemp(Ity_I32);
   9464                      t7 = newTemp(Ity_I32);
   9465                      t8 = newTemp(Ity_I32);
   9466                      t9 = newTemp(Ity_I8);
   9467                      t10 = newTemp(Ity_I8);
   9468                      t11 = newTemp(Ity_I8);
   9469                      t12 = newTemp(Ity_I8);
   9470 
   9471                      /* Extract each byte of rs and rt. */
   9472                      assign(t1, unop(Iop_8Uto32,
   9473                                      unop(Iop_16to8,
   9474                                           unop(Iop_32to16, getIReg(rs)))));
   9475                      assign(t2, unop(Iop_8Uto32,
   9476                                      unop(Iop_16HIto8,
   9477                                           unop(Iop_32to16, getIReg(rs)))));
   9478                      assign(t3, unop(Iop_8Uto32,
   9479                                      unop(Iop_16to8,
   9480                                           unop(Iop_32HIto16, getIReg(rs)))));
   9481                      assign(t4, unop(Iop_8Uto32,
   9482                                      unop(Iop_16HIto8,
   9483                                           unop(Iop_32HIto16, getIReg(rs)))));
   9484 
   9485                      assign(t5, unop(Iop_8Uto32,
   9486                                      unop(Iop_16to8,
   9487                                           unop(Iop_32to16, getIReg(rt)))));
   9488                      assign(t6, unop(Iop_8Uto32,
   9489                                      unop(Iop_16HIto8,
   9490                                           unop(Iop_32to16, getIReg(rt)))));
   9491                      assign(t7, unop(Iop_8Uto32,
   9492                                      unop(Iop_16to8,
   9493                                           unop(Iop_32HIto16, getIReg(rt)))));
   9494                      assign(t8, unop(Iop_8Uto32,
   9495                                      unop(Iop_16HIto8,
   9496                                           unop(Iop_32HIto16, getIReg(rt)))));
   9497 
   9498                      /* Add 1 to each resulting byte and half the results. */
   9499                      assign(t9, unop(Iop_16to8,
   9500                                      unop(Iop_32to16,
   9501                                           binop(Iop_Shr32,
   9502                                                 binop(Iop_Add32,
   9503                                                       binop(Iop_Sub32,
   9504                                                             mkexpr(t1),
   9505                                                             mkexpr(t5)),
   9506                                                       mkU32(0x00000001)),
   9507                                                 mkU8(0x01)))));
   9508                      assign(t10, unop(Iop_16to8,
   9509                                       unop(Iop_32to16,
   9510                                            binop(Iop_Shr32,
   9511                                                  binop(Iop_Add32,
   9512                                                        binop(Iop_Sub32,
   9513                                                              mkexpr(t2),
   9514                                                              mkexpr(t6)),
   9515                                                        mkU32(0x00000001)),
   9516                                                  mkU8(0x01)))));
   9517                      assign(t11, unop(Iop_16to8,
   9518                                       unop(Iop_32to16,
   9519                                             binop(Iop_Shr32,
   9520                                                   binop(Iop_Add32,
   9521                                                         binop(Iop_Sub32,
   9522                                                               mkexpr(t3),
   9523                                                               mkexpr(t7)),
   9524                                                         mkU32(0x00000001)),
   9525                                                   mkU8(0x01)))));
   9526                      assign(t12, unop(Iop_16to8,
   9527                                       unop(Iop_32to16,
   9528                                            binop(Iop_Shr32,
   9529                                                  binop(Iop_Add32,
   9530                                                        binop(Iop_Sub32,
   9531                                                              mkexpr(t4),
   9532                                                              mkexpr(t8)),
   9533                                                        mkU32(0x00000001)),
   9534                                                  mkU8(0x01)))));
   9535 
   9536                      putIReg(rd, binop(Iop_16HLto32,
   9537                                        binop(Iop_8HLto16,
   9538                                              mkexpr(t12), mkexpr(t11)),
   9539                                        binop(Iop_8HLto16,
   9540                                              mkexpr(t10), mkexpr(t9))));
   9541                      break;
   9542                   }
   9543                   case 0x8: {  /* ADDQH.PH */
   9544                      DIP("addqh.ph r%d, r%d, r%d", rd, rs, rt);
   9545                      vassert(!mode64);
   9546                      t0 = newTemp(Ity_I32);
   9547                      t1 = newTemp(Ity_I16);
   9548                      t2 = newTemp(Ity_I32);
   9549                      t3 = newTemp(Ity_I16);
   9550 
   9551                      /* Add lower halfs of rs and rt
   9552                         and right shift the result by 1. */
   9553                      assign(t0, binop(Iop_Add32,
   9554                                       unop(Iop_16Sto32,
   9555                                            unop(Iop_32to16, getIReg(rs))),
   9556                                       unop(Iop_16Sto32,
   9557                                            unop(Iop_32to16, getIReg(rt)))));
   9558                      assign(t1, unop(Iop_32to16,
   9559                                      binop(Iop_Shr32,
   9560                                            binop(Iop_And32,
   9561                                                  mkexpr(t0),
   9562                                                  mkU32(0x0001fffe)),
   9563                                            mkU8(0x1))));
   9564                      /* Add higher halfs of rs and rt
   9565                         and right shift the result by 1. */
   9566                      assign(t2, binop(Iop_Add32,
   9567                                       unop(Iop_16Sto32,
   9568                                            unop(Iop_32HIto16, getIReg(rs))),
   9569                                       unop(Iop_16Sto32,
   9570                                            unop(Iop_32HIto16, getIReg(rt)))));
   9571                      assign(t3, unop(Iop_32to16,
   9572                                      binop(Iop_Shr32,
   9573                                            binop(Iop_And32,
   9574                                                  mkexpr(t2),
   9575                                                  mkU32(0x0001fffe)),
   9576                                            mkU8(0x1))));
   9577                      putIReg(rd, binop(Iop_16HLto32, mkexpr(t3), mkexpr(t1)));
   9578                      break;
   9579                   }
   9580                   case 0x9: {  /* SUBQH.PH */
   9581                      DIP("subqh.ph r%d, r%d, r%d", rd, rs, rt);
   9582                      vassert(!mode64);
   9583 
   9584                      putIReg(rd, binop(Iop_HSub16Sx2,
   9585                                        getIReg(rs), getIReg(rt)));
   9586                      break;
   9587                   }
   9588                   case 0xA: {/* ADDQH_R.PH */
   9589                      DIP("addqh_r.ph r%d, r%d, r%d", rd, rs, rt);
   9590                      vassert(!mode64);
   9591                      t0 = newTemp(Ity_I32);
   9592                      t1 = newTemp(Ity_I16);
   9593                      t2 = newTemp(Ity_I32);
   9594                      t3 = newTemp(Ity_I16);
   9595 
   9596                      /* Add lower halfs of rs and rt, add 1
   9597                         and right shift the result by 1. */
   9598                      assign(t0, binop(Iop_Add32,
   9599                                       unop(Iop_16Sto32,
   9600                                            unop(Iop_32to16, getIReg(rs))),
   9601                                       unop(Iop_16Sto32,
   9602                                            unop(Iop_32to16, getIReg(rt)))));
   9603                      assign(t1, unop(Iop_32to16,
   9604                                      binop(Iop_Shr32,
   9605                                            binop(Iop_And32,
   9606                                                  binop(Iop_Add32,
   9607                                                        mkexpr(t0),
   9608                                                        mkU32(0x1)),
   9609                                                  mkU32(0x0001fffe)),
   9610                                            mkU8(0x1))));
   9611                      /* Add higher halfs of rs and rt, add 1
   9612                         and right shift the result by 1. */
   9613                      assign(t2, binop(Iop_Add32,
   9614                                       unop(Iop_16Sto32,
   9615                                            unop(Iop_32HIto16, getIReg(rs))),
   9616                                       unop(Iop_16Sto32,
   9617                                            unop(Iop_32HIto16, getIReg(rt)))));
   9618                      assign(t3, unop(Iop_32to16,
   9619                                      binop(Iop_Shr32,
   9620                                            binop(Iop_And32,
   9621                                                  binop(Iop_Add32,
   9622                                                        mkexpr(t2),
   9623                                                        mkU32(0x1)),
   9624                                                  mkU32(0x0001fffe)),
   9625                                            mkU8(0x1))));
   9626 
   9627                      putIReg(rd, binop(Iop_16HLto32, mkexpr(t3), mkexpr(t1)));
   9628                      break;
   9629                   }
   9630                   case 0xB: {  /* SUBQH_R.PH */
   9631                      DIP("subqh_r.ph r%d, r%d, r%d", rd, rs, rt);
   9632                      vassert(!mode64);
   9633                      t0 = newTemp(Ity_I32);
   9634                      t1 = newTemp(Ity_I16);
   9635                      t2 = newTemp(Ity_I32);
   9636                      t3 = newTemp(Ity_I16);
   9637 
   9638                      /* Sub lower halfs of rs and rt, add 1
   9639                         and right shift the result by 1. */
   9640                      assign(t0, binop(Iop_Sub32,
   9641                                       unop(Iop_16Sto32,
   9642                                            unop(Iop_32to16, getIReg(rs))),
   9643                                       unop(Iop_16Sto32,
   9644                                            unop(Iop_32to16, getIReg(rt)))));
   9645                      assign(t1, unop(Iop_32to16,
   9646                                      binop(Iop_Shr32,
   9647                                            binop(Iop_And32,
   9648                                                  binop(Iop_Add32,
   9649                                                        mkexpr(t0),
   9650                                                        mkU32(0x1)),
   9651                                                  mkU32(0x0001fffe)),
   9652                                            mkU8(0x1))));
   9653                      /* Sub higher halfs of rs and rt, add 1
   9654                         and right shift the result by 1. */
   9655                      assign(t2, binop(Iop_Sub32,
   9656                                       unop(Iop_16Sto32,
   9657                                            unop(Iop_32HIto16, getIReg(rs))),
   9658                                       unop(Iop_16Sto32,
   9659                                            unop(Iop_32HIto16, getIReg(rt)))));
   9660                      assign(t3, unop(Iop_32to16,
   9661                                      binop(Iop_Shr32,
   9662                                            binop(Iop_And32,
   9663                                                  binop(Iop_Add32,
   9664                                                        mkexpr(t2),
   9665                                                        mkU32(0x1)),
   9666                                                  mkU32(0x0001fffe)),
   9667                                            mkU8(0x1))));
   9668 
   9669                      putIReg(rd, binop(Iop_16HLto32, mkexpr(t3), mkexpr(t1)));
   9670                      break;
   9671                   }
   9672                   case 0xC: {  /* MUL.PH */
   9673                      DIP("mul.ph r%d, r%d, r%d", rd, rs, rt);
   9674                      vassert(!mode64);
   9675                      t0 = newTemp(Ity_I32);
   9676                      t1 = newTemp(Ity_I32);
   9677                      t2 = newTemp(Ity_I32);
   9678 
   9679                      assign(t0,
   9680                             binop(Iop_Mul32,
   9681                                   unop(Iop_16Sto32,
   9682                                        unop(Iop_32HIto16, getIReg(rs))),
   9683                                   unop(Iop_16Sto32,
   9684                                        unop(Iop_32HIto16, getIReg(rt)))));
   9685                      /* DSP Control flag. */
   9686                      putDSPControl(IRExpr_ITE(unop(Iop_Not1,
   9687                                                    binop(Iop_CmpLE32S,
   9688                                                          mkexpr(t0),
   9689                                                          mkU32(0x7FFF))),
   9690                                               binop(Iop_Or32,
   9691                                                     getDSPControl(),
   9692                                                     mkU32(0x00200000)),
   9693                                               IRExpr_ITE(binop(Iop_CmpLT32S,
   9694                                                                mkexpr(t0),
   9695                                                                mkU32(0xFFFF8000)
   9696                                                              ),
   9697                                                          binop(Iop_Or32,
   9698                                                                getDSPControl(),
   9699                                                                mkU32(0x00200000)
   9700                                                               ),
   9701                                                          getDSPControl())));
   9702 
   9703                      assign(t1,
   9704                             binop(Iop_Mul32,
   9705                                   unop(Iop_16Sto32,
   9706                                        unop(Iop_32to16, getIReg(rs))),
   9707                                   unop(Iop_16Sto32,
   9708                                        unop(Iop_32to16, getIReg(rt)))));
   9709                      /* DSP Control flag. */
   9710                      putDSPControl(IRExpr_ITE(unop(Iop_Not1,
   9711                                                    binop(Iop_CmpLE32S,
   9712                                                          mkexpr(t1),
   9713                                                          mkU32(0x7FFF))),
   9714                                               binop(Iop_Or32,
   9715                                                     getDSPControl(),
   9716                                                     mkU32(0x00200000)),
   9717                                               IRExpr_ITE(binop(Iop_CmpLT32S,
   9718                                                                mkexpr(t1),
   9719                                                                mkU32(0xFFFF8000)
   9720                                                               ),
   9721                                                          binop(Iop_Or32,
   9722                                                                getDSPControl(),
   9723                                                                mkU32(0x00200000)
   9724                                                               ),
   9725                                                          getDSPControl())));
   9726 
   9727                      assign(t2, binop(Iop_16HLto32,
   9728                                       unop(Iop_32to16, mkexpr(t0)),
   9729                                       unop(Iop_32to16, mkexpr(t1))));
   9730                      putIReg(rd, mkexpr(t2));
   9731                      break;
   9732                   }
   9733                   case 0xE: {  /* MUL_S.PH */
   9734                      DIP("mul_s.ph r%d r%d, r%d", rd, rs, rt);
   9735                      vassert(!mode64);
   9736 
   9737                      t0 = newTemp(Ity_I32);
   9738                      t1 = newTemp(Ity_I32);
   9739                      t2 = newTemp(Ity_I32);
   9740                      t3 = newTemp(Ity_I32);
   9741                      t4 = newTemp(Ity_I32);
   9742 
   9743                      /* t0 - signed intermediate result. */
   9744                      assign(t0,
   9745                            binop(Iop_Mul32,
   9746                                  unop(Iop_16Sto32,
   9747                                       unop(Iop_32HIto16, getIReg(rs))),
   9748                                  unop(Iop_16Sto32,
   9749                                       unop(Iop_32HIto16, getIReg(rt)))));
   9750 
   9751                      assign(t1,
   9752                             IRExpr_ITE(unop(Iop_Not1,
   9753                                             binop(Iop_CmpLE32S,
   9754                                                   mkexpr(t0),
   9755                                                   mkU32(0x7FFF))),
   9756                                        mkU32(0x00007FFF),
   9757                                        IRExpr_ITE(binop(Iop_CmpLT32S,
   9758                                                         mkexpr(t0),
   9759                                                         mkU32(0xFFFF8000)),
   9760                                                   mkU32(0xFFFF8000),
   9761                                                   mkexpr(t0))));
   9762 
   9763                      /* DSP Control flag. */
   9764                      putDSPControl(IRExpr_ITE(unop(Iop_Not1,
   9765                                                    binop(Iop_CmpLE32S,
   9766                                                          mkexpr(t0),
   9767                                                          mkU32(0x7FFF))),
   9768                                               binop(Iop_Or32,
   9769                                                     getDSPControl(),
   9770                                                     mkU32(0x00200000)),
   9771                                               IRExpr_ITE(binop(Iop_CmpLT32S,
   9772                                                                mkexpr(t0),
   9773                                                                mkU32(0xFFFF8000)
   9774                                                               ),
   9775                                                          binop(Iop_Or32,
   9776                                                                getDSPControl(),
   9777                                                                mkU32(0x00200000)
   9778                                                               ),
   9779                                                          getDSPControl())));
   9780 
   9781                      /* t2 - signed intermediate result. */
   9782                      assign(t2, binop(Iop_Mul32,
   9783                                       unop(Iop_16Sto32,
   9784                                            unop(Iop_32to16, getIReg(rs))),
   9785                                       unop(Iop_16Sto32,
   9786                                            unop(Iop_32to16, getIReg(rt)))));
   9787 
   9788                      assign(t3, IRExpr_ITE(unop(Iop_Not1,
   9789                                                 binop(Iop_CmpLE32S,
   9790                                                       mkexpr(t2),
   9791                                                       mkU32(0x7FFF))),
   9792                                            mkU32(0x00007FFF),
   9793                                            IRExpr_ITE(binop(Iop_CmpLT32S,
   9794                                                             mkexpr(t2),
   9795                                                             mkU32(0xFFFF8000)),
   9796                                                       mkU32(0xFFFF8000),
   9797                                                       mkexpr(t2))));
   9798 
   9799                      /* DSP Control flag. */
   9800                      putDSPControl(IRExpr_ITE(unop(Iop_Not1,
   9801                                                    binop(Iop_CmpLE32S,
   9802                                                          mkexpr(t2),
   9803                                                          mkU32(0x7FFF))),
   9804                                               binop(Iop_Or32,
   9805                                                     getDSPControl(),
   9806                                                     mkU32(0x00200000)),
   9807                                               IRExpr_ITE(binop(Iop_CmpLT32S,
   9808                                                                mkexpr(t2),
   9809                                                                mkU32(0xFFFF8000)
   9810                                                               ),
   9811                                                          binop(Iop_Or32,
   9812                                                                getDSPControl(),
   9813                                                                mkU32(0x00200000)
   9814                                                               ),
   9815                                                          getDSPControl())));
   9816 
   9817                      assign(t4, binop(Iop_16HLto32,
   9818                                       unop(Iop_32to16, mkexpr(t1)),
   9819                                       unop(Iop_32to16, mkexpr(t3))));
   9820                      putIReg(rd, mkexpr(t4));
   9821                      break;
   9822                   }
   9823                   case 0x10: {  /* ADDQH.W */
   9824                      DIP("addqh.w r%d, r%d, r%d", rd, rs, rt);
   9825                      vassert(!mode64);
   9826                      t0 = newTemp(Ity_I64);
   9827                      t1 = newTemp(Ity_I64);
   9828 
   9829                      assign(t0, binop(Iop_Add64,
   9830                                       unop(Iop_32Sto64, getIReg(rs)),
   9831                                       unop(Iop_32Sto64, getIReg(rt))));
   9832                      assign(t1, binop(Iop_And64,
   9833                                       mkexpr(t0),
   9834                                       mkU64(0x00000001fffffffeULL)));
   9835                      putIReg(rd, unop(Iop_64to32,
   9836                                       binop(Iop_Shr64, mkexpr(t1), mkU8(0x1))));
   9837                      break;
   9838                   }
   9839                   case 0x11: {  /* SUBQH.W */
   9840                      DIP("subqh.w r%d, r%d, r%d", rd, rs, rt);
   9841                      vassert(!mode64);
   9842                      t0 = newTemp(Ity_I64);
   9843                      t1 = newTemp(Ity_I64);
   9844 
   9845                      assign(t0, binop(Iop_Sub64,
   9846                                       unop(Iop_32Sto64, getIReg(rs)),
   9847                                       unop(Iop_32Sto64, getIReg(rt))));
   9848                      assign(t1, binop(Iop_And64,
   9849                                       mkexpr(t0),
   9850                                       mkU64(0x00000001fffffffeULL)));
   9851                      putIReg(rd, unop(Iop_64to32,
   9852                                       binop(Iop_Shr64, mkexpr(t1), mkU8(0x1))));
   9853                      break;
   9854                   }
   9855                   case 0x12: {  /* ADDQH_R.W */
   9856                      DIP("addqh_r.w r%d, r%d, r%d", rd, rs, rt);
   9857                      vassert(!mode64);
   9858                      t0 = newTemp(Ity_I64);
   9859                      t1 = newTemp(Ity_I64);
   9860                      t2 = newTemp(Ity_I64);
   9861 
   9862                      assign(t0, binop(Iop_Add64,
   9863                                       unop(Iop_32Sto64, getIReg(rs)),
   9864                                       unop(Iop_32Sto64, getIReg(rt))));
   9865                      assign(t1, binop(Iop_Add64,
   9866                                       mkexpr(t0),
   9867                                       mkU64(0x0000000000000001ULL)));
   9868                      assign(t2, binop(Iop_And64,
   9869                                       mkexpr(t1),
   9870                                       mkU64(0x00000001fffffffeULL)));
   9871                      putIReg(rd, unop(Iop_64to32,
   9872                                       binop(Iop_Shr64, mkexpr(t2), mkU8(0x1))));
   9873                      break;
   9874                   }
   9875                   case 0x13: {  /* SUBQH_R.W */
   9876                      DIP("subqh_r.w r%d, r%d, r%d", rd, rs, rt);
   9877                      vassert(!mode64);
   9878                      t0 = newTemp(Ity_I64);
   9879                      t1 = newTemp(Ity_I64);
   9880                      t2 = newTemp(Ity_I64);
   9881 
   9882                      assign(t0, binop(Iop_Sub64,
   9883                                       unop(Iop_32Sto64, getIReg(rs)),
   9884                                       unop(Iop_32Sto64, getIReg(rt))));
   9885                      assign(t1, binop(Iop_Add64,
   9886                                       mkexpr(t0),
   9887                                       mkU64(0x0000000000000001ULL)));
   9888                      assign(t2, binop(Iop_And64,
   9889                                       mkexpr(t1),
   9890                                       mkU64(0x00000001fffffffeULL)));
   9891                      putIReg(rd, unop(Iop_64to32,
   9892                                       binop(Iop_Shr64, mkexpr(t2), mkU8(0x1))));
   9893                      break;
   9894                   }
   9895                   case 0x16: {  /* MULQ_S.W */
   9896                      DIP("mulq_s.w r%d, r%d, r%d", rd, rs, rt);
   9897                      vassert(!mode64);
   9898                      t0 = newTemp(Ity_I64);
   9899                      t1 = newTemp(Ity_I1);
   9900                      t2 = newTemp(Ity_I1);
   9901 
   9902                      assign(t0, binop(Iop_Shl64,
   9903                                       binop(Iop_MullS32,
   9904                                             getIReg(rt), getIReg(rs)),
   9905                                       mkU8(0x1)));
   9906                      assign(t1, binop(Iop_CmpEQ32,
   9907                                       getIReg(rt), mkU32(0x80000000)));
   9908                      assign(t2, binop(Iop_CmpEQ32,
   9909                                       getIReg(rs), mkU32(0x80000000)));
   9910 
   9911                      putDSPControl(IRExpr_ITE(mkexpr(t1),
   9912                                               IRExpr_ITE(mkexpr(t2),
   9913                                                          binop(Iop_Or32,
   9914                                                                getDSPControl(),
   9915                                                                mkU32(0x00200000)
   9916                                                               ),
   9917                                                          getDSPControl()),
   9918                                               getDSPControl()));
   9919                      putIReg(rd, IRExpr_ITE(mkexpr(t1),
   9920                                             IRExpr_ITE(mkexpr(t2),
   9921                                                        mkU32(0x7fffffff),
   9922                                                        unop(Iop_64HIto32,
   9923                                                             mkexpr(t0))),
   9924                                             unop(Iop_64HIto32, mkexpr(t0))));
   9925                      break;
   9926                   }
   9927                   case 0x17: {  /* MULQ_RS.W */
   9928                      DIP("mulq_rs.w r%d, r%d, r%d", rd, rs, rt);
   9929                      vassert(!mode64);
   9930                      t0 = newTemp(Ity_I64);
   9931                      t1 = newTemp(Ity_I1);
   9932                      t2 = newTemp(Ity_I1);
   9933 
   9934                      assign(t0, binop(Iop_Add64,
   9935                                       binop(Iop_Shl64,
   9936                                             binop(Iop_MullS32,
   9937                                                   getIReg(rt),
   9938                                                   getIReg(rs)),
   9939                                             mkU8(0x1)),
   9940                                       mkU64(0x0000000080000000ULL)));
   9941                      assign(t1,
   9942                             binop(Iop_CmpEQ32, getIReg(rt), mkU32(0x80000000)));
   9943                      assign(t2,
   9944                             binop(Iop_CmpEQ32, getIReg(rs), mkU32(0x80000000)));
   9945                      putDSPControl(IRExpr_ITE(mkexpr(t1),
   9946                                               IRExpr_ITE(mkexpr(t2),
   9947                                                          binop(Iop_Or32,
   9948                                                                getDSPControl(),
   9949                                                                mkU32(0x00200000)
   9950                                                               ),
   9951                                                          getDSPControl()),
   9952                                               getDSPControl()));
   9953                      putIReg(rd, IRExpr_ITE(mkexpr(t1),
   9954                                             IRExpr_ITE(mkexpr(t2),
   9955                                                        mkU32(0x7fffffff),
   9956                                                        unop(Iop_64HIto32,
   9957                                                             mkexpr(t0))),
   9958                                             unop(Iop_64HIto32, mkexpr(t0))));
   9959                      break;
   9960                   }
   9961                   default:
   9962                      return -1;
   9963                }
   9964                break;  /* end of ADDUH.QB/MUL.PH */
   9965             }
   9966             case 0x30: {  /* DPAQ.W.PH */
   9967                switch(sa) {
   9968                   case 0x0: {  /* DPA.W.PH */
   9969                      DIP("dpa.w.ph ac%d, r%d, r%d", ac, rs, rt);
   9970                      vassert(!mode64);
   9971 
   9972                      t0 = newTemp(Ity_I64);
   9973                      t1 = newTemp(Ity_I64);
   9974                      t2 = newTemp(Ity_I64);
   9975 
   9976                      assign(t0,
   9977                             unop(Iop_32Sto64,
   9978                                  binop(Iop_Mul32,
   9979                                        unop(Iop_16Sto32,
   9980                                             unop(Iop_32HIto16, getIReg(rs))),
   9981                                        unop(Iop_16Sto32,
   9982                                             unop(Iop_32HIto16, getIReg(rt))))));
   9983                      assign(t1,
   9984                             unop(Iop_32Sto64,
   9985                                  binop(Iop_Mul32,
   9986                                        unop(Iop_16Sto32,
   9987                                             unop(Iop_32to16, getIReg(rs))),
   9988                                        unop(Iop_16Sto32,
   9989                                             unop(Iop_32to16, getIReg(rt))))));
   9990                      assign(t2,
   9991                             binop(Iop_Add64,
   9992                                   getAcc(ac),
   9993                                   binop(Iop_Add64, mkexpr(t0), mkexpr(t1))));
   9994                      putAcc(ac, mkexpr(t2));
   9995                      break;
   9996                   }
   9997                   case 0x1: {  /* DPS.W.PH */
   9998                      DIP("dps.w.ph ac%d, r%d, r%d", ac, rs, rt);
   9999                      vassert(!mode64);
   10000 
   10001                      t0 = newTemp(Ity_I64);
   10002                      t1 = newTemp(Ity_I64);
   10003                      t2 = newTemp(Ity_I64);
   10004 
   10005                      assign(t0,
   10006                             unop(Iop_32Sto64,
   10007                                  binop(Iop_Mul32,
   10008                                        unop(Iop_16Sto32,
   10009                                             unop(Iop_32HIto16, getIReg(rs))),
   10010                                        unop(Iop_16Sto32,
   10011                                             unop(Iop_32HIto16, getIReg(rt))))));
   10012                      assign(t1,
   10013                             unop(Iop_32Sto64,
   10014                                  binop(Iop_Mul32,
   10015                                        unop(Iop_16Sto32,
   10016                                             unop(Iop_32to16, getIReg(rs))),
   10017                                        unop(Iop_16Sto32,
   10018                                             unop(Iop_32to16, getIReg(rt))))));
   10019                      assign(t2,
   10020                             binop(Iop_Sub64,
   10021                                   getAcc(ac),
   10022                                   binop(Iop_Add64, mkexpr(t0), mkexpr(t1))));
   10023                      putAcc(ac, mkexpr(t2));
   10024                      break;
   10025                   }
   10026                   case 0x2: {  /* MULSA.W.PH */
   10027                      DIP("mulsa.w.ph ac%d, r%d, r%d", ac, rs, rt);
   10028                      vassert(!mode64);
   10029                      t0 = newTemp(Ity_I32);
   10030                      t1 = newTemp(Ity_I32);
   10031                      t2 = newTemp(Ity_I32);
   10032                      t3 = newTemp(Ity_I1);
   10033                      t4 = newTemp(Ity_I64);
   10034 
   10035                      assign(t4, getAcc(ac));
   10036                      assign(t0, binop(Iop_Mul32,
   10037                                       unop(Iop_16Sto32,
   10038                                            unop(Iop_32to16, getIReg(rt))),
   10039                                       unop(Iop_16Sto32,
   10040                                            unop(Iop_32to16, getIReg(rs)))));
   10041                      assign(t1, binop(Iop_Mul32,
   10042                                       unop(Iop_16Sto32,
   10043                                            unop(Iop_32HIto16, getIReg(rt))),
   10044                                       unop(Iop_16Sto32,
   10045                                            unop(Iop_32HIto16, getIReg(rs)))));
   10046                      assign(t2, binop(Iop_Sub32, mkexpr(t1), mkexpr(t0)));
   10047                      putAcc(ac, binop(Iop_Add64,
   10048                                       mkexpr(t4),
   10049                                       unop(Iop_32Sto64, mkexpr(t2))));
   10050                      break;
   10051                   }
   10052                   case 0x3: {  /* DPAU.H.QBL */
   10053                      DIP("dpau.h.qbl ac%d, r%d, r%d", ac, rs, rt);
   10054                      vassert(!mode64);
   10055                      t0 = newTemp(Ity_I32);
   10056                      t1 = newTemp(Ity_I32);
   10057                      t2 = newTemp(Ity_I64);
   10058                      t3 = newTemp(Ity_I64);
   10059 
   10060                      assign(t0,
   10061                             binop(Iop_Mul32,
   10062                                   unop(Iop_8Uto32,
   10063                                        unop(Iop_16HIto8,
   10064                                             unop(Iop_32HIto16, getIReg(rs)))),
   10065                                   unop(Iop_8Uto32,
   10066                                        unop(Iop_16HIto8,
   10067                                             unop(Iop_32HIto16, getIReg(rt))))));
   10068                      assign(t1,
   10069                             binop(Iop_Mul32,
   10070                                   unop(Iop_8Uto32,
   10071                                        unop(Iop_16to8,
   10072                                             unop(Iop_32HIto16, getIReg(rs)))),
   10073                                   unop(Iop_8Uto32,
   10074                                        unop(Iop_16to8,
   10075                                             unop(Iop_32HIto16, getIReg(rt))))));
   10076                      assign(t2,
   10077                             unop(Iop_32Uto64,
   10078                                  binop(Iop_Add32,
   10079                                        mkexpr(t0),
   10080                                        mkexpr(t1))));
   10081                      assign(t3,
   10082                             binop(Iop_Add64, getAcc(ac), mkexpr(t2)));
   10083                      putAcc(ac, mkexpr(t3));
   10084                      break;
   10085                   }
   10086                   case 0x4: {  /* DPAQ_S.W.PH */
   10087                      DIP("dpaq_s.w.ph ac%d, r%d, r%d", ac, rs, rt);
   10088                      vassert(!mode64);
   10089                      t0 = newTemp(Ity_I64);
   10090                      t1 = newTemp(Ity_I64);
   10091                      t2 = newTemp(Ity_I1);
   10092                      t3 = newTemp(Ity_I1);
   10093                      t4 = newTemp(Ity_I64);
   10094                      t5 = newTemp(Ity_I64);
   10095                      t6 = newTemp(Ity_I1);
   10096                      t7 = newTemp(Ity_I1);
   10097                      t8 = newTemp(Ity_I64);
   10098                      t9 = newTemp(Ity_I64);
   10099 
   10100                      assign(t0, getAcc(ac));
   10101 
   10102                      assign(t1, binop(Iop_Shl64,
   10103                                       binop(Iop_MullS32,
   10104                                             unop(Iop_16Sto32,
   10105                                                  unop(Iop_32HIto16,
   10106                                                       getIReg(rs))),
   10107                                             unop(Iop_16Sto32,
   10108                                                  unop(Iop_32HIto16,
   10109                                                       getIReg(rt)))),
   10110                                       mkU8(0x1)));
   10111                      assign(t2, binop(Iop_CmpEQ32,
   10112                                       unop(Iop_16Uto32,
   10113                                            unop(Iop_32HIto16, getIReg(rs))),
   10114                                       mkU32(0x00008000)));
   10115                      assign(t3, binop(Iop_CmpEQ32,
   10116                                       unop(Iop_16Uto32,
   10117                                            unop(Iop_32HIto16, getIReg(rt))),
   10118                                       mkU32(0x00008000)));
   10119                      assign(t4,
   10120                             IRExpr_ITE(mkexpr(t2),
   10121                                        IRExpr_ITE(mkexpr(t3),
   10122                                                   mkU64(0x000000007fffffffULL),
   10123                                                   mkexpr(t1)),
   10124                                        mkexpr(t1)));
   10125 
   10126                      putDSPControl(IRExpr_ITE(mkexpr(t2),
   10127                                               IRExpr_ITE(mkexpr(t3),
   10128                                                          binop(Iop_Or32,
   10129                                                                getDSPControl(),
   10130                                                                binop(Iop_Shl32,
   10131                                                                      mkU32(0x1),
   10132                                                                      mkU8(ac+16)
   10133                                                                     )
   10134                                                               ),
   10135                                                          getDSPControl()),
   10136                                               getDSPControl()));
   10137 
   10138                      assign(t5, binop(Iop_Shl64,
   10139                                       binop(Iop_MullS32,
   10140                                             unop(Iop_16Sto32,
   10141                                                  unop(Iop_32to16, getIReg(rs))),
   10142                                             unop(Iop_16Sto32,
   10143                                                  unop(Iop_32to16, getIReg(rt)))
   10144                                            ),
   10145                                       mkU8(0x1)));
   10146                      assign(t6, binop(Iop_CmpEQ32,
   10147                                       unop(Iop_16Uto32,
   10148                                            unop(Iop_32to16, getIReg(rs))),
   10149                                       mkU32(0x00008000)));
   10150                      assign(t7, binop(Iop_CmpEQ32,
   10151                                       unop(Iop_16Uto32,
   10152                                            unop(Iop_32to16, getIReg(rt))),
   10153                                       mkU32(0x00008000)));
   10154                      assign(t8,
   10155                             IRExpr_ITE(mkexpr(t6),
   10156                                        IRExpr_ITE(mkexpr(t7),
   10157                                                   mkU64(0x000000007fffffffULL),
   10158                                                   mkexpr(t5)),
   10159                                        mkexpr(t5)));
   10160 
   10161                      putDSPControl(IRExpr_ITE(mkexpr(t6),
   10162                                               IRExpr_ITE(mkexpr(t7),
   10163                                                          binop(Iop_Or32,
   10164                                                                getDSPControl(),
   10165                                                                binop(Iop_Shl32,
   10166                                                                      mkU32(0x1),
   10167                                                                      mkU8(ac+16)
   10168                                                                     )
   10169                                                               ),
   10170                                                          getDSPControl()),
   10171                                               getDSPControl()));
   10172 
   10173                      assign(t9, binop(Iop_Add64,
   10174                                       binop(Iop_Add64, mkexpr(t4), mkexpr(t8)),
   10175                                       mkexpr(t0)));
   10176                      putAcc(ac, mkexpr(t9));
   10177                      break;
   10178                   }
   10179                   case 0x5: {  /* DPSQ_S.W.PH */
   10180                      DIP("dpsq_s.w.ph ac%d r%d, r%d", ac, rs, rt);
   10181                      vassert(!mode64);
   10182                      t0 = newTemp(Ity_I64);
   10183                      t1 = newTemp(Ity_I64);
   10184                      t2 = newTemp(Ity_I1);
   10185                      t3 = newTemp(Ity_I1);
   10186                      t4 = newTemp(Ity_I64);
   10187                      t5 = newTemp(Ity_I64);
   10188                      t6 = newTemp(Ity_I1);
   10189                      t7 = newTemp(Ity_I1);
   10190                      t8 = newTemp(Ity_I64);
   10191                      t9 = newTemp(Ity_I64);
   10192 
   10193                      assign(t0, getAcc(ac));
   10194 
   10195                      assign(t1, binop(Iop_Shl64,
   10196                                       binop(Iop_MullS32,
   10197                                             unop(Iop_16Sto32,
   10198                                                  unop(Iop_32HIto16,
   10199                                                       getIReg(rs))),
   10200                                             unop(Iop_16Sto32,
   10201                                                  unop(Iop_32HIto16,
   10202                                                       getIReg(rt)))),
   10203                                       mkU8(0x1)));
   10204                      assign(t2, binop(Iop_CmpEQ32,
   10205                                       unop(Iop_16Uto32,
   10206                                            unop(Iop_32HIto16, getIReg(rs))),
   10207                                       mkU32(0x00008000)));
   10208                      assign(t3, binop(Iop_CmpEQ32,
   10209                                       unop(Iop_16Uto32,
   10210                                            unop(Iop_32HIto16, getIReg(rt))),
   10211                                       mkU32(0x00008000)));
   10212                      assign(t4,
   10213                             IRExpr_ITE(mkexpr(t2),
   10214                                        IRExpr_ITE(mkexpr(t3),
   10215                                                   mkU64(0x000000007fffffffULL),
   10216                                                   mkexpr(t1)),
   10217                                        mkexpr(t1)));
   10218 
   10219                      putDSPControl(IRExpr_ITE(mkexpr(t2),
   10220                                               IRExpr_ITE(mkexpr(t3),
   10221                                                          binop(Iop_Or32,
   10222                                                                getDSPControl(),
   10223                                                                binop(Iop_Shl32,
   10224                                                                      mkU32(0x1),
   10225                                                                      mkU8(ac+16)
   10226                                                                     )
   10227                                                               ),
   10228                                                          getDSPControl()),
   10229                                               getDSPControl()));
   10230 
   10231                      assign(t5,
   10232                             binop(Iop_Shl64,
   10233                                   binop(Iop_MullS32,
   10234                                         unop(Iop_16Sto32,
   10235                                              unop(Iop_32to16, getIReg(rs))),
   10236                                         unop(Iop_16Sto32,
   10237                                              unop(Iop_32to16, getIReg(rt)))),
   10238                                   mkU8(0x1)));
   10239                      assign(t6, binop(Iop_CmpEQ32,
   10240                                       unop(Iop_16Uto32,
   10241                                            unop(Iop_32to16, getIReg(rs))),
   10242                                       mkU32(0x00008000)));
   10243                      assign(t7, binop(Iop_CmpEQ32,
   10244                                       unop(Iop_16Uto32,
   10245                                            unop(Iop_32to16, getIReg(rt))),
   10246                                       mkU32(0x00008000)));
   10247                      assign(t8,
   10248                             IRExpr_ITE(mkexpr(t6),
   10249                                        IRExpr_ITE(mkexpr(t7),
   10250                                                   mkU64(0x000000007fffffffULL),
   10251                                                   mkexpr(t5)),
   10252                                        mkexpr(t5)));
   10253 
   10254                      putDSPControl(IRExpr_ITE(mkexpr(t6),
   10255                                               IRExpr_ITE(mkexpr(t7),
   10256                                                          binop(Iop_Or32,
   10257                                                                getDSPControl(),
   10258                                                                binop(Iop_Shl32,
   10259                                                                      mkU32(0x1),
   10260                                                                      mkU8(ac+16)
   10261                                                                     )
   10262                                                               ),
   10263                                                          getDSPControl()),
   10264                                               getDSPControl()));
   10265 
   10266                      assign(t9,
   10267                             binop(Iop_Sub64,
   10268                                   mkexpr(t0),
   10269                                   binop(Iop_Add64, mkexpr(t4), mkexpr(t8))));
   10270                      putAcc(ac, mkexpr(t9));
   10271                      break;
   10272                   }
   10273                   case 0x6: {  /* MULSAQ_S.W.PH */
   10274                      DIP("mulsaq_s.w.ph ac%d r%d, r%d", ac, rs, rt);
   10275                      vassert(!mode64);
   10276 
   10277                      t0 = newTemp(Ity_I32);
   10278                      t1 = newTemp(Ity_I32);
   10279                      t2 = newTemp(Ity_I32);
   10280                      t3 = newTemp(Ity_I32);
   10281                      t4 = newTemp(Ity_I32);
   10282                      t5 = newTemp(Ity_I32);
   10283                      t6 = newTemp(Ity_I64);
   10284                      t7 = newTemp(Ity_I64);
   10285                      t8 = newTemp(Ity_I32);
   10286                      t9 = newTemp(Ity_I32);
   10287 
   10288                      assign(t0, unop(Iop_16Sto32,
   10289                                      unop(Iop_32HIto16, getIReg(rs))));
   10290                      assign(t1, unop(Iop_16Sto32,
   10291                                      unop(Iop_32HIto16, getIReg(rt))));
   10292 
   10293                      assign(t8, binop(Iop_And32,
   10294                                       unop(Iop_1Sto32,
   10295                                            binop(Iop_CmpEQ32,
   10296                                                  unop(Iop_16Uto32,
   10297                                                       unop(Iop_32HIto16,
   10298                                                            getIReg(rs))),
   10299                                                  mkU32(0x8000))),
   10300                                     unop(Iop_1Sto32,
   10301                                          binop(Iop_CmpEQ32,
   10302                                                unop(Iop_16Uto32,
   10303                                                     unop(Iop_32HIto16,
   10304                                                          getIReg(rt))),
   10305                                                mkU32(0x8000)))));
   10306                      /* DSPControl_outflag:16+acc <- 1 */
   10307                      putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32,
   10308                                                     mkexpr(t8),
   10309                                                     mkU32(0x0)),
   10310                                               binop(Iop_Or32,
   10311                                                     getDSPControl(),
   10312                                                     binop(Iop_Shl32,
   10313                                                           mkU32(0x00010000),
   10314                                                           mkU8(ac))),
   10315                                               getDSPControl()));
   10316 
   10317                      /* tempB_31..0 */
   10318                      assign(t2,
   10319                             IRExpr_ITE(binop(Iop_CmpNE32,
   10320                                              mkexpr(t8), mkU32(0x0)),
   10321                                        mkU32(0x7FFFFFFF),
   10322                                        binop(Iop_Shl32,
   10323                                              binop(Iop_Mul32,
   10324                                                    mkexpr(t0), mkexpr(t1)),
   10325                                              mkU8(1))));
   10326 
   10327                      assign(t3, unop(Iop_16Sto32,
   10328                                      unop(Iop_32to16, getIReg(rs))));
   10329                      assign(t4, unop(Iop_16Sto32,
   10330                                      unop(Iop_32to16, getIReg(rt))));
   10331 
   10332                      assign(t9, binop(Iop_And32,
   10333                                       unop(Iop_1Sto32,
   10334                                            binop(Iop_CmpEQ32,
   10335                                                  unop(Iop_16Uto32,
   10336                                                       unop(Iop_32to16,
   10337                                                            getIReg(rs))),
   10338                                                  mkU32(0x8000))),
   10339                                       unop(Iop_1Sto32,
   10340                                            binop(Iop_CmpEQ32,
   10341                                                  unop(Iop_16Uto32,
   10342                                                       unop(Iop_32to16,
   10343                                                            getIReg(rt))),
   10344                                                  mkU32(0x8000)))));
   10345                      /* DSPControl_outflag:16+acc <- 1 */
   10346                      putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32,
   10347                                                     mkexpr(t9),
   10348                                                     mkU32(0x0)),
   10349                                               binop(Iop_Or32,
   10350                                                     getDSPControl(),
   10351                                                     binop(Iop_Shl32,
   10352                                                           mkU32(0x00010000),
   10353                                                           mkU8(ac))),
   10354                                               getDSPControl()));
   10355                      /* tempA_31..0 */
   10356                      assign(t5,
   10357                             IRExpr_ITE(binop(Iop_CmpNE32,
   10358                                              mkexpr(t9),
   10359                                              mkU32(0x0)),
   10360                                        mkU32(0x7FFFFFFF),
   10361                                        binop(Iop_Shl32,
   10362                                              binop(Iop_Mul32,
   10363                                                    mkexpr(t3),
   10364                                                    mkexpr(t4)),
   10365                                              mkU8(1))));
   10366                      /* dotp_63..0 */
   10367                      assign(t6,
   10368                             binop(Iop_Sub64,
   10369                                   unop(Iop_32Sto64, mkexpr(t2)),
   10370                                   unop(Iop_32Sto64, mkexpr(t5))));
   10371                      /* tempC_63..0 */
   10372                      assign(t7, binop(Iop_Add64, getAcc(ac), mkexpr(t6)));
   10373 
   10374                      putAcc(ac, mkexpr(t7));
   10375                      break;
   10376                   }
   10377                   case 0x7: {  /* DPAU.H.QBR */
   10378                      DIP("dpau.h.qbr ac%d, r%d, r%d", ac, rs, rt);
   10379                      vassert(!mode64);
   10380                      t0 = newTemp(Ity_I32);
   10381                      t1 = newTemp(Ity_I32);
   10382                      t2 = newTemp(Ity_I64);
   10383                      t3 = newTemp(Ity_I64);
   10384 
   10385                      assign(t0,
   10386                             binop(Iop_Mul32,
   10387                                   unop(Iop_8Uto32,
   10388                                        unop(Iop_16HIto8,
   10389                                             unop(Iop_32to16, getIReg(rs)))),
   10390                                   unop(Iop_8Uto32,
   10391                                        unop(Iop_16HIto8,
   10392                                             unop(Iop_32to16, getIReg(rt))))));
   10393                      assign(t1,
   10394                             binop(Iop_Mul32,
   10395                                   unop(Iop_8Uto32,
   10396                                        unop(Iop_16to8,
   10397                                             unop(Iop_32to16, getIReg(rs)))),
   10398                                   unop(Iop_8Uto32,
   10399                                        unop(Iop_16to8,
   10400                                             unop(Iop_32to16, getIReg(rt))))));
   10401                      assign(t2, unop(Iop_32Uto64,
   10402                                      binop(Iop_Add32, mkexpr(t0), mkexpr(t1))));
   10403                      assign(t3, binop(Iop_Add64, getAcc(ac), mkexpr(t2)));
   10404                      putAcc(ac, mkexpr(t3));
   10405                      break;
   10406                   }
   10407                   case 0x8: {  /* DPAX.W.PH */
   10408                      DIP("dpax.w.ph ac%d, r%d, r%d", ac, rs, rt);
   10409                      vassert(!mode64);
   10410                      t0 = newTemp(Ity_I64);
   10411                      t1 = newTemp(Ity_I64);
   10412                      t2 = newTemp(Ity_I64);
   10413 
   10414                      assign(t0,
   10415                             unop(Iop_32Sto64,
   10416                                  binop(Iop_Mul32,
   10417                                        unop(Iop_16Sto32,
   10418                                             unop(Iop_32HIto16, getIReg(rs))),
   10419                                        unop(Iop_16Sto32,
   10420                                             unop(Iop_32to16, getIReg(rt))))));
   10421                      assign(t1,
   10422                             unop(Iop_32Sto64,
   10423                                  binop(Iop_Mul32,
   10424                                        unop(Iop_16Sto32,
   10425                                             unop(Iop_32to16, getIReg(rs))),
   10426                                        unop(Iop_16Sto32,
   10427                                             unop(Iop_32HIto16, getIReg(rt))))));
   10428                      assign(t2,
   10429                             binop(Iop_Add64,
   10430                                   getAcc(ac),
   10431                                   binop(Iop_Add64, mkexpr(t0), mkexpr(t1))));
   10432                      putAcc(ac, mkexpr(t2));
   10433                      break;
   10434                   }
   10435                   case 0x9: {  /* DPSX.W.PH */
   10436                      DIP("dpsx.w.ph ac%d r%d, r%d", ac, rs, rt);
   10437                      vassert(!mode64);
   10438 
   10439                      t0 = newTemp(Ity_I64);
   10440                      t1 = newTemp(Ity_I64);
   10441                      t2 = newTemp(Ity_I64);
   10442 
   10443                      assign(t0,
   10444                             unop(Iop_32Sto64,
   10445                                  binop(Iop_Mul32,
   10446                                        unop(Iop_16Sto32,
   10447                                             unop(Iop_32HIto16, getIReg(rs))),
   10448                                        unop(Iop_16Sto32,
   10449                                             unop(Iop_32to16, getIReg(rt))))));
   10450                      assign(t1,
   10451                             unop(Iop_32Sto64,
   10452                                  binop(Iop_Mul32,
   10453                                        unop(Iop_16Sto32,
   10454                                             unop(Iop_32to16, getIReg(rs))),
   10455                                        unop(Iop_16Sto32,
   10456                                             unop(Iop_32HIto16, getIReg(rt))))));
   10457                      assign(t2,
   10458                             binop(Iop_Sub64,
   10459                                   getAcc(ac),
   10460                                   binop(Iop_Add64, mkexpr(t0), mkexpr(t1))));
   10461                      putAcc(ac, mkexpr(t2));
   10462                      break;
   10463                   }
   10464                   case 0xB: {  /* DPSU.H.QBL */
   10465                      DIP("dpsu.h.qbl ac%d, r%d, r%d", ac, rs, rt);
   10466                      vassert(!mode64);
   10467 
   10468                      t0 = newTemp(Ity_I32);
   10469                      t1 = newTemp(Ity_I32);
   10470                      t2 = newTemp(Ity_I64);
   10471                      t3 = newTemp(Ity_I64);
   10472 
   10473                      assign(t0,
   10474                             binop(Iop_Mul32,
   10475                                   unop(Iop_8Uto32,
   10476                                        unop(Iop_16HIto8,
   10477                                             unop(Iop_32HIto16, getIReg(rs)))),
   10478                                   unop(Iop_8Uto32,
   10479                                        unop(Iop_16HIto8,
   10480                                             unop(Iop_32HIto16, getIReg(rt))))));
   10481                      assign(t1,
   10482                             binop(Iop_Mul32,
   10483                                   unop(Iop_8Uto32,
   10484                                        unop(Iop_16to8,
   10485                                             unop(Iop_32HIto16, getIReg(rs)))),
   10486                                   unop(Iop_8Uto32,
   10487                                        unop(Iop_16to8,
   10488                                             unop(Iop_32HIto16, getIReg(rt))))));
   10489                      assign(t2,
   10490                             unop(Iop_32Uto64,
   10491                                  binop(Iop_Add32, mkexpr(t0), mkexpr(t1))));
   10492                      assign(t3,
   10493                             binop(Iop_Sub64, getAcc(ac), mkexpr(t2)));
   10494                      putAcc(ac, mkexpr(t3));
   10495                      break;
   10496                   }
   10497                   case 0xC: {  /* DPAQ_SA.L.W */
   10498                      DIP("dpaq_sa.l.w ac%d, r%d, r%d", ac, rs, rt);
   10499                      vassert(!mode64);
   10500                      t0 = newTemp(Ity_I64);
   10501                      t1 = newTemp(Ity_I64);
   10502                      t2 = newTemp(Ity_I1);
   10503                      t3 = newTemp(Ity_I1);
   10504                      t4 = newTemp(Ity_I64);
   10505                      t5 = newTemp(Ity_I64);
   10506                      t6 = newTemp(Ity_I64);
   10507                      t7 = newTemp(Ity_I64);
   10508                      t8 = newTemp(Ity_I1);
   10509                      t9 = newTemp(Ity_I1);
   10510 
   10511                      assign(t0, getAcc(ac));
   10512 
   10513                      assign(t1, binop(Iop_Shl64,
   10514                                       binop(Iop_MullS32,
   10515                                             getIReg(rs), getIReg(rt)),
   10516                                       mkU8(0x1)));
   10517 
   10518                      assign(t2, binop(Iop_CmpEQ32,
   10519                                       getIReg(rs),
   10520                                       mkU32(0x80000000)));
   10521                      assign(t3, binop(Iop_CmpEQ32,
   10522                                       getIReg(rt),
   10523                                       mkU32(0x80000000)));
   10524 
   10525                      assign(t4,
   10526                             IRExpr_ITE(mkexpr(t2),
   10527                                        IRExpr_ITE(mkexpr(t3),
   10528                                                   mkU64(0x7fffffffffffffffULL),
   10529                                                   mkexpr(t1)),
   10530                                        mkexpr(t1)));
   10531 
   10532                      putDSPControl(IRExpr_ITE(mkexpr(t2),
   10533                                               IRExpr_ITE(mkexpr(t3),
   10534                                                          binop(Iop_Or32,
   10535                                                                getDSPControl(),
   10536                                                                binop(Iop_Shl32,
   10537                                                                      mkU32(0x1),
   10538                                                                      mkU8(ac+16)
   10539                                                                     )
   10540                                                               ),
   10541                                                          getDSPControl()),
   10542                                               getDSPControl()));
   10543 
   10544                      assign(t5, binop(Iop_Add64,
   10545                                       unop(Iop_32Uto64,
   10546                                            unop(Iop_64to32, mkexpr(t0))),
   10547                                       unop(Iop_32Uto64,
   10548                                            unop(Iop_64to32, mkexpr(t4)))));
   10549                      assign(t6,
   10550                             binop(Iop_Add64,
   10551                                   binop(Iop_Add64,
   10552                                         unop(Iop_32Sto64,
   10553                                              unop(Iop_64HIto32, mkexpr(t0))),
   10554                                         unop(Iop_32Sto64,
   10555                                              unop(Iop_64HIto32, mkexpr(t4)))),
   10556                                   unop(Iop_32Uto64,
   10557                                        binop(Iop_And32,
   10558                                              unop(Iop_64HIto32, mkexpr(t5)),
   10559                                              mkU32(0x1)))));
   10560                      assign(t7, binop(Iop_32HLto64,
   10561                                       unop(Iop_64to32, mkexpr(t6)),
   10562                                       unop(Iop_64to32, mkexpr(t5))));
   10563                      assign(t8, binop(Iop_CmpEQ32,
   10564                                       binop(Iop_Shr32,
   10565                                             binop(Iop_And32,
   10566                                                   unop(Iop_64to32, mkexpr(t6)),
   10567                                                   mkU32(0x80000000)),
   10568                                             mkU8(31)),
   10569                                       binop(Iop_And32,
   10570                                             unop(Iop_64HIto32, mkexpr(t6)),
   10571                                             mkU32(0x00000001))));
   10572                      assign(t9, binop(Iop_CmpEQ32,
   10573                                       binop(Iop_And32,
   10574                                             unop(Iop_64HIto32,
   10575                                                  mkexpr(t6)),
   10576                                             mkU32(0x00000001)),
   10577                                       mkU32(0x1)));
   10578                      putDSPControl(IRExpr_ITE(mkexpr(t8),
   10579                                               getDSPControl(),
   10580                                               binop(Iop_Or32,
   10581                                                     getDSPControl(),
   10582                                                     binop(Iop_Shl32,
   10583                                                           mkU32(0x1),
   10584                                                           mkU8(ac+16)))));
   10585                      putAcc(ac,
   10586                             IRExpr_ITE(mkexpr(t8),
   10587                                        mkexpr(t7),
   10588                                        IRExpr_ITE(mkexpr(t9),
   10589                                                   mkU64(0x8000000000000000ULL),
   10590                                                   mkU64(0x7fffffffffffffffULL)))
   10591                            );
   10592                      break;
   10593                   }
   10594                   case 0xD: {  /* DPSQ_SA.L.W */
   10595                      DIP("dpsq_sa.l.w ac%d, r%d, r%d", ac, rs, rt);
   10596                      vassert(!mode64);
   10597                      t0 = newTemp(Ity_I64);
   10598                      t1 = newTemp(Ity_I64);
   10599                      t2 = newTemp(Ity_I1);
   10600                      t3 = newTemp(Ity_I1);
   10601                      t4 = newTemp(Ity_I64);
   10602                      t5 = newTemp(Ity_I64);
   10603                      t6 = newTemp(Ity_I64);
   10604                      t7 = newTemp(Ity_I64);
   10605                      t8 = newTemp(Ity_I1);
   10606                      t9 = newTemp(Ity_I1);
   10607 
   10608                      assign(t0, getAcc(ac));
   10609 
   10610                      assign(t1, binop(Iop_Shl64,
   10611                                       binop(Iop_MullS32,
   10612                                             getIReg(rs), getIReg(rt)),
   10613                                       mkU8(0x1)));
   10614 
   10615                      assign(t2, binop(Iop_CmpEQ32,
   10616                                       getIReg(rs),
   10617                                       mkU32(0x80000000)));
   10618                      assign(t3, binop(Iop_CmpEQ32,
   10619                                       getIReg(rt),
   10620                                       mkU32(0x80000000)));
   10621 
   10622                      assign(t4,
   10623                             IRExpr_ITE(mkexpr(t2),
   10624                                        IRExpr_ITE(mkexpr(t3),
   10625                                                   mkU64(0x7fffffffffffffffULL),
   10626                                                   mkexpr(t1)),
   10627                                        mkexpr(t1)));
   10628 
   10629                      putDSPControl(IRExpr_ITE(mkexpr(t2),
   10630                                               IRExpr_ITE(mkexpr(t3),
   10631                                                          binop(Iop_Or32,
   10632                                                                getDSPControl(),
   10633                                                                binop(Iop_Shl32,
   10634                                                                      mkU32(0x1),
   10635                                                                      mkU8(ac+16)
   10636                                                                     )
   10637                                                               ),
   10638                                                          getDSPControl()),
   10639                                               getDSPControl()));
   10640 
   10641                      assign(t5, binop(Iop_Sub64,
   10642                                       unop(Iop_32Uto64,
   10643                                            unop(Iop_64to32, mkexpr(t0))),
   10644                                       unop(Iop_32Uto64,
   10645                                            unop(Iop_64to32, mkexpr(t4)))));
   10646                      assign(t6, binop(Iop_Sub64,
   10647                                       binop(Iop_Add64,
   10648                                             unop(Iop_32Sto64,
   10649                                                  unop(Iop_64HIto32, mkexpr(t0))
   10650                                                 ),
   10651                                             unop(Iop_32Sto64,
   10652                                                  unop(Iop_1Sto32,
   10653                                                       binop(Iop_CmpLT32U,
   10654                                                             unop(Iop_64to32,
   10655                                                                  mkexpr(t0)),
   10656                                                             unop(Iop_64to32,
   10657                                                                 mkexpr(t4)))))),
   10658                                       unop(Iop_32Sto64,
   10659                                            unop(Iop_64HIto32, mkexpr(t4)))));
   10660                      assign(t7, binop(Iop_32HLto64,
   10661                                       unop(Iop_64to32, mkexpr(t6)),
   10662                                       unop(Iop_64to32, mkexpr(t5))));
   10663                      assign(t8, binop(Iop_CmpEQ32,
   10664                                       binop(Iop_Shr32,
   10665                                             binop(Iop_And32,
   10666                                                   unop(Iop_64to32, mkexpr(t6)),
   10667                                                   mkU32(0x80000000)),
   10668                                             mkU8(31)),
   10669                                       binop(Iop_And32,
   10670                                             unop(Iop_64HIto32, mkexpr(t6)),
   10671                                             mkU32(0x00000001))));
   10672                      assign(t9, binop(Iop_CmpEQ32,
   10673                                       binop(Iop_And32,
   10674                                             unop(Iop_64HIto32, mkexpr(t6)),
   10675                                             mkU32(0x00000001)),
   10676                                       mkU32(0x1)));
   10677                      putDSPControl(IRExpr_ITE(mkexpr(t8),
   10678                                               getDSPControl(),
   10679                                               binop(Iop_Or32,
   10680                                                     getDSPControl(),
   10681                                                     binop(Iop_Shl32,
   10682                                                           mkU32(0x1),
   10683                                                           mkU8(ac+16)))));
   10684                      putAcc(ac,
   10685                             IRExpr_ITE(mkexpr(t8),
   10686                                        mkexpr(t7),
   10687                                        IRExpr_ITE(mkexpr(t9),
   10688                                                   mkU64(0x8000000000000000ULL),
   10689                                                   mkU64(0x7fffffffffffffffULL)))
   10690                            );
   10691                      break;
   10692                   }
   10693                   case 0xF: {  /* DPSU.H.QBR */
   10694                      DIP("dpsu.h.qbr ac%d r%d, r%d", ac, rs, rt);
   10695                      vassert(!mode64);
   10696 
   10697                      t0 = newTemp(Ity_I32);
   10698                      t1 = newTemp(Ity_I32);
   10699                      t2 = newTemp(Ity_I64);
   10700                      t3 = newTemp(Ity_I64);
   10701 
   10702                      assign(t0,
   10703                             binop(Iop_Mul32,
   10704                                   unop(Iop_8Uto32,
   10705                                        unop(Iop_16HIto8,
   10706                                             unop(Iop_32to16, getIReg(rs)))),
   10707                                   unop(Iop_8Uto32,
   10708                                        unop(Iop_16HIto8,
   10709                                             unop(Iop_32to16, getIReg(rt))))));
   10710                      assign(t1,
   10711                             binop(Iop_Mul32,
   10712                                   unop(Iop_8Uto32,
   10713                                        unop(Iop_16to8,
   10714                                             unop(Iop_32to16, getIReg(rs)))),
   10715                                   unop(Iop_8Uto32,
   10716                                        unop(Iop_16to8,
   10717                                             unop(Iop_32to16, getIReg(rt))))));
   10718                      assign(t2, unop(Iop_32Uto64,
   10719                                      binop(Iop_Add32, mkexpr(t0), mkexpr(t1))));
   10720                      assign(t3, binop(Iop_Sub64, getAcc(ac), mkexpr(t2)));
   10721                      putAcc(ac, mkexpr(t3));
   10722 
   10723                      break;
   10724                   }
   10725                   case 0x10: {  /* MAQ_SA.W.PHL */
   10726                      DIP("maq_sa.w.phl ac%d, r%d, r%d", ac, rs, rt);
   10727                      vassert(!mode64);
   10728                      t0 = newTemp(Ity_I64);
   10729                      t1 = newTemp(Ity_I64);
   10730                      t2 = newTemp(Ity_I1);
   10731                      t3 = newTemp(Ity_I1);
   10732                      t4 = newTemp(Ity_I64);
   10733                      t5 = newTemp(Ity_I64);
   10734                      t6 = newTemp(Ity_I1);
   10735                      t7 = newTemp(Ity_I64);
   10736 
   10737                      assign(t0, getAcc(ac));
   10738                      assign(t1, unop(Iop_32Sto64,
   10739                                      binop(Iop_Shl32,
   10740                                            binop(Iop_Mul32,
   10741                                                  unop(Iop_16Sto32,
   10742                                                       unop(Iop_32HIto16,
   10743                                                            getIReg(rs))),
   10744                                                  unop(Iop_16Sto32,
   10745                                                       unop(Iop_32HIto16,
   10746                                                            getIReg(rt)))),
   10747                                            mkU8(0x1))));
   10748 
   10749                      /* If both input arguments are equal 0x8000, saturate
   10750                         intermediate product and write to DSPControl register.
   10751                      */
   10752                      assign(t2, binop(Iop_CmpEQ32,
   10753                                       unop(Iop_16Uto32,
   10754                                            unop(Iop_32HIto16, getIReg(rs))),
   10755                                       mkU32(0x00008000)));
   10756                      assign(t3, binop(Iop_CmpEQ32,
   10757                                       unop(Iop_16Uto32,
   10758                                            unop(Iop_32HIto16, getIReg(rt))),
   10759                                       mkU32(0x00008000)));
   10760 
   10761                      assign(t4,
   10762                             IRExpr_ITE(mkexpr(t2),
   10763                                        IRExpr_ITE(mkexpr(t3),
   10764                                                   mkU64(0x000000007fffffffULL),
   10765                                                   mkexpr(t1)),
   10766                                        mkexpr(t1)));
   10767 
   10768                      putDSPControl(IRExpr_ITE(mkexpr(t2),
   10769                                               IRExpr_ITE(mkexpr(t3),
   10770                                                          binop(Iop_Or32,
   10771                                                                getDSPControl(),
   10772                                                                binop(Iop_Shl32,
   10773                                                                      mkU32(0x1),
   10774                                                                      mkU8(ac+16)
   10775                                                                     )
   10776                                                               ),
   10777                                                          getDSPControl()),
   10778                                               getDSPControl()));
   10779                      /* Add intermediate product and value in the
   10780                         accumulator. */
   10781                      assign(t5, binop(Iop_Add64, mkexpr(t0), mkexpr(t4)));
   10782 
   10783                      /* Compare bits 31 and 32 of the value in t5. */
   10784                      assign(t6, binop(Iop_CmpEQ32,
   10785                                       binop(Iop_Shr32,
   10786                                             binop(Iop_And32,
   10787                                                   unop(Iop_64to32, mkexpr(t5)),
   10788                                                   mkU32(0x80000000)),
   10789                                             mkU8(31)),
   10790                                       binop(Iop_And32,
   10791                                             unop(Iop_64HIto32, mkexpr(t5)),
   10792                                             mkU32(1))));
   10793                      putDSPControl(IRExpr_ITE(mkexpr(t6),
   10794                                               getDSPControl(),
   10795                                               binop(Iop_Or32,
   10796                                                     getDSPControl(),
   10797                                                     binop(Iop_Shl32,
   10798                                                           mkU32(0x1),
   10799                                                           mkU8(ac+16)))));
   10800                      assign(t7,
   10801                             IRExpr_ITE(mkexpr(t6),
   10802                                        mkexpr(t5),
   10803                                        IRExpr_ITE(binop(Iop_CmpEQ32,
   10804                                                         binop(Iop_And32,
   10805                                                               unop(Iop_64HIto32,
   10806                                                                    mkexpr(t5)),
   10807                                                               mkU32(1)),
   10808                                                         mkU32(0x0)),
   10809                                                   mkU64(0x000000007fffffffULL),
   10810                                                   mkU64(0xffffffff80000000ULL)))
   10811                            );
   10812                      putAcc(ac, mkexpr(t7));
   10813                      break;
   10814                   }
   10815                   case 0x12: {  /* MAQ_SA.W.PHR */
   10816                      DIP("maq_sa.w.phr ac%d, r%d, r%d", ac, rs, rt);
   10817                      vassert(!mode64);
   10818                      t0 = newTemp(Ity_I64);
   10819                      t1 = newTemp(Ity_I64);
   10820                      t2 = newTemp(Ity_I1);
   10821                      t3 = newTemp(Ity_I1);
   10822                      t4 = newTemp(Ity_I64);
   10823                      t5 = newTemp(Ity_I64);
   10824                      t6 = newTemp(Ity_I1);
   10825                      t7 = newTemp(Ity_I64);
   10826 
   10827                      assign(t0, getAcc(ac));
   10828                      assign(t1, unop(Iop_32Sto64,
   10829                                      binop(Iop_Shl32,
   10830                                            binop(Iop_Mul32,
   10831                                                  unop(Iop_16Sto32,
   10832                                                       unop(Iop_32to16,
   10833                                                            getIReg(rs))),
   10834                                                  unop(Iop_16Sto32,
   10835                                                       unop(Iop_32to16,
   10836                                                            getIReg(rt)))),
   10837                                            mkU8(0x1))));
   10838 
   10839                      /* If both input arguments are equal 0x8000, saturate
   10840                         intermediate product and write to DSPControl
   10841                         register. */
   10842                      assign(t2, binop(Iop_CmpEQ32,
   10843                                       unop(Iop_16Uto32,
   10844                                            unop(Iop_32to16, getIReg(rs))),
   10845                                       mkU32(0x00008000)));
   10846                      assign(t3, binop(Iop_CmpEQ32,
   10847                                       unop(Iop_16Uto32,
   10848                                            unop(Iop_32to16, getIReg(rt))),
   10849                                       mkU32(0x00008000)));
   10850 
   10851                      assign(t4,
   10852                             IRExpr_ITE(mkexpr(t2),
   10853                                        IRExpr_ITE(mkexpr(t3),
   10854                                                   mkU64(0x000000007fffffffULL),
   10855                                                   mkexpr(t1)),
   10856                                        mkexpr(t1)));
   10857 
   10858                      putDSPControl(IRExpr_ITE(mkexpr(t2),
   10859                                               IRExpr_ITE(mkexpr(t3),
   10860                                                          binop(Iop_Or32,
   10861                                                                getDSPControl(),
   10862                                                                binop(Iop_Shl32,
   10863                                                                      mkU32(0x1),
   10864                                                                      mkU8(ac+16)
   10865                                                                     )
   10866                                                               ),
   10867                                                          getDSPControl()),
   10868                                               getDSPControl()));
   10869                      /* Add intermediate product and value in the
   10870                         accumulator. */
   10871                      assign(t5, binop(Iop_Add64, mkexpr(t0), mkexpr(t4)));
   10872 
   10873                      /* Compare bits 31 and 32 of the value in t5. */
   10874                      assign(t6, binop(Iop_CmpEQ32,
   10875                                       binop(Iop_Shr32,
   10876                                             binop(Iop_And32,
   10877                                                   unop(Iop_64to32, mkexpr(t5)),
   10878                                                   mkU32(0x80000000)),
   10879                                             mkU8(31)),
   10880                                       binop(Iop_And32,
   10881                                             unop(Iop_64HIto32, mkexpr(t5)),
   10882                                             mkU32(1))));
   10883                      putDSPControl(IRExpr_ITE(mkexpr(t6),
   10884                                               getDSPControl(),
   10885                                               binop(Iop_Or32,
   10886                                                     getDSPControl(),
   10887                                                     binop(Iop_Shl32,
   10888                                                           mkU32(0x1),
   10889                                                           mkU8(ac+16)))));
   10890                      assign(t7,
   10891                             IRExpr_ITE(mkexpr(t6),
   10892                                        mkexpr(t5),
   10893                                        IRExpr_ITE(binop(Iop_CmpEQ32,
   10894                                                         binop(Iop_And32,
   10895                                                               unop(Iop_64HIto32,
   10896                                                                    mkexpr(t5)),
   10897                                                               mkU32(1)),
   10898                                                         mkU32(0x0)),
   10899                                                   mkU64(0x000000007fffffffULL),
   10900                                                   mkU64(0xffffffff80000000ULL)))
   10901                            );
   10902                      putAcc(ac, mkexpr(t7));
   10903                      break;
   10904                   }
   10905                   case 0x14: {  /* MAQ_S.W.PHL */
   10906                      DIP("maq_s.w.phl ac%d, r%d, r%d", ac, rs, rt);
   10907                      vassert(!mode64);
   10908                      t0 = newTemp(Ity_I32);
   10909                      t1 = newTemp(Ity_I32);
   10910                      t2 = newTemp(Ity_I32);
   10911                      t3 = newTemp(Ity_I1);
   10912                      t4 = newTemp(Ity_I32);
   10913                      t5 = newTemp(Ity_I64);
   10914 
   10915                      assign(t5, getAcc(ac));
   10916 
   10917                      assign(t0, unop(Iop_16Sto32,
   10918                                      unop(Iop_32HIto16, getIReg(rs))));
   10919                      assign(t1, unop(Iop_16Sto32,
   10920                                      unop(Iop_32HIto16, getIReg(rt))));
   10921 
   10922                      assign(t2, binop(Iop_And32,
   10923                                       unop(Iop_1Sto32,
   10924                                            binop(Iop_CmpEQ32,
   10925                                                  binop(Iop_And32,
   10926                                                        mkexpr(t0),
   10927                                                        mkU32(0xffff)),
   10928                                                  mkU32(0x8000))),
   10929                                       unop(Iop_1Sto32,
   10930                                            binop(Iop_CmpEQ32,
   10931                                                  binop(Iop_And32,
   10932                                                        mkexpr(t1),
   10933                                                        mkU32(0xffff)),
   10934                                                  mkU32(0x8000)))));
   10935 
   10936                      assign(t3, binop(Iop_CmpEQ32, mkexpr(t2), mkU32(0x0)));
   10937 
   10938                      putDSPControl(IRExpr_ITE(mkexpr(t3),
   10939                                               getDSPControl(),
   10940                                               binop(Iop_Or32,
   10941                                                     getDSPControl(),
   10942                                                     binop(Iop_Shl32,
   10943                                                           mkU32(0x1),
   10944                                                           mkU8(ac+16)))));
   10945 
   10946                      assign(t4, unop(Iop_64to32,
   10947                                      binop(Iop_MullS32,
   10948                                            mkexpr(t0), mkexpr(t1))));
   10949                      putAcc(ac, IRExpr_ITE(mkexpr(t3),
   10950                                            binop(Iop_Add64,
   10951                                                  unop(Iop_32Sto64,
   10952                                                       binop(Iop_Shl32,
   10953                                                             mkexpr(t4),
   10954                                                             mkU8(0x1))),
   10955                                                  mkexpr(t5)),
   10956                                            binop(Iop_Add64,
   10957                                                  mkexpr(t5),
   10958                                                  unop(Iop_32Sto64,
   10959                                                       mkU32(0x7fffffff)))));
   10960                      break;
   10961                   }
   10962                   case 0x16: {  /* MAQ_S.W.PHR */
   10963                      DIP("maq_s.w.phr ac%d, r%d, r%d", ac, rs, rt);
   10964                      vassert(!mode64);
   10965                      t0 = newTemp(Ity_I32);
   10966                      t1 = newTemp(Ity_I32);
   10967                      t2 = newTemp(Ity_I32);
   10968                      t3 = newTemp(Ity_I1);
   10969                      t4 = newTemp(Ity_I32);
   10970                      t5 = newTemp(Ity_I64);
   10971 
   10972                      assign(t5, getAcc(ac));
   10973 
   10974                      assign(t0, unop(Iop_16Sto32,
   10975                                      unop(Iop_32to16, getIReg(rs))));
   10976                      assign(t1, unop(Iop_16Sto32,
   10977                                      unop(Iop_32to16, getIReg(rt))));
   10978 
   10979                      assign(t2, binop(Iop_And32,
   10980                                       unop(Iop_1Sto32,
   10981                                            binop(Iop_CmpEQ32,
   10982                                                  binop(Iop_And32,
   10983                                                        mkexpr(t0),
   10984                                                        mkU32(0xffff)),
   10985                                                  mkU32(0x8000))),
   10986                                       unop(Iop_1Sto32,
   10987                                            binop(Iop_CmpEQ32,
   10988                                                  binop(Iop_And32,
   10989                                                        mkexpr(t1),
   10990                                                        mkU32(0xffff)),
   10991                                                  mkU32(0x8000)))));
   10992 
   10993                      assign(t3, binop(Iop_CmpEQ32, mkexpr(t2), mkU32(0x0)));
   10994 
   10995                      putDSPControl(IRExpr_ITE(mkexpr(t3),
   10996                                               getDSPControl(),
   10997                                               binop(Iop_Or32,
   10998                                                     getDSPControl(),
   10999                                                     binop(Iop_Shl32,
   11000                                                           mkU32(0x1),
   11001                                                           mkU8(ac+16)))));
   11002 
   11003                      assign(t4, unop(Iop_64to32,
   11004                                      binop(Iop_MullS32,
   11005                                            mkexpr(t0), mkexpr(t1))));
   11006                      putAcc(ac, IRExpr_ITE(mkexpr(t3),
   11007                                            binop(Iop_Add64,
   11008                                                  unop(Iop_32Sto64,
   11009                                                       binop(Iop_Shl32,
   11010                                                             mkexpr(t4),
   11011                                                             mkU8(0x1))),
   11012                                                  mkexpr(t5)),
   11013                                            binop(Iop_Add64,
   11014                                                  mkexpr(t5),
   11015                                                  unop(Iop_32Sto64,
   11016                                                       mkU32(0x7fffffff)))));
   11017                      break;
   11018                   }
   11019                   case 0x18: {  /* DPAQX_S.W.PH */
   11020                      DIP("dpaqx_s.w.ph ac%d, r%d, r%d", ac, rs, rt);
   11021                      vassert(!mode64);
   11022                      t0 = newTemp(Ity_I64);
   11023                      t1 = newTemp(Ity_I64);
   11024                      t2 = newTemp(Ity_I1);
   11025                      t3 = newTemp(Ity_I1);
   11026                      t4 = newTemp(Ity_I64);
   11027                      t5 = newTemp(Ity_I64);
   11028                      t6 = newTemp(Ity_I1);
   11029                      t7 = newTemp(Ity_I1);
   11030                      t8 = newTemp(Ity_I64);
   11031                      t9 = newTemp(Ity_I64);
   11032 
   11033                      assign(t0, getAcc(ac));
   11034 
   11035                      assign(t1, binop(Iop_Shl64,
   11036                                       binop(Iop_MullS32,
   11037                                             unop(Iop_16Sto32,
   11038                                                  unop(Iop_32HIto16,
   11039                                                       getIReg(rs))),
   11040                                             unop(Iop_16Sto32,
   11041                                                  unop(Iop_32to16,
   11042                                                       getIReg(rt)))),
   11043                                       mkU8(0x1)));
   11044                      assign(t2, binop(Iop_CmpEQ32,
   11045                                       unop(Iop_16Uto32,
   11046                                            unop(Iop_32HIto16, getIReg(rs))),
   11047                                       mkU32(0x00008000)));
   11048                      assign(t3, binop(Iop_CmpEQ32,
   11049                                       unop(Iop_16Uto32,
   11050                                            unop(Iop_32to16, getIReg(rt))),
   11051                                       mkU32(0x00008000)));
   11052                      assign(t4,
   11053                             IRExpr_ITE(mkexpr(t2),
   11054                                        IRExpr_ITE(mkexpr(t3),
   11055                                                   mkU64(0x000000007fffffffULL),
   11056                                                   mkexpr(t1)),
   11057                                        mkexpr(t1)));
   11058 
   11059                      putDSPControl(IRExpr_ITE(mkexpr(t2),
   11060                                               IRExpr_ITE(mkexpr(t3),
   11061                                                          binop(Iop_Or32,
   11062                                                                getDSPControl(),
   11063                                                                binop(Iop_Shl32,
   11064                                                                   mkU32(0x1),
   11065                                                                   mkU8(ac+16))),
   11066                                                          getDSPControl()),
   11067                                               getDSPControl()));
   11068 
   11069                      assign(t5, binop(Iop_Shl64,
   11070                                       binop(Iop_MullS32,
   11071                                             unop(Iop_16Sto32,
   11072                                                  unop(Iop_32to16,
   11073                                                       getIReg(rs))),
   11074                                             unop(Iop_16Sto32,
   11075                                                  unop(Iop_32HIto16,
   11076                                                       getIReg(rt)))),
   11077                                       mkU8(0x1)));
   11078                      assign(t6, binop(Iop_CmpEQ32,
   11079                                       unop(Iop_16Uto32,
   11080                                            unop(Iop_32to16, getIReg(rs))),
   11081                                       mkU32(0x00008000)));
   11082                      assign(t7, binop(Iop_CmpEQ32,
   11083                                       unop(Iop_16Uto32,
   11084                                            unop(Iop_32HIto16, getIReg(rt))),
   11085                                       mkU32(0x00008000)));
   11086                      assign(t8,
   11087                             IRExpr_ITE(mkexpr(t6),
   11088                                        IRExpr_ITE(mkexpr(t7),
   11089                                                   mkU64(0x000000007fffffffULL),
   11090                                                   mkexpr(t5)),
   11091                                        mkexpr(t5)));
   11092 
   11093                      putDSPControl(IRExpr_ITE(mkexpr(t6),
   11094                                               IRExpr_ITE(mkexpr(t7),
   11095                                                          binop(Iop_Or32,
   11096                                                                getDSPControl(),
   11097                                                                binop(Iop_Shl32,
   11098                                                                      mkU32(0x1),
   11099                                                                      mkU8(ac+16)
   11100                                                                     )
   11101                                                               ),
   11102                                                          getDSPControl()),
   11103                                               getDSPControl()));
   11104 
   11105                      assign(t9, binop(Iop_Add64,
   11106                                       binop(Iop_Add64, mkexpr(t4), mkexpr(t8)),
   11107                                       mkexpr(t0)));
   11108                      putAcc(ac, mkexpr(t9));
   11109                      break;
   11110                   }
   11111                   case 0x19: {  /* DPSQX_S.W.PH */
   11112                      DIP("dpsqx_s.w.ph ac%d, r%d, r%d", ac, rs, rt);
   11113                      vassert(!mode64);
   11114                      t0 = newTemp(Ity_I64);
   11115                      t1 = newTemp(Ity_I64);
   11116                      t2 = newTemp(Ity_I1);
   11117                      t3 = newTemp(Ity_I1);
   11118                      t4 = newTemp(Ity_I64);
   11119                      t5 = newTemp(Ity_I64);
   11120                      t6 = newTemp(Ity_I1);
   11121                      t7 = newTemp(Ity_I1);
   11122                      t8 = newTemp(Ity_I64);
   11123                      t9 = newTemp(Ity_I64);
   11124 
   11125                      assign(t0, getAcc(ac));
   11126 
   11127                      assign(t1, binop(Iop_Shl64,
   11128                                       binop(Iop_MullS32,
   11129                                             unop(Iop_16Sto32,
   11130                                                  unop(Iop_32HIto16,
   11131                                                       getIReg(rs))),
   11132                                             unop(Iop_16Sto32,
   11133                                                  unop(Iop_32to16,
   11134                                                       getIReg(rt)))),
   11135                                       mkU8(0x1)));
   11136                      assign(t2, binop(Iop_CmpEQ32,
   11137                                       unop(Iop_16Uto32,
   11138                                            unop(Iop_32HIto16, getIReg(rs))),
   11139                                       mkU32(0x00008000)));
   11140                      assign(t3, binop(Iop_CmpEQ32,
   11141                                       unop(Iop_16Uto32,
   11142                                            unop(Iop_32to16, getIReg(rt))),
   11143                                       mkU32(0x00008000)));
   11144                      assign(t4,
   11145                             IRExpr_ITE(mkexpr(t2),
   11146                                        IRExpr_ITE(mkexpr(t3),
   11147                                                   mkU64(0x000000007fffffffULL),
   11148                                                   mkexpr(t1)),
   11149                                        mkexpr(t1)));
   11150 
   11151                      putDSPControl(IRExpr_ITE(mkexpr(t2),
   11152                                               IRExpr_ITE(mkexpr(t3),
   11153                                                          binop(Iop_Or32,
   11154                                                                getDSPControl(),
   11155                                                                binop(Iop_Shl32,
   11156                                                                      mkU32(0x1),
   11157                                                                      mkU8(ac+16)
   11158                                                                     )
   11159                                                               ),
   11160                                                          getDSPControl()),
   11161                                               getDSPControl()));
   11162 
   11163                      assign(t5, binop(Iop_Shl64,
   11164                                       binop(Iop_MullS32,
   11165                                             unop(Iop_16Sto32,
   11166                                                  unop(Iop_32to16,
   11167                                                       getIReg(rs))),
   11168                                             unop(Iop_16Sto32,
   11169                                                  unop(Iop_32HIto16,
   11170                                                       getIReg(rt)))),
   11171                                       mkU8(0x1)));
   11172                      assign(t6, binop(Iop_CmpEQ32,
   11173                                       unop(Iop_16Uto32,
   11174                                            unop(Iop_32to16, getIReg(rs))),
   11175                                       mkU32(0x00008000)));
   11176                      assign(t7, binop(Iop_CmpEQ32,
   11177                                       unop(Iop_16Uto32,
   11178                                            unop(Iop_32HIto16, getIReg(rt))),
   11179                                       mkU32(0x00008000)));
   11180                      assign(t8,
   11181                             IRExpr_ITE(mkexpr(t6),
   11182                                        IRExpr_ITE(mkexpr(t7),
   11183                                                   mkU64(0x000000007fffffffULL),
   11184                                                   mkexpr(t5)),
   11185                                        mkexpr(t5)));
   11186 
   11187                      putDSPControl(IRExpr_ITE(mkexpr(t6),
   11188                                               IRExpr_ITE(mkexpr(t7),
   11189                                                          binop(Iop_Or32,
   11190                                                                getDSPControl(),
   11191                                                                binop(Iop_Shl32,
   11192                                                                      mkU32(0x1),
   11193                                                                      mkU8(ac+16)
   11194                                                                     )
   11195                                                               ),
   11196                                                          getDSPControl()),
   11197                                               getDSPControl()));
   11198 
   11199                      assign(t9, binop(Iop_Sub64,
   11200                                      mkexpr(t0),
   11201                                      binop(Iop_Add64, mkexpr(t4), mkexpr(t8))));
   11202                      putAcc(ac, mkexpr(t9));
   11203                      break;
   11204                   }
   11205                   case 0x1A: {  /* DPAQX_SA.W.PH */
   11206                      DIP("dpaqx_sa.w.ph ac%d, r%d, r%d", ac, rs, rt);
   11207                      vassert(!mode64);
   11208                      t0 = newTemp(Ity_I64);
   11209                      t1 = newTemp(Ity_I64);
   11210                      t2 = newTemp(Ity_I1);
   11211                      t3 = newTemp(Ity_I1);
   11212                      t4 = newTemp(Ity_I64);
   11213                      t5 = newTemp(Ity_I64);
   11214                      t6 = newTemp(Ity_I1);
   11215                      t7 = newTemp(Ity_I1);
   11216                      t8 = newTemp(Ity_I64);
   11217                      t9 = newTemp(Ity_I64);
   11218                      t10 = newTemp(Ity_I32);
   11219 
   11220                      assign(t0, getAcc(ac));
   11221                      /* Calculate the first cross dot product and saturate if
   11222                         needed. */
   11223                      assign(t1, unop(Iop_32Sto64,
   11224                                      binop(Iop_Shl32,
   11225                                            binop(Iop_Mul32,
   11226                                                  unop(Iop_16Sto32,
   11227                                                       unop(Iop_32HIto16,
   11228                                                            getIReg(rs))),
   11229                                                  unop(Iop_16Sto32,
   11230                                                       unop(Iop_32to16,
   11231                                                            getIReg(rt)))),
   11232                                            mkU8(0x1))));
   11233 
   11234                      /* If both input arguments are equal 0x8000, saturate
   11235                         intermediate product and write to DSPControl
   11236                         register. */
   11237                      assign(t2, binop(Iop_CmpEQ32,
   11238                                       unop(Iop_16Uto32,
   11239                                            unop(Iop_32HIto16, getIReg(rs))),
   11240                                       mkU32(0x00008000)));
   11241                      assign(t3, binop(Iop_CmpEQ32,
   11242                                       unop(Iop_16Uto32,
   11243                                            unop(Iop_32to16, getIReg(rt))),
   11244                                       mkU32(0x00008000)));
   11245 
   11246                      assign(t4, IRExpr_ITE(binop(Iop_CmpNE32,
   11247                                                  binop(Iop_And32,
   11248                                                        unop(Iop_1Sto32,
   11249                                                             mkexpr(t2)),
   11250                                                        unop(Iop_1Sto32,
   11251                                                             mkexpr(t3))),
   11252                                                  mkU32(0)),
   11253                                            mkU64(0x000000007fffffffULL),
   11254                                            mkexpr(t1)));
   11255 
   11256                      putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32,
   11257                                                     binop(Iop_And32,
   11258                                                           unop(Iop_1Sto32,
   11259                                                                mkexpr(t2)),
   11260                                                           unop(Iop_1Sto32,
   11261                                                                mkexpr(t3))),
   11262                                                     mkU32(0)),
   11263                                               binop(Iop_Or32,
   11264                                                     getDSPControl(),
   11265                                                     binop(Iop_Shl32,
   11266                                                           mkU32(0x1),
   11267                                                           mkU8(ac+16))),
   11268                                               getDSPControl()));
   11269                      /* Calculate second cross dot product and saturate if
   11270                         needed. */
   11271                      assign(t5, unop(Iop_32Sto64,
   11272                                      binop(Iop_Shl32,
   11273                                            binop(Iop_Mul32,
   11274                                                  unop(Iop_16Sto32,
   11275                                                       unop(Iop_32to16,
   11276                                                            getIReg(rs))),
   11277                                                  unop(Iop_16Sto32,
   11278                                                       unop(Iop_32HIto16,
   11279                                                            getIReg(rt)))),
   11280                                            mkU8(0x1))));
   11281 
   11282                      /* If both input arguments are equal 0x8000, saturate
   11283                         intermediate product and write to DSPControl
   11284                         register. */
   11285                      assign(t6, binop(Iop_CmpEQ32,
   11286                                       unop(Iop_16Uto32,
   11287                                            unop(Iop_32to16, getIReg(rs))),
   11288                                       mkU32(0x00008000)));
   11289                      assign(t7, binop(Iop_CmpEQ32,
   11290                                       unop(Iop_16Uto32,
   11291                                            unop(Iop_32HIto16, getIReg(rt))),
   11292                                       mkU32(0x00008000)));
   11293 
   11294                      assign(t8, IRExpr_ITE(binop(Iop_CmpNE32,
   11295                                                  binop(Iop_And32,
   11296                                                        unop(Iop_1Sto32,
   11297                                                             mkexpr(t6)),
   11298                                                        unop(Iop_1Sto32,
   11299                                                             mkexpr(t7))),
   11300                                                  mkU32(0)),
   11301                                            mkU64(0x000000007fffffffULL),
   11302                                            mkexpr(t5)));
   11303 
   11304                      putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32,
   11305                                                     binop(Iop_And32,
   11306                                                           unop(Iop_1Sto32,
   11307                                                                mkexpr(t6)),
   11308                                                           unop(Iop_1Sto32,
   11309                                                                mkexpr(t7))),
   11310                                                     mkU32(0)),
   11311                                               binop(Iop_Or32,
   11312                                                     getDSPControl(),
   11313                                                     binop(Iop_Shl32,
   11314                                                           mkU32(0x1),
   11315                                                           mkU8(ac+16))),
   11316                                               getDSPControl()));
   11317                      /* Subtract intermediate products from value in the
   11318                         accumulator. */
   11319                      assign(t9,
   11320                             binop(Iop_Add64,
   11321                                   mkexpr(t0),
   11322                                   binop(Iop_Add64, mkexpr(t8), mkexpr(t4))));
   11323 
   11324                      putAcc(ac,
   11325                             IRExpr_ITE(binop(Iop_CmpEQ32,
   11326                                              binop(Iop_And32,
   11327                                                    unop(Iop_64HIto32,
   11328                                                         mkexpr(t9)),
   11329                                                    mkU32(0x80000000)),
   11330                                              mkU32(0x0)),
   11331                                        IRExpr_ITE(binop(Iop_CmpNE32,
   11332                                                         unop(Iop_64HIto32,
   11333                                                              binop(Iop_Shl64,
   11334                                                                    mkexpr(t9),
   11335                                                                    mkU8(1))),
   11336                                                         mkU32(0x0)),
   11337                                                   mkU64(0x000000007fffffffULL),
   11338                                                   mkexpr(t9)),
   11339                                        IRExpr_ITE(binop(Iop_CmpNE32,
   11340                                                         unop(Iop_64HIto32,
   11341                                                              binop(Iop_Shl64,
   11342                                                                    mkexpr(t9),
   11343                                                                    mkU8(1))),
   11344                                                         mkU32(0xffffffff)),
   11345                                                   mkU64(0xffffffff80000000ULL),
   11346                                                   mkexpr(t9))));
   11347                      assign(t10, IRExpr_ITE(binop(Iop_CmpEQ32,
   11348                                                   unop(Iop_64to32,
   11349                                                        mkexpr(t9)),
   11350                                                   unop(Iop_64to32,
   11351                                                        getAcc(ac))),
   11352                                            getDSPControl(),
   11353                                            binop(Iop_Or32,
   11354                                                  getDSPControl(),
   11355                                                  binop(Iop_Shl32,
   11356                                                        mkU32(0x1),
   11357                                                        mkU8(ac+16)))));
   11358                      putDSPControl(IRExpr_ITE(binop(Iop_CmpEQ32,
   11359                                                     unop(Iop_64HIto32,
   11360                                                          mkexpr(t9)),
   11361                                                     unop(Iop_64HIto32,
   11362                                                          getAcc(ac))),
   11363                                               mkexpr(t10),
   11364                                               binop(Iop_Or32,
   11365                                                     getDSPControl(),
   11366                                                     binop(Iop_Shl32,
   11367                                                           mkU32(0x1),
   11368                                                           mkU8(ac+16)))));
   11369                      break;
   11370                   }
   11371                   case 0x1B: {  /* DPSQX_SA.W.PH */
   11372                      DIP("dpsqx_sa.w.ph ac%d, r%d, r%d", ac, rs, rt);
   11373                      vassert(!mode64);
   11374                      t0 = newTemp(Ity_I64);
   11375                      t1 = newTemp(Ity_I64);
   11376                      t2 = newTemp(Ity_I1);
   11377                      t3 = newTemp(Ity_I1);
   11378                      t4 = newTemp(Ity_I64);
   11379                      t5 = newTemp(Ity_I64);
   11380                      t6 = newTemp(Ity_I1);
   11381                      t7 = newTemp(Ity_I1);
   11382                      t8 = newTemp(Ity_I64);
   11383                      t9 = newTemp(Ity_I64);
   11384                      t10 = newTemp(Ity_I32);
   11385 
   11386                      assign(t0, getAcc(ac));
   11387                      /* Calculate the first cross dot product and saturate if
   11388                         needed. */
   11389                      assign(t1, unop(Iop_32Sto64,
   11390                                      binop(Iop_Shl32,
   11391                                            binop(Iop_Mul32,
   11392                                                  unop(Iop_16Sto32,
   11393                                                       unop(Iop_32HIto16,
   11394                                                            getIReg(rs))),
   11395                                                  unop(Iop_16Sto32,
   11396                                                       unop(Iop_32to16,
   11397                                                            getIReg(rt)))),
   11398                                            mkU8(0x1))));
   11399 
   11400                      /* If both input arguments are equal 0x8000, saturate
   11401                         intermediate product and write to DSPControl
   11402                         register. */
   11403                      assign(t2, binop(Iop_CmpEQ32,
   11404                                       unop(Iop_16Uto32,
   11405                                            unop(Iop_32HIto16, getIReg(rs))),
   11406                                       mkU32(0x00008000)));
   11407                      assign(t3, binop(Iop_CmpEQ32,
   11408                                       unop(Iop_16Uto32,
   11409                                            unop(Iop_32to16, getIReg(rt))),
   11410                                       mkU32(0x00008000)));
   11411 
   11412                      assign(t4, IRExpr_ITE(binop(Iop_CmpNE32,
   11413                                                  binop(Iop_And32,
   11414                                                        unop(Iop_1Sto32,
   11415                                                             mkexpr(t2)),
   11416                                                        unop(Iop_1Sto32,
   11417                                                             mkexpr(t3))),
   11418                                                  mkU32(0)),
   11419                                            mkU64(0x000000007fffffffULL),
   11420                                            mkexpr(t1)));
   11421 
   11422                      putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32,
   11423                                                     binop(Iop_And32,
   11424                                                           unop(Iop_1Sto32,
   11425                                                                mkexpr(t2)),
   11426                                                           unop(Iop_1Sto32,
   11427                                                                mkexpr(t3))),
   11428                                                     mkU32(0)),
   11429                                               binop(Iop_Or32,
   11430                                                     getDSPControl(),
   11431                                                     binop(Iop_Shl32,
   11432                                                           mkU32(0x1),
   11433                                                           mkU8(ac+16))),
   11434                                               getDSPControl()));
   11435                      /* Calculate second cross dot product and saturate if
   11436                         needed. */
   11437                      assign(t5, unop(Iop_32Sto64,
   11438                                      binop(Iop_Shl32,
   11439                                            binop(Iop_Mul32,
   11440                                                  unop(Iop_16Sto32,
   11441                                                       unop(Iop_32to16,
   11442                                                            getIReg(rs))),
   11443                                                  unop(Iop_16Sto32,
   11444                                                       unop(Iop_32HIto16,
   11445                                                            getIReg(rt)))),
   11446                                            mkU8(0x1))));
   11447 
   11448                      /* If both input arguments are equal 0x8000, saturate
   11449                         intermediate product and write to DSPControl
   11450                         register. */
   11451                      assign(t6, binop(Iop_CmpEQ32,
   11452                                       unop(Iop_16Uto32,
   11453                                            unop(Iop_32to16, getIReg(rs))),
   11454                                       mkU32(0x00008000)));
   11455                      assign(t7, binop(Iop_CmpEQ32,
   11456                                       unop(Iop_16Uto32,
   11457                                            unop(Iop_32HIto16, getIReg(rt))),
   11458                                       mkU32(0x00008000)));
   11459 
   11460                      assign(t8, IRExpr_ITE(binop(Iop_CmpNE32,
   11461                                                  binop(Iop_And32,
   11462                                                        unop(Iop_1Sto32,
   11463                                                             mkexpr(t6)),
   11464                                                        unop(Iop_1Sto32,
   11465                                                             mkexpr(t7))),
   11466                                                  mkU32(0)),
   11467                                            mkU64(0x000000007fffffffULL),
   11468                                            mkexpr(t5)));
   11469 
   11470                      putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32,
   11471                                                     binop(Iop_And32,
   11472                                                           unop(Iop_1Sto32,
   11473                                                                mkexpr(t6)),
   11474                                                           unop(Iop_1Sto32,
   11475                                                                mkexpr(t7))),
   11476                                                     mkU32(0)),
   11477                                               binop(Iop_Or32,
   11478                                                     getDSPControl(),
   11479                                                     binop(Iop_Shl32,
   11480                                                           mkU32(0x1),
   11481                                                           mkU8(ac+16))),
   11482                                               getDSPControl()));
   11483                      /* Subtract intermediate products from value in the
   11484                         accumulator. */
   11485                      assign(t9,
   11486                             binop(Iop_Sub64,
   11487                                   mkexpr(t0),
   11488                                   binop(Iop_Add64, mkexpr(t8), mkexpr(t4))));
   11489 
   11490                      putAcc(ac,
   11491                             IRExpr_ITE(binop(Iop_CmpEQ32,
   11492                                              binop(Iop_And32,
   11493                                                    unop(Iop_64HIto32,
   11494                                                         mkexpr(t9)),
   11495                                                    mkU32(0x80000000)),
   11496                                              mkU32(0x0)),
   11497                                        IRExpr_ITE(binop(Iop_CmpNE32,
   11498                                                         unop(Iop_64HIto32,
   11499                                                              binop(Iop_Shl64,
   11500                                                                    mkexpr(t9),
   11501                                                                    mkU8(1))),
   11502                                                         mkU32(0x0)),
   11503                                                   mkU64(0x000000007fffffffULL),
   11504                                                   mkexpr(t9)),
   11505                                        IRExpr_ITE(binop(Iop_CmpNE32,
   11506                                                         unop(Iop_64HIto32,
   11507                                                              binop(Iop_Shl64,
   11508                                                                    mkexpr(t9),
   11509                                                                    mkU8(1))),
   11510                                                         mkU32(0xffffffff)),
   11511                                                   mkU64(0xffffffff80000000ULL),
   11512                                                   mkexpr(t9))));
   11513                      assign(t10, IRExpr_ITE(binop(Iop_CmpEQ32,
   11514                                                   unop(Iop_64to32,
   11515                                                        mkexpr(t9)),
   11516                                                   unop(Iop_64to32,
   11517                                                        getAcc(ac))),
   11518                                            getDSPControl(),
   11519                                            binop(Iop_Or32,
   11520                                                  getDSPControl(),
   11521                                                  binop(Iop_Shl32,
   11522                                                        mkU32(0x1),
   11523                                                        mkU8(ac+16)))));
   11524                      putDSPControl(IRExpr_ITE(binop(Iop_CmpEQ32,
   11525                                                     unop(Iop_64HIto32,
   11526                                                          mkexpr(t9)),
   11527                                                     unop(Iop_64HIto32,
   11528                                                          getAcc(ac))),
   11529                                               mkexpr(t10),
   11530                                               binop(Iop_Or32,
   11531                                                     getDSPControl(),
   11532                                                     binop(Iop_Shl32,
   11533                                                           mkU32(0x1),
   11534                                                           mkU8(ac+16)))));
   11535                      break;
   11536                   }
   11537                   default:
   11538                      return -1;
   11539                }
   11540                break;  /* end of DPAQ.W.PH */
   11541             }
   11542             case 0x31: {  /* APPEND */
   11543                switch(sa) {
   11544                   case 0x0: {  /* APPEND */
   11545                      DIP("append r%d, r%d, %d", rt, rs, rd);
   11546                      vassert(!mode64);
   11547                      t1 = newTemp(Ity_I32);
   11548                      t2 = newTemp(Ity_I32);
   11549                      t3 = newTemp(Ity_I32);
   11550 
   11551                      assign(t1, binop(Iop_Shl32, getIReg(rt), mkU8(rd)));
   11552 
   11553                      if (31 == rd) {
   11554                         putIReg(rt, binop(Iop_Or32,
   11555                                           mkexpr(t1),
   11556                                           binop(Iop_And32,
   11557                                                 getIReg(rs),
   11558                                                 mkU32(0x7fffffff))));
   11559                      } else if (1 == rd) {
   11560                         putIReg(rt,
   11561                                 binop(Iop_Or32,
   11562                                       mkexpr(t1),
   11563                                       binop(Iop_And32,
   11564                                             getIReg(rs), mkU32(0x1))));
   11565                      } else {
   11566                         assign(t2,
   11567                                unop(Iop_Not32,
   11568                                     binop(Iop_Shl32,
   11569                                           mkU32(0xffffffff), mkU8(rd))));
   11570 
   11571                         putIReg(rt, binop(Iop_Or32,
   11572                                           mkexpr(t1),
   11573                                           binop(Iop_And32,
   11574                                                 getIReg(rs), mkexpr(t2))));
   11575                      }
   11576                      break;
   11577                   }
   11578                   case 0x1: {  /* PREPEND */
   11579                      DIP("prepend r%d, r%d, %d", rt, rs, rd);
   11580                      vassert(!mode64);
   11581                      t1 = newTemp(Ity_I32);
   11582                      t2 = newTemp(Ity_I32);
   11583                      t3 = newTemp(Ity_I32);
   11584 
   11585                      if (0 != rd) {
   11586                         assign(t1, binop(Iop_Shr32, getIReg(rt), mkU8(rd)));
   11587 
   11588                         if (31 == rd) {
   11589                            putIReg(rt, binop(Iop_Or32,
   11590                                              mkexpr(t1),
   11591                                              binop(Iop_Shl32,
   11592                                                    binop(Iop_And32,
   11593                                                          getIReg(rs),
   11594                                                          mkU32(0x7fffffff)),
   11595                                                    mkU8(1))));
   11596                         } else if (1 == rd) {
   11597                            putIReg(rt, binop(Iop_Or32,
   11598                                              mkexpr(t1),
   11599                                              binop(Iop_Shl32,
   11600                                                    binop(Iop_And32,
   11601                                                          getIReg(rs),
   11602                                                          mkU32(0x1)),
   11603                                                    mkU8(31))));
   11604                         } else {
   11605                            assign(t2, binop(Iop_Add32, mkU32(rd), mkU32(0x1)));
   11606 
   11607                            assign(t3, unop(Iop_Not32,
   11608                                            binop(Iop_Shl32,
   11609                                                  mkU32(0xffffffff),
   11610                                                  unop(Iop_32to8, mkexpr(t2)))));
   11611 
   11612                            putIReg(rt, binop(Iop_Or32,
   11613                                              mkexpr(t1),
   11614                                              binop(Iop_Shl32,
   11615                                                    binop(Iop_And32,
   11616                                                          getIReg(rs),
   11617                                                          mkexpr(t3)),
   11618                                                    mkU8(32-rd))));
   11619                         }
   11620                      }
   11621                      break;
   11622                   }
   11623                   case 0x10: {  /* BALIGN */
   11624                      DIP("balign r%d, r%d, %d", rt, rs, rd);
   11625                      vassert(!mode64);
   11626                      t1 = newTemp(Ity_I32);
   11627                      t2 = newTemp(Ity_I32);
   11628                      t3 = newTemp(Ity_I32);
   11629 
   11630                      if ((2 != rd) && (0 != rd)) {
   11631                         assign(t1, binop(Iop_Shl32,
   11632                                          binop(Iop_And32,
   11633                                                mkU32(rd), mkU32(0x3)),
   11634                                          mkU8(0x3)));
   11635                         assign(t2, binop(Iop_Shl32,
   11636                                          getIReg(rt),
   11637                                          unop(Iop_32to8, mkexpr(t1))));
   11638                         assign(t3, binop(Iop_Shr32,
   11639                                          getIReg(rs),
   11640                                          unop(Iop_32to8,
   11641                                               binop(Iop_Shl32,
   11642                                                     binop(Iop_Sub32,
   11643                                                           mkU32(0x4),
   11644                                                           binop(Iop_And32,
   11645                                                                 mkU32(rd),
   11646                                                                 mkU32(0x3))),
   11647                                                     mkU8(0x3)))));
   11648                         putIReg(rt, binop(Iop_Or32, mkexpr(t2), mkexpr(t3)));
   11649                      }
   11650                      break;
   11651                   }
   11652                   default:
   11653                      return -1;
   11654                }
   11655                break;  /* end of APPEND */
   11656             }
   11657             default:
   11658                return -1;
   11659          }
   11660          break;
   11661       }
   11662       default:
   11663             return -1;
   11664    }
   11665    return 0;
   11666 }
   11667 
   11668 /*------------------------------------------------------------*/
   11669 /*---          Disassemble a single instruction            ---*/
   11670 /*------------------------------------------------------------*/
   11671 
   11672 /* Disassemble a single instruction into IR. The instruction is
   11673    located in host memory at guest_instr, and has guest IP of
   11674    guest_PC_curr_instr, which will have been set before the call
   11675    here. */
   11676 
   11677 static DisResult disInstr_MIPS_WRK ( Bool(*resteerOkFn) (/*opaque */void *,
   11678                                                                     Addr64),
   11679                                      Bool         resteerCisOk,
   11680                                      void*        callback_opaque,
   11681                                      Long         delta64,
   11682                                      VexArchInfo* archinfo,
   11683                                      VexAbiInfo*  abiinfo,
   11684                                      Bool         sigill_diag )
   11685 {
   11686    IRTemp t0, t1 = 0, t2, t3, t4, t5, t6, t7;
   11687 
   11688    UInt opcode, cins, rs, rt, rd, sa, ft, fs, fd, fmt, tf, nd, function,
   11689         trap_code, imm, instr_index, p, msb, lsb, size, rot, sel;
   11690    /* Additional variables for instruction fields in DSP ASE insructions */
   11691    UInt ac;
   11692 
   11693    DisResult dres;
   11694 
   11695    static IRExpr *lastn = NULL;  /* last jump addr */
   11696    static IRStmt *bstmt = NULL;  /* branch (Exit) stmt */
   11697 
   11698    /* The running delta */
   11699    Int delta = (Int) delta64;
   11700 
   11701    /* Holds eip at the start of the insn, so that we can print
   11702       consistent error messages for unimplemented insns. */
   11703    Int delta_start = delta;
   11704 
   11705    /* Are we in a delay slot ? */
   11706    Bool delay_slot_branch, likely_delay_slot, delay_slot_jump;
   11707 
   11708    /* Set result defaults. */
   11709    dres.whatNext = Dis_Continue;
   11710    dres.len = 0;
   11711    dres.continueAt = 0;
   11712    dres.jk_StopHere = Ijk_INVALID;
   11713 
   11714    delay_slot_branch = likely_delay_slot = delay_slot_jump = False;
   11715 
   11716    UChar *code = (UChar *) (guest_code + delta);
   11717    cins = getUInt(code);
   11718    DIP("\t0x%lx:\t0x%08x\t", (long)guest_PC_curr_instr, cins);
   11719 
   11720    if (delta != 0) {
   11721       if (branch_or_jump(guest_code + delta - 4)) {
   11722          if (lastn == NULL && bstmt == NULL) {
   11723             vassert(0);
   11724          } else {
   11725             dres.whatNext = Dis_StopHere;
   11726             if (lastn != NULL) {
   11727                delay_slot_jump = True;
   11728             } else if (bstmt != NULL) {
   11729                delay_slot_branch = True;
   11730             }
   11731          }
   11732       }
   11733 
   11734       if (branch_or_link_likely(guest_code + delta - 4)) {
   11735          likely_delay_slot = True;
   11736       }
   11737    }
   11738 
   11739    /* Spot "Special" instructions (see comment at top of file). */
   11740    {
   11741       /* Spot the 16-byte preamble:
   11742        ****mips32****
   11743        "srl $0, $0, 13
   11744        "srl $0, $0, 29
   11745        "srl $0, $0, 3
   11746        "srl $0, $0, 19
   11747 
   11748        ****mips64****
   11749        dsll $0, $0, 3
   11750        dsll $0, $0, 13
   11751        dsll $0, $0, 29
   11752        dsll $0, $0, 19 */
   11753 
   11754       UInt word1 = mode64 ? 0xF8  : 0x342;
   11755       UInt word2 = mode64 ? 0x378 : 0x742;
   11756       UInt word3 = mode64 ? 0x778 : 0xC2;
   11757       UInt word4 = mode64 ? 0x4F8 : 0x4C2;
   11758       if (getUInt(code + 0) == word1 && getUInt(code + 4) == word2 &&
   11759           getUInt(code + 8) == word3 && getUInt(code + 12) == word4) {
   11760          /* Got a "Special" instruction preamble. Which one is it? */
   11761          if (getUInt(code + 16) == 0x01ad6825 /* or $13, $13, $13 */ ) {
   11762             /* $11 = client_request ( $12 ) */
   11763             DIP("$11 = client_request ( $12 )");
   11764             if (mode64)
   11765                putPC(mkU64(guest_PC_curr_instr + 20));
   11766             else
   11767                putPC(mkU32(guest_PC_curr_instr + 20));
   11768             dres.jk_StopHere = Ijk_ClientReq;
   11769             dres.whatNext    = Dis_StopHere;
   11770 
   11771             goto decode_success;
   11772          } else if (getUInt(code + 16) == 0x01ce7025 /* or $14, $14, $14 */ ) {
   11773             /* $11 = guest_NRADDR */
   11774             DIP("$11 = guest_NRADDR");
   11775             dres.len = 20;
   11776             delta += 20;
   11777             if (mode64)
   11778                putIReg(11, IRExpr_Get(offsetof(VexGuestMIPS64State,
   11779                                                guest_NRADDR), Ity_I64));
   11780             else
   11781                putIReg(11, IRExpr_Get(offsetof(VexGuestMIPS32State,
   11782                                                guest_NRADDR), Ity_I32));
   11783             goto decode_success;
   11784          } else if (getUInt(code + 16) == 0x01ef7825 /* or $15, $15, $15 */ ) {
   11785             /*  branch-and-link-to-noredir $25 */
   11786             DIP("branch-and-link-to-noredir $25");
   11787             if (mode64)
   11788                putIReg(31, mkU64(guest_PC_curr_instr + 20));
   11789             else
   11790                putIReg(31, mkU32(guest_PC_curr_instr + 20));
   11791             putPC(getIReg(25));
   11792             dres.jk_StopHere = Ijk_NoRedir;
   11793             dres.whatNext    = Dis_StopHere;
   11794             goto decode_success;
   11795          } else if (getUInt(code + 16) == 0x016b5825 /* or $11,$11,$11 */ ) {
   11796            /* IR injection */
   11797             DIP("IR injection");
   11798 #if defined (_MIPSEL)
   11799             vex_inject_ir(irsb, Iend_LE);
   11800 #elif defined (_MIPSEB)
   11801             vex_inject_ir(irsb, Iend_BE);
   11802 #endif
   11803             if (mode64) {
   11804                stmt(IRStmt_Put(offsetof(VexGuestMIPS64State, guest_CMSTART),
   11805                                mkU64(guest_PC_curr_instr)));
   11806                stmt(IRStmt_Put(offsetof(VexGuestMIPS64State, guest_CMLEN),
   11807                                mkU64(20)));
   11808 
   11809                putPC(mkU64(guest_PC_curr_instr + 20));
   11810             } else {
   11811                stmt(IRStmt_Put(offsetof(VexGuestMIPS32State, guest_CMSTART),
   11812                                mkU32(guest_PC_curr_instr)));
   11813                stmt(IRStmt_Put(offsetof(VexGuestMIPS32State, guest_CMLEN),
   11814                                mkU32(20)));
   11815 
   11816                putPC(mkU32(guest_PC_curr_instr + 20));
   11817             }
   11818             dres.whatNext    = Dis_StopHere;
   11819             dres.jk_StopHere = Ijk_InvalICache;
   11820             dres.len = 20;
   11821             delta += 20;
   11822             goto decode_success;
   11823          }
   11824 
   11825          /* We don't know what it is.  Set opc1/opc2 so decode_failure
   11826             can print the insn following the Special-insn preamble. */
   11827          delta += 16;
   11828          goto decode_failure;
   11829        /*NOTREACHED*/}
   11830    }
   11831 
   11832    opcode = get_opcode(cins);
   11833    imm = get_imm(cins);
   11834    rs = get_rs(cins);
   11835    rt = get_rt(cins);
   11836    rd = get_rd(cins);
   11837    sa = get_sa(cins);
   11838    fs = get_fs(cins);
   11839    fd = get_fd(cins);
   11840    ft = get_ft(cins);
   11841    tf = get_tf(cins);
   11842    nd = get_nd(cins);
   11843    sel = get_sel(cins);
   11844    fmt = get_fmt(cins);
   11845    instr_index = get_instr_index(cins);
   11846    trap_code = get_code(cins);
   11847    function = get_function(cins);
   11848    IRType ty = mode64 ? Ity_I64 : Ity_I32;
   11849    IRType tyF = fp_mode64 ? Ity_F64 : Ity_F32;
   11850 
   11851    ac = get_acNo(cins);
   11852 
   11853    switch (opcode) {
   11854 
   11855    case 0x03:     /* JAL */
   11856       DIP("jal 0x%x", instr_index);
   11857       if (mode64) {
   11858          putIReg(31, mkU64(guest_PC_curr_instr + 8));
   11859          t0 = newTemp(ty);
   11860          assign(t0, mkU64((guest_PC_curr_instr & 0xFFFFFFFFF0000000ULL) |
   11861                           (instr_index << 2)));
   11862       } else {
   11863          putIReg(31, mkU32(guest_PC_curr_instr + 8));
   11864          t0 = newTemp(ty);
   11865          assign(t0, mkU32((guest_PC_curr_instr & 0xF0000000) |
   11866                           (instr_index << 2)));
   11867       }
   11868       lastn = mkexpr(t0);
   11869       break;
   11870    case 0x02:     /* J */
   11871       DIP("j 0x%x", instr_index);
   11872       t0 = newTemp(ty);
   11873       if (mode64)
   11874          assign(t0, mkU64((guest_PC_curr_instr & 0xFFFFFFFFF0000000ULL) |
   11875                           (instr_index << 2)));
   11876       else
   11877          assign(t0, mkU32((guest_PC_curr_instr & 0xF0000000) |
   11878                           (instr_index << 2)));
   11879       lastn = mkexpr(t0);
   11880       break;
   11881 
   11882    case 0x11: {  /* COP1 */
   11883       if (fmt == 0x3 && fd == 0 && function == 0) {  /* MFHC1 */
   11884          DIP("mfhc1 r%d, f%d", rt, fs);
   11885          if (fp_mode64) {
   11886             t0 = newTemp(Ity_I64);
   11887             t1 = newTemp(Ity_I32);
   11888             assign(t0, unop(Iop_ReinterpF64asI64, getDReg(fs)));
   11889             assign(t1, unop(Iop_64HIto32, mkexpr(t0)));
   11890             putIReg(rt, mkWidenFrom32(ty, mkexpr(t1), True));
   11891          } else {
   11892             ILLEGAL_INSTRUCTON;
   11893          }
   11894          break;
   11895       } else if (fmt == 0x7 && fd == 0 && function == 0) {  /* MTHC1 */
   11896          DIP("mthc1 r%d, f%d", rt, fs);
   11897          if (fp_mode64) {
   11898             t0 = newTemp(Ity_I64);
   11899             assign(t0, binop(Iop_32HLto64, getIReg(rt),
   11900                              unop(Iop_ReinterpF32asI32,
   11901                                   getLoFromF64(Ity_F64 /* 32FPR mode. */,
   11902                                                getDReg(fs)))));
   11903             putDReg(fs, unop(Iop_ReinterpI64asF64, mkexpr(t0)));
   11904          } else {
   11905             ILLEGAL_INSTRUCTON;
   11906          }
   11907          break;
   11908       } else if (fmt == 0x8) {  /* BC */
   11909          /* FcConditionalCode(bc1_cc) */
   11910          UInt bc1_cc = get_bc1_cc(cins);
   11911          t1 = newTemp(Ity_I1);
   11912          t2 = newTemp(Ity_I32);
   11913          t3 = newTemp(Ity_I1);
   11914 
   11915          assign(t1, binop(Iop_CmpEQ32, mkU32(0), mkU32(bc1_cc)));
   11916          assign(t2, IRExpr_ITE(mkexpr(t1),
   11917                                binop(Iop_And32,
   11918                                      binop(Iop_Shr32, getFCSR(), mkU8(23)),
   11919                                      mkU32(0x1)),
   11920                                binop(Iop_And32,
   11921                                      binop(Iop_Shr32, getFCSR(),
   11922                                            mkU8(24 + bc1_cc)),
   11923                                      mkU32(0x1))));
   11924 
   11925          if (tf == 1 && nd == 0) {
   11926             /* branch on true */
   11927             DIP("bc1t %d, %d", bc1_cc, imm);
   11928             assign(t3, binop(Iop_CmpEQ32, mkU32(1), mkexpr(t2)));
   11929             dis_branch(False, mkexpr(t3), imm, &bstmt);
   11930             break;
   11931          } else if (tf == 0 && nd == 0) {
   11932             /* branch on false */
   11933             DIP("bc1f %d, %d", bc1_cc, imm);
   11934             assign(t3, binop(Iop_CmpEQ32, mkU32(0), mkexpr(t2)));
   11935             dis_branch(False, mkexpr(t3), imm, &bstmt);
   11936             break;
   11937          } else if (nd == 1 && tf == 0) {
   11938             DIP("bc1fl %d, %d", bc1_cc, imm);
   11939             lastn = dis_branch_likely(binop(Iop_CmpNE32, mkexpr(t2),
   11940                                             mkU32(0x0)), imm);
   11941             break;
   11942          } else if (nd == 1 && tf == 1) {
   11943             DIP("bc1tl %d, %d", bc1_cc, imm);
   11944             lastn = dis_branch_likely(binop(Iop_CmpEQ32, mkexpr(t2),
   11945                                             mkU32(0x0)), imm);
   11946             break;
   11947          } else
   11948             goto decode_failure;
   11949       } else {
   11950          switch (function) {
   11951             case 0x4: {  /* SQRT.fmt */
   11952                switch (fmt) {
   11953                   case 0x10: {  /* S */
   11954                      IRExpr *rm = get_IR_roundingmode();
   11955                      putFReg(fd, mkWidenFromF32(tyF, binop(Iop_SqrtF32, rm,
   11956                                  getLoFromF64(tyF, getFReg(fs)))));
   11957                      break;
   11958                   }
   11959                   case 0x11: {  /* D */
   11960                      IRExpr *rm = get_IR_roundingmode();
   11961                      putDReg(fd, binop(Iop_SqrtF64, rm, getDReg(fs)));
   11962                      break;
   11963                   }
   11964                   default:
   11965                      goto decode_failure;
   11966                   }
   11967                }
   11968                break;
   11969             case 0x5:  /* abs.fmt */
   11970                switch (fmt) {
   11971                   case 0x10:  /* S */
   11972                      DIP("abs.s f%d, f%d", fd, fs);
   11973                      putFReg(fd, mkWidenFromF32(tyF, unop(Iop_AbsF32,
   11974                                  getLoFromF64(tyF, getFReg(fs)))));
   11975                      break;
   11976                   case 0x11:  /* D  */
   11977                      DIP("abs.d f%d, f%d", fd, fs);
   11978                      putDReg(fd, unop(Iop_AbsF64, getDReg(fs)));
   11979                      break;
   11980                   default:
   11981                      goto decode_failure;
   11982                }
   11983                break;  /* case 0x5 */
   11984 
   11985             case 0x02:  /* MUL.fmt */
   11986                switch (fmt) {
   11987                   case 0x11: {  /* D */
   11988                      DIP("mul.d f%d, f%d, f%d", fd, fs, ft);
   11989                      IRExpr *rm = get_IR_roundingmode();
   11990                      putDReg(fd, triop(Iop_MulF64, rm, getDReg(fs),
   11991                                        getDReg(ft)));
   11992                      break;
   11993                   }
   11994                   case 0x10: {  /* S */
   11995                      DIP("mul.s f%d, f%d, f%d", fd, fs, ft);
   11996                      IRExpr *rm = get_IR_roundingmode();
   11997                      putFReg(fd, mkWidenFromF32(tyF, triop(Iop_MulF32, rm,
   11998                                  getLoFromF64(tyF, getFReg(fs)),
   11999                                  getLoFromF64(tyF, getFReg(ft)))));
   12000                      break;
   12001                   }
   12002                   default:
   12003                      goto decode_failure;
   12004                }
   12005                break;  /* MUL.fmt */
   12006 
   12007             case 0x03:  /* DIV.fmt */
   12008                switch (fmt) {
   12009                   case 0x11: {  /* D */
   12010                      DIP("div.d f%d, f%d, f%d", fd, fs, ft);
   12011                      IRExpr *rm = get_IR_roundingmode();
   12012                      putDReg(fd, triop(Iop_DivF64, rm, getDReg(fs),
   12013                                  getDReg(ft)));
   12014                      break;
   12015                   }
   12016                   case 0x10: {  /* S */
   12017                      DIP("div.s f%d, f%d, f%d", fd, fs, ft);
   12018                      calculateFCSR(fs, ft, DIVS, False, 2);
   12019                      IRExpr *rm = get_IR_roundingmode();
   12020                      putFReg(fd, mkWidenFromF32(tyF, triop(Iop_DivF32, rm,
   12021                                  getLoFromF64(tyF, getFReg(fs)),
   12022                                  getLoFromF64(tyF, getFReg(ft)))));
   12023                      break;
   12024                   }
   12025                   default:
   12026                      goto decode_failure;
   12027                }
   12028                break;  /* DIV.fmt */
   12029 
   12030             case 0x01:  /* SUB.fmt */
   12031                switch (fmt) {
   12032                   case 0x11: {  /* D */
   12033                      DIP("sub.d f%d, f%d, f%d", fd, fs, ft);
   12034                      calculateFCSR(fs, ft, SUBD, False, 2);
   12035                      IRExpr *rm = get_IR_roundingmode();
   12036                      putDReg(fd, triop(Iop_SubF64, rm, getDReg(fs),
   12037                                        getDReg(ft)));
   12038                      break;
   12039                   }
   12040                   case 0x10: {  /* S */
   12041                      DIP("sub.s f%d, f%d, f%d", fd, fs, ft);
   12042                      calculateFCSR(fs, ft, SUBS, True, 2);
   12043                      IRExpr *rm = get_IR_roundingmode();
   12044                      putFReg(fd, mkWidenFromF32(tyF, triop(Iop_SubF32, rm,
   12045                                  getLoFromF64(tyF, getFReg(fs)),
   12046                                  getLoFromF64(tyF, getFReg(ft)))));
   12047                      break;
   12048                   }
   12049                   default:
   12050                      goto decode_failure;
   12051                }
   12052                break;  /* SUB.fmt */
   12053 
   12054             case 0x06:  /* MOV.fmt */
   12055                switch (fmt) {
   12056                   case 0x11:  /* D */
   12057                      DIP("mov.d f%d, f%d", fd, fs);
   12058                      if (fp_mode64) {
   12059                         putDReg(fd, getDReg(fs));
   12060                      } else {
   12061                         putFReg(fd, getFReg(fs));
   12062                         putFReg(fd + 1, getFReg(fs + 1));
   12063                      }
   12064                      break;
   12065                   case 0x10:  /* S */
   12066                      DIP("mov.s f%d, f%d", fd, fs);
   12067                      putFReg(fd, getFReg(fs));
   12068                      break;
   12069                   default:
   12070                      goto decode_failure;
   12071                }
   12072                break;  /* MOV.fmt */
   12073 
   12074             case 0x7:  /* neg.fmt */
   12075                switch (fmt) {
   12076                   case 0x10:  /* S */
   12077                      DIP("neg.s f%d, f%d", fd, fs);
   12078                      putFReg(fd, mkWidenFromF32(tyF, unop(Iop_NegF32,
   12079                                  getLoFromF64(tyF, getFReg(fs)))));
   12080                      break;
   12081                   case 0x11:  /* D */
   12082                      DIP("neg.d f%d, f%d", fd, fs);
   12083                      putDReg(fd, unop(Iop_NegF64, getDReg(fs)));
   12084                      break;
   12085                   default:
   12086                      goto decode_failure;
   12087                }
   12088                break;  /* case 0x7 */
   12089 
   12090             case 0x08:  /* ROUND.L.fmt */
   12091                switch (fmt) {
   12092                   case 0x10:  /* S */
   12093                      DIP("round.l.s f%d, f%d", fd, fs);
   12094                      if (fp_mode64) {
   12095                         calculateFCSR(fs, 0, ROUNDLS, True, 1);
   12096                         t0 = newTemp(Ity_I64);
   12097 
   12098                         assign(t0, binop(Iop_F32toI64S, mkU32(0x0),
   12099                                          getLoFromF64(Ity_F64, getFReg(fs))));
   12100 
   12101                         putDReg(fd, unop(Iop_ReinterpI64asF64, mkexpr(t0)));
   12102                      } else {
   12103                         ILLEGAL_INSTRUCTON;
   12104                      }
   12105                      break;
   12106                   case 0x11:  /* D */
   12107                      DIP("round.l.d f%d, f%d", fd, fs);
   12108                      if (fp_mode64) {
   12109                         calculateFCSR(fs, 0, ROUNDLD, False, 1);
   12110                         putDReg(fd, binop(Iop_RoundF64toInt, mkU32(0x0),
   12111                                           getDReg(fs)));
   12112                      } else {
   12113                         ILLEGAL_INSTRUCTON;
   12114                      }
   12115                      break;
   12116                   default:
   12117                     goto decode_failure;
   12118 
   12119                }
   12120                break;  /* ROUND.L.fmt */
   12121 
   12122             case 0x09:  /* TRUNC.L.fmt */
   12123                switch (fmt) {
   12124                   case 0x10:  /* S */
   12125                      DIP("trunc.l.s f%d, f%d", fd, fs);
   12126                      if (fp_mode64) {
   12127                         calculateFCSR(fs, 0, TRUNCLS, True, 1);
   12128                         t0 = newTemp(Ity_I64);
   12129                         assign(t0, binop(Iop_F32toI64S, mkU32(0x3),
   12130                                          getLoFromF64(Ity_F64, getFReg(fs))));
   12131 
   12132                         putDReg(fd, unop(Iop_ReinterpI64asF64, mkexpr(t0)));
   12133                      } else {
   12134                         ILLEGAL_INSTRUCTON;
   12135                      }
   12136                      break;
   12137                   case 0x11:  /* D */
   12138                      DIP("trunc.l.d f%d, f%d", fd, fs);
   12139                      if (fp_mode64) {
   12140                         calculateFCSR(fs, 0, TRUNCLD, False, 1);
   12141                         putDReg(fd, binop(Iop_RoundF64toInt, mkU32(0x3),
   12142                                           getDReg(fs)));
   12143                      } else {
   12144                         ILLEGAL_INSTRUCTON;
   12145                      }
   12146                      break;
   12147                   default:
   12148                      goto decode_failure;
   12149                  }
   12150               break;  /* TRUNC.L.fmt */
   12151 
   12152             case 0x15:  /* RECIP.fmt */
   12153                switch (fmt) {
   12154                   case 0x10: {  /* S */
   12155                      DIP("recip.s f%d, f%d", fd, fs);
   12156                      IRExpr *rm = get_IR_roundingmode();
   12157                      putFReg(fd, mkWidenFromF32(tyF, triop(Iop_DivF32,
   12158                                  rm, unop(Iop_ReinterpI32asF32,
   12159                                  mkU32(ONE_SINGLE)), getLoFromF64(tyF,
   12160                                  getFReg(fs)))));
   12161                      break;
   12162                   }
   12163                   case 0x11: {  /* D */
   12164                      DIP("recip.d f%d, f%d", fd, fs);
   12165                      IRExpr *rm = get_IR_roundingmode();
   12166                      /* putDReg(fd, 1.0/getDreg(fs)); */
   12167                      putDReg(fd, triop(Iop_DivF64, rm,
   12168                                  unop(Iop_ReinterpI64asF64,
   12169                                  mkU64(ONE_DOUBLE)), getDReg(fs)));
   12170                      break;
   12171                   }
   12172                default:
   12173                   goto decode_failure;
   12174 
   12175                }
   12176                break;  /* case 0x15 */
   12177 
   12178             case 0x13:  /* MOVN.fmt */
   12179                switch (fmt) {
   12180                case 0x10:  /* S */
   12181                   DIP("movn.s f%d, f%d, r%d", fd, fs, rt);
   12182                   t1 = newTemp(Ity_F64);
   12183                   t2 = newTemp(Ity_F64);
   12184                   t3 = newTemp(Ity_I1);
   12185                   t4 = newTemp(Ity_F64);
   12186                   if (mode64) {
   12187                      assign(t1, getFReg(fs));
   12188                      assign(t2, getFReg(fd));
   12189                      assign(t3, binop(Iop_CmpNE64, mkU64(0), getIReg(rt)));
   12190                   } else {
   12191                      if (fp_mode64) {
   12192                         assign(t1, getFReg(fs));
   12193                         assign(t2, getFReg(fd));
   12194                         assign(t3, binop(Iop_CmpNE32, mkU32(0), getIReg(rt)));
   12195                      } else {
   12196                         assign(t1, unop(Iop_F32toF64, getFReg(fs)));
   12197                         assign(t2, unop(Iop_F32toF64, getFReg(fd)));
   12198                         assign(t3, binop(Iop_CmpNE32, mkU32(0), getIReg(rt)));
   12199                      }
   12200                   }
   12201 
   12202                   assign(t4, IRExpr_ITE(mkexpr(t3), mkexpr(t1), mkexpr(t2)));
   12203                   if (fp_mode64) {
   12204                      IRTemp f = newTemp(Ity_F64);
   12205                      IRTemp fd_hi = newTemp(Ity_I32);
   12206                      t5 = newTemp(Ity_I64);
   12207                      assign(f, getFReg(fd));
   12208                      assign(fd_hi, unop(Iop_64HIto32, unop(Iop_ReinterpF64asI64,
   12209                                         mkexpr(f))));
   12210 
   12211                      assign(t5, mkWidenFrom32(Ity_I64, unop(Iop_64to32,
   12212                                 unop(Iop_ReinterpF64asI64, mkexpr(t4))), True));
   12213 
   12214                      putFReg(fd, unop (Iop_ReinterpI64asF64, mkexpr(t5)));
   12215                   } else
   12216                      putFReg(fd, binop(Iop_F64toF32, get_IR_roundingmode(),
   12217                                        mkexpr(t4)));
   12218                   break;
   12219                case 0x11:  /* D */
   12220                   DIP("movn.d f%d, f%d, r%d", fd, fs, rt);
   12221 
   12222                   t3 = newTemp(Ity_I1);
   12223                   t4 = newTemp(Ity_F64);
   12224 
   12225                   if (mode64)
   12226                      assign(t3, binop(Iop_CmpNE64, mkU64(0), getIReg(rt)));
   12227                   else
   12228                      assign(t3, binop(Iop_CmpNE32, mkU32(0), getIReg(rt)));
   12229 
   12230                   putDReg(fd, IRExpr_ITE(mkexpr(t3), getDReg(fs), getDReg(fd)));
   12231                   break;
   12232                default:
   12233                   goto decode_failure;
   12234                }
   12235                break;  /* MOVN.fmt */
   12236 
   12237             case 0x12:  /* MOVZ.fmt */
   12238                switch (fmt) {
   12239                case 0x10:  /* S */
   12240                   DIP("movz.s f%d, f%d, r%d", fd, fs, rt);
   12241 
   12242                   t1 = newTemp(Ity_F64);
   12243                   t2 = newTemp(Ity_F64);
   12244                   t3 = newTemp(Ity_I1);
   12245                   t4 = newTemp(Ity_F64);
   12246                   if (fp_mode64) {
   12247                      assign(t1, getFReg(fs));
   12248                      assign(t2, getFReg(fd));
   12249                      if (mode64)
   12250                         assign(t3, binop(Iop_CmpEQ64, mkU64(0), getIReg(rt)));
   12251                      else
   12252                         assign(t3, binop(Iop_CmpEQ32, mkU32(0), getIReg(rt)));
   12253                   } else {
   12254                      assign(t1, unop(Iop_F32toF64, getFReg(fs)));
   12255                      assign(t2, unop(Iop_F32toF64, getFReg(fd)));
   12256                      assign(t3, binop(Iop_CmpEQ32, mkU32(0), getIReg(rt)));
   12257                   }
   12258                   assign(t4, IRExpr_ITE(mkexpr(t3), mkexpr(t1), mkexpr(t2)));
   12259 
   12260                  if (fp_mode64) {
   12261                      IRTemp f = newTemp(Ity_F64);
   12262                      IRTemp fd_hi = newTemp(Ity_I32);
   12263                      t7 = newTemp(Ity_I64);
   12264                      assign(f, getFReg(fd));
   12265                      assign(fd_hi, unop(Iop_64HIto32,
   12266                                    unop(Iop_ReinterpF64asI64, mkexpr(f))));
   12267                      assign(t7, mkWidenFrom32(Ity_I64, unop(Iop_64to32,
   12268                                 unop(Iop_ReinterpF64asI64, mkexpr(t4))), True));
   12269 
   12270                      putFReg(fd, unop(Iop_ReinterpI64asF64, mkexpr(t7)));
   12271                   } else
   12272                      putFReg(fd, binop(Iop_F64toF32, get_IR_roundingmode(),
   12273                                        mkexpr(t4)));
   12274 
   12275                   break;
   12276                case 0x11:  /* D */
   12277                   DIP("movz.d f%d, f%d, r%d", fd, fs, rt);
   12278                   t3 = newTemp(Ity_I1);
   12279                   t4 = newTemp(Ity_F64);
   12280                   if (mode64)
   12281                      assign(t3, binop(Iop_CmpEQ64, mkU64(0), getIReg(rt)));
   12282                   else
   12283                      assign(t3, binop(Iop_CmpEQ32, mkU32(0), getIReg(rt)));
   12284 
   12285                   putDReg(fd, IRExpr_ITE(mkexpr(t3), getDReg(fs), getDReg(fd)));
   12286                   break;
   12287                default:
   12288                   goto decode_failure;
   12289                }
   12290                break;  /* MOVZ.fmt */
   12291 
   12292             case 0x11:  /* MOVT.fmt */
   12293                if (tf == 1) {
   12294                   UInt mov_cc = get_mov_cc(cins);
   12295                   switch (fmt) {  /* MOVCF = 010001 */
   12296                   case 0x11:  /* D */
   12297                      DIP("movt.d f%d, f%d, %d", fd, fs, mov_cc);
   12298                      t1 = newTemp(Ity_I1);
   12299                      t2 = newTemp(Ity_I32);
   12300                      t3 = newTemp(Ity_I1);
   12301                      t4 = newTemp(Ity_F64);
   12302 
   12303                      assign(t1, binop(Iop_CmpEQ32, mkU32(0), mkU32(mov_cc)));
   12304                      assign(t2, IRExpr_ITE(mkexpr(t1),
   12305                                            binop(Iop_And32,
   12306                                                  binop(Iop_Shr32, getFCSR(),
   12307                                                        mkU8(23)),
   12308                                                  mkU32(0x1)),
   12309                                            binop(Iop_And32,
   12310                                                  binop(Iop_Shr32, getFCSR(),
   12311                                                        mkU8(24 + mov_cc)),
   12312                                                  mkU32(0x1))
   12313                                            ));
   12314 
   12315                      assign(t3, binop(Iop_CmpEQ32, mkU32(1), mkexpr(t2)));
   12316                      assign(t4, IRExpr_ITE(mkexpr(t3),
   12317                                            getDReg(fs), getDReg(fd)));
   12318                      putDReg(fd, mkexpr(t4));
   12319                      break;
   12320                   case 0x10:  /* S */
   12321                      DIP("movt.s f%d, f%d, %d", fd, fs, mov_cc);
   12322                      t1 = newTemp(Ity_I1);
   12323                      t2 = newTemp(Ity_I32);
   12324                      t3 = newTemp(Ity_I1);
   12325                      t4 = newTemp(Ity_F64);
   12326                      t5 = newTemp(Ity_F64);
   12327                      t6 = newTemp(Ity_F64);
   12328                      t7 = newTemp(Ity_I64);
   12329 
   12330                      if (fp_mode64) {
   12331                         assign(t5, getFReg(fs));
   12332                         assign(t6, getFReg(fd));
   12333                      } else {
   12334                         assign(t5, unop(Iop_F32toF64, getFReg(fs)));
   12335                         assign(t6, unop(Iop_F32toF64, getFReg(fd)));
   12336                      }
   12337 
   12338                      assign(t1, binop(Iop_CmpEQ32, mkU32(0), mkU32(mov_cc)));
   12339                      assign(t2, IRExpr_ITE(mkexpr(t1),
   12340                                            binop(Iop_And32,
   12341                                                  binop(Iop_Shr32, getFCSR(),
   12342                                                        mkU8(23)),
   12343                                                  mkU32(0x1)),
   12344                                            binop(Iop_And32,
   12345                                                  binop(Iop_Shr32, getFCSR(),
   12346                                                        mkU8(24 + mov_cc)),
   12347                                                  mkU32(0x1))
   12348                                            ));
   12349 
   12350                      assign(t3, binop(Iop_CmpEQ32, mkU32(1), mkexpr(t2)));
   12351                      assign(t4, IRExpr_ITE(mkexpr(t3),
   12352                                            mkexpr(t5), mkexpr(t6)));
   12353 
   12354                      if (fp_mode64) {
   12355                         IRTemp f = newTemp(Ity_F64);
   12356                         IRTemp fd_hi = newTemp(Ity_I32);
   12357                         assign(f, getFReg(fd));
   12358                         assign(fd_hi, unop(Iop_64HIto32,
   12359                                       unop(Iop_ReinterpF64asI64, mkexpr(f))));
   12360                         assign(t7, mkWidenFrom32(Ity_I64, unop(Iop_64to32,
   12361                                       unop(Iop_ReinterpF64asI64, mkexpr(t4))),
   12362                                       True));
   12363 
   12364                         putFReg(fd, unop(Iop_ReinterpI64asF64, mkexpr(t7)));
   12365                      } else
   12366                         putFReg(fd, binop(Iop_F64toF32, get_IR_roundingmode(),
   12367                                           mkexpr(t4)));
   12368                      break;
   12369                   default:
   12370                      goto decode_failure;
   12371                   }
   12372                } else if (tf == 0)  /* movf.fmt */
   12373                {
   12374                   UInt mov_cc = get_mov_cc(cins);
   12375                   switch (fmt)  /* MOVCF = 010001 */
   12376                   {
   12377                   case 0x11:  /* D */
   12378                      DIP("movf.d f%d, f%d, %d", fd, fs, mov_cc);
   12379                      t1 = newTemp(Ity_I1);
   12380                      t2 = newTemp(Ity_I32);
   12381                      t3 = newTemp(Ity_I1);
   12382                      t4 = newTemp(Ity_F64);
   12383 
   12384                      assign(t1, binop(Iop_CmpEQ32, mkU32(0), mkU32(mov_cc)));
   12385                      assign(t2, IRExpr_ITE(mkexpr(t1),
   12386                                            binop(Iop_And32,
   12387                                                  binop(Iop_Shr32, getFCSR(),
   12388                                                        mkU8(23)),
   12389                                                  mkU32(0x1)),
   12390                                            binop(Iop_And32,
   12391                                                  binop(Iop_Shr32, getFCSR(),
   12392                                                        mkU8(24 + mov_cc)),
   12393                                                  mkU32(0x1))
   12394                                            ));
   12395 
   12396                      assign(t3, binop(Iop_CmpEQ32, mkU32(0), mkexpr(t2)));
   12397                      assign(t4, IRExpr_ITE(mkexpr(t3),
   12398                                            getDReg(fs), getDReg(fd)));
   12399                      putDReg(fd, mkexpr(t4));
   12400                      break;
   12401                   case 0x10:  /* S */
   12402                      DIP("movf.s f%d, f%d, %d", fd, fs, mov_cc);
   12403                      t1 = newTemp(Ity_I1);
   12404                      t2 = newTemp(Ity_I32);
   12405                      t3 = newTemp(Ity_I1);
   12406                      t4 = newTemp(Ity_F64);
   12407                      t5 = newTemp(Ity_F64);
   12408                      t6 = newTemp(Ity_F64);
   12409 
   12410                      if (fp_mode64) {
   12411                         assign(t5, getFReg(fs));
   12412                         assign(t6, getFReg(fd));
   12413                      } else {
   12414                         assign(t5, unop(Iop_F32toF64, getFReg(fs)));
   12415                         assign(t6, unop(Iop_F32toF64, getFReg(fd)));
   12416                      }
   12417 
   12418                      assign(t1, binop(Iop_CmpEQ32, mkU32(0), mkU32(mov_cc)));
   12419                      assign(t2, IRExpr_ITE(mkexpr(t1),
   12420                                            binop(Iop_And32,
   12421                                                  binop(Iop_Shr32, getFCSR(),
   12422                                                        mkU8(23)),
   12423                                                  mkU32(0x1)),
   12424                                            binop(Iop_And32,
   12425                                                  binop(Iop_Shr32, getFCSR(),
   12426                                                        mkU8(24 + mov_cc)),
   12427                                                  mkU32(0x1))
   12428                                            ));
   12429 
   12430                      assign(t3, binop(Iop_CmpEQ32, mkU32(0), mkexpr(t2)));
   12431                      assign(t4, IRExpr_ITE(mkexpr(t3),
   12432                                            mkexpr(t5), mkexpr(t6)));
   12433 
   12434                      if (fp_mode64) {
   12435                         IRTemp f = newTemp(Ity_F64);
   12436                         IRTemp fd_hi = newTemp(Ity_I32);
   12437                         t7 = newTemp(Ity_I64);
   12438                         assign(f, getFReg(fd));
   12439                         assign(fd_hi, unop(Iop_64HIto32,
   12440                                       unop(Iop_ReinterpF64asI64, mkexpr(f))));
   12441                         assign(t7, mkWidenFrom32(Ity_I64, unop(Iop_64to32,
   12442                                    unop(Iop_ReinterpF64asI64, mkexpr(t4))),
   12443                                    True));
   12444 
   12445                         putFReg(fd, unop(Iop_ReinterpI64asF64, mkexpr(t7)));
   12446                      } else
   12447                         putFReg(fd, binop(Iop_F64toF32, get_IR_roundingmode(),
   12448                                           mkexpr(t4)));
   12449                      break;
   12450                   default:
   12451                      goto decode_failure;
   12452                   }
   12453                }
   12454 
   12455                break;  /* MOVT.fmt */
   12456 
   12457             case 0x0:  /* add.fmt */
   12458                switch (fmt) {
   12459                case 0x10: {  /* S */
   12460                   DIP("add.s f%d, f%d, f%d", fd, fs, ft);
   12461                   calculateFCSR(fs, ft, ADDS, True, 2);
   12462                   IRExpr *rm = get_IR_roundingmode();
   12463                   putFReg(fd, mkWidenFromF32(tyF, triop(Iop_AddF32, rm,
   12464                               getLoFromF64(tyF, getFReg(fs)),
   12465                               getLoFromF64(tyF, getFReg(ft)))));
   12466                   break;
   12467                }
   12468                case 0x11: {  /* D */
   12469                   DIP("add.d f%d, f%d, f%d", fd, fs, ft);
   12470                   calculateFCSR(fs, ft, ADDD, False, 2);
   12471                   IRExpr *rm = get_IR_roundingmode();
   12472                   putDReg(fd, triop(Iop_AddF64, rm, getDReg(fs), getDReg(ft)));
   12473                   break;
   12474                }
   12475 
   12476                case 0x4:  /* MTC1 (Move Word to Floating Point) */
   12477                   DIP("mtc1 r%d, f%d", rt, fs);
   12478                   if (fp_mode64) {
   12479                      t0 = newTemp(Ity_I32);
   12480                      t1 = newTemp(Ity_F32);
   12481                      assign(t0, mkNarrowTo32(ty, getIReg(rt)));
   12482                      assign(t1, unop(Iop_ReinterpI32asF32, mkexpr(t0)));
   12483 
   12484                      putFReg(fs, mkWidenFromF32(tyF, mkexpr(t1)));
   12485                   } else
   12486                      putFReg(fs, unop(Iop_ReinterpI32asF32, getIReg(rt)));
   12487                   break;
   12488 
   12489                case 0x5:  /* Doubleword Move to Floating Point DMTC1; MIPS64 */
   12490                   DIP("dmtc1 r%d, f%d", rt, fs);
   12491                   vassert(mode64);
   12492                   putFReg(fs, unop(Iop_ReinterpI64asF64, getIReg(rt)));
   12493                   break;
   12494 
   12495                case 0x0:  /* MFC1 */
   12496                   DIP("mfc1 r%d, f%d", rt, fs);
   12497                   if (fp_mode64) {
   12498                      t0 = newTemp(Ity_I64);
   12499                      t1 = newTemp(Ity_I32);
   12500                      assign(t0, unop(Iop_ReinterpF64asI64, getFReg(fs)));
   12501                      assign(t1, unop(Iop_64to32, mkexpr(t0)));
   12502                      putIReg(rt, mkWidenFrom32(ty, mkexpr(t1), True));
   12503                   } else
   12504                      putIReg(rt, unop(Iop_ReinterpF32asI32, getFReg(fs)));
   12505                   break;
   12506 
   12507                case 0x1:  /* Doubleword Move from Floating Point DMFC1;
   12508                              MIPS64 */
   12509                   DIP("dmfc1 r%d, f%d", rt, fs);
   12510                   putIReg(rt, unop(Iop_ReinterpF64asI64, getFReg(fs)));
   12511                   break;
   12512 
   12513                case 0x6:  /* CTC1 */
   12514                   DIP("ctc1 r%d, f%d", rt, fs);
   12515                   t0 = newTemp(Ity_I32);
   12516                   t1 = newTemp(Ity_I32);
   12517                   t2 = newTemp(Ity_I32);
   12518                   t3 = newTemp(Ity_I32);
   12519                   t4 = newTemp(Ity_I32);
   12520                   t5 = newTemp(Ity_I32);
   12521                   t6 = newTemp(Ity_I32);
   12522                   assign(t0, mkNarrowTo32(ty, getIReg(rt)));
   12523                   if (fs == 25) {  /* FCCR */
   12524                      assign(t1, binop(Iop_Shl32, binop(Iop_And32, mkexpr(t0),
   12525                                       mkU32(0x000000FE)), mkU8(24)));
   12526                      assign(t2, binop(Iop_And32, mkexpr(t0),
   12527                                       mkU32(0x01000000)));
   12528                      assign(t3, binop(Iop_Shl32, binop(Iop_And32, mkexpr(t0),
   12529                                       mkU32(0x00000001)), mkU8(23)));
   12530                      assign(t4, binop(Iop_And32, mkexpr(t0),
   12531                                       mkU32(0x007FFFFF)));
   12532                      putFCSR(binop(Iop_Or32, binop(Iop_Or32, mkexpr(t1),
   12533                                    mkexpr(t2)), binop(Iop_Or32, mkexpr(t3),
   12534                                    mkexpr(t4))));
   12535                   } else if (fs == 26) {  /* FEXR */
   12536                      assign(t1, binop(Iop_And32, getFCSR(), mkU32(0xFFFC0000)));
   12537                      assign(t2, binop(Iop_And32, mkexpr(t0),
   12538                                       mkU32(0x0003F000)));
   12539                      assign(t3, binop(Iop_And32, getFCSR(), mkU32(0x00000F80)));
   12540                      assign(t4, binop(Iop_And32, mkexpr(t0),
   12541                                       mkU32(0x0000007C)));
   12542                      assign(t5, binop(Iop_And32, getFCSR(), mkU32(0x00000003)));
   12543                      putFCSR(binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Or32,
   12544                                    mkexpr(t1), mkexpr(t2)), binop(Iop_Or32,
   12545                                    mkexpr(t3), mkexpr(t4))), mkexpr(t5)));
   12546                   } else if (fs == 28) {
   12547                      assign(t1, binop(Iop_And32, getFCSR(), mkU32(0xFE000000)));
   12548                      assign(t2, binop(Iop_Shl32, binop(Iop_And32, mkexpr(t0),
   12549                                 mkU32(0x00000002)), mkU8(22)));
   12550                      assign(t3, binop(Iop_And32, getFCSR(), mkU32(0x00FFF000)));
   12551                      assign(t4, binop(Iop_And32, mkexpr(t0),
   12552                                 mkU32(0x00000F80)));
   12553                      assign(t5, binop(Iop_And32, getFCSR(), mkU32(0x0000007C)));
   12554                      assign(t6, binop(Iop_And32, mkexpr(t0),
   12555                                 mkU32(0x00000003)));
   12556                      putFCSR(binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Or32,
   12557                                    mkexpr(t1), mkexpr(t2)), binop(Iop_Or32,
   12558                                    mkexpr(t3), mkexpr(t4))), binop(Iop_Or32,
   12559                                    mkexpr(t5), mkexpr(t6))));
   12560                   } else if (fs == 31) {
   12561                      putFCSR(mkexpr(t0));
   12562                   }
   12563                   break;
   12564                case 0x2:  /* CFC1 */
   12565                   DIP("cfc1 r%d, f%d", rt, fs);
   12566                   t0 = newTemp(Ity_I32);
   12567                   t1 = newTemp(Ity_I32);
   12568                   t2 = newTemp(Ity_I32);
   12569                   t3 = newTemp(Ity_I32);
   12570                   t4 = newTemp(Ity_I32);
   12571                   t5 = newTemp(Ity_I32);
   12572                   t6 = newTemp(Ity_I32);
   12573                   assign(t0, getFCSR());
   12574                   if (fs == 0) {
   12575                      putIReg(rt, mkWidenFrom32(ty,
   12576                              IRExpr_Get(offsetof(VexGuestMIPS32State,
   12577                                                  guest_FIR),
   12578                                        Ity_I32),
   12579                              False));
   12580                   } else if (fs == 25) {
   12581                      assign(t1, mkU32(0x000000FF));
   12582                      assign(t2, binop(Iop_Shr32, binop(Iop_And32, mkexpr(t0),
   12583                                       mkU32(0xFE000000)), mkU8(25)));
   12584                      assign(t3, binop(Iop_Shr32, binop(Iop_And32, mkexpr(t0),
   12585                                       mkU32(0x00800000)), mkU8(23)));
   12586                      putIReg(rt, mkWidenFrom32(ty, binop(Iop_Or32,
   12587                                  binop(Iop_Or32, mkexpr(t1), mkexpr(t2)),
   12588                                  mkexpr(t3)), False));
   12589                   } else if (fs == 26) {
   12590                      assign(t1, mkU32(0xFFFFF07C));
   12591                      assign(t2, binop(Iop_And32, mkexpr(t0),
   12592                                 mkU32(0x0003F000)));
   12593                      assign(t3, binop(Iop_And32, mkexpr(t0),
   12594                                       mkU32(0x0000007C)));
   12595                      putIReg(rt, mkWidenFrom32(ty, binop(Iop_Or32,
   12596                                  binop(Iop_Or32, mkexpr(t1), mkexpr(t2)),
   12597                                  mkexpr(t3)), False));
   12598                   } else if (fs == 28) {
   12599                      assign(t1, mkU32(0x00000F87));
   12600                      assign(t2, binop(Iop_And32, mkexpr(t0),
   12601                                       mkU32(0x00000F83)));
   12602                      assign(t3, binop(Iop_Shr32, binop(Iop_And32, mkexpr(t0),
   12603                                       mkU32(0x01000000)), mkU8(22)));
   12604                      putIReg(rt, mkWidenFrom32(ty, binop(Iop_Or32,
   12605                                  binop(Iop_Or32, mkexpr(t1), mkexpr(t2)),
   12606                                  mkexpr(t3)), False));
   12607                   } else if (fs == 31) {
   12608                      putIReg(rt, mkWidenFrom32(ty, getFCSR(), False));
   12609                   }
   12610                   break;
   12611                default:
   12612                   goto decode_failure;
   12613                }
   12614                break;
   12615 
   12616             case 0x21:  /* CVT.D */
   12617                switch (fmt) {
   12618                   case 0x10:  /* S */
   12619                      DIP("cvt.d.s f%d, f%d", fd, fs);
   12620                      calculateFCSR(fs, 0, CVTDS, True, 1);
   12621                      if (fp_mode64) {
   12622                         t0 = newTemp(Ity_I64);
   12623                         t1 = newTemp(Ity_I32);
   12624                         t3 = newTemp(Ity_F32);
   12625                         t4 = newTemp(Ity_F32);
   12626                         /* get lo half of FPR */
   12627                         assign(t0, unop(Iop_ReinterpF64asI64, getFReg(fs)));
   12628 
   12629                         assign(t1, unop(Iop_64to32, mkexpr(t0)));
   12630 
   12631                         assign(t3, unop(Iop_ReinterpI32asF32, mkexpr(t1)));
   12632 
   12633                         putFReg(fd, unop(Iop_F32toF64, mkexpr(t3)));
   12634                      } else
   12635                         putDReg(fd, unop(Iop_F32toF64, getFReg(fs)));
   12636                      break;
   12637 
   12638                   case 0x14:
   12639                      DIP("cvt.d.w %d, %d", fd, fs);
   12640                      calculateFCSR(fs, 0, CVTDW, True, 1);
   12641                      if (fp_mode64) {
   12642                         t0 = newTemp(Ity_I64);
   12643                         t1 = newTemp(Ity_I32);
   12644                         t3 = newTemp(Ity_F32);
   12645                         t4 = newTemp(Ity_F32);
   12646                         /* get lo half of FPR */
   12647                         assign(t0, unop(Iop_ReinterpF64asI64, getFReg(fs)));
   12648 
   12649                         assign(t1, unop(Iop_64to32, mkexpr(t0)));
   12650                         putDReg(fd,unop(Iop_I32StoF64, mkexpr(t1)));
   12651                         break;
   12652                      } else {
   12653                         t0 = newTemp(Ity_I32);
   12654                         assign(t0, unop(Iop_ReinterpF32asI32, getFReg(fs)));
   12655                         putDReg(fd, unop(Iop_I32StoF64, mkexpr(t0)));
   12656                         break;
   12657                      }
   12658 
   12659                   case 0x15: {  /* L */
   12660                      if (fp_mode64) {
   12661                         DIP("cvt.d.l %d, %d", fd, fs);
   12662                         calculateFCSR(fs, 0, CVTDL, False, 1);
   12663                         t0 = newTemp(Ity_I64);
   12664                         assign(t0, unop(Iop_ReinterpF64asI64, getFReg(fs)));
   12665 
   12666                         putFReg(fd, binop(Iop_I64StoF64,
   12667                                           get_IR_roundingmode(), mkexpr(t0)));
   12668                         break;
   12669                      } else
   12670                         goto decode_failure;
   12671                   }
   12672                   default:
   12673                      goto decode_failure;
   12674                }
   12675                break;  /* CVT.D */
   12676 
   12677             case 0x20:  /* cvt.s */
   12678                switch (fmt) {
   12679                   case 0x14:  /* W */
   12680                      DIP("cvt.s.w %d, %d", fd, fs);
   12681                      calculateFCSR(fs, 0, CVTSW, True, 1);
   12682                      if (fp_mode64) {
   12683                         t0 = newTemp(Ity_I64);
   12684                         t1 = newTemp(Ity_I32);
   12685                         t3 = newTemp(Ity_F32);
   12686                         t4 = newTemp(Ity_F32);
   12687                         /* get lo half of FPR */
   12688                         assign(t0, unop(Iop_ReinterpF64asI64, getFReg(fs)));
   12689 
   12690                         assign(t1, unop(Iop_64to32, mkexpr(t0)));
   12691                         putFReg(fd, mkWidenFromF32(tyF, binop(Iop_I32StoF32,
   12692                                     get_IR_roundingmode(), mkexpr(t1))));
   12693                      } else {
   12694                         t0 = newTemp(Ity_I32);
   12695                         assign(t0, unop(Iop_ReinterpF32asI32, getFReg(fs)));
   12696                         putFReg(fd, binop(Iop_I32StoF32, get_IR_roundingmode(),
   12697                                     mkexpr(t0)));
   12698                      }
   12699                      break;
   12700 
   12701                   case 0x11:  /* D */
   12702                      DIP("cvt.s.d %d, %d", fd, fs);
   12703                      calculateFCSR(fs, 0, CVTSD, False, 1);
   12704                      t0 = newTemp(Ity_F32);
   12705                      assign(t0, binop(Iop_F64toF32, get_IR_roundingmode(),
   12706                                       getDReg(fs)));
   12707                      putFReg(fd, mkWidenFromF32(tyF, mkexpr(t0)));
   12708                      break;
   12709 
   12710                   case 0x15:  /* L */
   12711                      DIP("cvt.s.l %d, %d", fd, fs);
   12712                      calculateFCSR(fs, 0, CVTSL, False, 1);
   12713                      t0 = newTemp(Ity_I64);
   12714                      assign(t0, unop(Iop_ReinterpF64asI64, getFReg(fs)));
   12715 
   12716                      putFReg(fd, mkWidenFromF32(tyF, binop(Iop_I64StoF32,
   12717                                  get_IR_roundingmode(), mkexpr(t0))));
   12718                      break;
   12719 
   12720                   default:
   12721                      goto decode_failure;
   12722                }
   12723                break;  /* cvt.s */
   12724 
   12725             case 0x24:  /* cvt.w */
   12726                switch (fmt) {
   12727                case 0x10:  /* S */
   12728                   DIP("cvt.w.s %d, %d", fd, fs);
   12729                   calculateFCSR(fs, 0, CVTWS, True, 1);
   12730                   putFReg(fd,
   12731                           mkWidenFromF32(tyF,
   12732                                          binop(Iop_RoundF32toInt,
   12733                                                get_IR_roundingmode(),
   12734                                                getLoFromF64(tyF, getFReg(fs))))
   12735                          );
   12736                   break;
   12737 
   12738                case 0x11:
   12739                   DIP("cvt.w.d %d, %d", fd, fs);
   12740                   calculateFCSR(fs, 0, CVTWD, False, 1);
   12741                   t0 = newTemp(Ity_I32);
   12742                   t1 = newTemp(Ity_F32);
   12743                   assign(t0, binop(Iop_F64toI32S, get_IR_roundingmode(),
   12744                                    getDReg(fs)));
   12745                   assign(t1, unop(Iop_ReinterpI32asF32, mkexpr(t0)));
   12746                   putFReg(fd, mkWidenFromF32(tyF, mkexpr(t1)));
   12747                   break;
   12748 
   12749                default:
   12750                   goto decode_failure;
   12751 
   12752                }
   12753                break;
   12754 
   12755             case 0x25:  /* cvt.l */
   12756                switch (fmt) {
   12757                   case 0x10:  /* S */
   12758                      DIP("cvt.l.s %d, %d", fd, fs);
   12759                      if (fp_mode64) {
   12760                         calculateFCSR(fs, 0, CVTLS, True, 1);
   12761                         t0 = newTemp(Ity_I64);
   12762 
   12763                         assign(t0, binop(Iop_F32toI64S, get_IR_roundingmode(),
   12764                                          getLoFromF64(tyF, getFReg(fs))));
   12765 
   12766                         putDReg(fd, unop(Iop_ReinterpI64asF64, mkexpr(t0)));
   12767                      } else {
   12768                         ILLEGAL_INSTRUCTON;
   12769                      }
   12770                      break;
   12771 
   12772                   case 0x11: {  /* D */
   12773                      DIP("cvt.l.d %d, %d", fd, fs);
   12774                      if (fp_mode64) {
   12775                         calculateFCSR(fs, 0, CVTLD, False, 1);
   12776                         putDReg(fd, binop(Iop_RoundF64toInt,
   12777                                 get_IR_roundingmode(), getDReg(fs)));
   12778                      } else {
   12779                         ILLEGAL_INSTRUCTON;
   12780                      }
   12781                      break;
   12782                   }
   12783 
   12784                   default:
   12785                      goto decode_failure;
   12786                }
   12787                break;
   12788 
   12789             case 0x0B:  /* FLOOR.L.fmt */
   12790                switch (fmt) {
   12791                   case 0x10:  /* S */
   12792                      DIP("floor.l.s %d, %d", fd, fs);
   12793                      if (fp_mode64) {
   12794                         calculateFCSR(fs, 0, FLOORLS, True, 1);
   12795                         t0 = newTemp(Ity_I64);
   12796 
   12797                         assign(t0, binop(Iop_F32toI64S, mkU32(0x1),
   12798                                          getLoFromF64(tyF, getFReg(fs))));
   12799 
   12800                         putDReg(fd, unop(Iop_ReinterpI64asF64, mkexpr(t0)));
   12801                      } else {
   12802                         ILLEGAL_INSTRUCTON;
   12803                      }
   12804                      break;
   12805 
   12806                   case 0x11:  /* D */
   12807                      DIP("floor.l.d %d, %d", fd, fs);
   12808                      if (fp_mode64) {
   12809                         calculateFCSR(fs, 0, FLOORLD, False, 1);
   12810                         putDReg(fd, binop(Iop_RoundF64toInt, mkU32(0x1),
   12811                                           getDReg(fs)));
   12812                      } else {
   12813                         ILLEGAL_INSTRUCTON;
   12814                      }
   12815                      break;
   12816                   default:
   12817                      goto decode_failure;
   12818                }
   12819                break;
   12820 
   12821             case 0x0C:  /* ROUND.W.fmt */
   12822                switch (fmt) {
   12823                   case 0x10:  /* S */
   12824                      DIP("round.w.s f%d, f%d", fd, fs);
   12825                      calculateFCSR(fs, 0, ROUNDWS, True, 1);
   12826                      if (fp_mode64) {
   12827                         t0 = newTemp(Ity_I64);
   12828                         t1 = newTemp(Ity_I32);
   12829                         t3 = newTemp(Ity_F32);
   12830                         t4 = newTemp(Ity_F32);
   12831                         /* get lo half of FPR */
   12832                         assign(t0, unop(Iop_ReinterpF64asI64, getFReg(fs)));
   12833 
   12834                         assign(t1, unop(Iop_64to32, mkexpr(t0)));
   12835 
   12836                         assign(t3, unop(Iop_ReinterpI32asF32, mkexpr(t1)));
   12837 
   12838                         assign(t4, binop(Iop_RoundF32toInt, mkU32(0x0),
   12839                                          mkexpr(t3)));
   12840 
   12841                         putFReg(fd, mkWidenFromF32(tyF, mkexpr(t4)));
   12842                      } else
   12843                         putFReg(fd, binop(Iop_RoundF32toInt, mkU32(0x0),
   12844                                           getFReg(fs)));
   12845                      break;
   12846 
   12847                   case 0x11:  /* D */
   12848                      DIP("round.w.d f%d, f%d", fd, fs);
   12849                      calculateFCSR(fs, 0, ROUNDWD, False, 1);
   12850                      if (fp_mode64) {
   12851                         t0 = newTemp(Ity_I32);
   12852                         assign(t0, binop(Iop_F64toI32S, mkU32(0x0),
   12853                                          getDReg(fs)));
   12854                         putFReg(fd, mkWidenFromF32(tyF,
   12855                                     unop(Iop_ReinterpI32asF32, mkexpr(t0))));
   12856                      } else {
   12857                         t0 = newTemp(Ity_I32);
   12858 
   12859                         assign(t0, binop(Iop_F64toI32S, mkU32(0x0),
   12860                                          getDReg(fs)));
   12861 
   12862                         putFReg(fd, unop(Iop_ReinterpI32asF32, mkexpr(t0)));
   12863                      }
   12864                      break;
   12865                   default:
   12866                      goto decode_failure;
   12867 
   12868                   }
   12869                   break;  /* ROUND.W.fmt */
   12870 
   12871             case 0x0F:  /* FLOOR.W.fmt */
   12872                switch (fmt) {
   12873                   case 0x10:  /* S */
   12874                      DIP("floor.w.s f%d, f%d", fd, fs);
   12875                      calculateFCSR(fs, 0, FLOORWS, True, 1);
   12876                      if (fp_mode64) {
   12877                         t0 = newTemp(Ity_I64);
   12878                         t1 = newTemp(Ity_I32);
   12879                         t3 = newTemp(Ity_F32);
   12880                         t4 = newTemp(Ity_F32);
   12881                         /* get lo half of FPR */
   12882                         assign(t0, unop(Iop_ReinterpF64asI64, getFReg(fs)));
   12883 
   12884                         assign(t1, unop(Iop_64to32, mkexpr(t0)));
   12885 
   12886                         assign(t3, unop(Iop_ReinterpI32asF32, mkexpr(t1)));
   12887 
   12888                         assign(t4, binop(Iop_RoundF32toInt, mkU32(0x1),
   12889                                          mkexpr(t3)));
   12890 
   12891                         putFReg(fd, mkWidenFromF32(tyF, mkexpr(t4)));
   12892                      } else
   12893                         putFReg(fd, binop(Iop_RoundF32toInt, mkU32(0x1),
   12894                                          getFReg(fs)));
   12895                      break;
   12896 
   12897                   case 0x11:  /* D */
   12898                      DIP("floor.w.d f%d, f%d", fd, fs);
   12899                      calculateFCSR(fs, 0, FLOORWD, False, 1);
   12900                      if (fp_mode64) {
   12901                         t0 = newTemp(Ity_I32);
   12902                         assign(t0, binop(Iop_F64toI32S, mkU32(0x1),
   12903                                          getDReg(fs)));
   12904                         putFReg(fd, mkWidenFromF32(tyF,
   12905                                     unop(Iop_ReinterpI32asF32, mkexpr(t0))));
   12906                         break;
   12907                      } else {
   12908                         t0 = newTemp(Ity_I32);
   12909 
   12910                         assign(t0, binop(Iop_F64toI32S, mkU32(0x1),
   12911                                          getDReg(fs)));
   12912 
   12913                         putFReg(fd, unop(Iop_ReinterpI32asF32, mkexpr(t0)));
   12914                         break;
   12915                      }
   12916                   default:
   12917                      goto decode_failure;
   12918 
   12919                }
   12920                break;  /* FLOOR.W.fmt */
   12921 
   12922             case 0x0D:  /* TRUNC.W */
   12923                switch (fmt) {
   12924                   case 0x10:  /* S */
   12925                      DIP("trunc.w.s %d, %d", fd, fs);
   12926                      calculateFCSR(fs, 0, TRUNCWS, True, 1);
   12927                      if (fp_mode64) {
   12928                         t0 = newTemp(Ity_I64);
   12929                         t1 = newTemp(Ity_I32);
   12930                         t3 = newTemp(Ity_F32);
   12931                         t4 = newTemp(Ity_F32);
   12932                         /* get lo half of FPR */
   12933                         assign(t0, unop(Iop_ReinterpF64asI64, getFReg(fs)));
   12934 
   12935                         assign(t1, unop(Iop_64to32, mkexpr(t0)));
   12936 
   12937                         assign(t3, unop(Iop_ReinterpI32asF32, mkexpr(t1)));
   12938 
   12939                         assign(t4, binop(Iop_RoundF32toInt, mkU32(0x3),
   12940                                          mkexpr(t3)));
   12941 
   12942                         putFReg(fd, mkWidenFromF32(tyF, mkexpr(t4)));
   12943                      } else
   12944                         putFReg(fd, binop(Iop_RoundF32toInt, mkU32(0x3),
   12945                                        getFReg(fs)));
   12946                      break;
   12947                   case 0x11:  /* D */
   12948                      DIP("trunc.w.d %d, %d", fd, fs);
   12949                      calculateFCSR(fs, 0, TRUNCWD, False, 1);
   12950                      if (fp_mode64) {
   12951                         t0 = newTemp(Ity_I32);
   12952 
   12953                         assign(t0, binop(Iop_F64toI32S, mkU32(0x3),
   12954                                          getFReg(fs)));
   12955 
   12956                         putFReg(fd, mkWidenFromF32(tyF,
   12957                                     unop(Iop_ReinterpI32asF32, mkexpr(t0))));
   12958                      } else {
   12959                         t0 = newTemp(Ity_I32);
   12960 
   12961                         assign(t0, binop(Iop_F64toI32S, mkU32(0x3),
   12962                                          getDReg(fs)));
   12963 
   12964                         putFReg(fd, unop(Iop_ReinterpI32asF32, mkexpr(t0)));
   12965                      }
   12966                      break;
   12967                   default:
   12968                      goto decode_failure;
   12969 
   12970                }
   12971                break;
   12972 
   12973             case 0x0E:  /* CEIL.W.fmt */
   12974                switch (fmt) {
   12975                   case 0x10:  /* S */
   12976                      DIP("ceil.w.s %d, %d", fd, fs);
   12977                      calculateFCSR(fs, 0, CEILWS, True, 1);
   12978                      if (fp_mode64) {
   12979                         t0 = newTemp(Ity_I64);
   12980                         t1 = newTemp(Ity_I32);
   12981                         t3 = newTemp(Ity_F32);
   12982                         t4 = newTemp(Ity_F32);
   12983                         /* get lo half of FPR */
   12984                         assign(t0, unop(Iop_ReinterpF64asI64, getFReg(fs)));
   12985 
   12986                         assign(t1, unop(Iop_64to32, mkexpr(t0)));
   12987 
   12988                         assign(t3, unop(Iop_ReinterpI32asF32, mkexpr(t1)));
   12989 
   12990                         assign(t4, binop(Iop_RoundF32toInt, mkU32(0x2),
   12991                                          mkexpr(t3)));
   12992 
   12993                         putFReg(fd, mkWidenFromF32(tyF, mkexpr(t4)));
   12994                      } else
   12995                         putFReg(fd, binop(Iop_RoundF32toInt, mkU32(0x2),
   12996                                           getFReg(fs)));
   12997                      break;
   12998 
   12999                   case 0x11:  /* D */
   13000                      DIP("ceil.w.d %d, %d", fd, fs);
   13001                      calculateFCSR(fs, 0, CEILWD, False, 1);
   13002                      if (!fp_mode64) {
   13003                         t0 = newTemp(Ity_I32);
   13004                         assign(t0, binop(Iop_F64toI32S, mkU32(0x2),
   13005                                          getDReg(fs)));
   13006                         putFReg(fd, unop(Iop_ReinterpI32asF32, mkexpr(t0)));
   13007                      } else {
   13008                         t0 = newTemp(Ity_I32);
   13009                         assign(t0, binop(Iop_F64toI32S, mkU32(0x2),
   13010                                          getDReg(fs)));
   13011                         putFReg(fd, mkWidenFromF32(tyF,
   13012                                     unop(Iop_ReinterpI32asF32, mkexpr(t0))));
   13013                      }
   13014                      break;
   13015                   default:
   13016                      goto decode_failure;
   13017 
   13018                }
   13019                break;
   13020 
   13021             case 0x0A:  /* CEIL.L.fmt */
   13022                switch (fmt) {
   13023                   case 0x10:  /* S */
   13024                      DIP("ceil.l.s %d, %d", fd, fs);
   13025                      if (fp_mode64) {
   13026                         calculateFCSR(fs, 0, CEILLS, True, 1);
   13027                         t0 = newTemp(Ity_I64);
   13028 
   13029                         assign(t0, binop(Iop_F32toI64S, mkU32(0x2),
   13030                                    getLoFromF64(tyF, getFReg(fs))));
   13031 
   13032                         putFReg(fd, unop(Iop_ReinterpI64asF64, mkexpr(t0)));
   13033                      } else {
   13034                         ILLEGAL_INSTRUCTON;
   13035                      }
   13036                      break;
   13037 
   13038                   case 0x11:  /* D */
   13039                      DIP("ceil.l.d %d, %d", fd, fs);
   13040                      if (fp_mode64) {
   13041                         calculateFCSR(fs, 0, CEILLD, False, 1);
   13042                         putFReg(fd, binop(Iop_RoundF64toInt, mkU32(0x2),
   13043                                           getFReg(fs)));
   13044                      } else {
   13045                         ILLEGAL_INSTRUCTON;
   13046                      }
   13047                      break;
   13048 
   13049                   default:
   13050                      goto decode_failure;
   13051 
   13052                }
   13053                break;
   13054 
   13055             case 0x16:  /* RSQRT.fmt */
   13056                switch (fmt) {
   13057                   case 0x10: {  /* S */
   13058                      DIP("rsqrt.s %d, %d", fd, fs);
   13059                      IRExpr *rm = get_IR_roundingmode();
   13060                      putFReg(fd, mkWidenFromF32(tyF, triop(Iop_DivF32, rm,
   13061                                  unop(Iop_ReinterpI32asF32, mkU32(ONE_SINGLE)),
   13062                                  binop(Iop_SqrtF32, rm, getLoFromF64(tyF,
   13063                                  getFReg(fs))))));
   13064                      break;
   13065                   }
   13066                   case 0x11: {  /* D */
   13067                      DIP("rsqrt.d %d, %d", fd, fs);
   13068                      IRExpr *rm = get_IR_roundingmode();
   13069                      putDReg(fd, triop(Iop_DivF64, rm,
   13070                                  unop(Iop_ReinterpI64asF64,
   13071                                  mkU64(ONE_DOUBLE)),
   13072                                  binop(Iop_SqrtF64, rm, getDReg(fs))));
   13073                      break;
   13074                   }
   13075                   default:
   13076                      goto decode_failure;
   13077 
   13078                }
   13079                break;
   13080 
   13081             default:
   13082                if (dis_instr_CCondFmt(cins))
   13083                   break;
   13084                goto decode_failure;
   13085 
   13086             }
   13087 
   13088          }
   13089       }
   13090       break;  /* COP1 */
   13091    case 0x10:  /* COP0 */
   13092       if (rs == 0) {  /* MFC0 */
   13093          DIP("mfc0 r%d, r%d, %d", rt, rd, sel);
   13094          IRTemp   val  = newTemp(Ity_I32);
   13095          IRExpr** args = mkIRExprVec_3 (IRExpr_BBPTR(), mkU32(rd), mkU32(sel));
   13096          IRDirty *d = unsafeIRDirty_1_N(val,
   13097                                         0,
   13098                                         "mips32_dirtyhelper_mfc0",
   13099                                         &mips32_dirtyhelper_mfc0,
   13100                                         args);
   13101          stmt(IRStmt_Dirty(d));
   13102          putIReg(rt, mkexpr(val));
   13103       } else if (rs == 1) {
   13104          /* Doubleword Move from Coprocessor 0 - DMFC0; MIPS64 */
   13105          DIP("dmfc0 r%d, r%d, %d", rt, rd, sel);
   13106          IRTemp   val  = newTemp(Ity_I64);
   13107          IRExpr** args = mkIRExprVec_3 (IRExpr_BBPTR(), mkU64(rd), mkU64(sel));
   13108          IRDirty *d = unsafeIRDirty_1_N(val,
   13109                                         0,
   13110                                         "mips64_dirtyhelper_dmfc0",
   13111                                         &mips64_dirtyhelper_dmfc0,
   13112                                         args);
   13113          stmt(IRStmt_Dirty(d));
   13114          putDReg(rt, mkexpr(val));
   13115       } else
   13116          goto decode_failure;
   13117       break;
   13118 
   13119    case 0x31:  /* LWC1 */
   13120       /* Load Word to Floating Point - LWC1 (MIPS32) */
   13121       DIP("lwc1 f%d, %d(r%d)", ft, imm, rs);
   13122       if (fp_mode64) {
   13123          t1 = newTemp(Ity_F32);
   13124          t2 = newTemp(Ity_I64);
   13125          if (mode64) {
   13126             t0 = newTemp(Ity_I64);
   13127             /* new LO */
   13128             assign(t0, binop(Iop_Add64, getIReg(rs),
   13129                              mkU64(extend_s_16to64(imm))));
   13130          } else {
   13131             t0 = newTemp(Ity_I32);
   13132             /* new LO */
   13133             assign(t0, binop(Iop_Add32, getIReg(rs),
   13134                              mkU32(extend_s_16to32(imm))));
   13135          }
   13136          assign(t1, load(Ity_F32, mkexpr(t0)));
   13137          assign(t2, mkWidenFrom32(Ity_I64, unop(Iop_ReinterpF32asI32,
   13138                                                 mkexpr(t1)), True));
   13139          putDReg(ft, unop(Iop_ReinterpI64asF64, mkexpr(t2)));
   13140       } else {
   13141          t0 = newTemp(Ity_I32);
   13142          assign(t0, binop(Iop_Add32, getIReg(rs),
   13143                            mkU32(extend_s_16to32(imm))));
   13144          putFReg(ft, load(Ity_F32, mkexpr(t0)));
   13145       }
   13146       break;
   13147 
   13148    case 0x39:  /* SWC1 */
   13149       DIP("swc1 f%d, %d(r%d)", ft, imm, rs);
   13150       if (fp_mode64) {
   13151          t0 = newTemp(Ity_I64);
   13152          t2 = newTemp(Ity_I32);
   13153          LOAD_STORE_PATTERN;
   13154          assign(t0, unop(Iop_ReinterpF64asI64, getFReg(ft)));
   13155          assign(t2, unop(Iop_64to32, mkexpr(t0)));
   13156          store(mkexpr(t1), unop(Iop_ReinterpI32asF32, mkexpr(t2)));
   13157       } else {
   13158          LOAD_STORE_PATTERN;
   13159          store(mkexpr(t1), getFReg(ft));
   13160       }
   13161       break;
   13162 
   13163    case 0x33:  /* PREF */
   13164       DIP("pref");
   13165       break;
   13166 
   13167    case 0x35:
   13168       /* Load Doubleword to Floating Point - LDC1 (MIPS32) */
   13169       DIP("ldc1 f%d, %d(%d)", rt, imm, rs);
   13170       LOAD_STORE_PATTERN;
   13171       putDReg(ft, load(Ity_F64, mkexpr(t1)));
   13172       break;
   13173 
   13174    case 0x3D:
   13175       /* Store Doubleword from Floating Point - SDC1 */
   13176       DIP("sdc1 f%d, %d(%d)", ft, imm, rs);
   13177       LOAD_STORE_PATTERN;
   13178       store(mkexpr(t1), getDReg(ft));
   13179       break;
   13180 
   13181    case 0x23:  /* LW */
   13182       DIP("lw r%d, %d(r%d)", rt, imm, rs);
   13183       LOAD_STORE_PATTERN;
   13184       putIReg(rt, mkWidenFrom32(ty, load(Ity_I32, mkexpr(t1)), True));
   13185       break;
   13186 
   13187    case 0x20:  /* LB */
   13188       DIP("lb r%d, %d(r%d)", rt, imm, rs);
   13189       LOAD_STORE_PATTERN;
   13190       if (mode64)
   13191          putIReg(rt, unop(Iop_8Sto64, load(Ity_I8, mkexpr(t1))));
   13192       else
   13193          putIReg(rt, unop(Iop_8Sto32, load(Ity_I8, mkexpr(t1))));
   13194       break;
   13195 
   13196    case 0x24:  /* LBU */
   13197       DIP("lbu r%d, %d(r%d)", rt, imm, rs);
   13198       LOAD_STORE_PATTERN;
   13199       if (mode64)
   13200          putIReg(rt, unop(Iop_8Uto64, load(Ity_I8, mkexpr(t1))));
   13201       else
   13202          putIReg(rt, unop(Iop_8Uto32, load(Ity_I8, mkexpr(t1))));
   13203       break;
   13204 
   13205    case 0x21:  /* LH */
   13206       DIP("lh r%d, %d(r%d)", rt, imm, rs);
   13207       LOAD_STORE_PATTERN;
   13208       if (mode64)
   13209          putIReg(rt, unop(Iop_16Sto64, load(Ity_I16, mkexpr(t1))));
   13210       else
   13211          putIReg(rt, unop(Iop_16Sto32, load(Ity_I16, mkexpr(t1))));
   13212       break;
   13213 
   13214    case 0x25:  /* LHU */
   13215       DIP("lhu r%d, %d(r%d)", rt, imm, rs);
   13216       LOAD_STORE_PATTERN;
   13217       if (mode64)
   13218          putIReg(rt, unop(Iop_16Uto64, load(Ity_I16, mkexpr(t1))));
   13219       else
   13220          putIReg(rt, unop(Iop_16Uto32, load(Ity_I16, mkexpr(t1))));
   13221       break;
   13222 
   13223    case 0x0F:  /* LUI */
   13224       p = (imm << 16);
   13225       DIP("lui r%d, imm: 0x%x", rt, imm);
   13226       if (mode64)
   13227          putIReg(rt, mkU64(extend_s_32to64(p)));
   13228       else
   13229          putIReg(rt, mkU32(p));
   13230       break;
   13231 
   13232    case 0x13:  /* COP1X */
   13233       switch (function) {
   13234       case 0x0: {  /* LWXC1 */
   13235          /* Load Word  Indexed to Floating Point - LWXC1 (MIPS32r2) */
   13236          DIP("lwxc1 f%d, r%d(r%d)", fd, rt, rs);
   13237          if (fp_mode64) {
   13238             t0 = newTemp(Ity_I64);
   13239             t1 = newTemp(Ity_I32);
   13240             t3 = newTemp(Ity_F32);
   13241             t4 = newTemp(Ity_I64);
   13242 
   13243             t2 = newTemp(ty);
   13244             /* new LO */
   13245             assign(t2, binop(mode64 ? Iop_Add64 : Iop_Add32, getIReg(rs),
   13246                              getIReg(rt)));
   13247             assign(t3, load(Ity_F32, mkexpr(t2)));
   13248 
   13249             assign(t4, mkWidenFrom32(Ity_I64, unop(Iop_ReinterpF32asI32,
   13250                                                    mkexpr(t3)), True));
   13251 
   13252             putFReg(fd, unop(Iop_ReinterpI64asF64, mkexpr(t4)));
   13253          } else {
   13254             t0 = newTemp(Ity_I32);
   13255             assign(t0, binop(Iop_Add32, getIReg(rs), getIReg(rt)));
   13256             putFReg(fd, load(Ity_F32, mkexpr(t0)));
   13257          }
   13258          break;
   13259       }
   13260 
   13261       case 0x1: {  /* LDXC1 */
   13262          /* Load Doubleword  Indexed to Floating Point
   13263             LDXC1 (MIPS32r2 and MIPS64) */
   13264          if (fp_mode64) {
   13265             DIP("ldxc1 f%d, r%d(r%d)", fd, rt, rs);
   13266             t0 = newTemp(ty);
   13267             assign(t0, binop(mode64 ? Iop_Add64 : Iop_Add32, getIReg(rs),
   13268                              getIReg(rt)));
   13269             putFReg(fd, load(Ity_F64, mkexpr(t0)));
   13270             break;
   13271          } else {
   13272             t0 = newTemp(Ity_I32);
   13273             assign(t0, binop(Iop_Add32, getIReg(rs), getIReg(rt)));
   13274 
   13275             t1 = newTemp(Ity_I32);
   13276             assign(t1, binop(Iop_Add32, mkexpr(t0), mkU32(4)));
   13277 
   13278 #if defined (_MIPSEL)
   13279             putFReg(fd, load(Ity_F32, mkexpr(t0)));
   13280             putFReg(fd + 1, load(Ity_F32, mkexpr(t1)));
   13281 #elif defined (_MIPSEB)
   13282             putFReg(fd + 1, load(Ity_F32, mkexpr(t0)));
   13283             putFReg(fd, load(Ity_F32, mkexpr(t1)));
   13284 #endif
   13285             break;
   13286          }
   13287       }
   13288 
   13289       case 0x5:  /* Load Doubleword Indexed Unaligned to Floating Point - LUXC1;
   13290                     MIPS32r2 */
   13291          DIP("luxc1 f%d, r%d(r%d)", fd, rt, rs);
   13292          t0 = newTemp(Ity_I64);
   13293          t1 = newTemp(Ity_I64);
   13294          assign(t0, binop(Iop_Add64, getIReg(rs), getIReg(rt)));
   13295          assign(t1, binop(Iop_And64, mkexpr(t0),
   13296                                      mkU64(0xfffffffffffffff8ULL)));
   13297          putFReg(fd, load(Ity_F64, mkexpr(t1)));
   13298          break;
   13299 
   13300       case 0x8: {  /* Store Word Indexed from Floating Point - SWXC1 */
   13301          DIP("swxc1 f%d, r%d(r%d)", ft, rt, rs);
   13302          if (fp_mode64) {
   13303             t0 = newTemp(ty);
   13304             assign(t0, binop(mode64 ? Iop_Add64 : Iop_Add32, getIReg(rs),
   13305                              getIReg(rt)));
   13306             store(mkexpr(t0), getLoFromF64(tyF, getFReg(fs)));
   13307 
   13308          } else {
   13309             t0 = newTemp(Ity_I32);
   13310             assign(t0, binop(Iop_Add32, getIReg(rs), getIReg(rt)));
   13311 
   13312             store(mkexpr(t0), getFReg(fs));
   13313          }
   13314          break;
   13315       }
   13316       case 0x9: {  /* Store Doubleword Indexed from Floating Point - SDXC1 */
   13317          DIP("sdc1 f%d, %d(%d)", ft, imm, rs);
   13318          if (fp_mode64) {
   13319             t0 = newTemp(ty);
   13320             assign(t0, binop(mode64 ? Iop_Add64 : Iop_Add32, getIReg(rs),
   13321                              getIReg(rt)));
   13322             store(mkexpr(t0), getFReg(fs));
   13323          } else {
   13324             t0 = newTemp(Ity_I32);
   13325             assign(t0, binop(Iop_Add32, getIReg(rs), getIReg(rt)));
   13326 
   13327             t1 = newTemp(Ity_I32);
   13328             assign(t1, binop(Iop_Add32, mkexpr(t0), mkU32(4)));
   13329 
   13330 #if defined (_MIPSEL)
   13331             store(mkexpr(t0), getFReg(fs));
   13332             store(mkexpr(t1), getFReg(fs + 1));
   13333 #elif defined (_MIPSEB)
   13334             store(mkexpr(t0), getFReg(fs + 1));
   13335             store(mkexpr(t1), getFReg(fs));
   13336 #endif
   13337          }
   13338          break;
   13339       }
   13340       case 0xD:  /* Store Doubleword Indexed Unaligned from Floating Point -
   13341                     SUXC1; MIPS64 MIPS32r2 */
   13342          DIP("suxc1 f%d, r%d(r%d)", fd, rt, rs);
   13343          t0 = newTemp(Ity_I64);
   13344          t1 = newTemp(Ity_I64);
   13345          assign(t0, binop(Iop_Add64, getIReg(rs), getIReg(rt)));
   13346          assign(t1, binop(Iop_And64, mkexpr(t0), mkU64(0xfffffffffffffff8ULL)));
   13347          store(mkexpr(t1), getFReg(fs));
   13348          break;
   13349 
   13350       case 0x0F: {
   13351          DIP("prefx");
   13352          break;
   13353       }
   13354       case 0x20:  {  /* MADD.S */
   13355          DIP("madd.s f%d, f%d, f%d, f%d", fd, fmt, fs, ft);
   13356          IRExpr *rm = get_IR_roundingmode();
   13357          t1 = newTemp(Ity_F32);
   13358          assign(t1, qop(Iop_MAddF32, rm,
   13359                         getLoFromF64(tyF, getFReg(fmt)),
   13360                         getLoFromF64(tyF, getFReg(fs)),
   13361                         getLoFromF64(tyF, getFReg(ft))));
   13362          putFReg(fd, mkWidenFromF32(tyF, mkexpr(t1)));
   13363          break;  /* MADD.S */
   13364       }
   13365       case 0x21: {  /* MADD.D */
   13366          DIP("madd.d f%d, f%d, f%d, f%d", fd, fmt, fs, ft);
   13367          IRExpr *rm = get_IR_roundingmode();
   13368          putDReg(fd, qop(Iop_MAddF64, rm, getDReg(fmt), getDReg(fs),
   13369                          getDReg(ft)));
   13370          break;  /* MADD.D */
   13371       }
   13372       case 0x28: {  /* MSUB.S */
   13373          DIP("msub.s f%d, f%d, f%d, f%d", fd, fmt, fs, ft);
   13374          IRExpr *rm = get_IR_roundingmode();
   13375          t1 = newTemp(Ity_F32);
   13376          assign(t1, qop(Iop_MSubF32, rm,
   13377                         getLoFromF64(tyF, getFReg(fmt)),
   13378                         getLoFromF64(tyF, getFReg(fs)),
   13379                         getLoFromF64(tyF, getFReg(ft))));
   13380          putFReg(fd, mkWidenFromF32(tyF, mkexpr(t1)));
   13381          break;  /* MSUB.S */
   13382       }
   13383       case 0x29: {  /* MSUB.D */
   13384          DIP("msub.d f%d, f%d, f%d, f%d", fd, fmt, fs, ft);
   13385          IRExpr *rm = get_IR_roundingmode();
   13386          putDReg(fd, qop(Iop_MSubF64, rm, getDReg(fmt), getDReg(fs),
   13387                          getDReg(ft)));
   13388          break;  /* MSUB.D */
   13389       }
   13390       case 0x30: {  /* NMADD.S */
   13391          DIP("nmadd.s f%d, f%d, f%d, f%d", fd, fmt, fs, ft);
   13392          IRExpr *rm = get_IR_roundingmode();
   13393          t1 = newTemp(Ity_F32);
   13394          assign(t1, qop(Iop_MAddF32, rm,
   13395                         getLoFromF64(tyF, getFReg(fmt)),
   13396                         getLoFromF64(tyF, getFReg(fs)),
   13397                         getLoFromF64(tyF, getFReg(ft))));
   13398 
   13399          putFReg(fd, mkWidenFromF32(tyF, unop(Iop_NegF32, mkexpr(t1))));
   13400          break;  /* NMADD.S */
   13401       }
   13402       case 0x31: {  /* NMADD.D */
   13403          DIP("nmadd.d f%d, f%d, f%d, f%d", fd, fmt, fs, ft);
   13404          IRExpr *rm = get_IR_roundingmode();
   13405          t1 = newTemp(Ity_F64);
   13406          assign(t1, qop(Iop_MAddF64, rm, getDReg(fmt), getDReg(fs),
   13407                         getDReg(ft)));
   13408          putDReg(fd, unop(Iop_NegF64, mkexpr(t1)));
   13409          break;  /* NMADD.D */
   13410       }
   13411       case 0x38: {  /* NMSUBB.S */
   13412          DIP("nmsub.s f%d, f%d, f%d, f%d", fd, fmt, fs, ft);
   13413          IRExpr *rm = get_IR_roundingmode();
   13414          t1 = newTemp(Ity_F32);
   13415          assign(t1, qop(Iop_MSubF32, rm,
   13416                         getLoFromF64(tyF, getFReg(fmt)),
   13417                         getLoFromF64(tyF, getFReg(fs)),
   13418                         getLoFromF64(tyF, getFReg(ft))));
   13419 
   13420          putFReg(fd, mkWidenFromF32(tyF, unop(Iop_NegF32, mkexpr(t1))));
   13421          break;  /* NMSUBB.S */
   13422       }
   13423       case 0x39: {  /* NMSUBB.D */
   13424          DIP("nmsub.d f%d, f%d, f%d, f%d", fd, fmt, fs, ft);
   13425          IRExpr *rm = get_IR_roundingmode();
   13426          t1 = newTemp(Ity_F64);
   13427          assign(t1, qop(Iop_MSubF64, rm, getDReg(fmt), getDReg(fs),
   13428                         getDReg(ft)));
   13429          putDReg(fd, unop(Iop_NegF64, mkexpr(t1)));
   13430          break;  /* NMSUBB.D */
   13431       }
   13432 
   13433       default:
   13434          goto decode_failure;
   13435       }
   13436       break;
   13437 
   13438    case 0x22:  /* LWL */
   13439       DIP("lwl r%d, %d(r%d)", rt, imm, rs);
   13440       if (mode64) {
   13441          /* t1 = addr */
   13442          t1 = newTemp(Ity_I64);
   13443 #if defined (_MIPSEL)
   13444          assign(t1, binop(Iop_Add64, getIReg(rs), mkU64(extend_s_16to64(imm))));
   13445          /* t2 = word addr */
   13446          /* t4 = addr mod 4 */
   13447          LWX_SWX_PATTERN64;
   13448 
   13449          /* t3 = word content - shifted */
   13450          t3 = newTemp(Ity_I32);
   13451          assign(t3, binop(Iop_Shl32, mkNarrowTo32(ty, load(Ity_I64,
   13452                           mkexpr(t2))), narrowTo(Ity_I8, binop(Iop_Shl32,
   13453                     binop(Iop_Sub32, mkU32(0x03), mkexpr(t4)), mkU8(3)))));
   13454 
   13455          /* rt content - adjusted */
   13456          t5 = newTemp(Ity_I32);
   13457          assign(t5, binop(Iop_And32,
   13458                           mkNarrowTo32(ty, getIReg(rt)),
   13459                           binop(Iop_Shr32,
   13460                                 mkU32(0x00FFFFFF),
   13461                                       narrowTo(Ity_I8, binop(Iop_Mul32,
   13462                                                              mkU32(0x08),
   13463                                                              mkexpr(t4))))));
   13464 
   13465          putIReg(rt, mkWidenFrom32(ty, binop(Iop_Or32, mkexpr(t5),
   13466                                              mkexpr(t3)), True));
   13467 #elif defined (_MIPSEB)
   13468          assign(t1, binop(Iop_Xor64, mkU64(0x3),
   13469                 binop(Iop_Add64, getIReg(rs), mkU64(extend_s_16to64(imm)))));
   13470          /* t2 = word addr */
   13471          /* t4 = addr mod 4 */
   13472          LWX_SWX_PATTERN64;
   13473 
   13474          /* t3 = word content - shifted */
   13475          t3 = newTemp(Ity_I32);
   13476          assign(t3, binop(Iop_Shl32, unop(Iop_64HIto32, load(Ity_I64,
   13477                           mkexpr(t2))), narrowTo(Ity_I8, binop(Iop_Shl32,
   13478                     binop(Iop_Sub32, mkU32(0x03), mkexpr(t4)), mkU8(3)))));
   13479 
   13480          /* rt content - adjusted */
   13481          t5 = newTemp(Ity_I32);
   13482          assign(t5, binop(Iop_And32,
   13483                           mkNarrowTo32(ty, getIReg(rt)),
   13484                           binop(Iop_Shr32,
   13485                                 mkU32(0x00FFFFFF),
   13486                                       narrowTo(Ity_I8, binop(Iop_Mul32,
   13487                                                              mkU32(0x08),
   13488                                                              mkexpr(t4))))));
   13489 
   13490          putIReg(rt, mkWidenFrom32(ty, binop(Iop_Or32, mkexpr(t5),
   13491                                              mkexpr(t3)), True));
   13492 #endif
   13493       } else {
   13494          /* t1 = addr */
   13495          t1 = newTemp(Ity_I32);
   13496 #if defined (_MIPSEL)
   13497          assign(t1, binop(Iop_Add32, getIReg(rs), mkU32(extend_s_16to32(imm))));
   13498 #elif defined (_MIPSEB)
   13499          assign(t1, binop(Iop_Xor32, mkU32(0x3), binop(Iop_Add32, getIReg(rs),
   13500                                      mkU32(extend_s_16to32(imm)))));
   13501 #endif
   13502 
   13503          /* t2 = word addr */
   13504          /* t4 = addr mod 4 */
   13505          LWX_SWX_PATTERN;
   13506 
   13507          /* t3 = word content - shifted */
   13508          t3 = newTemp(Ity_I32);
   13509          assign(t3, binop(Iop_Shl32, load(Ity_I32, mkexpr(t2)), narrowTo(Ity_I8,
   13510                     binop(Iop_Shl32, binop(Iop_Sub32, mkU32(0x03), mkexpr(t4)),
   13511                     mkU8(3)))));
   13512 
   13513          /* rt content  - adjusted */
   13514          t5 = newTemp(Ity_I32);
   13515          assign(t5, binop(Iop_And32,
   13516                           getIReg(rt),
   13517                           binop(Iop_Shr32,
   13518                                 mkU32(0x00FFFFFF),
   13519                                       narrowTo(Ity_I8, binop(Iop_Mul32,
   13520                                                              mkU32(0x08),
   13521                                                              mkexpr(t4))))));
   13522 
   13523          putIReg(rt, binop(Iop_Or32, mkexpr(t5), mkexpr(t3)));
   13524       }
   13525       break;
   13526 
   13527    case 0x26:  /* LWR */
   13528       DIP("lwr r%d, %d(r%d)", rt, imm, rs);
   13529       if (mode64) {
   13530          /* t1 = addr */
   13531          t1 = newTemp(Ity_I64);
   13532 #if defined (_MIPSEL)
   13533          assign(t1, binop(Iop_Add64, getIReg(rs), mkU64(extend_s_16to64(imm))));
   13534          /* t2 = word addr */
   13535          /* t4 = addr mod 8 */
   13536          LWX_SWX_PATTERN64;
   13537 
   13538          /* t3 = word content - shifted */
   13539          t3 = newTemp(Ity_I32);
   13540          assign(t3, binop(Iop_Shr32, mkNarrowTo32(ty, load(Ity_I64,mkexpr(t2))),
   13541                     narrowTo(Ity_I8, binop(Iop_Shl32, mkexpr(t4), mkU8(3)))));
   13542 
   13543          /* rt content  - adjusted */
   13544          t5 = newTemp(Ity_I32);
   13545          assign(t5, binop(Iop_And32, mkNarrowTo32(ty, getIReg(rt)),
   13546                 unop(Iop_Not32, binop(Iop_Shr32, mkU32(0xFFFFFFFF),
   13547                 narrowTo(Ity_I8, binop(Iop_Shl32, mkexpr(t4), mkU8(0x3)))))));
   13548 
   13549          putIReg(rt, mkWidenFrom32(ty, binop(Iop_Or32, mkexpr(t5),
   13550                                        mkexpr(t3)), True));
   13551 #elif defined (_MIPSEB)
   13552          assign(t1, binop(Iop_Xor64, mkU64(0x3), binop(Iop_Add64, getIReg(rs),
   13553                           mkU64(extend_s_16to64(imm)))));
   13554          /* t2 = word addr */
   13555          /* t4 = addr mod 4 */
   13556          LWX_SWX_PATTERN64;
   13557 
   13558          /* t3 = word content - shifted */
   13559          t3 = newTemp(Ity_I32);
   13560          assign(t3, binop(Iop_Shr32, unop(Iop_64HIto32, load(Ity_I64,mkexpr(t2))),
   13561                     narrowTo(Ity_I8, binop(Iop_Shl32, mkexpr(t4), mkU8(3)))));
   13562 
   13563          /* rt content  - adjusted */
   13564          t5 = newTemp(Ity_I32);
   13565          assign(t5, binop(Iop_And32, mkNarrowTo32(ty, getIReg(rt)),
   13566                 unop(Iop_Not32, binop(Iop_Shr32, mkU32(0xFFFFFFFF),
   13567                 narrowTo(Ity_I8, binop(Iop_Shl32, mkexpr(t4), mkU8(0x3)))))));
   13568 
   13569          putIReg(rt, mkWidenFrom32(ty, binop(Iop_Or32, mkexpr(t5),
   13570                                        mkexpr(t3)), True));
   13571 #endif
   13572 
   13573       } else {
   13574          /* t1 = addr */
   13575          t1 = newTemp(Ity_I32);
   13576 #if defined (_MIPSEL)
   13577          assign(t1, binop(Iop_Add32, getIReg(rs), mkU32(extend_s_16to32(imm))));
   13578 #elif defined (_MIPSEB)
   13579          assign(t1, binop(Iop_Xor32, mkU32(0x3), binop(Iop_Add32, getIReg(rs),
   13580                                      mkU32(extend_s_16to32(imm)))));
   13581 #endif
   13582 
   13583          /* t2 = word addr */
   13584          /* t4 = addr mod 4 */
   13585          LWX_SWX_PATTERN;
   13586 
   13587          /* t3 = word content - shifted */
   13588          t3 = newTemp(Ity_I32);
   13589          assign(t3, binop(Iop_Shr32, load(Ity_I32, mkexpr(t2)),
   13590                     narrowTo(Ity_I8, binop(Iop_Shl32, mkexpr(t4),
   13591                     mkU8(3)))));
   13592 
   13593          /* rt content  - adjusted */
   13594          t5 = newTemp(Ity_I32);
   13595          assign(t5, binop(Iop_And32, getIReg(rt), unop(Iop_Not32,
   13596                     binop(Iop_Shr32, mkU32(0xFFFFFFFF), narrowTo(Ity_I8,
   13597                           binop(Iop_Shl32, mkexpr(t4), mkU8(0x3)))))));
   13598 
   13599          putIReg(rt, binop(Iop_Or32, mkexpr(t5), mkexpr(t3)));
   13600       }
   13601       break;
   13602 
   13603    case 0x2B:  /* SW */
   13604       DIP("sw r%d, %d(r%d)", rt, imm, rs);
   13605       LOAD_STORE_PATTERN;
   13606       store(mkexpr(t1), mkNarrowTo32(ty, getIReg(rt)));
   13607       break;
   13608 
   13609    case 0x2C: {  /* SDL rt, offset(base) MIPS64 */
   13610       DIP("sdl r%u, %d(r%u)", rt, (Int) imm, rs);
   13611       vassert(mode64);
   13612       IRTemp A_byte = newTemp(Ity_I8);
   13613       IRTemp B_byte = newTemp(Ity_I8);
   13614       IRTemp C_byte = newTemp(Ity_I8);
   13615       IRTemp D_byte = newTemp(Ity_I8);
   13616       IRTemp E_byte = newTemp(Ity_I8);
   13617       IRTemp F_byte = newTemp(Ity_I8);
   13618       IRTemp G_byte = newTemp(Ity_I8);
   13619       IRTemp H_byte = newTemp(Ity_I8);
   13620       IRTemp B_pos  = newTemp(Ity_I64);
   13621       IRTemp C_pos  = newTemp(Ity_I64);
   13622       IRTemp D_pos  = newTemp(Ity_I64);
   13623       IRTemp E_pos  = newTemp(Ity_I64);
   13624       IRTemp F_pos  = newTemp(Ity_I64);
   13625       IRTemp G_pos  = newTemp(Ity_I64);
   13626 
   13627       /* H byte */
   13628       assign(H_byte, getByteFromReg(rt, 0));
   13629       /* G byte */
   13630       assign(G_byte, getByteFromReg(rt, 1));
   13631       /* F byte */
   13632       assign(F_byte, getByteFromReg(rt, 2));
   13633       /* E byte */
   13634       assign(E_byte, getByteFromReg(rt, 3));
   13635       /* D byte */
   13636       assign(D_byte, getByteFromReg(rt, 4));
   13637       /* C byte */
   13638       assign(C_byte, getByteFromReg(rt, 5));
   13639       /* B byte */
   13640       assign(B_byte, getByteFromReg(rt, 6));
   13641       /* A byte */
   13642       assign(A_byte, getByteFromReg(rt, 7));
   13643 
   13644       /* t1 = addr */
   13645       t1 = newTemp(Ity_I64);
   13646       assign(t1, binop(Iop_Add64, getIReg(rs), mkU64(extend_s_16to64(imm))));
   13647 
   13648       /* t2 = word addr */
   13649       t2 = newTemp(Ity_I64);
   13650       assign(t2, binop(Iop_And64, mkexpr(t1), mkU64(0xFFFFFFFFFFFFFFF8ULL)));
   13651 
   13652       /* t3 = addr mod 7 */
   13653       t3 = newTemp(Ity_I64);
   13654       assign(t3, binop(Iop_And64, mkexpr(t1), mkU64(0x7)));
   13655 
   13656 #if defined (_MIPSEL)
   13657       /* Calculate X_byte position. */
   13658       assign(B_pos, IRExpr_ITE(binop(Iop_CmpLT64U, mkexpr(t3), mkU64(0x1)),
   13659                                mkU64(0x0),
   13660                                mkU64(0x1)));
   13661 
   13662       assign(C_pos, IRExpr_ITE(binop(Iop_CmpLT64U, mkexpr(t3), mkU64(0x2)),
   13663                                mkU64(0x0),
   13664                                mkU64(0x2)));
   13665 
   13666       assign(D_pos, IRExpr_ITE(binop(Iop_CmpLT64U, mkexpr(t3), mkU64(0x3)),
   13667                                mkU64(0x0),
   13668                                mkU64(0x3)));
   13669 
   13670       assign(E_pos, IRExpr_ITE(binop(Iop_CmpLT64U, mkexpr(t3), mkU64(0x4)),
   13671                                mkU64(0x0),
   13672                                mkU64(0x4)));
   13673 
   13674       assign(F_pos, IRExpr_ITE(binop(Iop_CmpLT64U, mkexpr(t3), mkU64(0x5)),
   13675                                mkU64(0x0),
   13676                                mkU64(0x5)));
   13677 
   13678       assign(G_pos, IRExpr_ITE(binop(Iop_CmpEQ64, mkexpr(t3), mkU64(0x7)),
   13679                                mkU64(0x1),
   13680                                mkU64(0x0)));
   13681 
   13682       /* Store X_byte on the right place. */
   13683       store(mkexpr(t2), mkexpr(H_byte));
   13684       store(binop(Iop_Add64, mkexpr(t2), mkexpr(G_pos)), mkexpr(G_byte));
   13685       store(binop(Iop_Sub64, mkexpr(t1), mkexpr(F_pos)), mkexpr(F_byte));
   13686       store(binop(Iop_Sub64, mkexpr(t1), mkexpr(E_pos)), mkexpr(E_byte));
   13687       store(binop(Iop_Sub64, mkexpr(t1), mkexpr(D_pos)), mkexpr(D_byte));
   13688       store(binop(Iop_Sub64, mkexpr(t1), mkexpr(C_pos)), mkexpr(C_byte));
   13689       store(binop(Iop_Sub64, mkexpr(t1), mkexpr(B_pos)), mkexpr(B_byte));
   13690       store(mkexpr(t1), mkexpr(A_byte));
   13691 
   13692 #else /* _MIPSEB */
   13693       /* Calculate X_byte position. */
   13694       assign(B_pos, IRExpr_ITE(binop(Iop_CmpEQ64, mkexpr(t3), mkU64(0x7)),
   13695                                mkU64(0x0),
   13696                                mkU64(0x1)));
   13697 
   13698       assign(C_pos, IRExpr_ITE(binop(Iop_CmpLT64U, mkexpr(t3), mkU64(0x6)),
   13699                                mkU64(0x2),
   13700                                mkU64(0x0)));
   13701 
   13702       assign(D_pos, IRExpr_ITE(binop(Iop_CmpLT64U, mkexpr(t3), mkU64(0x5)),
   13703                                mkU64(0x3),
   13704                                mkU64(0x0)));
   13705 
   13706       assign(E_pos, IRExpr_ITE(binop(Iop_CmpLT64U, mkexpr(t3), mkU64(0x4)),
   13707                                mkU64(0x4),
   13708                                mkU64(0x0)));
   13709 
   13710       assign(F_pos, IRExpr_ITE(binop(Iop_CmpLT64U, mkexpr(t3), mkU64(0x3)),
   13711                                mkU64(0x5),
   13712                                mkU64(0x0)));
   13713 
   13714       assign(G_pos, IRExpr_ITE(binop(Iop_CmpEQ64, mkexpr(t3), mkU64(0x0)),
   13715                                mkU64(0x6),
   13716                                mkU64(0x7)));
   13717 
   13718       /* Store X_byte on the right place. */
   13719       store(binop(Iop_Add64, mkexpr(t2), mkU64(0x7)), mkexpr(H_byte));
   13720       store(binop(Iop_Add64, mkexpr(t2), mkexpr(G_pos)), mkexpr(G_byte));
   13721       store(binop(Iop_Add64, mkexpr(t1), mkexpr(F_pos)), mkexpr(F_byte));
   13722       store(binop(Iop_Add64, mkexpr(t1), mkexpr(E_pos)), mkexpr(E_byte));
   13723       store(binop(Iop_Add64, mkexpr(t1), mkexpr(D_pos)), mkexpr(D_byte));
   13724       store(binop(Iop_Add64, mkexpr(t1), mkexpr(C_pos)), mkexpr(C_byte));
   13725       store(binop(Iop_Add64, mkexpr(t1), mkexpr(B_pos)), mkexpr(B_byte));
   13726       store(mkexpr(t1), mkexpr(A_byte));
   13727 #endif
   13728 
   13729       break;
   13730    }
   13731 
   13732    case 0x2D: {
   13733       /* SDR rt, offset(base) - MIPS64 */
   13734       vassert(mode64);
   13735       DIP("sdr r%u, %d(r%u)", rt, imm, rs);
   13736       IRTemp A_byte = newTemp(Ity_I8);
   13737       IRTemp B_byte = newTemp(Ity_I8);
   13738       IRTemp C_byte = newTemp(Ity_I8);
   13739       IRTemp D_byte = newTemp(Ity_I8);
   13740       IRTemp E_byte = newTemp(Ity_I8);
   13741       IRTemp F_byte = newTemp(Ity_I8);
   13742       IRTemp G_byte = newTemp(Ity_I8);
   13743       IRTemp H_byte = newTemp(Ity_I8);
   13744       IRTemp B_pos  = newTemp(Ity_I64);
   13745       IRTemp C_pos  = newTemp(Ity_I64);
   13746       IRTemp D_pos  = newTemp(Ity_I64);
   13747       IRTemp E_pos  = newTemp(Ity_I64);
   13748       IRTemp F_pos  = newTemp(Ity_I64);
   13749       IRTemp G_pos  = newTemp(Ity_I64);
   13750 
   13751       /* H byte */
   13752       assign(H_byte, getByteFromReg(rt, 0));
   13753       /* G byte */
   13754       assign(G_byte, getByteFromReg(rt, 1));
   13755       /* F byte */
   13756       assign(F_byte, getByteFromReg(rt, 2));
   13757       /* E byte */
   13758       assign(E_byte, getByteFromReg(rt, 3));
   13759       /* D byte */
   13760       assign(D_byte, getByteFromReg(rt, 4));
   13761       /* C byte */
   13762       assign(C_byte, getByteFromReg(rt, 5));
   13763       /* B byte */
   13764       assign(B_byte, getByteFromReg(rt, 6));
   13765       /* A byte */
   13766       assign(A_byte, getByteFromReg(rt, 7));
   13767 
   13768       /* t1 = addr */
   13769       t1 = newTemp(Ity_I64);
   13770       assign(t1, binop(Iop_Add64, getIReg(rs), mkU64(extend_s_16to64(imm))));
   13771 
   13772       /* t2 = word addr */
   13773       t2 = newTemp(Ity_I64);
   13774       assign(t2, binop(Iop_And64, mkexpr(t1), mkU64(0xFFFFFFFFFFFFFFF8ULL)));
   13775 
   13776       /* t3 = addr mod 7 */
   13777       t3 = newTemp(Ity_I64);
   13778       assign(t3, binop(Iop_And64, mkexpr(t1), mkU64(0x7)));
   13779 
   13780 #if defined (_MIPSEL)
   13781       /* Calculate X_byte position. */
   13782       assign(B_pos, IRExpr_ITE(binop(Iop_CmpLT64U, mkU64(0x1), mkexpr(t3)),
   13783                                mkU64(0x0),
   13784                                mkU64(0x6)));
   13785 
   13786       assign(C_pos, IRExpr_ITE(binop(Iop_CmpLT64U, mkU64(0x2), mkexpr(t3)),
   13787                                mkU64(0x0),
   13788                                mkU64(0x5)));
   13789 
   13790       assign(D_pos, IRExpr_ITE(binop(Iop_CmpLT64U, mkU64(0x3), mkexpr(t3)),
   13791                                mkU64(0x0),
   13792                                mkU64(0x4)));
   13793 
   13794       assign(E_pos, IRExpr_ITE(binop(Iop_CmpLT64U, mkU64(0x4), mkexpr(t3)),
   13795                                mkU64(0x0),
   13796                                mkU64(0x3)));
   13797 
   13798       assign(F_pos, IRExpr_ITE(binop(Iop_CmpLT64U, mkU64(0x5), mkexpr(t3)),
   13799                                mkU64(0x0),
   13800                                mkU64(0x2)));
   13801 
   13802       assign(G_pos, IRExpr_ITE(binop(Iop_CmpEQ64, mkexpr(t3), mkU64(0x7)),
   13803                                mkU64(0x0),
   13804                                mkU64(0x1)));
   13805 
   13806       /* Store X_byte on the right place. */
   13807       store(binop(Iop_Add64, mkexpr(t2), mkU64(0x7)), mkexpr(A_byte));
   13808       store(binop(Iop_Add64, mkexpr(t1), mkexpr(B_pos)), mkexpr(B_byte));
   13809       store(binop(Iop_Add64, mkexpr(t1), mkexpr(C_pos)), mkexpr(C_byte));
   13810       store(binop(Iop_Add64, mkexpr(t1), mkexpr(D_pos)), mkexpr(D_byte));
   13811       store(binop(Iop_Add64, mkexpr(t1), mkexpr(E_pos)), mkexpr(E_byte));
   13812       store(binop(Iop_Add64, mkexpr(t1), mkexpr(F_pos)), mkexpr(F_byte));
   13813       store(binop(Iop_Add64, mkexpr(t1), mkexpr(G_pos)), mkexpr(G_byte));
   13814       store(mkexpr(t1), mkexpr(H_byte));
   13815 
   13816 #else /* _MIPSEB */
   13817       /* Calculate X_byte position. */
   13818       assign(B_pos, IRExpr_ITE(binop(Iop_CmpLT64U, mkU64(0x5), mkexpr(t3)),
   13819                                mkU64(0x6),
   13820                                mkU64(0x0)));
   13821 
   13822       assign(C_pos, IRExpr_ITE(binop(Iop_CmpLT64U, mkU64(0x4), mkexpr(t3)),
   13823                                mkU64(0x5),
   13824                                mkU64(0x0)));
   13825 
   13826       assign(D_pos, IRExpr_ITE(binop(Iop_CmpLT64U, mkU64(0x3), mkexpr(t3)),
   13827                                mkU64(0x4),
   13828                                mkU64(0x0)));
   13829 
   13830       assign(E_pos, IRExpr_ITE(binop(Iop_CmpLT64U, mkU64(0x2), mkexpr(t3)),
   13831                                mkU64(0x3),
   13832                                mkU64(0x0)));
   13833 
   13834       assign(F_pos, IRExpr_ITE(binop(Iop_CmpLT64U, mkU64(0x1), mkexpr(t3)),
   13835                                mkU64(0x2),
   13836                                mkU64(0x0)));
   13837 
   13838       assign(G_pos, IRExpr_ITE(binop(Iop_CmpEQ64, mkexpr(t3), mkU64(0x0)),
   13839                                mkU64(0x0),
   13840                                mkU64(0x1)));
   13841 
   13842       /* Store X_byte on the right place. */
   13843       store(mkexpr(t2), mkexpr(A_byte));
   13844       store(binop(Iop_Sub64, mkexpr(t1), mkexpr(B_pos)), mkexpr(B_byte));
   13845       store(binop(Iop_Sub64, mkexpr(t1), mkexpr(C_pos)), mkexpr(C_byte));
   13846       store(binop(Iop_Sub64, mkexpr(t1), mkexpr(D_pos)), mkexpr(D_byte));
   13847       store(binop(Iop_Sub64, mkexpr(t1), mkexpr(E_pos)), mkexpr(E_byte));
   13848       store(binop(Iop_Sub64, mkexpr(t1), mkexpr(F_pos)), mkexpr(F_byte));
   13849       store(binop(Iop_Sub64, mkexpr(t1), mkexpr(G_pos)), mkexpr(G_byte));
   13850       store(mkexpr(t1), mkexpr(H_byte));
   13851 #endif
   13852       break;
   13853    }
   13854 
   13855    case 0x28:  /* SB */
   13856       DIP("sb r%d, %d(r%d)", rt, imm, rs);
   13857       LOAD_STORE_PATTERN;
   13858       store(mkexpr(t1), narrowTo(Ity_I8, getIReg(rt)));
   13859       break;
   13860 
   13861    case 0x29:  /* SH */
   13862       DIP("sh r%d, %d(r%d)", rt, imm, rs);
   13863       LOAD_STORE_PATTERN;
   13864       store(mkexpr(t1), narrowTo(Ity_I16, getIReg(rt)));
   13865       break;
   13866 
   13867    case 0x2A:  /* SWL */
   13868       DIP("swl r%d, %d(r%d)", rt, imm, rs);
   13869       if (mode64) {
   13870          IRTemp E_byte = newTemp(Ity_I8);
   13871          IRTemp F_byte = newTemp(Ity_I8);
   13872          IRTemp G_byte = newTemp(Ity_I8);
   13873          IRTemp H_byte = newTemp(Ity_I8);
   13874          IRTemp F_pos  = newTemp(Ity_I64);
   13875          IRTemp G_pos  = newTemp(Ity_I64);
   13876 
   13877          /* H byte */
   13878          assign(H_byte, getByteFromReg(rt, 0));
   13879          /* G byte */
   13880          assign(G_byte, getByteFromReg(rt, 1));
   13881          /* F byte */
   13882          assign(F_byte, getByteFromReg(rt, 2));
   13883          /* E byte */
   13884          assign(E_byte, getByteFromReg(rt, 3));
   13885 
   13886          /* t1 = addr */
   13887          t1 = newTemp(Ity_I64);
   13888          assign(t1, binop(Iop_Add64, getIReg(rs), mkU64(extend_s_16to64(imm))));
   13889 
   13890          /* t2 = word addr */
   13891          t2 = newTemp(Ity_I64);
   13892          assign(t2, binop(Iop_And64, mkexpr(t1), mkU64(0xFFFFFFFFFFFFFFFCULL)));
   13893 
   13894          /* t3 = addr mod 4 */
   13895          t3 = newTemp(Ity_I64);
   13896          assign(t3, binop(Iop_And64, mkexpr(t1), mkU64(0x3)));
   13897 
   13898 #if defined (_MIPSEL)
   13899          /* Calculate X_byte position. */
   13900          assign(F_pos, IRExpr_ITE(binop(Iop_CmpEQ64, mkexpr(t3), mkU64(0x0)),
   13901                                   mkU64(0x0),
   13902                                   mkU64(0x1)));
   13903 
   13904          assign(G_pos, IRExpr_ITE(binop(Iop_CmpEQ64, mkexpr(t3), mkU64(0x3)),
   13905                                   mkU64(0x1),
   13906                                   mkU64(0x0)));
   13907 
   13908          /* Store X_byte on the right place. */
   13909          store(mkexpr(t2), mkexpr(H_byte));
   13910          store(binop(Iop_Add64, mkexpr(t2), mkexpr(G_pos)), mkexpr(G_byte));
   13911          store(binop(Iop_Sub64, mkexpr(t1), mkexpr(F_pos)), mkexpr(F_byte));
   13912          store(mkexpr(t1), mkexpr(E_byte));
   13913 
   13914 #else    /* _MIPSEB */
   13915          /* Calculate X_byte position. */
   13916          assign(F_pos, IRExpr_ITE(binop(Iop_CmpEQ64, mkexpr(t3), mkU64(0x3)),
   13917                                   mkU64(0x0),
   13918                                   mkU64(0x1)));
   13919 
   13920          assign(G_pos, IRExpr_ITE(binop(Iop_CmpEQ64, mkexpr(t3), mkU64(0x0)),
   13921                                   mkU64(0x2),
   13922                                   mkU64(0x3)));
   13923 
   13924          store(binop(Iop_Add64, mkexpr(t2), mkU64(3)), mkexpr(H_byte));
   13925          store(binop(Iop_Add64, mkexpr(t2), mkexpr(G_pos)), mkexpr(G_byte));
   13926          store(binop(Iop_Add64, mkexpr(t1), mkexpr(F_pos)), mkexpr(F_byte));
   13927          store(mkexpr(t1), mkexpr(E_byte));
   13928 
   13929 #endif
   13930       } else {
   13931          IRTemp E_byte = newTemp(Ity_I8);
   13932          IRTemp F_byte = newTemp(Ity_I8);
   13933          IRTemp G_byte = newTemp(Ity_I8);
   13934          IRTemp H_byte = newTemp(Ity_I8);
   13935          IRTemp F_pos  = newTemp(Ity_I32);
   13936          IRTemp G_pos  = newTemp(Ity_I32);
   13937 
   13938          /* H byte */
   13939          assign(H_byte, getByteFromReg(rt, 0));
   13940          /* G byte */
   13941          assign(G_byte, getByteFromReg(rt, 1));
   13942          /* F byte */
   13943          assign(F_byte, getByteFromReg(rt, 2));
   13944          /* E byte */
   13945          assign(E_byte, getByteFromReg(rt, 3));
   13946 
   13947          /* t1 = addr */
   13948          t1 = newTemp(Ity_I32);
   13949          assign(t1, binop(Iop_Add32, getIReg(rs), mkU32(extend_s_16to32(imm))));
   13950 
   13951          /* t2 = word addr */
   13952          t2 = newTemp(Ity_I32);
   13953          assign(t2, binop(Iop_And32, mkexpr(t1), mkU32(0xFFFFFFFCULL)));
   13954 
   13955          /* t3 = addr mod 4 */
   13956          t3 = newTemp(Ity_I32);
   13957          assign(t3, binop(Iop_And32, mkexpr(t1), mkU32(0x3)));
   13958 
   13959 #if defined (_MIPSEL)
   13960          /* Calculate X_byte position. */
   13961          assign(F_pos, IRExpr_ITE(binop(Iop_CmpEQ32, mkexpr(t3), mkU32(0x0)),
   13962                                   mkU32(0x0),
   13963                                   mkU32(0x1)));
   13964 
   13965          assign(G_pos, IRExpr_ITE(binop(Iop_CmpEQ32, mkexpr(t3), mkU32(0x3)),
   13966                                   mkU32(0x1),
   13967                                   mkU32(0x0)));
   13968 
   13969          /* Store X_byte on the right place. */
   13970          store(mkexpr(t2), mkexpr(H_byte));
   13971          store(binop(Iop_Add32, mkexpr(t2), mkexpr(G_pos)), mkexpr(G_byte));
   13972          store(binop(Iop_Sub32, mkexpr(t1), mkexpr(F_pos)), mkexpr(F_byte));
   13973          store(mkexpr(t1), mkexpr(E_byte));
   13974 
   13975 #else    /* _MIPSEB */
   13976          /* Calculate X_byte position. */
   13977          assign(F_pos, IRExpr_ITE(binop(Iop_CmpEQ32, mkexpr(t3), mkU32(0x3)),
   13978                                   mkU32(0x0),
   13979                                   mkU32(0x1)));
   13980 
   13981          assign(G_pos, IRExpr_ITE(binop(Iop_CmpEQ32, mkexpr(t3), mkU32(0x0)),
   13982                                   mkU32(0x2),
   13983                                   mkU32(0x3)));
   13984 
   13985          store(binop(Iop_Add32, mkexpr(t2), mkU32(3)), mkexpr(H_byte));
   13986          store(binop(Iop_Add32, mkexpr(t2), mkexpr(G_pos)), mkexpr(G_byte));
   13987          store(binop(Iop_Add32, mkexpr(t1), mkexpr(F_pos)), mkexpr(F_byte));
   13988          store(mkexpr(t1), mkexpr(E_byte));
   13989 
   13990 #endif
   13991       }
   13992       break;
   13993 
   13994    case 0x2E:  /* SWR */
   13995       DIP("swr r%d, %d(r%d)", rt, imm, rs);
   13996       if (mode64) {
   13997          IRTemp E_byte = newTemp(Ity_I8);
   13998          IRTemp F_byte = newTemp(Ity_I8);
   13999          IRTemp G_byte = newTemp(Ity_I8);
   14000          IRTemp H_byte = newTemp(Ity_I8);
   14001          IRTemp F_pos  = newTemp(Ity_I64);
   14002          IRTemp G_pos  = newTemp(Ity_I64);
   14003 
   14004          /* H byte */
   14005          assign(H_byte, getByteFromReg(rt, 0));
   14006          /* G byte */
   14007          assign(G_byte, getByteFromReg(rt, 1));
   14008          /* F byte */
   14009          assign(F_byte, getByteFromReg(rt, 2));
   14010          /* E byte */
   14011          assign(E_byte, getByteFromReg(rt, 3));
   14012 
   14013          /* t1 = addr */
   14014          t1 = newTemp(Ity_I64);
   14015          assign(t1, binop(Iop_Add64, getIReg(rs), mkU64(extend_s_16to64(imm))));
   14016 
   14017          /* t2 = word addr */
   14018          t2 = newTemp(Ity_I64);
   14019          assign(t2, binop(Iop_And64, mkexpr(t1), mkU64(0xFFFFFFFFFFFFFFFCULL)));
   14020 
   14021          /* t3 = addr mod 4 */
   14022          t3 = newTemp(Ity_I64);
   14023          assign(t3, binop(Iop_And64, mkexpr(t1), mkU64(0x3)));
   14024 
   14025 #if defined (_MIPSEL)
   14026          /* Calculate X_byte position. */
   14027          assign(F_pos, IRExpr_ITE(binop(Iop_CmpEQ64, mkexpr(t3), mkU64(0x0)),
   14028                                   mkU64(0x2),
   14029                                   mkU64(0x3)));
   14030 
   14031          assign(G_pos, IRExpr_ITE(binop(Iop_CmpEQ64, mkexpr(t3), mkU64(0x3)),
   14032                                   mkU64(0x0),
   14033                                   mkU64(0x1)));
   14034 
   14035          /* Store X_byte on the right place. */
   14036          store(binop(Iop_Add64, mkexpr(t2), mkU64(0x3)), mkexpr(E_byte));
   14037          store(binop(Iop_Add64, mkexpr(t2), mkexpr(F_pos)), mkexpr(F_byte));
   14038          store(binop(Iop_Add64, mkexpr(t1), mkexpr(G_pos)), mkexpr(G_byte));
   14039          store(mkexpr(t1), mkexpr(H_byte));
   14040 
   14041 #else    /* _MIPSEB */
   14042          /* Calculate X_byte position. */
   14043          assign(F_pos, IRExpr_ITE(binop(Iop_CmpEQ64, mkexpr(t3), mkU64(0x3)),
   14044                                   mkU64(0x1),
   14045                                   mkU64(0x0)));
   14046 
   14047          assign(G_pos, IRExpr_ITE(binop(Iop_CmpEQ64, mkexpr(t3), mkU64(0x0)),
   14048                                   mkU64(0x0),
   14049                                   mkU64(0x1)));
   14050 
   14051          /* Store X_byte on the right place. */
   14052          store(mkexpr(t2), mkexpr(E_byte));
   14053          store(binop(Iop_Add64, mkexpr(t2), mkexpr(F_pos)), mkexpr(F_byte));
   14054          store(binop(Iop_Sub64, mkexpr(t1), mkexpr(G_pos)), mkexpr(G_byte));
   14055          store(mkexpr(t1), mkexpr(H_byte));
   14056 #endif
   14057       } else {
   14058          IRTemp E_byte = newTemp(Ity_I8);
   14059          IRTemp F_byte = newTemp(Ity_I8);
   14060          IRTemp G_byte = newTemp(Ity_I8);
   14061          IRTemp H_byte = newTemp(Ity_I8);
   14062          IRTemp F_pos  = newTemp(Ity_I32);
   14063          IRTemp G_pos  = newTemp(Ity_I32);
   14064 
   14065          /* H byte */
   14066          assign(H_byte, getByteFromReg(rt, 0));
   14067          /* G byte */
   14068          assign(G_byte, getByteFromReg(rt, 1));
   14069          /* F byte */
   14070          assign(F_byte, getByteFromReg(rt, 2));
   14071          /* E byte */
   14072          assign(E_byte, getByteFromReg(rt, 3));
   14073 
   14074          /* t1 = addr */
   14075          t1 = newTemp(Ity_I32);
   14076          assign(t1, binop(Iop_Add32, getIReg(rs), mkU32(extend_s_16to32(imm))));
   14077 
   14078          /* t2 = word addr */
   14079          t2 = newTemp(Ity_I32);
   14080          assign(t2, binop(Iop_And32, mkexpr(t1), mkU32(0xFFFFFFFCULL)));
   14081 
   14082          /* t3 = addr mod 4 */
   14083          t3 = newTemp(Ity_I32);
   14084          assign(t3, binop(Iop_And32, mkexpr(t1), mkU32(0x3)));
   14085 
   14086 #if defined (_MIPSEL)
   14087          /* Calculate X_byte position. */
   14088          assign(F_pos, IRExpr_ITE(binop(Iop_CmpEQ32, mkexpr(t3), mkU32(0x0)),
   14089                                   mkU32(0x2),
   14090                                   mkU32(0x3)));
   14091 
   14092          assign(G_pos, IRExpr_ITE(binop(Iop_CmpEQ32, mkexpr(t3), mkU32(0x3)),
   14093                                   mkU32(0x0),
   14094                                   mkU32(0x1)));
   14095 
   14096          /* Store X_byte on the right place. */
   14097          store(binop(Iop_Add32, mkexpr(t2), mkU32(0x3)), mkexpr(E_byte));
   14098          store(binop(Iop_Add32, mkexpr(t2), mkexpr(F_pos)), mkexpr(F_byte));
   14099          store(binop(Iop_Add32, mkexpr(t1), mkexpr(G_pos)), mkexpr(G_byte));
   14100          store(mkexpr(t1), mkexpr(H_byte));
   14101 
   14102 #else    /* _MIPSEB */
   14103          /* Calculate X_byte position. */
   14104          assign(F_pos, IRExpr_ITE(binop(Iop_CmpEQ32, mkexpr(t3), mkU32(0x3)),
   14105                                   mkU32(0x1),
   14106                                   mkU32(0x0)));
   14107 
   14108          assign(G_pos, IRExpr_ITE(binop(Iop_CmpEQ32, mkexpr(t3), mkU32(0x0)),
   14109                                   mkU32(0x0),
   14110                                   mkU32(0x1)));
   14111 
   14112          /* Store X_byte on the right place. */
   14113          store(mkexpr(t2), mkexpr(E_byte));
   14114          store(binop(Iop_Add32, mkexpr(t2), mkexpr(F_pos)), mkexpr(F_byte));
   14115          store(binop(Iop_Sub32, mkexpr(t1), mkexpr(G_pos)), mkexpr(G_byte));
   14116          store(mkexpr(t1), mkexpr(H_byte));
   14117 #endif
   14118       }
   14119       break;
   14120 
   14121    case 0x1C:  /* Special2 */
   14122       switch (function) {
   14123       /* Cavium Specific instructions */
   14124       case 0x03: case 0x32: case 0x33:  /* DMUL, CINS , CINS32 */
   14125       case 0x3A: case 0x3B: case 0x2B:  /* EXT,  EXT32, SNE    */
   14126       /* CVM Compare Instructions */
   14127       case 0x2A: case 0x2E: case 0x2F:  /* SEQ,  SEQI,  SNEI   */
   14128          if (VEX_MIPS_COMP_ID(archinfo->hwcaps) == VEX_PRID_COMP_CAVIUM) {
   14129             if (dis_instr_CVM(cins))
   14130                break;
   14131             goto decode_failure;
   14132          } else {
   14133             goto decode_failure;
   14134          }
   14135          break;
   14136       case 0x02: {  /* MUL */
   14137          DIP("mul r%d, r%d, r%d", rd, rs, rt);
   14138          if (mode64) {
   14139             IRTemp tmpRs32 = newTemp(Ity_I32);
   14140             IRTemp tmpRt32 = newTemp(Ity_I32);
   14141             IRTemp tmpRes = newTemp(Ity_I32);
   14142 
   14143             assign(tmpRs32, mkNarrowTo32(ty, getIReg(rs)));
   14144             assign(tmpRt32, mkNarrowTo32(ty, getIReg(rt)));
   14145             assign(tmpRes, binop(Iop_Mul32, mkexpr(tmpRs32), mkexpr(tmpRt32)));
   14146             putIReg(rd, mkWidenFrom32(ty, mkexpr(tmpRes), True));
   14147          } else
   14148             putIReg(rd, binop(Iop_Mul32, getIReg(rs), getIReg(rt)));
   14149          break;
   14150       }
   14151 
   14152          case 0x00: {  /* MADD */
   14153             if (mode64) {
   14154                DIP("madd r%d, r%d", rs, rt);
   14155                t1 = newTemp(Ity_I32);
   14156                t2 = newTemp(Ity_I32);
   14157                t3 = newTemp(Ity_I64);
   14158                t4 = newTemp(Ity_I64);
   14159                t5 = newTemp(Ity_I64);
   14160                t6 = newTemp(Ity_I32);
   14161 
   14162                assign(t1, mkNarrowTo32(ty, getHI()));
   14163                assign(t2, mkNarrowTo32(ty, getLO()));
   14164 
   14165                assign(t3, binop(Iop_MullS32, mkNarrowTo32(ty, getIReg(rs)),
   14166                                              mkNarrowTo32(ty, getIReg(rt))));
   14167 
   14168                assign(t4, binop(Iop_32HLto64, mkexpr(t1), mkexpr(t2)));
   14169                assign(t5, binop(Iop_Add64, mkexpr(t3), mkexpr(t4)));
   14170 
   14171                putHI(mkWidenFrom32(ty, unop(Iop_64HIto32, mkexpr(t5)), True));
   14172                putLO(mkWidenFrom32(ty, unop(Iop_64to32, mkexpr(t5)), True));
   14173             } else {
   14174                if ( (1 <= ac) && ( 3 >= ac) ) {
   14175                   if (VEX_MIPS_PROC_DSP(archinfo->hwcaps)) {
   14176                      /* If DSP is present -> DSP ASE MADD */
   14177                      UInt retVal = disDSPInstr_MIPS_WRK ( cins );
   14178                      if (0 != retVal ) {
   14179                         goto decode_failure_dsp;
   14180                      }
   14181                      break;
   14182                   } else {
   14183                      goto decode_failure_dsp;
   14184                   }
   14185                } else {
   14186                   DIP("madd r%d, r%d", rs, rt);
   14187                   t1 = newTemp(Ity_I32);
   14188                   t2 = newTemp(Ity_I32);
   14189                   t3 = newTemp(Ity_I64);
   14190                   t4 = newTemp(Ity_I32);
   14191                   t5 = newTemp(Ity_I32);
   14192                   t6 = newTemp(Ity_I32);
   14193 
   14194                   assign(t1, getHI());
   14195                   assign(t2, getLO());
   14196 
   14197                   assign(t3, binop(Iop_MullS32, getIReg(rs), getIReg(rt)));
   14198 
   14199                   assign(t4, binop(Iop_Add32, mkexpr(t2), unop(Iop_64to32,
   14200                                                                mkexpr(t3))));
   14201 
   14202                   assign(t5, unop(Iop_1Uto32, binop(Iop_CmpLT32U, mkexpr(t4),
   14203                                               unop(Iop_64to32, mkexpr(t3)))));
   14204                   assign(t6, binop(Iop_Add32, mkexpr(t5), mkexpr(t1)));
   14205 
   14206                   putHI(binop(Iop_Add32, mkexpr(t6), unop(Iop_64HIto32,
   14207                                                           mkexpr(t3))));
   14208                   putLO(mkexpr(t4));
   14209                   break;
   14210                }
   14211             }
   14212             break;
   14213          }
   14214 
   14215       case 0x01: {  /* MADDU */
   14216          if (mode64) {
   14217             DIP("maddu r%d, r%d", rs, rt);
   14218             t1 = newTemp(Ity_I32);
   14219             t2 = newTemp(Ity_I32);
   14220             t3 = newTemp(Ity_I64);
   14221             t4 = newTemp(Ity_I64);
   14222             t5 = newTemp(Ity_I64);
   14223             t6 = newTemp(Ity_I32);
   14224 
   14225             assign(t1, mkNarrowTo32(ty, getHI()));
   14226             assign(t2, mkNarrowTo32(ty, getLO()));
   14227 
   14228             assign(t3, binop(Iop_MullU32, mkNarrowTo32(ty, getIReg(rs)),
   14229                                           mkNarrowTo32(ty, getIReg(rt))));
   14230 
   14231             assign(t4, binop(Iop_32HLto64, mkexpr(t1), mkexpr(t2)));
   14232             assign(t5, binop(Iop_Add64, mkexpr(t3), mkexpr(t4)));
   14233 
   14234             putHI(mkWidenFrom32(ty, unop(Iop_64HIto32, mkexpr(t5)), True));
   14235             putLO(mkWidenFrom32(ty, unop(Iop_64to32, mkexpr(t5)), True));
   14236          } else {
   14237             if ( (1 <= ac) && ( 3 >= ac) ) {
   14238                if (VEX_MIPS_PROC_DSP(archinfo->hwcaps)) {
   14239                   /* If DSP is present -> DSP ASE MADDU */
   14240                   UInt retVal = disDSPInstr_MIPS_WRK ( cins );
   14241                   if (0 != retVal ) {
   14242                      goto decode_failure_dsp;
   14243                   }
   14244                   break;
   14245                } else {
   14246                   goto decode_failure_dsp;
   14247                }
   14248             } else {
   14249                DIP("maddu r%d, r%d", rs, rt);
   14250                t1 = newTemp(Ity_I32);
   14251                t2 = newTemp(Ity_I32);
   14252                t3 = newTemp(Ity_I64);
   14253                t4 = newTemp(Ity_I32);
   14254                t5 = newTemp(Ity_I32);
   14255                t6 = newTemp(Ity_I32);
   14256 
   14257                assign(t1, getHI());
   14258                assign(t2, getLO());
   14259 
   14260                assign(t3, binop(Iop_MullU32, getIReg(rs), getIReg(rt)));
   14261 
   14262                assign(t4, binop(Iop_Add32, mkexpr(t2), unop(Iop_64to32,
   14263                                                             mkexpr(t3))));
   14264                assign(t5, unop(Iop_1Uto32, binop(Iop_CmpLT32U, mkexpr(t4),
   14265                                            unop(Iop_64to32, mkexpr(t3)))));
   14266                assign(t6, binop(Iop_Add32, mkexpr(t5), mkexpr(t1)));
   14267 
   14268                putHI(binop(Iop_Add32, mkexpr(t6), unop(Iop_64HIto32,
   14269                                                       mkexpr(t3))));
   14270                putLO(mkexpr(t4));
   14271                break;
   14272             }
   14273          }
   14274          break;
   14275       }
   14276 
   14277       case 0x04: {  /* MSUB */
   14278          if (mode64) {
   14279             DIP("msub r%d, r%d", rs, rt);
   14280             t1 = newTemp(Ity_I32);
   14281             t2 = newTemp(Ity_I32);
   14282             t3 = newTemp(Ity_I64);
   14283             t4 = newTemp(Ity_I64);
   14284             t5 = newTemp(Ity_I64);
   14285             t6 = newTemp(Ity_I32);
   14286 
   14287             assign(t1, mkNarrowTo32(ty, getHI()));
   14288             assign(t2, mkNarrowTo32(ty, getLO()));
   14289 
   14290             assign(t3, binop(Iop_MullS32, mkNarrowTo32(ty, getIReg(rs)),
   14291                                           mkNarrowTo32(ty, getIReg(rt))));
   14292 
   14293             assign(t4, binop(Iop_32HLto64, mkexpr(t1), mkexpr(t2)));
   14294             assign(t5, binop(Iop_Sub64, mkexpr(t4), mkexpr(t3)));
   14295 
   14296             putHI(mkWidenFrom32(ty, unop(Iop_64HIto32, mkexpr(t5)), True));
   14297             putLO(mkWidenFrom32(ty, unop(Iop_64to32, mkexpr(t5)), True));
   14298          } else {
   14299             if ( (1 <= ac) && ( 3 >= ac) ) {
   14300                if (VEX_MIPS_PROC_DSP(archinfo->hwcaps)) {
   14301                   /* If DSP is present -> DSP ASE MSUB */
   14302                   UInt retVal = disDSPInstr_MIPS_WRK ( cins );
   14303                   if (0 != retVal ) {
   14304                      goto decode_failure_dsp;
   14305                   }
   14306                   break;
   14307                } else {
   14308                   goto decode_failure_dsp;
   14309                }
   14310             } else {
   14311                DIP("msub r%d, r%d", rs, rt);
   14312                t1 = newTemp(Ity_I32);
   14313                t2 = newTemp(Ity_I32);
   14314                t3 = newTemp(Ity_I64);
   14315                t4 = newTemp(Ity_I32);
   14316                t5 = newTemp(Ity_I1);
   14317                t6 = newTemp(Ity_I32);
   14318 
   14319                assign(t1, getHI());
   14320                assign(t2, getLO());
   14321 
   14322                assign(t3, binop(Iop_MullS32, getIReg(rs), getIReg(rt)));
   14323                assign(t4, unop(Iop_64to32, mkexpr(t3)));  /* new lo */
   14324 
   14325                /* if lo<lo(mul) hi = hi - 1 */
   14326                assign(t5, binop(Iop_CmpLT32U,
   14327                                  mkexpr(t2),
   14328                                  mkexpr(t4)));
   14329 
   14330                assign(t6, IRExpr_ITE(mkexpr(t5),
   14331                                        binop(Iop_Sub32, mkexpr(t1), mkU32(0x1)),
   14332                                        mkexpr(t1)));
   14333 
   14334                putHI(binop(Iop_Sub32, mkexpr(t6), unop(Iop_64HIto32,
   14335                                                       mkexpr(t3))));
   14336                putLO(binop(Iop_Sub32, mkexpr(t2), mkexpr(t4)));
   14337                break;
   14338             }
   14339          }
   14340          break;
   14341       }
   14342 
   14343       case 0x05: {  /* MSUBU */
   14344          if (mode64) {
   14345             DIP("msubu r%d, r%d", rs, rt);
   14346             t1 = newTemp(Ity_I32);
   14347             t2 = newTemp(Ity_I32);
   14348             t3 = newTemp(Ity_I64);
   14349             t4 = newTemp(Ity_I64);
   14350             t5 = newTemp(Ity_I64);
   14351             t6 = newTemp(Ity_I32);
   14352 
   14353             assign(t1, mkNarrowTo32(ty, getHI()));
   14354             assign(t2, mkNarrowTo32(ty, getLO()));
   14355 
   14356             assign(t3, binop(Iop_MullU32, mkNarrowTo32(ty, getIReg(rs)),
   14357                                           mkNarrowTo32(ty, getIReg(rt))));
   14358 
   14359             assign(t4, binop(Iop_32HLto64, mkexpr(t1), mkexpr(t2)));
   14360             assign(t5, binop(Iop_Sub64, mkexpr(t4), mkexpr(t3)));
   14361 
   14362             putHI(mkWidenFrom32(ty, unop(Iop_64HIto32, mkexpr(t5)), True));
   14363             putLO(mkWidenFrom32(ty, unop(Iop_64to32, mkexpr(t5)), True));
   14364          } else {
   14365             if ( (1 <= ac) && ( 3 >= ac) ) {
   14366                if (VEX_MIPS_PROC_DSP(archinfo->hwcaps)) {
   14367                   /* If DSP is present -> DSP ASE MSUBU */
   14368                   UInt retVal = disDSPInstr_MIPS_WRK ( cins );
   14369                   if (0 != retVal ) {
   14370                      goto decode_failure_dsp;
   14371                   }
   14372                   break;
   14373                } else {
   14374                   goto decode_failure_dsp;
   14375                }
   14376             } else {
   14377                DIP("msubu r%d, r%d", rs, rt);
   14378                t1 = newTemp(Ity_I32);
   14379                t2 = newTemp(Ity_I32);
   14380                t3 = newTemp(Ity_I64);
   14381                t4 = newTemp(Ity_I32);
   14382                t5 = newTemp(Ity_I1);
   14383                t6 = newTemp(Ity_I32);
   14384 
   14385                assign(t1, getHI());
   14386                assign(t2, getLO());
   14387 
   14388                assign(t3, binop(Iop_MullU32, getIReg(rs), getIReg(rt)));
   14389                assign(t4, unop(Iop_64to32, mkexpr(t3)));  /* new lo */
   14390 
   14391                /* if lo<lo(mul) hi = hi - 1 */
   14392                assign(t5, binop(Iop_CmpLT32U,
   14393                                  mkexpr(t2),
   14394                                  mkexpr(t4)));
   14395 
   14396                assign(t6, IRExpr_ITE(mkexpr(t5),
   14397                                     binop(Iop_Sub32,
   14398                                           mkexpr(t1),
   14399                                           mkU32(0x1)),
   14400                                     mkexpr(t1)));
   14401 
   14402                putHI(binop(Iop_Sub32, mkexpr(t6), unop(Iop_64HIto32,
   14403                                                       mkexpr(t3))));
   14404                putLO(binop(Iop_Sub32, mkexpr(t2), mkexpr(t4)));
   14405                break;
   14406             }
   14407          }
   14408          break;
   14409       }
   14410 
   14411       case 0x6:  /* dmul MIPS64 - Netlogic */
   14412          DIP("dmul r%u, r%u, r%u", rd, rs, rt);
   14413          t0 = newTemp(Ity_I128);
   14414 
   14415          assign(t0, binop(Iop_MullU64, getIReg(rs), getIReg(rt)));
   14416 
   14417          putIReg(rd, unop(Iop_128to64, mkexpr(t0)));
   14418          break;
   14419 
   14420       case 0x10:  /* LDADDW - Swap Word - Netlogic */
   14421          DIP("ldaddw r%u, r%u", rt, rs);
   14422          t0 = newTemp(Ity_I32);
   14423          t1 = newTemp(Ity_I32);
   14424          t2 = newTemp(Ity_I32);
   14425          t3 = newTemp(Ity_I64);
   14426          t4 = newTemp(Ity_I32);
   14427          t5 = newTemp(Ity_I32);
   14428          t6 = newTemp(Ity_I32);
   14429 
   14430          /* v = GPR[rt] */
   14431          assign(t0, mkNarrowTo32(ty, getIReg(rt)));
   14432 
   14433          /* GPR[rt] = memory[base]; */
   14434          assign(t1, load(Ity_I32, getIReg(rs)));
   14435          putIReg(rt, mkWidenFrom32(ty, mkexpr(t1), True));
   14436 
   14437          /* memory[base] = memory[base] + v; */
   14438          store(getIReg(rs), binop(Iop_Add32, mkexpr(t0), mkexpr(t1)));
   14439          break;
   14440 
   14441       case 0x12:  /* LDADDD - Swap Word - Netlogic */
   14442          DIP("ldaddw r%u, r%u", rt, rs);
   14443          t0 = newTemp(Ity_I64);
   14444          t1 = newTemp(Ity_I64);
   14445 
   14446          /*  v = GPR[rt] */
   14447          assign(t0, getIReg(rt));
   14448 
   14449          /* GPR[rt] = memory[base]; */
   14450          assign(t1, load(Ity_I64, getIReg(rs)));
   14451          putIReg(rt, mkexpr(t1));
   14452 
   14453          /* memory[base] = memory[base] + v; */
   14454          store(getIReg(rs), binop(Iop_Add64, mkexpr(t0), mkexpr(t1)));
   14455          break;
   14456 
   14457       case 0x14:  /* SWAPW - Swap Word - Netlogic */
   14458          DIP("swapw r%u, r%u", rt, rs);
   14459          t0 = newTemp(Ity_I32);
   14460          t1 = newTemp(Ity_I32);
   14461          assign(t0, mkNarrowTo32(ty, getIReg(rt)));
   14462          assign(t1, load(Ity_I32, getIReg(rs)));
   14463          putIReg(rt, mkWidenFrom32(ty, mkexpr(t1), True));
   14464          store(getIReg(rs), mkexpr(t0));
   14465          break;
   14466 
   14467       case 0x16:  /* SWAPD - Swap Double - Netlogic */
   14468          DIP("swapw r%u, r%u", rt, rs);
   14469          t0 = newTemp(Ity_I64);
   14470          t1 = newTemp(Ity_I64);
   14471          assign(t0, getIReg(rt));
   14472          assign(t1, load(Ity_I64, getIReg(rs)));
   14473          putIReg(rt, mkexpr(t1));
   14474          store(getIReg(rs), mkexpr(t0));
   14475          break;
   14476 
   14477       case 0x20: {  /* CLZ */
   14478          DIP("clz r%d, r%d", rd, rs);
   14479          if (mode64) {
   14480             IRTemp tmpClz32 = newTemp(Ity_I32);
   14481             IRTemp tmpRs32 = newTemp(Ity_I32);
   14482 
   14483             assign(tmpRs32, mkNarrowTo32(ty, getIReg(rs)));
   14484             assign(tmpClz32, unop(Iop_Clz32, mkexpr(tmpRs32)));
   14485             putIReg(rd, mkWidenFrom32(ty, mkexpr(tmpClz32), True));
   14486          } else {
   14487             t1 = newTemp(Ity_I1);
   14488             assign(t1, binop(Iop_CmpEQ32, getIReg(rs), mkU32(0)));
   14489             putIReg(rd, IRExpr_ITE(mkexpr(t1),
   14490                                    mkU32(0x00000020),
   14491                                    unop(Iop_Clz32, getIReg(rs))));
   14492          }
   14493          break;
   14494       }
   14495 
   14496       case 0x21: {  /* CLO */
   14497          DIP("clo r%d, r%d", rd, rs);
   14498          if (mode64) {
   14499             IRTemp tmpClo32 = newTemp(Ity_I32);
   14500             IRTemp tmpRs32 = newTemp(Ity_I32);
   14501             assign(tmpRs32, mkNarrowTo32(ty, getIReg(rs)));
   14502 
   14503             t1 = newTemp(Ity_I1);
   14504             assign(t1, binop(Iop_CmpEQ32, mkexpr(tmpRs32), mkU32(0xffffffff)));
   14505             assign(tmpClo32, IRExpr_ITE(mkexpr(t1),
   14506                       mkU32(0x00000020),
   14507                       unop(Iop_Clz32, unop(Iop_Not32, mkexpr(tmpRs32)))));
   14508 
   14509             putIReg(rd, mkWidenFrom32(ty, mkexpr(tmpClo32), True));
   14510             break;
   14511          } else {
   14512             t1 = newTemp(Ity_I1);
   14513             assign(t1, binop(Iop_CmpEQ32, getIReg(rs), mkU32(0xffffffff)));
   14514             putIReg(rd, IRExpr_ITE(mkexpr(t1),
   14515                                    mkU32(0x00000020),
   14516                                    unop(Iop_Clz32,
   14517                                         unop(Iop_Not32, getIReg(rs)))));
   14518             break;
   14519          }
   14520       }
   14521 
   14522       case 0x24:  /* Count Leading Zeros in Doubleword - DCLZ; MIPS64 */
   14523          DIP("dclz r%d, r%d", rd, rs);
   14524          t1 = newTemp(Ity_I1);
   14525          assign(t1, binop(Iop_CmpEQ64, getIReg(rs), mkU64(0)));
   14526          putIReg(rd, IRExpr_ITE(mkexpr(t1),
   14527                      mkU64(0x00000040),
   14528                      unop(Iop_Clz64, getIReg(rs))));
   14529          break;
   14530 
   14531       case 0x25:  /* Count Leading Ones in Doubleword - DCLO; MIPS64 */
   14532          DIP("dclo r%d, r%d", rd, rs);
   14533          t1 = newTemp(Ity_I1);
   14534          assign(t1, binop(Iop_CmpEQ64, getIReg(rs),
   14535                                         mkU64(0xffffffffffffffffULL)));
   14536          putIReg(rd, IRExpr_ITE(mkexpr(t1),
   14537                                 mkU64(0x40),
   14538                                 unop(Iop_Clz64, unop(Iop_Not64,
   14539                                                      getIReg(rs)))));
   14540          break;
   14541 
   14542       default:
   14543          goto decode_failure;
   14544       }
   14545       break;
   14546 
   14547    case 0x1F:  /* Special3 */
   14548       switch (function) {
   14549          case 0x01: {
   14550             /* Doubleword Extract Bit Field - DEXTM; MIPS64r2 */
   14551             msb = get_msb(cins);
   14552             lsb = get_lsb(cins);
   14553             size = msb + 1;
   14554             UInt srcPos = lsb;
   14555             UInt dstSz = msb + 33;
   14556             t1 = newTemp(Ity_I64);
   14557             DIP("dextm r%u, r%u, %d, %d", rt, rs, lsb, msb + 1);
   14558 
   14559             UChar lsAmt = 64 - (srcPos + dstSz);  /* left shift amount; */
   14560             UChar rsAmt = 64 - dstSz;  /* right shift amount; */
   14561 
   14562             assign(t1, binop(Iop_Shl64, getIReg(rs), mkU8(lsAmt)));
   14563             putIReg(rt, binop(Iop_Shr64, mkexpr(t1), mkU8(rsAmt)));
   14564 
   14565             break;
   14566          }
   14567          case 0x02: {
   14568             /* Doubleword Extract Bit Field Upper - DEXTU; MIPS64r2 */
   14569             msb = get_msb(cins);
   14570             lsb = get_lsb(cins);
   14571             size = msb + 1;
   14572             UInt srcPos = lsb + 32;
   14573             UInt dstSz = msb + 1;
   14574             DIP("dextu r%u, r%u, %d, %d", rt, rs, srcPos, dstSz);
   14575             t1 = newTemp(Ity_I64);
   14576 
   14577             vassert(srcPos >= 32 && srcPos < 64);
   14578             vassert(dstSz > 0 && dstSz <= 32);
   14579             vassert((srcPos + dstSz) > 32 && (srcPos + dstSz) <= 64);
   14580 
   14581             UChar lsAmt = 64 - (srcPos + dstSz);  /* left shift amount; */
   14582             UChar rsAmt = 64 - dstSz;  /* right shift amount; */
   14583 
   14584             assign(t1, binop(Iop_Shl64, getIReg(rs), mkU8(lsAmt)));
   14585             putIReg(rt, binop(Iop_Shr64, mkexpr(t1), mkU8(rsAmt)));
   14586             break;
   14587          }
   14588          case 0x05: {
   14589             /* Doubleword Insert Bit Field Middle - DINSM; MIPS64r2 */
   14590             msb = get_msb(cins);
   14591             lsb = get_lsb(cins);
   14592             size = msb + 1;
   14593             UInt dstPos = lsb;
   14594             UInt srcSz = msb - lsb + 33;
   14595             t1 = newTemp(ty);
   14596             t2 = newTemp(ty);
   14597             t3 = newTemp(ty);
   14598             t4 = newTemp(ty);
   14599             IRTemp tmpT1 = newTemp(ty);
   14600             IRTemp tmpT2 = newTemp(ty);
   14601             IRTemp tmpT3 = newTemp(ty);
   14602             IRTemp tmpT4 = newTemp(ty);
   14603             IRTemp tmpT5 = newTemp(ty);
   14604             IRTemp tmpT6 = newTemp(ty);
   14605             IRTemp tmpT7 = newTemp(ty);
   14606             IRTemp tmpRs = newTemp(ty);
   14607             IRTemp tmpRt = newTemp(ty);
   14608             IRTemp tmpRd = newTemp(ty);
   14609 
   14610             assign(tmpRs, getIReg(rs));
   14611             assign(tmpRt, getIReg(rt));
   14612             DIP("dinsm r%u, r%u, %d, %d", rt, rs, lsb, msb);
   14613 
   14614             UChar lsAmt = dstPos + srcSz - 1;   /* left shift amount; */
   14615             UChar rsAmt = dstPos + srcSz - 1;   /* right shift amount; */
   14616 
   14617             assign(t1, binop(Iop_Shr64, mkexpr(tmpRt), mkU8(rsAmt)));
   14618             assign(tmpT1, binop(Iop_Shr64, mkexpr(t1), mkU8(1)));
   14619             assign(t2, binop(Iop_Shl64, mkexpr(tmpT1), mkU8(lsAmt)));
   14620             assign(tmpT2, binop(Iop_Shl64, mkexpr(t2), mkU8(1)));
   14621 
   14622             lsAmt = 63 - dstPos; /* left shift amount; */
   14623             rsAmt = 63 - dstPos; /* right shift amount; */
   14624 
   14625             assign(t3, binop(Iop_Shl64, mkexpr(tmpRt), mkU8(lsAmt)));
   14626             assign(tmpT3, binop(Iop_Shl64, mkexpr(t3), mkU8(1)));
   14627             assign(t4, binop(Iop_Shr64, mkexpr(tmpT3), mkU8(rsAmt)));
   14628             assign(tmpT4, binop(Iop_Shr64, mkexpr(t4), mkU8(1)));
   14629 
   14630             /* extract size from src register */
   14631             lsAmt = 64 - srcSz;  /* left shift amount; */
   14632             rsAmt = 64 - (lsb + srcSz);   /* right shift amount; */
   14633 
   14634             assign(tmpT5, binop(Iop_Shl64, mkexpr(tmpRs), mkU8(lsAmt)));
   14635             assign(tmpT6, binop(Iop_Shr64, mkexpr(tmpT5), mkU8(rsAmt)));
   14636 
   14637             assign(tmpT7, binop(Iop_Or64, mkexpr(tmpT2), mkexpr(tmpT4)));
   14638             assign(tmpRd, binop(Iop_Or64, mkexpr(tmpT6), mkexpr(tmpT7)));
   14639             putIReg(rt, mkexpr(tmpRd));
   14640             break;
   14641          }
   14642          case 0x06: {
   14643             /* Doubleword Insert Bit Field Upper - DINSU; MIPS64r2 */
   14644             msb = get_msb(cins);
   14645             lsb = get_lsb(cins);
   14646             size = msb + 1;
   14647             UInt dstPos = lsb + 32;
   14648             UInt srcSz = msb - lsb + 1;
   14649             IRTemp tmpT1 = newTemp(ty);
   14650             IRTemp tmpT2 = newTemp(ty);
   14651             IRTemp tmpT3 = newTemp(ty);
   14652             IRTemp tmpT4 = newTemp(ty);
   14653             IRTemp tmpT5 = newTemp(ty);
   14654             IRTemp tmpT6 = newTemp(ty);
   14655             IRTemp tmpT7 = newTemp(ty);
   14656             IRTemp tmpT8 = newTemp(ty);
   14657             IRTemp tmpT9 = newTemp(ty);
   14658             IRTemp tmpRs = newTemp(ty);
   14659             IRTemp tmpRt = newTemp(ty);
   14660             IRTemp tmpRd = newTemp(ty);
   14661 
   14662             assign(tmpRs, getIReg(rs));
   14663             assign(tmpRt, getIReg(rt));
   14664             DIP("dinsu r%u, r%u, %d, %d", rt, rs, lsb, msb);
   14665 
   14666             UChar lsAmt = 64 - srcSz;  /* left shift amount; */
   14667             UChar rsAmt = 64 - (dstPos + srcSz);  /* right shift amount; */
   14668             assign(tmpT1, binop(Iop_Shl64, mkexpr(tmpRs), mkU8(lsAmt)));
   14669             assign(tmpT2, binop(Iop_Shr64, mkexpr(tmpT1), mkU8(rsAmt)));
   14670 
   14671             lsAmt = 64 - dstPos;  /* left shift amount; */
   14672             rsAmt = 64 - dstPos;  /* right shift amount; */
   14673             assign(tmpT3, binop(Iop_Shl64, mkexpr(tmpRt), mkU8(lsAmt)));
   14674             assign(tmpT4, binop(Iop_Shr64, mkexpr(tmpT3), mkU8(rsAmt)));
   14675 
   14676             lsAmt = dstPos;  /* left shift amount; */
   14677             rsAmt = srcSz;  /* right shift amount; */
   14678             assign(tmpT5, binop(Iop_Shr64, mkexpr(tmpRt), mkU8(rsAmt)));
   14679             assign(tmpT6, binop(Iop_Shr64, mkexpr(tmpT5), mkU8(lsAmt)));
   14680 
   14681             assign(tmpT7, binop(Iop_Shl64, mkexpr(tmpT6), mkU8(rsAmt)));
   14682             assign(tmpT8, binop(Iop_Shl64, mkexpr(tmpT7), mkU8(lsAmt)));
   14683 
   14684             assign(tmpT9, binop(Iop_Or64, mkexpr(tmpT8), mkexpr(tmpT4)));
   14685             assign(tmpRd, binop(Iop_Or64, mkexpr(tmpT2), mkexpr(tmpT9)));
   14686             putIReg(rt, mkexpr(tmpRd));
   14687             break;
   14688          }
   14689          case 0x07: {
   14690             /* Doubleword Insert Bit Field - DINS; MIPS64r2 */
   14691             IRTemp tmp1 = newTemp(ty);
   14692             IRTemp tmpT1 = newTemp(ty);
   14693             IRTemp tmpT2 = newTemp(ty);
   14694             IRTemp tmpT3 = newTemp(ty);
   14695             IRTemp tmpT4 = newTemp(ty);
   14696             IRTemp tmpT5 = newTemp(ty);
   14697             IRTemp tmpT6 = newTemp(ty);
   14698             IRTemp tmpT7 = newTemp(ty);
   14699             IRTemp tmpT8 = newTemp(ty);
   14700             IRTemp tmpT9 = newTemp(ty);
   14701             IRTemp tmp = newTemp(ty);
   14702             IRTemp tmpRs = newTemp(ty);
   14703             IRTemp tmpRt = newTemp(ty);
   14704             IRTemp tmpRd = newTemp(ty);
   14705 
   14706             assign(tmpRs, getIReg(rs));
   14707             assign(tmpRt, getIReg(rt));
   14708 
   14709             msb = get_msb(cins);
   14710             lsb = get_lsb(cins);
   14711             size = msb + 1;
   14712             DIP("dins r%u, r%u, %d, %d", rt, rs, lsb,
   14713                 msb - lsb + 1);
   14714             UChar lsAmt = 63 - lsb;  /* left shift amount; */
   14715             UChar rsAmt = 63 - lsb;  /* right shift amount; */
   14716             assign(tmp, binop(Iop_Shl64, mkexpr(tmpRt), mkU8(lsAmt)));
   14717             assign(tmpT1, binop(Iop_Shl64, mkexpr(tmp), mkU8(1)));
   14718             assign(tmp1, binop(Iop_Shr64, mkexpr(tmpT1), mkU8(rsAmt)));
   14719             assign(tmpT2, binop(Iop_Shr64, mkexpr(tmp1), mkU8(1)));
   14720 
   14721             lsAmt = msb;  /* left shift amount; */
   14722             rsAmt = 1;  /*right shift amount; */
   14723             assign(tmpT3, binop(Iop_Shr64, mkexpr(tmpRt), mkU8(rsAmt)));
   14724             assign(tmpT4, binop(Iop_Shr64, mkexpr(tmpT3), mkU8(lsAmt)));
   14725             assign(tmpT5, binop(Iop_Shl64, mkexpr(tmpT4), mkU8(rsAmt)));
   14726             assign(tmpT6, binop(Iop_Shl64, mkexpr(tmpT5), mkU8(lsAmt)));
   14727 
   14728             lsAmt = 64 - (msb - lsb + 1);  /* left shift amount; */
   14729             rsAmt = 64 - (msb + 1);  /* right shift amount; */
   14730             assign(tmpT7, binop(Iop_Shl64, mkexpr(tmpRs), mkU8(lsAmt)));
   14731             assign(tmpT8, binop(Iop_Shr64, mkexpr(tmpT7), mkU8(rsAmt)));
   14732 
   14733             assign(tmpT9, binop(Iop_Or64, mkexpr(tmpT2), mkexpr(tmpT8)));
   14734             assign(tmpRd, binop(Iop_Or64, mkexpr(tmpT6), mkexpr(tmpT9)));
   14735             putIReg(rt, mkexpr(tmpRd));
   14736             break;
   14737          }
   14738       case 0x24:  /* DBSHFL */
   14739          lsb = get_lsb(cins);
   14740          IRTemp tmpRs = newTemp(ty);
   14741          IRTemp tmpRt = newTemp(ty);
   14742          IRTemp tmpRd = newTemp(ty);
   14743          assign(tmpRs, getIReg(rs));
   14744          assign(tmpRt, getIReg(rt));
   14745          switch (lsb) {
   14746             case 0x02: {  /* DSBH */
   14747                DIP("dsbh r%u, r%u", rd, rt);
   14748                IRTemp tmpT1 = newTemp(ty);
   14749                IRTemp tmpT2 = newTemp(ty);
   14750                IRTemp tmpT3 = newTemp(ty);
   14751                IRTemp tmpT4 = newTemp(ty);
   14752                IRTemp tmpT5 = newTemp(Ity_I64);
   14753                IRTemp tmpT6 = newTemp(ty);
   14754                assign(tmpT5, mkU64(0xFF00FF00FF00FF00ULL));
   14755                assign(tmpT6, mkU64(0x00FF00FF00FF00FFULL));
   14756                assign(tmpT1, binop(Iop_And64, mkexpr(tmpRt), mkexpr(tmpT5)));
   14757                assign(tmpT2, binop(Iop_Shr64, mkexpr(tmpT1), mkU8(8)));
   14758                assign(tmpT3, binop(Iop_And64, mkexpr(tmpRt), mkexpr(tmpT6)));
   14759                assign(tmpT4, binop(Iop_Shl64, mkexpr(tmpT3), mkU8(8)));
   14760                assign(tmpRd, binop(Iop_Or64, mkexpr(tmpT4), mkexpr(tmpT2)));
   14761                putIReg(rd, mkexpr(tmpRd));
   14762                break;
   14763             }
   14764             case 0x05: {  /* DSHD */
   14765                DIP("dshd r%u, r%u\n", rd, rt);
   14766                IRTemp tmpT1 = newTemp(ty);
   14767                IRTemp tmpT2 = newTemp(ty);
   14768                IRTemp tmpT3 = newTemp(ty);
   14769                IRTemp tmpT4 = newTemp(ty);
   14770                IRTemp tmpT5 = newTemp(Ity_I64);
   14771                IRTemp tmpT6 = newTemp(ty);
   14772                IRTemp tmpT7 = newTemp(ty);
   14773                IRTemp tmpT8 = newTemp(ty);
   14774                IRTemp tmpT9 = newTemp(ty);
   14775                assign(tmpT5, mkU64(0xFFFF0000FFFF0000ULL));
   14776                assign(tmpT6, mkU64(0x0000FFFF0000FFFFULL));
   14777                assign(tmpT1, binop(Iop_And64, mkexpr(tmpRt), mkexpr(tmpT5)));
   14778                assign(tmpT2, binop(Iop_Shr64, mkexpr(tmpT1), mkU8(16)));
   14779                assign(tmpT3, binop(Iop_And64, mkexpr(tmpRt), mkexpr(tmpT6)));
   14780                assign(tmpT4, binop(Iop_Shl64, mkexpr(tmpT3), mkU8(16)));
   14781                assign(tmpT7, binop(Iop_Or64, mkexpr(tmpT4), mkexpr(tmpT2)));
   14782                assign(tmpT8, binop(Iop_Shl64, mkexpr(tmpT7), mkU8(32)));
   14783                assign(tmpT9, binop(Iop_Shr64, mkexpr(tmpT7), mkU8(32)));
   14784                assign(tmpRd, binop(Iop_Or64, mkexpr(tmpT8), mkexpr(tmpT9)));
   14785                putIReg(rd, mkexpr(tmpRd));
   14786                break;
   14787             }
   14788          default:
   14789             vex_printf("\nop6o10 = %d", lsb);
   14790             goto decode_failure;;
   14791          }
   14792          break;
   14793       case 0x3B: {  /* RDHWR */
   14794          DIP("rdhwr r%d, r%d", rt, rd);
   14795             if (rd == 29) {
   14796                putIReg(rt, getULR());
   14797 #if defined(__mips__) && ((defined(__mips_isa_rev) && __mips_isa_rev >= 2))
   14798             } else if (rd == 1) {
   14799                if (mode64) {
   14800                   IRTemp   val  = newTemp(Ity_I64);
   14801                   IRExpr** args = mkIRExprVec_2 (mkU64(rt), mkU64(rd));
   14802                   IRDirty *d = unsafeIRDirty_1_N(val,
   14803                                                  0,
   14804                                                  "mips64_dirtyhelper_rdhwr",
   14805                                                  &mips64_dirtyhelper_rdhwr,
   14806                                                  args);
   14807                   stmt(IRStmt_Dirty(d));
   14808                   putIReg(rt, mkexpr(val));
   14809                } else {
   14810                   IRTemp   val  = newTemp(Ity_I32);
   14811                   IRExpr** args = mkIRExprVec_2 (mkU32(rt), mkU32(rd));
   14812                   IRDirty *d = unsafeIRDirty_1_N(val,
   14813                                                  0,
   14814                                                  "mips32_dirtyhelper_rdhwr",
   14815                                                  &mips32_dirtyhelper_rdhwr,
   14816                                                  args);
   14817                   stmt(IRStmt_Dirty(d));
   14818                   putIReg(rt, mkexpr(val));
   14819                }
   14820 #endif
   14821             } else
   14822                goto decode_failure;
   14823             break;
   14824          }
   14825       case 0x04:  /* INS */
   14826          msb = get_msb(cins);
   14827          lsb = get_lsb(cins);
   14828          size = msb - lsb + 1;
   14829          DIP("ins size:%d msb:%d lsb:%d", size, msb, lsb);
   14830 
   14831          vassert(lsb + size <= 32);
   14832          vassert(lsb + size > 0);
   14833 
   14834          /* put size bits from rs at the pos in temporary */
   14835          t0 = newTemp(Ity_I32);
   14836          t3 = newTemp(Ity_I32);
   14837          /* shift left for 32 - size to clear leading bits and get zeros
   14838             at the end */
   14839          assign(t0, binop(Iop_Shl32, mkNarrowTo32(ty, getIReg(rs)),
   14840                           mkU8(32 - size)));
   14841          /* now set it at pos */
   14842          t1 = newTemp(Ity_I32);
   14843          assign(t1, binop(Iop_Shr32, mkexpr(t0), mkU8(32 - size - lsb)));
   14844 
   14845          if (lsb > 0) {
   14846             t2 = newTemp(Ity_I32);
   14847             /* clear everything but lower pos bits from rt */
   14848             assign(t2, binop(Iop_Shl32, mkNarrowTo32(ty, getIReg(rt)),
   14849                              mkU8(32 - lsb)));
   14850             assign(t3, binop(Iop_Shr32, mkexpr(t2), mkU8(32 - lsb)));
   14851          } else
   14852             assign(t3, mkU32(0));
   14853 
   14854          if (msb < 31) {
   14855             t4 = newTemp(Ity_I32);
   14856             /* clear everything but upper msb + 1 bits from rt */
   14857             assign(t4, binop(Iop_Shr32, mkNarrowTo32(ty, getIReg(rt)),
   14858                              mkU8(msb + 1)));
   14859             t5 = newTemp(Ity_I32);
   14860             assign(t5, binop(Iop_Shl32, mkexpr(t4), mkU8(msb + 1)));
   14861 
   14862             /* now combine these registers */
   14863             if (lsb > 0) {
   14864                t6 = newTemp(Ity_I32);
   14865                assign(t6, binop(Iop_Or32, mkexpr(t5), mkexpr(t1)));
   14866                putIReg(rt, mkWidenFrom32(ty, binop(Iop_Or32, mkexpr(t6),
   14867                                                    mkexpr(t3)), True));
   14868             } else {
   14869                putIReg(rt, mkWidenFrom32(ty, binop(Iop_Or32, mkexpr(t1),
   14870                                                    mkexpr(t5)), True));
   14871             }
   14872          } else {
   14873             putIReg(rt, mkWidenFrom32(ty, binop(Iop_Or32, mkexpr(t1),
   14874                                                 mkexpr(t3)), True));
   14875          }
   14876          break;
   14877 
   14878       case 0x00:  /* EXT */
   14879          msb = get_msb(cins);
   14880          lsb = get_lsb(cins);
   14881          size = msb + 1;
   14882          DIP("ext size:%d msb:%d lsb:%d", size, msb, lsb);
   14883          vassert(lsb + size <= 32);
   14884          vassert(lsb + size > 0);
   14885          /* put size bits from rs at the top of in temporary */
   14886          if (lsb + size < 32) {
   14887             t0 = newTemp(Ity_I32);
   14888             assign(t0, binop(Iop_Shl32, mkNarrowTo32(ty, getIReg(rs)),
   14889                              mkU8(32 - lsb - size)));
   14890 
   14891             putIReg(rt, mkWidenFrom32(ty, binop(Iop_Shr32, mkexpr(t0),
   14892                                                 mkU8(32 - size)), True));
   14893          } else {
   14894             putIReg(rt, mkWidenFrom32(ty, binop(Iop_Shr32,
   14895                                                 mkNarrowTo32(ty, getIReg(rs)),
   14896                                                 mkU8(32 - size)), True));
   14897          }
   14898          break;
   14899 
   14900       case 0x03:  /* Doubleword Extract Bit Field - DEXT; MIPS64r2 */
   14901          msb = get_msb(cins);
   14902          lsb = get_lsb(cins);
   14903          size = msb + 1;
   14904          DIP("dext r%u, r%u, %d, %d", rt, rs, lsb, msb + 1);
   14905          t1 = newTemp(Ity_I64);
   14906          vassert(lsb >= 0 && lsb < 32);
   14907          vassert(size > 0 && size <= 32);
   14908          vassert((lsb + size) > 0 && (lsb + size) <= 63);
   14909 
   14910          UChar lsAmt = 63 - (lsb + msb);  /* left shift amount; */
   14911          UChar rsAmt = 63 - msb;  /* right shift amount; */
   14912 
   14913          assign(t1, binop(Iop_Shl64, getIReg(rs), mkU8(lsAmt)));
   14914          putIReg(rt, binop(Iop_Shr64, mkexpr(t1), mkU8(rsAmt)));
   14915 
   14916          break;
   14917 
   14918       case 0x20:  /* BSHFL */
   14919          switch (sa) {
   14920             case 0x02:  /* WSBH */
   14921                DIP("wsbh r%d, r%d", rd, rt);
   14922                t0 = newTemp(Ity_I32);
   14923                t1 = newTemp(Ity_I32);
   14924                t2 = newTemp(Ity_I32);
   14925                t3 = newTemp(Ity_I32);
   14926                assign(t0, binop(Iop_Shl32, binop(Iop_And32, mkNarrowTo32(ty,
   14927                                            getIReg(rt)), mkU32(0x00FF0000)),
   14928                                            mkU8(0x8)));
   14929                assign(t1, binop(Iop_Shr32, binop(Iop_And32, mkNarrowTo32(ty,
   14930                                 getIReg(rt)), mkU32(0xFF000000)), mkU8(0x8)));
   14931                assign(t2, binop(Iop_Shl32, binop(Iop_And32, mkNarrowTo32(ty,
   14932                                 getIReg(rt)), mkU32(0x000000FF)), mkU8(0x8)));
   14933                assign(t3, binop(Iop_Shr32, binop(Iop_And32, mkNarrowTo32(ty,
   14934                                 getIReg(rt)), mkU32(0x0000FF00)), mkU8(0x8)));
   14935                putIReg(rd, mkWidenFrom32(ty, binop(Iop_Or32, binop(Iop_Or32,
   14936                                          mkexpr(t0), mkexpr(t1)),
   14937                                          binop(Iop_Or32, mkexpr(t2),
   14938                                          mkexpr(t3))), True));
   14939                break;
   14940 
   14941             case 0x10:  /* SEB */
   14942                DIP("seb r%d, r%d", rd, rt);
   14943                if (mode64)
   14944                   putIReg(rd, unop(Iop_8Sto64, unop(Iop_64to8, getIReg(rt))));
   14945                else
   14946                   putIReg(rd, unop(Iop_8Sto32, unop(Iop_32to8, getIReg(rt))));
   14947                break;
   14948 
   14949             case 0x18:  /* SEH */
   14950                DIP("seh r%d, r%d", rd, rt);
   14951                if (mode64)
   14952                   putIReg(rd, unop(Iop_16Sto64, unop(Iop_64to16, getIReg(rt))));
   14953                else
   14954                   putIReg(rd, unop(Iop_16Sto32, unop(Iop_32to16, getIReg(rt))));
   14955                break;
   14956 
   14957             default:
   14958                goto decode_failure;
   14959 
   14960          }
   14961          break;  /* BSHFL */
   14962 
   14963       /* --- MIPS32(r2) DSP ASE(r2) / Cavium Specfic (LX) instructions --- */
   14964       case 0xA:  /* LX */
   14965          if (VEX_MIPS_COMP_ID(archinfo->hwcaps) == VEX_PRID_COMP_CAVIUM) {
   14966             if (dis_instr_CVM(cins))
   14967                break;
   14968             goto decode_failure;
   14969          }
   14970       case 0xC:  /* INSV */
   14971       case 0x38: {  /* EXTR.W */
   14972          if (VEX_MIPS_PROC_DSP(archinfo->hwcaps)) {
   14973             UInt retVal = disDSPInstr_MIPS_WRK ( cins );
   14974             if (0 != retVal ) {
   14975                goto decode_failure_dsp;
   14976             }
   14977             break;
   14978          } else {
   14979             goto decode_failure_dsp;
   14980          }
   14981          break;
   14982       }
   14983       case 0x10: {  /* ADDU.QB */
   14984          switch(sa) {
   14985             case  0xC:  /* SUBU_S.PH */
   14986             case  0xD:  /* ADDU_S.PH */
   14987             case 0x1E: {  /* MULQ_S.PH */
   14988                if (VEX_MIPS_PROC_DSP2(archinfo->hwcaps)) {
   14989                   UInt retVal = disDSPInstr_MIPS_WRK ( cins );
   14990                   if (0 != retVal ) {
   14991                      goto decode_failure_dsp;
   14992                   }
   14993                   break;
   14994                } else {
   14995                   goto decode_failure_dsp;
   14996                }
   14997                break;
   14998             }
   14999             default: {
   15000                if (VEX_MIPS_PROC_DSP(archinfo->hwcaps)) {
   15001                   UInt retVal = disDSPInstr_MIPS_WRK ( cins );
   15002                   if (0 != retVal ) {
   15003                      goto decode_failure_dsp;
   15004                   }
   15005                   break;
   15006                } else {
   15007                   goto decode_failure_dsp;
   15008                }
   15009                break;
   15010             }
   15011          }
   15012          break;
   15013       }
   15014       case 0x11: {  /* CMPU.EQ.QB */
   15015          switch(sa) {
   15016             case 0x18:  /* CMPGDU.EQ.QB */
   15017             case 0x19:  /* CMPGDU.LT.QB */
   15018             case 0x1A:  /* CMPGDU.LE.QB */
   15019             case 0x0D:  /* PRECR.QB.PH */
   15020             case 0x1E:  /* PRECR_SRA.PH.W */
   15021             case 0x1F: {  /* PRECR_SRA_R.PH.W */
   15022                if (VEX_MIPS_PROC_DSP2(archinfo->hwcaps)) {
   15023                   UInt retVal = disDSPInstr_MIPS_WRK ( cins );
   15024                   if (0 != retVal ) {
   15025                      goto decode_failure_dsp;
   15026                   }
   15027                   break;
   15028                } else {
   15029                   goto decode_failure_dsp;
   15030                }
   15031                break;
   15032             }
   15033             default: {
   15034                if (VEX_MIPS_PROC_DSP(archinfo->hwcaps)) {
   15035                   UInt retVal = disDSPInstr_MIPS_WRK ( cins );
   15036                   if (0 != retVal ) {
   15037                      goto decode_failure_dsp;
   15038                   }
   15039                   break;
   15040                } else {
   15041                   goto decode_failure_dsp;
   15042                }
   15043                break;
   15044             }
   15045          }
   15046          break;
   15047       }
   15048       case 0x12: {  /* ABSQ_S.PH */
   15049          switch(sa){
   15050             case 0x1: {  /* ABSQ_S.QB */
   15051                if (VEX_MIPS_PROC_DSP2(archinfo->hwcaps)) {
   15052                   UInt retVal = disDSPInstr_MIPS_WRK ( cins );
   15053                   if (0 != retVal ) {
   15054                      goto decode_failure_dsp;
   15055                   }
   15056                   break;
   15057                } else {
   15058                   goto decode_failure_dsp;
   15059                }
   15060                break;
   15061             }
   15062             default: {
   15063                if (VEX_MIPS_PROC_DSP(archinfo->hwcaps)) {
   15064                   UInt retVal = disDSPInstr_MIPS_WRK ( cins );
   15065                   if (0 != retVal ) {
   15066                      goto decode_failure_dsp;
   15067                   }
   15068                   break;
   15069                } else {
   15070                   goto decode_failure_dsp;
   15071                }
   15072                break;
   15073             }
   15074          }
   15075          break;
   15076       }
   15077       case 0x13: {  /* SHLL.QB */
   15078          switch(sa) {
   15079             case 0x04:  /* SHRA.QB */
   15080             case 0x05:  /* SHRA_R.QB */
   15081             case 0x06:  /* SHRAV.QB */
   15082             case 0x07:  /* SHRAV_R.QB */
   15083             case 0x19:  /* SHLR.PH */
   15084             case 0x1B: {  /* SHLRV.PH */
   15085                if (VEX_MIPS_PROC_DSP2(archinfo->hwcaps)) {
   15086                   UInt retVal = disDSPInstr_MIPS_WRK ( cins );
   15087                   if (0 != retVal ) {
   15088                      goto decode_failure_dsp;
   15089                   }
   15090                   break;
   15091                } else {
   15092                   goto decode_failure_dsp;
   15093                }
   15094                break;
   15095             }
   15096             default: {
   15097                if (VEX_MIPS_PROC_DSP(archinfo->hwcaps)) {
   15098                   UInt retVal = disDSPInstr_MIPS_WRK ( cins );
   15099                   if (0 != retVal ) {
   15100                      goto decode_failure_dsp;
   15101                   }
   15102                   break;
   15103                } else {
   15104                   goto decode_failure_dsp;
   15105                }
   15106                break;
   15107             }
   15108          }
   15109          break;
   15110       }
   15111       case 0x30: {  /* DPAQ.W.PH */
   15112          switch(sa) {
   15113             case  0x0:  /* DPA.W.PH */
   15114             case 0x18:  /* DPAQX_S.W.PH */
   15115             case 0x1A:  /* DPAQX_SA.W.PH */
   15116             case  0x8:  /* DPAX.W.PH */
   15117             case  0x1:  /* DPS.W.PH */
   15118             case 0x19:  /* DPSQX_S.W.PH */
   15119             case 0x1B:  /* DPSQX_SA.W.PH */
   15120             case  0x9:  /* DPSX.W.PH */
   15121             case  0x2: {  /* MULSA.W.PH */
   15122                if (VEX_MIPS_PROC_DSP2(archinfo->hwcaps)) {
   15123                   UInt retVal = disDSPInstr_MIPS_WRK ( cins );
   15124                   if (0 != retVal ) {
   15125                      goto decode_failure_dsp;
   15126                   }
   15127                   break;
   15128                } else {
   15129                   goto decode_failure_dsp;
   15130                }
   15131                break;
   15132             }
   15133             default: {
   15134                if (VEX_MIPS_PROC_DSP(archinfo->hwcaps)) {
   15135                   UInt retVal = disDSPInstr_MIPS_WRK ( cins );
   15136                   if (0 != retVal ) {
   15137                      goto decode_failure_dsp;
   15138                   }
   15139                   break;
   15140                } else {
   15141                   goto decode_failure_dsp;
   15142                }
   15143                break;
   15144             }
   15145          }
   15146          break;
   15147       }
   15148       case 0x18:  /* ADDUH.QB/MUL.PH */
   15149       case 0x31: {  /* APPEND */
   15150          if (VEX_MIPS_PROC_DSP2(archinfo->hwcaps)) {
   15151             UInt retVal = disDSPInstr_MIPS_WRK ( cins );
   15152             if (0 != retVal ) {
   15153                goto decode_failure_dsp;
   15154             }
   15155             break;
   15156          } else {
   15157             goto decode_failure_dsp;
   15158          }
   15159       }
   15160       default:
   15161          goto decode_failure;
   15162 
   15163    }
   15164       break;  /* Special3 */
   15165 
   15166    case 0x3B:
   15167       if (0x3B == function &&
   15168           (VEX_MIPS_COMP_ID(archinfo->hwcaps) == VEX_PRID_COMP_BROADCOM)) {
   15169          /*RDHWR*/
   15170          DIP("rdhwr r%d, r%d", rt, rd);
   15171          if (rd == 29) {
   15172             putIReg(rt, getULR());
   15173          } else
   15174             goto decode_failure;
   15175          break;
   15176       } else {
   15177          goto decode_failure;
   15178       }
   15179 
   15180    case 0x00:  /* Special */
   15181 
   15182       switch (function) {
   15183       case 0x1: {
   15184          UInt mov_cc = get_mov_cc(cins);
   15185          if (tf == 0) {  /* MOVF */
   15186             DIP("movf r%d, r%d, %d", rd, rs, mov_cc);
   15187             t1 = newTemp(Ity_I1);
   15188             t2 = newTemp(Ity_I32);
   15189             t3 = newTemp(Ity_I1);
   15190 
   15191             assign(t1, binop(Iop_CmpEQ32, mkU32(0), mkU32(mov_cc)));
   15192             assign(t2, IRExpr_ITE(mkexpr(t1),
   15193                                   binop(Iop_And32,
   15194                                         binop(Iop_Shr32, getFCSR(),
   15195                                               mkU8(23)),
   15196                                         mkU32(0x1)),
   15197                                   binop(Iop_And32,
   15198                                         binop(Iop_Shr32, getFCSR(),
   15199                                               mkU8(24 + mov_cc)),
   15200                                         mkU32(0x1))
   15201                                   ));
   15202             assign(t3, binop(Iop_CmpEQ32, mkU32(0), mkexpr(t2)));
   15203             putIReg(rd, IRExpr_ITE(mkexpr(t3), getIReg(rs), getIReg(rd)));
   15204          } else if (tf == 1) {  /* MOVT */
   15205             DIP("movt r%d, r%d, %d", rd, rs, mov_cc);
   15206             t1 = newTemp(Ity_I1);
   15207             t2 = newTemp(Ity_I32);
   15208             t3 = newTemp(Ity_I1);
   15209 
   15210             assign(t1, binop(Iop_CmpEQ32, mkU32(0), mkU32(mov_cc)));
   15211             assign(t2, IRExpr_ITE(mkexpr(t1),
   15212                                   binop(Iop_And32,
   15213                                         binop(Iop_Shr32, getFCSR(),
   15214                                               mkU8(23)),
   15215                                         mkU32(0x1)),
   15216                                   binop(Iop_And32,
   15217                                         binop(Iop_Shr32, getFCSR(),
   15218                                               mkU8(24 + mov_cc)),
   15219                                         mkU32(0x1))
   15220                                   ));
   15221             assign(t3, binop(Iop_CmpEQ32, mkU32(1), mkexpr(t2)));
   15222             putIReg(rd, IRExpr_ITE(mkexpr(t3), getIReg(rs), getIReg(rd)));
   15223          }
   15224          break;
   15225       }
   15226       case 0x0A: {  /* MOVZ */
   15227          DIP("movz r%d, r%d, r%d", rd, rs, rt);
   15228          t1 = newTemp(ty);
   15229          t2 = newTemp(ty);
   15230          if (mode64) {
   15231             assign(t1, unop(Iop_32Sto64, unop(Iop_1Sto32, binop(Iop_CmpEQ64,
   15232                             getIReg(rt), mkU64(0x0)))));
   15233             assign(t2, unop(Iop_32Sto64, unop(Iop_1Sto32, binop(Iop_CmpNE64,
   15234                             getIReg(rt), mkU64(0x0)))));
   15235             putIReg(rd, binop(Iop_Add64, binop(Iop_And64, getIReg(rs),
   15236                         mkexpr(t1)), binop(Iop_And64, getIReg(rd),mkexpr(t2))));
   15237          } else {
   15238             assign(t1, unop(Iop_1Sto32, binop(Iop_CmpEQ32, getIReg(rt),
   15239                                               mkU32(0x0))));
   15240             assign(t2, unop(Iop_1Sto32, binop(Iop_CmpNE32, getIReg(rt),
   15241                                               mkU32(0x0))));
   15242             putIReg(rd, binop(Iop_Add32, binop(Iop_And32, getIReg(rs),
   15243                         mkexpr(t1)), binop(Iop_And32, getIReg(rd),
   15244                         mkexpr(t2))));
   15245          }
   15246          break;
   15247       }
   15248 
   15249       case 0x0B: {  /* MOVN */
   15250          DIP("movn r%d, r%d, r%d", rd, rs, rt);
   15251          t1 = newTemp(ty);
   15252          t2 = newTemp(ty);
   15253          if (mode64) {
   15254             assign(t1, unop(Iop_32Sto64, unop(Iop_1Sto32, binop(Iop_CmpEQ64,
   15255                             getIReg(rt), mkU64(0x0)))));
   15256             assign(t2, unop(Iop_32Sto64, unop(Iop_1Sto32, binop(Iop_CmpNE64,
   15257                             getIReg(rt), mkU64(0x0)))));
   15258             putIReg(rd, binop(Iop_Add64, binop(Iop_And64, getIReg(rs),
   15259                         mkexpr(t2)), binop(Iop_And64, getIReg(rd),
   15260                                            mkexpr(t1))));
   15261          } else {
   15262             assign(t1, unop(Iop_1Sto32, binop(Iop_CmpEQ32, getIReg(rt),
   15263                                               mkU32(0x0))));
   15264             assign(t2, unop(Iop_1Sto32, binop(Iop_CmpNE32, getIReg(rt),
   15265                                               mkU32(0x0))));
   15266             putIReg(rd, binop(Iop_Add32, binop(Iop_And32, getIReg(rs),
   15267                         mkexpr(t2)), binop(Iop_And32, getIReg(rd),
   15268                         mkexpr(t1))));
   15269          }
   15270          break;
   15271       }
   15272 
   15273       case 0x18:  {  /* MULT */
   15274          if ( (1 <= ac) && ( 3 >= ac) ) {
   15275             if (VEX_MIPS_PROC_DSP(archinfo->hwcaps)) {
   15276                /* If DSP is present -> DSP ASE MULT */
   15277                UInt retVal = disDSPInstr_MIPS_WRK ( cins );
   15278                if (0 != retVal ) {
   15279                   goto decode_failure_dsp;
   15280                }
   15281                break;
   15282             } else {
   15283                goto decode_failure_dsp;
   15284             }
   15285          } else {
   15286             DIP("mult r%d, r%d", rs, rt);
   15287             t2 = newTemp(Ity_I64);
   15288 
   15289             assign(t2, binop(Iop_MullS32, mkNarrowTo32(ty, getIReg(rs)),
   15290                                           mkNarrowTo32(ty, getIReg(rt))));
   15291 
   15292             putHI(mkWidenFrom32(ty, unop(Iop_64HIto32, mkexpr(t2)), True));
   15293             putLO(mkWidenFrom32(ty, unop(Iop_64to32, mkexpr(t2)), True));
   15294             break;
   15295          }
   15296       }
   15297       case 0x19:  {  /* MULTU */
   15298          if ( (1 <= ac) && ( 3 >= ac) ) {
   15299             if (VEX_MIPS_PROC_DSP(archinfo->hwcaps)) {
   15300                /* If DSP is present -> DSP ASE MULTU */
   15301                UInt retVal = disDSPInstr_MIPS_WRK ( cins );
   15302                if (0 != retVal ) {
   15303                   goto decode_failure_dsp;
   15304                }
   15305                break;
   15306             } else {
   15307                goto decode_failure_dsp;
   15308             }
   15309          } else {
   15310             DIP("multu r%d, r%d", rs, rt);
   15311             t2 = newTemp(Ity_I64);
   15312 
   15313             assign(t2, binop(Iop_MullU32, mkNarrowTo32(ty, getIReg(rs)),
   15314                                           mkNarrowTo32(ty, getIReg(rt))));
   15315 
   15316             putHI(mkWidenFrom32(ty, unop(Iop_64HIto32, mkexpr(t2)), True));
   15317             putLO(mkWidenFrom32(ty, unop(Iop_64to32, mkexpr(t2)), True));
   15318             break;
   15319          }
   15320       }
   15321       case 0x20: {  /* ADD */
   15322          DIP("add r%d, r%d, r%d", rd, rs, rt);
   15323          IRTemp tmpRs32 = newTemp(Ity_I32);
   15324          IRTemp tmpRt32 = newTemp(Ity_I32);
   15325 
   15326          assign(tmpRs32, mkNarrowTo32(ty, getIReg(rs)));
   15327          assign(tmpRt32, mkNarrowTo32(ty, getIReg(rt)));
   15328 
   15329          t0 = newTemp(Ity_I32);
   15330          t1 = newTemp(Ity_I32);
   15331          t2 = newTemp(Ity_I32);
   15332          t3 = newTemp(Ity_I32);
   15333          t4 = newTemp(Ity_I32);
   15334          /* dst = src0 + src1
   15335             if (sign(src0 ) != sign(src1 ))
   15336             goto no overflow;
   15337             if (sign(dst) == sign(src0 ))
   15338             goto no overflow;
   15339             we have overflow! */
   15340 
   15341          assign(t0, binop(Iop_Add32, mkexpr(tmpRs32), mkexpr(tmpRt32)));
   15342          assign(t1, binop(Iop_Xor32, mkexpr(tmpRs32), mkexpr(tmpRt32)));
   15343          assign(t2, unop(Iop_1Uto32,
   15344                          binop(Iop_CmpEQ32,
   15345                                binop(Iop_And32, mkexpr(t1), mkU32(0x80000000)),
   15346                                mkU32(0x80000000))));
   15347 
   15348          assign(t3, binop(Iop_Xor32, mkexpr(t0), mkexpr(tmpRs32)));
   15349          assign(t4, unop(Iop_1Uto32,
   15350                          binop(Iop_CmpNE32,
   15351                                binop(Iop_And32, mkexpr(t3), mkU32(0x80000000)),
   15352                                mkU32(0x80000000))));
   15353 
   15354          stmt(IRStmt_Exit(binop(Iop_CmpEQ32,
   15355                                 binop(Iop_Or32, mkexpr(t2), mkexpr(t4)),
   15356                                 mkU32(0)),
   15357                           Ijk_SigFPE_IntOvf,
   15358                           mode64 ? IRConst_U64(guest_PC_curr_instr + 4) :
   15359                                    IRConst_U32(guest_PC_curr_instr + 4),
   15360                           OFFB_PC));
   15361 
   15362          putIReg(rd,  mkWidenFrom32(ty, mkexpr(t0), True));
   15363          break;
   15364       }
   15365       case 0x1A:  /* DIV */
   15366          DIP("div r%d, r%d", rs, rt);
   15367          if (mode64) {
   15368             t2 = newTemp(Ity_I64);
   15369 
   15370             assign(t2, binop(Iop_DivModS64to32,
   15371                              getIReg(rs), mkNarrowTo32(ty, getIReg(rt))));
   15372 
   15373             putHI(mkWidenFrom32(ty, unop(Iop_64HIto32, mkexpr(t2)), True));
   15374             putLO(mkWidenFrom32(ty, unop(Iop_64to32, mkexpr(t2)), True));
   15375          } else {
   15376             t1 = newTemp(Ity_I64);
   15377             t2 = newTemp(Ity_I64);
   15378 
   15379             assign(t1, unop(Iop_32Sto64, getIReg(rs)));
   15380             assign(t2, binop(Iop_DivModS64to32, mkexpr(t1), getIReg(rt)));
   15381 
   15382             putHI(unop(Iop_64HIto32, mkexpr(t2)));
   15383             putLO(unop(Iop_64to32, mkexpr(t2)));
   15384          }
   15385          break;
   15386 
   15387       case 0x1B:  /* DIVU */
   15388          DIP("divu r%d, r%d", rs, rt);
   15389          if (mode64) {
   15390             t2 = newTemp(Ity_I64);
   15391 
   15392             assign(t2, binop(Iop_DivModU64to32,
   15393                              getIReg(rs), mkNarrowTo32(ty, getIReg(rt))));
   15394 
   15395             putHI(mkWidenFrom32(ty, unop(Iop_64HIto32, mkexpr(t2)), True));
   15396             putLO(mkWidenFrom32(ty, unop(Iop_64to32, mkexpr(t2)), True));
   15397          } else {
   15398             t1 = newTemp(Ity_I64);
   15399             t2 = newTemp(Ity_I64);
   15400             assign(t1, unop(Iop_32Uto64, getIReg(rs)));
   15401             assign(t2, binop(Iop_DivModU64to32, mkexpr(t1), getIReg(rt)));
   15402             putHI(unop(Iop_64HIto32, mkexpr(t2)));
   15403             putLO(unop(Iop_64to32, mkexpr(t2)));
   15404          }
   15405          break;
   15406 
   15407       case 0x1C:  /* Doubleword Multiply - DMULT; MIPS64 */
   15408          DIP("dmult r%u, r%u", rs, rt);
   15409          t0 = newTemp(Ity_I128);
   15410 
   15411          assign(t0, binop(Iop_MullS64, getIReg(rs), getIReg(rt)));
   15412 
   15413          putHI(unop(Iop_128HIto64, mkexpr(t0)));
   15414          putLO(unop(Iop_128to64, mkexpr(t0)));
   15415          break;
   15416 
   15417       case 0x1D:  /* Doubleword Multiply Unsigned - DMULTU; MIPS64 */
   15418          DIP("dmultu r%u, r%u", rs, rt);
   15419          t0 = newTemp(Ity_I128);
   15420 
   15421          assign(t0, binop(Iop_MullU64, getIReg(rs), getIReg(rt)));
   15422 
   15423          putHI(unop(Iop_128HIto64, mkexpr(t0)));
   15424          putLO(unop(Iop_128to64, mkexpr(t0)));
   15425          break;
   15426 
   15427       case 0x1E:  /* Doubleword Divide DDIV; MIPS64 */
   15428          DIP("ddiv r%u, r%u", rs, rt);
   15429          t1 = newTemp(Ity_I128);
   15430 
   15431          assign(t1, binop(Iop_DivModS64to64, getIReg(rs), getIReg(rt)));
   15432 
   15433          putHI(unop(Iop_128HIto64, mkexpr(t1)));
   15434          putLO(unop(Iop_128to64, mkexpr(t1)));
   15435          break;
   15436 
   15437       case 0x1F:  /* Doubleword Divide Unsigned DDIVU; MIPS64 check this */
   15438          DIP("ddivu r%u, r%u", rs, rt);
   15439          t1 = newTemp(Ity_I128);
   15440          t2 = newTemp(Ity_I128);
   15441 
   15442          assign(t1, binop(Iop_64HLto128, mkU64(0), getIReg(rs)));
   15443 
   15444          assign(t2, binop(Iop_DivModU128to64, mkexpr(t1), getIReg(rt)));
   15445 
   15446          putHI(unop(Iop_128HIto64, mkexpr(t2)));
   15447          putLO(unop(Iop_128to64, mkexpr(t2)));
   15448          break;
   15449 
   15450       case 0x10: {  /* MFHI */
   15451          if (VEX_MIPS_PROC_DSP(archinfo->hwcaps)) {
   15452             /* If DSP is present -> DSP ASE MFHI */
   15453             UInt retVal = disDSPInstr_MIPS_WRK ( cins );
   15454             if (0 != retVal ) {
   15455                goto decode_failure;
   15456             }
   15457             break;
   15458          } else {
   15459             DIP("mfhi r%d", rd);
   15460             putIReg(rd, getHI());
   15461             break;
   15462          }
   15463       }
   15464 
   15465       case 0x11:  {  /* MTHI */
   15466          if (VEX_MIPS_PROC_DSP(archinfo->hwcaps)) {
   15467             /* If DSP is present -> DSP ASE MTHI */
   15468             UInt retVal = disDSPInstr_MIPS_WRK ( cins );
   15469             if (0 != retVal ) {
   15470                goto decode_failure;
   15471             }
   15472             break;
   15473          } else {
   15474             DIP("mthi r%d", rs);
   15475             putHI(getIReg(rs));
   15476             break;
   15477          }
   15478       }
   15479 
   15480       case 0x12:  {  /* MFLO */
   15481          if (VEX_MIPS_PROC_DSP(archinfo->hwcaps)) {
   15482             /* If DSP is present -> DSP ASE MFLO */
   15483             UInt retVal = disDSPInstr_MIPS_WRK ( cins );
   15484             if (0 != retVal ) {
   15485                goto decode_failure;
   15486             }
   15487             break;
   15488          } else {
   15489             DIP("mflo r%d", rd);
   15490             putIReg(rd, getLO());
   15491             break;
   15492          }
   15493       }
   15494 
   15495       case 0x13:  {  /* MTLO */
   15496          if (VEX_MIPS_PROC_DSP(archinfo->hwcaps)) {
   15497             /* If DSP is present -> DSP ASE MTLO */
   15498             UInt retVal = disDSPInstr_MIPS_WRK ( cins );
   15499             if (0 != retVal ) {
   15500                goto decode_failure;
   15501             }
   15502             break;
   15503          } else {
   15504             DIP("mtlo r%d", rs);
   15505             putLO(getIReg(rs));
   15506             break;
   15507          }
   15508       }
   15509 
   15510       case 0x21:  /* ADDU */
   15511          DIP("addu r%d, r%d, r%d", rd, rs, rt);
   15512          if (mode64) {
   15513             ALU_PATTERN64(Iop_Add32);
   15514          } else {
   15515             ALU_PATTERN(Iop_Add32);
   15516          }
   15517          break;
   15518 
   15519       case 0x22: {  /* SUB */
   15520          DIP("sub r%d, r%d, r%d", rd, rs, rt);
   15521          IRTemp tmpRs32 = newTemp(Ity_I32);
   15522          IRTemp tmpRt32 = newTemp(Ity_I32);
   15523 
   15524          assign(tmpRs32, mkNarrowTo32(ty, getIReg(rs)));
   15525          assign(tmpRt32, mkNarrowTo32(ty, getIReg(rt)));
   15526          t0 = newTemp(Ity_I32);
   15527          t1 = newTemp(Ity_I32);
   15528          t2 = newTemp(Ity_I32);
   15529          t3 = newTemp(Ity_I32);
   15530          t4 = newTemp(Ity_I32);
   15531          t5 = newTemp(Ity_I32);
   15532          /* dst = src0 + (-1 * src1)
   15533             if(sign(src0 ) != sign((-1 * src1) ))
   15534             goto no overflow;
   15535             if(sign(dst) == sign(src0 ))
   15536             goto no overflow;
   15537             we have overflow! */
   15538 
   15539          assign(t5, binop(Iop_Mul32, mkexpr(tmpRt32), mkU32(-1)));
   15540          assign(t0, binop(Iop_Add32, mkexpr(tmpRs32), mkexpr(t5)));
   15541          assign(t1, binop(Iop_Xor32, mkexpr(tmpRs32), mkexpr(t5)));
   15542          assign(t2, unop(Iop_1Sto32, binop(Iop_CmpEQ32, binop(Iop_And32,
   15543                          mkexpr(t1), mkU32(0x80000000)), mkU32(0x80000000))));
   15544 
   15545          assign(t3, binop(Iop_Xor32, mkexpr(t0), mkexpr(tmpRs32)));
   15546          assign(t4, unop(Iop_1Sto32, binop(Iop_CmpNE32, binop(Iop_And32,
   15547                          mkexpr(t3), mkU32(0x80000000)), mkU32(0x80000000))));
   15548 
   15549          stmt(IRStmt_Exit(binop(Iop_CmpEQ32, binop(Iop_Or32, mkexpr(t2),
   15550                                 mkexpr(t4)), mkU32(0)), Ijk_SigFPE_IntOvf,
   15551                           mode64 ? IRConst_U64(guest_PC_curr_instr + 4) :
   15552                                    IRConst_U32(guest_PC_curr_instr + 4),
   15553                           OFFB_PC));
   15554 
   15555          putIReg(rd, mkWidenFrom32(ty, mkexpr(t0), True));
   15556          break;
   15557       }
   15558       case 0x23:  /* SUBU */
   15559          DIP("subu r%d, r%d, r%d", rd, rs, rt);
   15560          if (mode64) {
   15561             ALU_PATTERN64(Iop_Sub32);
   15562          } else {
   15563             ALU_PATTERN(Iop_Sub32);
   15564          }
   15565          break;
   15566 
   15567       case 0x24:  /* AND */
   15568          DIP("and r%d, r%d, r%d", rd, rs, rt);
   15569          if (mode64) {
   15570             ALU_PATTERN(Iop_And64);
   15571          } else {
   15572             ALU_PATTERN(Iop_And32);
   15573          }
   15574          break;
   15575 
   15576       case 0x25:  /* OR */
   15577          DIP("or r%d, r%d, r%d", rd, rs, rt);
   15578          if (mode64) {
   15579             ALU_PATTERN(Iop_Or64);
   15580          } else {
   15581             ALU_PATTERN(Iop_Or32);
   15582          }
   15583          break;
   15584 
   15585       case 0x26:  /* XOR */
   15586          DIP("xor r%d, r%d, r%d", rd, rs, rt);
   15587          if (mode64) {
   15588             ALU_PATTERN(Iop_Xor64);
   15589          } else {
   15590             ALU_PATTERN(Iop_Xor32);
   15591          }
   15592          break;
   15593 
   15594       case 0x27:  /* NOR */
   15595          DIP("nor r%d, r%d, r%d", rd, rs, rt);
   15596          if (mode64)
   15597             putIReg(rd, unop(Iop_Not64, binop(Iop_Or64, getIReg(rs),
   15598                                               getIReg(rt))));
   15599          else
   15600             putIReg(rd, unop(Iop_Not32, binop(Iop_Or32, getIReg(rs),
   15601                                               getIReg(rt))));
   15602          break;
   15603 
   15604       case 0x08:  /* JR */
   15605          DIP("jr r%d", rs);
   15606          t0 = newTemp(ty);
   15607          assign(t0, getIReg(rs));
   15608          lastn = mkexpr(t0);
   15609          break;
   15610 
   15611       case 0x09:  /* JALR */
   15612          DIP("jalr r%d r%d", rd, rs);
   15613          if (mode64) {
   15614             putIReg(rd, mkU64(guest_PC_curr_instr + 8));
   15615             t0 = newTemp(Ity_I64);
   15616             assign(t0, getIReg(rs));
   15617             lastn = mkexpr(t0);
   15618          } else {
   15619             putIReg(rd, mkU32(guest_PC_curr_instr + 8));
   15620             t0 = newTemp(Ity_I32);
   15621             assign(t0, getIReg(rs));
   15622             lastn = mkexpr(t0);
   15623          }
   15624          break;
   15625 
   15626       case 0x0C:  /* SYSCALL */
   15627          DIP("syscall");
   15628          if (mode64)
   15629             putPC(mkU64(guest_PC_curr_instr + 4));
   15630          else
   15631             putPC(mkU32(guest_PC_curr_instr + 4));
   15632          dres.jk_StopHere = Ijk_Sys_syscall;
   15633          dres.whatNext    = Dis_StopHere;
   15634          break;
   15635 
   15636       case 0x2A:  /* SLT */
   15637          DIP("slt r%d, r%d, r%d", rd, rs, rt);
   15638          if (mode64)
   15639             putIReg(rd, unop(Iop_1Uto64, binop(Iop_CmpLT64S, getIReg(rs),
   15640                                                getIReg(rt))));
   15641          else
   15642             putIReg(rd, unop(Iop_1Uto32, binop(Iop_CmpLT32S, getIReg(rs),
   15643                                                getIReg(rt))));
   15644          break;
   15645 
   15646       case 0x2B:  /* SLTU */
   15647          DIP("sltu r%d, r%d, r%d", rd, rs, rt);
   15648          if (mode64)
   15649             putIReg(rd, unop(Iop_1Uto64, binop(Iop_CmpLT64U, getIReg(rs),
   15650                                          getIReg(rt))));
   15651          else
   15652             putIReg(rd, unop(Iop_1Uto32, binop(Iop_CmpLT32U, getIReg(rs),
   15653                                          getIReg(rt))));
   15654          break;
   15655 
   15656       case 0x00: {  /* SLL */
   15657          DIP("sll r%d, r%d, %d", rd, rt, sa);
   15658          IRTemp tmpRt32 = newTemp(Ity_I32);
   15659          IRTemp tmpSh32 = newTemp(Ity_I32);
   15660          IRTemp tmpRd = newTemp(Ity_I64);
   15661          if (mode64) {
   15662             assign(tmpRt32, mkNarrowTo32(ty, getIReg(rt)));
   15663             assign(tmpSh32, binop(Iop_Shl32, mkexpr(tmpRt32), mkU8(sa)));
   15664             assign(tmpRd, mkWidenFrom32(ty, mkexpr(tmpSh32), True));
   15665             putIReg(rd, mkexpr(tmpRd));
   15666          } else
   15667             SXX_PATTERN(Iop_Shl32);
   15668          break;
   15669       }
   15670 
   15671       case 0x04: {  /* SLLV */
   15672          DIP("sllv r%d, r%d, r%d", rd, rt, rs);
   15673          if (mode64) {
   15674             IRTemp tmpRs8 = newTemp(Ity_I8);
   15675             IRTemp tmpRt32 = newTemp(Ity_I32);
   15676             IRTemp tmpSh32 = newTemp(Ity_I32);
   15677             IRTemp tmp = newTemp(ty);
   15678             assign(tmp, binop(mkSzOp(ty, Iop_And8), getIReg(rs),
   15679                               mkSzImm(ty, 31)));
   15680             assign(tmpRs8, mkNarrowTo8(ty, mkexpr(tmp)));
   15681             assign(tmpRt32, mkNarrowTo32(ty, getIReg(rt)));
   15682             assign(tmpSh32, binop(Iop_Shl32, mkexpr(tmpRt32), mkexpr(tmpRs8)));
   15683             putIReg(rd, mkWidenFrom32(ty, mkexpr(tmpSh32), True));
   15684          } else {
   15685             SXXV_PATTERN(Iop_Shl32);
   15686          }
   15687          break;
   15688       }
   15689 
   15690       case 0x03:  /* SRA */
   15691          DIP("sra r%d, r%d, %d", rd, rt, sa);
   15692          if (mode64) {
   15693             IRTemp tmpRt32 = newTemp(Ity_I32);
   15694             IRTemp tmpSh32 = newTemp(Ity_I32);
   15695 
   15696             t1 = newTemp(Ity_I64);
   15697             t2 = newTemp(Ity_I64);
   15698             t3 = newTemp(Ity_I64);
   15699 
   15700             assign(t1, binop(Iop_And64, getIReg(rt),  /* hi */
   15701                              mkU64(0xFFFFFFFF00000000ULL)));
   15702 
   15703             assign(t2, binop(Iop_Sar64, mkexpr(t1), mkU8(sa)));
   15704 
   15705             assign(tmpRt32, mkNarrowTo32(ty, getIReg(rt)));
   15706             assign(tmpSh32, binop(Iop_Sar32, mkexpr(tmpRt32), mkU8(sa)));
   15707 
   15708             putIReg(rd, mkWidenFrom32(ty, mkexpr(tmpSh32), True));
   15709          } else {
   15710             SXX_PATTERN(Iop_Sar32);
   15711          }
   15712          break;
   15713 
   15714       case 0x07:  /* SRAV */
   15715          DIP("srav r%d, r%d, r%d", rd, rt, rs);
   15716          if (mode64) {
   15717             IRTemp tmpRt32 = newTemp(Ity_I32);
   15718             IRTemp tmpSh32 = newTemp(Ity_I32);
   15719 
   15720             t1 = newTemp(Ity_I64);
   15721             t2 = newTemp(Ity_I64);
   15722             t3 = newTemp(Ity_I64);
   15723             t4 = newTemp(Ity_I8);
   15724 
   15725             assign(t4, unop(Iop_32to8, binop(Iop_And32,
   15726                        mkNarrowTo32(ty, getIReg(rs)), mkU32(0x0000001F))));
   15727 
   15728             assign(t1, binop(Iop_And64, getIReg(rt),  /* hi */
   15729                    mkU64(0xFFFFFFFF00000000ULL)));
   15730 
   15731             assign(t2, binop(Iop_Sar64, mkexpr(t1), mkexpr(t4)));
   15732 
   15733             assign(tmpRt32, mkNarrowTo32(ty, getIReg(rt)));
   15734             assign(tmpSh32, binop(Iop_Sar32, mkexpr(tmpRt32), mkexpr(t4)));
   15735 
   15736             putIReg(rd, mkWidenFrom32(ty, mkexpr(tmpSh32), True));
   15737          } else {
   15738             SXXV_PATTERN(Iop_Sar32);
   15739          }
   15740          break;
   15741 
   15742       case 0x02: {  /* SRL */
   15743          rot = get_rot(cins);
   15744          if (rot) {
   15745             DIP("rotr r%d, r%d, %d", rd, rt, sa);
   15746             putIReg(rd, mkWidenFrom32(ty, genROR32(mkNarrowTo32(ty,
   15747                         getIReg(rt)), sa), True));
   15748          } else {
   15749             DIP("srl r%d, r%d, %d", rd, rt, sa);
   15750             if (mode64) {
   15751                IRTemp tmpSh32 = newTemp(Ity_I32);
   15752                IRTemp tmpRt32 = newTemp(Ity_I32);
   15753 
   15754                assign(tmpRt32, mkNarrowTo32(ty, getIReg(rt)));
   15755                assign(tmpSh32, binop(Iop_Shr32, mkexpr(tmpRt32), mkU8(sa)));
   15756                putIReg(rd, mkWidenFrom32(ty, mkexpr(tmpSh32), True));
   15757             } else {
   15758                SXX_PATTERN(Iop_Shr32);
   15759             }
   15760          }
   15761       break;
   15762       }
   15763 
   15764       case 0x06: {
   15765          rot = get_rotv(cins);
   15766          if (rot) {
   15767             DIP("rotrv r%d, r%d, r%d", rd, rt, rs);
   15768             putIReg(rd, mkWidenFrom32(ty, genRORV32(mkNarrowTo32(ty,
   15769                         getIReg(rt)), mkNarrowTo32(ty, getIReg(rs))), True));
   15770             break;
   15771          } else {  /* SRLV */
   15772             DIP("srlv r%d, r%d, r%d", rd, rt, rs);
   15773             if (mode64) {
   15774                SXXV_PATTERN64(Iop_Shr32);
   15775             } else {
   15776                SXXV_PATTERN(Iop_Shr32);
   15777             }
   15778             break;
   15779          }
   15780       }
   15781 
   15782       case 0x0D:  /* BREAK */
   15783          DIP("break 0x%x", trap_code);
   15784          if (mode64)
   15785             jmp_lit64(&dres, Ijk_SigTRAP, (guest_PC_curr_instr + 4));
   15786          else
   15787             jmp_lit32(&dres, Ijk_SigTRAP, (guest_PC_curr_instr + 4));
   15788          vassert(dres.whatNext == Dis_StopHere);
   15789          break;
   15790 
   15791       case 0x30: {  /* TGE */
   15792          DIP("tge r%d, r%d %d", rs, rt, trap_code);
   15793          if (mode64) {
   15794             if (trap_code == 7)
   15795                stmt (IRStmt_Exit (unop (Iop_Not1,
   15796                                         binop (Iop_CmpLT64S,
   15797                                                getIReg (rs),
   15798                                                getIReg (rt))),
   15799                                 Ijk_SigFPE_IntDiv,
   15800                                 IRConst_U64(guest_PC_curr_instr + 4),
   15801                                 OFFB_PC));
   15802             else if (trap_code == 6)
   15803                stmt (IRStmt_Exit (unop (Iop_Not1,
   15804                                         binop (Iop_CmpLT64S,
   15805                                                getIReg (rs),
   15806                                                getIReg (rt))),
   15807                                 Ijk_SigFPE_IntOvf,
   15808                                 IRConst_U64(guest_PC_curr_instr + 4),
   15809                                 OFFB_PC));
   15810             else
   15811                stmt (IRStmt_Exit (unop (Iop_Not1,
   15812                                         binop (Iop_CmpLT64S,
   15813                                                getIReg (rs),
   15814                                                getIReg (rt))),
   15815                                 Ijk_SigTRAP,
   15816                                 IRConst_U64(guest_PC_curr_instr + 4),
   15817                                 OFFB_PC));
   15818          } else {
   15819             if (trap_code == 7)
   15820                stmt (IRStmt_Exit (unop (Iop_Not1,
   15821                                         binop (Iop_CmpLT32S,
   15822                                                getIReg (rs),
   15823                                                getIReg (rt))),
   15824                                   Ijk_SigFPE_IntDiv,
   15825                                   IRConst_U32(guest_PC_curr_instr + 4),
   15826                                   OFFB_PC));
   15827             else if (trap_code == 6)
   15828                stmt (IRStmt_Exit (unop (Iop_Not1,
   15829                                         binop (Iop_CmpLT32S,
   15830                                                getIReg (rs),
   15831                                                getIReg (rt))),
   15832                                   Ijk_SigFPE_IntOvf,
   15833                                   IRConst_U32(guest_PC_curr_instr + 4),
   15834                                   OFFB_PC));
   15835             else
   15836                stmt (IRStmt_Exit (unop (Iop_Not1,
   15837                                         binop (Iop_CmpLT32S,
   15838                                                getIReg (rs),
   15839                                                getIReg (rt))),
   15840                                   Ijk_SigTRAP,
   15841                                   IRConst_U32(guest_PC_curr_instr + 4),
   15842                                   OFFB_PC));
   15843          }
   15844          break;
   15845       }
   15846       case 0x31: {  /* TGEU */
   15847          DIP("tgeu r%d, r%d %d", rs, rt, trap_code);
   15848          if (mode64) {
   15849             if (trap_code == 7)
   15850                stmt (IRStmt_Exit (unop (Iop_Not1,
   15851                                         binop (Iop_CmpLT64U,
   15852                                                getIReg (rs),
   15853                                                getIReg (rt))),
   15854                                   Ijk_SigFPE_IntDiv,
   15855                                   IRConst_U64(guest_PC_curr_instr + 4),
   15856                                   OFFB_PC));
   15857             else if (trap_code == 6)
   15858                stmt (IRStmt_Exit (unop (Iop_Not1,
   15859                                         binop (Iop_CmpLT64U,
   15860                                                getIReg (rs),
   15861                                                getIReg (rt))),
   15862                                   Ijk_SigFPE_IntOvf,
   15863                                   IRConst_U64(guest_PC_curr_instr + 4),
   15864                                   OFFB_PC));
   15865             else
   15866                stmt (IRStmt_Exit (unop (Iop_Not1,
   15867                                         binop (Iop_CmpLT64U,
   15868                                                getIReg (rs),
   15869                                                getIReg (rt))),
   15870                                   Ijk_SigTRAP,
   15871                                   IRConst_U64(guest_PC_curr_instr + 4),
   15872                                   OFFB_PC));
   15873          } else {
   15874             if (trap_code == 7)
   15875                stmt (IRStmt_Exit (unop (Iop_Not1,
   15876                                         binop (Iop_CmpLT32U,
   15877                                                getIReg (rs),
   15878                                                getIReg (rt))),
   15879                                   Ijk_SigFPE_IntDiv,
   15880                                   IRConst_U32(guest_PC_curr_instr + 4),
   15881                                   OFFB_PC));
   15882             else if (trap_code == 6)
   15883                stmt (IRStmt_Exit (unop (Iop_Not1,
   15884                                         binop (Iop_CmpLT32U,
   15885                                                getIReg (rs),
   15886                                                getIReg (rt))),
   15887                                   Ijk_SigFPE_IntOvf,
   15888                                   IRConst_U32(guest_PC_curr_instr + 4),
   15889                                   OFFB_PC));
   15890             else
   15891                stmt (IRStmt_Exit (unop (Iop_Not1,
   15892                                         binop (Iop_CmpLT32U,
   15893                                                getIReg (rs),
   15894                                                getIReg (rt))),
   15895                                   Ijk_SigTRAP,
   15896                                   IRConst_U32(guest_PC_curr_instr + 4),
   15897                                   OFFB_PC));
   15898          }
   15899          break;
   15900       }
   15901       case 0x32: {  /* TLT */
   15902          DIP("tlt r%d, r%d %d", rs, rt, trap_code);
   15903          if (mode64) {
   15904             if (trap_code == 7)
   15905                stmt(IRStmt_Exit(binop(Iop_CmpLT64S, getIReg(rs),
   15906                                       getIReg(rt)), Ijk_SigFPE_IntDiv,
   15907                                 IRConst_U64(guest_PC_curr_instr + 4),
   15908                                 OFFB_PC));
   15909             else if (trap_code == 6)
   15910                stmt(IRStmt_Exit(binop(Iop_CmpLT64S, getIReg(rs),
   15911                                       getIReg(rt)), Ijk_SigFPE_IntOvf,
   15912                                 IRConst_U64(guest_PC_curr_instr + 4),
   15913                                 OFFB_PC));
   15914             else
   15915                stmt(IRStmt_Exit(binop(Iop_CmpLT64S, getIReg(rs),
   15916                                       getIReg(rt)), Ijk_SigTRAP,
   15917                                 IRConst_U64(guest_PC_curr_instr + 4),
   15918                                 OFFB_PC));
   15919          } else {
   15920             if (trap_code == 7)
   15921                stmt(IRStmt_Exit(binop(Iop_CmpLT32S, getIReg(rs),
   15922                                       getIReg(rt)), Ijk_SigFPE_IntDiv,
   15923                                 IRConst_U32(guest_PC_curr_instr + 4),
   15924                                 OFFB_PC));
   15925             else if (trap_code == 6)
   15926                stmt(IRStmt_Exit(binop(Iop_CmpLT32S, getIReg(rs),
   15927                                       getIReg(rt)), Ijk_SigFPE_IntOvf,
   15928                                 IRConst_U32(guest_PC_curr_instr + 4),
   15929                                 OFFB_PC));
   15930             else
   15931                stmt(IRStmt_Exit(binop(Iop_CmpLT32S, getIReg(rs),
   15932                                       getIReg(rt)), Ijk_SigTRAP,
   15933                                 IRConst_U32(guest_PC_curr_instr + 4),
   15934                                 OFFB_PC));
   15935          }
   15936          break;
   15937       }
   15938       case 0x33: {  /* TLTU */
   15939          DIP("tltu r%d, r%d %d", rs, rt, trap_code);
   15940          if (mode64) {
   15941             if (trap_code == 7)
   15942                stmt(IRStmt_Exit(binop(Iop_CmpLT64U, getIReg(rs),
   15943                                       getIReg(rt)), Ijk_SigFPE_IntDiv,
   15944                                 IRConst_U64(guest_PC_curr_instr + 4),
   15945                                 OFFB_PC));
   15946             else if (trap_code == 6)
   15947                stmt(IRStmt_Exit(binop(Iop_CmpLT64U, getIReg(rs),
   15948                                       getIReg(rt)), Ijk_SigFPE_IntOvf,
   15949                                 IRConst_U64(guest_PC_curr_instr + 4),
   15950                                 OFFB_PC));
   15951             else
   15952                stmt(IRStmt_Exit(binop(Iop_CmpLT64U, getIReg(rs),
   15953                                       getIReg(rt)), Ijk_SigTRAP,
   15954                                 IRConst_U64(guest_PC_curr_instr + 4),
   15955                                 OFFB_PC));
   15956          } else {
   15957             if (trap_code == 7)
   15958                stmt(IRStmt_Exit(binop(Iop_CmpLT32U, getIReg(rs),
   15959                                       getIReg(rt)), Ijk_SigFPE_IntDiv,
   15960                                 IRConst_U32(guest_PC_curr_instr + 4),
   15961                                 OFFB_PC));
   15962             else if (trap_code == 6)
   15963                stmt(IRStmt_Exit(binop(Iop_CmpLT32U, getIReg(rs),
   15964                                       getIReg(rt)), Ijk_SigFPE_IntOvf,
   15965                                 IRConst_U32(guest_PC_curr_instr + 4),
   15966                                 OFFB_PC));
   15967             else
   15968                stmt(IRStmt_Exit(binop(Iop_CmpLT32U, getIReg(rs),
   15969                                       getIReg (rt)), Ijk_SigTRAP,
   15970                                 IRConst_U32(guest_PC_curr_instr + 4),
   15971                                 OFFB_PC));
   15972          }
   15973          break;
   15974       }
   15975       case 0x34: {  /* TEQ */
   15976          DIP("teq r%d, r%d, %d", rs, rt, trap_code);
   15977          if (mode64) {
   15978             if (trap_code == 7)
   15979                stmt(IRStmt_Exit(binop(Iop_CmpEQ64, getIReg(rs),
   15980                                       getIReg(rt)), Ijk_SigFPE_IntDiv,
   15981                                 IRConst_U64(guest_PC_curr_instr + 4),
   15982                                 OFFB_PC));
   15983             else if (trap_code == 6)
   15984                stmt(IRStmt_Exit(binop(Iop_CmpEQ64, getIReg(rs),
   15985                                       getIReg(rt)), Ijk_SigFPE_IntOvf,
   15986                                 IRConst_U64(guest_PC_curr_instr + 4),
   15987                                 OFFB_PC));
   15988             else
   15989                stmt(IRStmt_Exit(binop(Iop_CmpEQ64, getIReg(rs),
   15990                                       getIReg(rt)), Ijk_SigTRAP,
   15991                                 IRConst_U64(guest_PC_curr_instr + 4),
   15992                                 OFFB_PC));
   15993          } else {
   15994             if (trap_code == 7)
   15995                stmt(IRStmt_Exit(binop(Iop_CmpEQ32, getIReg(rs),
   15996                                       getIReg(rt)), Ijk_SigFPE_IntDiv,
   15997                                 IRConst_U32(guest_PC_curr_instr + 4),
   15998                                 OFFB_PC));
   15999             else if (trap_code == 6)
   16000                stmt(IRStmt_Exit(binop(Iop_CmpEQ32, getIReg(rs),
   16001                                       getIReg(rt)), Ijk_SigFPE_IntOvf,
   16002                                 IRConst_U32(guest_PC_curr_instr + 4),
   16003                                 OFFB_PC));
   16004             else
   16005                stmt(IRStmt_Exit(binop(Iop_CmpEQ32, getIReg(rs),
   16006                                       getIReg(rt)), Ijk_SigTRAP,
   16007                                 IRConst_U32(guest_PC_curr_instr + 4),
   16008                                 OFFB_PC));
   16009          }
   16010          break;
   16011       }
   16012       case 0x36: {  /* TNE */
   16013          DIP("tne r%d, r%d %d", rs, rt, trap_code);
   16014          if (mode64) {
   16015             if (trap_code == 7)
   16016                stmt(IRStmt_Exit(binop(Iop_CmpNE64, getIReg(rs),
   16017                                       getIReg(rt)), Ijk_SigFPE_IntDiv,
   16018                                 IRConst_U64(guest_PC_curr_instr + 4),
   16019                                 OFFB_PC));
   16020             else if (trap_code == 6)
   16021                stmt(IRStmt_Exit(binop(Iop_CmpNE64, getIReg(rs),
   16022                                       getIReg(rt)), Ijk_SigFPE_IntOvf,
   16023                                 IRConst_U64(guest_PC_curr_instr + 4),
   16024                                 OFFB_PC));
   16025             else
   16026                stmt(IRStmt_Exit(binop(Iop_CmpNE64, getIReg(rs),
   16027                                       getIReg(rt)), Ijk_SigTRAP,
   16028                                 IRConst_U64(guest_PC_curr_instr + 4),
   16029                                 OFFB_PC));
   16030          } else {
   16031             if (trap_code == 7)
   16032                stmt(IRStmt_Exit(binop(Iop_CmpNE32, getIReg(rs),
   16033                                       getIReg(rt)), Ijk_SigFPE_IntDiv,
   16034                                 IRConst_U32(guest_PC_curr_instr + 4),
   16035                                 OFFB_PC));
   16036             else if (trap_code == 6)
   16037                stmt(IRStmt_Exit(binop(Iop_CmpNE32, getIReg(rs),
   16038                                       getIReg(rt)), Ijk_SigFPE_IntOvf,
   16039                                 IRConst_U32(guest_PC_curr_instr + 4),
   16040                                 OFFB_PC));
   16041             else
   16042                stmt(IRStmt_Exit(binop(Iop_CmpNE32, getIReg(rs),
   16043                                       getIReg(rt)), Ijk_SigTRAP,
   16044                                 IRConst_U32(guest_PC_curr_instr + 4),
   16045                                 OFFB_PC));
   16046          }
   16047          break;
   16048       }
   16049       case 0x14:
   16050       case 0x16:
   16051       case 0x17:  /* DSLLV, DROTRV:DSRLV, DSRAV */
   16052       case 0x38:
   16053       case 0x3A:
   16054       case 0x3B:  /* DSLL, DROTL:DSRL, DSRA  */
   16055       case 0x3C:
   16056       case 0x3E:
   16057       case 0x3F:  /* DSLL32, DROTR32:DSRL32, DSRA32 */
   16058          if (dis_instr_shrt(cins))
   16059             break;
   16060          goto decode_failure;
   16061 
   16062       case 0x0F:  /* SYNC */
   16063          DIP("sync 0x%x", sel);
   16064          /* Just ignore it. */
   16065          break;
   16066 
   16067       case 0x2C: {  /* Doubleword Add - DADD; MIPS64 */
   16068          DIP("dadd r%d, r%d, r%d", rd, rs, rt);
   16069          IRTemp tmpRs64 = newTemp(Ity_I64);
   16070          IRTemp tmpRt64 = newTemp(Ity_I64);
   16071 
   16072          assign(tmpRs64, getIReg(rs));
   16073          assign(tmpRt64, getIReg(rt));
   16074 
   16075          t0 = newTemp(Ity_I64);
   16076          t1 = newTemp(Ity_I64);
   16077          t2 = newTemp(Ity_I64);
   16078          t3 = newTemp(Ity_I64);
   16079          t4 = newTemp(Ity_I64);
   16080          /* dst = src0 + src1
   16081             if(sign(src0 ) != sign(src1 ))
   16082             goto no overflow;
   16083             if(sign(dst) == sign(src0 ))
   16084             goto no overflow;
   16085             we have overflow! */
   16086 
   16087          assign(t0, binop(Iop_Add64, mkexpr(tmpRs64), mkexpr(tmpRt64)));
   16088          assign(t1, binop(Iop_Xor64, mkexpr(tmpRs64), mkexpr(tmpRt64)));
   16089          assign(t2, unop(Iop_1Uto64,
   16090                          binop(Iop_CmpEQ64,
   16091                                binop(Iop_And64, mkexpr(t1),
   16092                                      mkU64(0x8000000000000000ULL)),
   16093                                mkU64(0x8000000000000000ULL))));
   16094 
   16095          assign(t3, binop(Iop_Xor64, mkexpr(t0), mkexpr(tmpRs64)));
   16096          assign(t4, unop(Iop_1Uto64,
   16097                          binop(Iop_CmpNE64,
   16098                                binop(Iop_And64, mkexpr(t3),
   16099                                      mkU64(0x8000000000000000ULL)),
   16100                                mkU64(0x8000000000000000ULL))));
   16101 
   16102          stmt(IRStmt_Exit(binop(Iop_CmpEQ64,
   16103                                 binop(Iop_Or64, mkexpr(t2), mkexpr(t4)),
   16104                                 mkU64(0)),
   16105                           Ijk_SigFPE_IntOvf,
   16106                           IRConst_U64(guest_PC_curr_instr + 4),
   16107                           OFFB_PC));
   16108 
   16109          putIReg(rd,  mkexpr(t0));
   16110          break;
   16111       }
   16112 
   16113       case 0x2D:  /* Doubleword Add Unsigned - DADDU; MIPS64 */
   16114          DIP("daddu r%d, r%d, r%d", rd, rs, rt);
   16115          ALU_PATTERN(Iop_Add64);
   16116          break;
   16117 
   16118       case 0x2E: {  /* Doubleword Subtract - DSUB; MIPS64 */
   16119          DIP("dsub r%u, r%u, r%u", rd, rs, rt);
   16120          IRTemp tmpRs64 = newTemp(Ity_I64);
   16121          IRTemp tmpRt64 = newTemp(Ity_I64);
   16122 
   16123          assign(tmpRs64, getIReg(rs));
   16124          assign(tmpRt64, getIReg(rt));
   16125          t0 = newTemp(Ity_I64);
   16126          t1 = newTemp(Ity_I64);
   16127          t2 = newTemp(Ity_I64);
   16128          t3 = newTemp(Ity_I64);
   16129          t4 = newTemp(Ity_I64);
   16130          t5 = newTemp(Ity_I64);
   16131          /* dst = src0 + (-1 * src1)
   16132             if(sign(src0 ) != sign((-1 * src1) ))
   16133             goto no overflow;
   16134             if(sign(dst) == sign(src0 ))
   16135             goto no overflow;
   16136             we have overflow! */
   16137 
   16138          assign(t5, binop(Iop_Mul64,
   16139                           mkexpr(tmpRt64),
   16140                           mkU64(0xffffffffffffffffULL)));
   16141          assign(t0, binop(Iop_Add64, mkexpr(tmpRs64), mkexpr(t5)));
   16142          assign(t1, binop(Iop_Xor64, mkexpr(tmpRs64), mkexpr(t5)));
   16143          assign(t2, unop(Iop_1Sto64,
   16144                          binop(Iop_CmpEQ64,
   16145                                binop(Iop_And64,
   16146                                      mkexpr(t1),
   16147                                      mkU64(0x8000000000000000ULL)),
   16148                                mkU64(0x8000000000000000ULL))));
   16149 
   16150          assign(t3, binop(Iop_Xor64, mkexpr(t0), mkexpr(tmpRs64)));
   16151          assign(t4, unop(Iop_1Sto64,
   16152                          binop(Iop_CmpNE64,
   16153                                binop(Iop_And64,
   16154                                      mkexpr(t3),
   16155                                      mkU64(0x8000000000000000ULL)),
   16156                                mkU64(0x8000000000000000ULL))));
   16157 
   16158          stmt(IRStmt_Exit(binop(Iop_CmpEQ64, binop(Iop_Or64, mkexpr(t2),
   16159                                 mkexpr(t4)), mkU64(0)), Ijk_SigFPE_IntOvf,
   16160                           IRConst_U64(guest_PC_curr_instr + 4),
   16161                           OFFB_PC));
   16162 
   16163          putIReg(rd, binop(Iop_Sub64, getIReg(rs), getIReg(rt)));
   16164          break;
   16165       }
   16166 
   16167       case 0x2F:  /* Doubleword Subtract Unsigned - DSUBU; MIPS64 */
   16168          DIP("dsub r%u, r%u,r%u", rd, rt, rt);
   16169          ALU_PATTERN(Iop_Sub64);
   16170          break;
   16171 
   16172       default:
   16173          goto decode_failure;
   16174       }
   16175       break;
   16176 
   16177    case 0x01:  /* Regimm */
   16178 
   16179       switch (rt) {
   16180       case 0x00:  /* BLTZ */
   16181          DIP("bltz r%d, %d", rs, imm);
   16182          if (mode64) {
   16183             if (!dis_instr_branch(cins, &dres, resteerOkFn,
   16184                         callback_opaque, &bstmt))
   16185                goto decode_failure;
   16186          } else
   16187             dis_branch(False, binop(Iop_CmpEQ32, binop(Iop_And32, getIReg(rs),
   16188                        mkU32(0x80000000)), mkU32(0x80000000)), imm, &bstmt);
   16189          break;
   16190 
   16191       case 0x01:  /* BGEZ */
   16192          DIP("bgez r%d, %d", rs, imm);
   16193          if (mode64) {
   16194             if (!dis_instr_branch(cins, &dres, resteerOkFn,
   16195                                   callback_opaque, &bstmt))
   16196                goto decode_failure;
   16197          } else
   16198             dis_branch(False, binop(Iop_CmpEQ32, binop(Iop_And32, getIReg(rs),
   16199                               mkU32(0x80000000)), mkU32(0x0)), imm, &bstmt);
   16200          break;
   16201 
   16202       case 0x02:  /* BLTZL */
   16203          DIP("bltzl r%d, %d", rs, imm);
   16204          lastn = dis_branch_likely(binop(mode64 ? Iop_CmpNE64 : Iop_CmpNE32,
   16205                      binop(mode64 ? Iop_And64 : Iop_And32, getIReg(rs),
   16206                      mode64 ? mkU64(0x8000000000000000ULL) : mkU32(0x80000000)),
   16207                      mode64 ? mkU64(0x8000000000000000ULL) : mkU32(0x80000000)),
   16208                      imm);
   16209          break;
   16210 
   16211       case 0x03:  /* BGEZL */
   16212          DIP("bgezl r%d, %d", rs, imm);
   16213          lastn = dis_branch_likely(binop(mode64 ? Iop_CmpNE64 : Iop_CmpNE32,
   16214                      binop(mode64 ? Iop_And64 : Iop_And32, getIReg(rs),
   16215                      mode64 ? mkU64(0x8000000000000000ULL) : mkU32(0x80000000)),
   16216                      mode64 ? mkU64(0x0) : mkU32(0x0)), imm);
   16217          break;
   16218 
   16219       case 0x10:  /* BLTZAL */
   16220          DIP("bltzal r%d, %d", rs, imm);
   16221          if (mode64) {
   16222             if (!dis_instr_branch(cins, &dres, resteerOkFn,
   16223                         callback_opaque, &bstmt))
   16224                goto decode_failure;
   16225          } else
   16226             dis_branch(True, binop(Iop_CmpEQ32, binop(Iop_And32, getIReg(rs),
   16227                        mkU32(0x80000000)), mkU32(0x80000000)), imm, &bstmt);
   16228          break;
   16229 
   16230       case 0x12:  /* BLTZALL */
   16231          DIP("bltzall r%d, %d", rs, imm);
   16232          putIReg(31, mode64 ? mkU64(guest_PC_curr_instr + 8) :
   16233                               mkU32(guest_PC_curr_instr + 8));
   16234          lastn = dis_branch_likely(binop(mode64 ? Iop_CmpNE64 : Iop_CmpNE32,
   16235                      binop(mode64 ? Iop_And64 : Iop_And32, getIReg(rs),
   16236                      mode64 ? mkU64(0x8000000000000000ULL) : mkU32(0x80000000)),
   16237                      mode64 ? mkU64(0x8000000000000000ULL) : mkU32(0x80000000)),
   16238                      imm);
   16239          break;
   16240 
   16241       case 0x11:  /* BGEZAL */
   16242          DIP("bgezal r%d, %d", rs, imm);
   16243          if (mode64) {
   16244             if (!dis_instr_branch(cins, &dres, resteerOkFn,
   16245                         callback_opaque, &bstmt))
   16246                goto decode_failure;
   16247          } else
   16248             dis_branch(True, binop(Iop_CmpEQ32, binop(Iop_And32, getIReg(rs),
   16249                        mkU32(0x80000000)), mkU32(0x0)), imm, &bstmt);
   16250          break;
   16251 
   16252       case 0x13:  /* BGEZALL */
   16253          DIP("bgezall r%d, %d", rs, imm);
   16254          if (mode64) {
   16255             putIReg(31, mkU64(guest_PC_curr_instr + 8));
   16256             lastn = dis_branch_likely(binop(Iop_CmpNE64,
   16257                                             binop(Iop_And64,
   16258                                                   getIReg(rs),
   16259                                                   mkU64(0x8000000000000000ULL)),
   16260                                             mkU64(0x0)),
   16261                                       imm);
   16262          } else {
   16263             putIReg(31, mkU32(guest_PC_curr_instr + 8));
   16264             lastn = dis_branch_likely(binop(Iop_CmpNE32, binop(Iop_And32,
   16265                                       getIReg(rs), mkU32(0x80000000)),
   16266                                       mkU32(0x0)), imm);
   16267          }
   16268          break;
   16269 
   16270       case 0x08:  /* TGEI */
   16271          DIP("tgei r%d, %d %d", rs, imm, trap_code);
   16272          if (mode64) {
   16273             stmt (IRStmt_Exit (unop (Iop_Not1,
   16274                                      binop (Iop_CmpLT64S,
   16275                                             getIReg (rs),
   16276                                             mkU64 (extend_s_16to64 (imm)))),
   16277                              Ijk_SigTRAP,
   16278                              IRConst_U64(guest_PC_curr_instr + 4),
   16279                              OFFB_PC));
   16280          } else {
   16281             stmt (IRStmt_Exit (unop (Iop_Not1,
   16282                                      binop (Iop_CmpLT32S,
   16283                                      getIReg (rs),
   16284                                      mkU32 (extend_s_16to32 (imm)))),
   16285                              Ijk_SigTRAP,
   16286                              IRConst_U32(guest_PC_curr_instr + 4),
   16287                              OFFB_PC));
   16288          }
   16289          break;
   16290 
   16291       case 0x09: {  /* TGEIU */
   16292          DIP("tgeiu r%d, %d %d", rs, imm, trap_code);
   16293          if (mode64) {
   16294             stmt (IRStmt_Exit (unop (Iop_Not1,
   16295                                      binop (Iop_CmpLT64U,
   16296                                             getIReg (rs),
   16297                                             mkU64 (extend_s_16to64 (imm)))),
   16298                              Ijk_SigTRAP,
   16299                              IRConst_U64(guest_PC_curr_instr + 4),
   16300                              OFFB_PC));
   16301          } else {
   16302             stmt (IRStmt_Exit (unop (Iop_Not1,
   16303                                      binop (Iop_CmpLT32U,
   16304                                             getIReg (rs),
   16305                                             mkU32 (extend_s_16to32 (imm)))),
   16306                                Ijk_SigTRAP,
   16307                                IRConst_U32(guest_PC_curr_instr + 4),
   16308                                OFFB_PC));
   16309          }
   16310          break;
   16311       }
   16312       case 0x0A: {  /* TLTI */
   16313          DIP("tlti r%d, %d %d", rs, imm, trap_code);
   16314          if (mode64) {
   16315             stmt (IRStmt_Exit (binop (Iop_CmpLT64S, getIReg (rs),
   16316                                       mkU64 (extend_s_16to64 (imm))),
   16317                              Ijk_SigTRAP,
   16318                              IRConst_U64(guest_PC_curr_instr + 4),
   16319                              OFFB_PC));
   16320          } else {
   16321             stmt (IRStmt_Exit (binop (Iop_CmpLT32S, getIReg (rs),
   16322                                       mkU32 (extend_s_16to32 (imm))),
   16323                                Ijk_SigTRAP,
   16324                                IRConst_U32(guest_PC_curr_instr + 4),
   16325                                OFFB_PC));
   16326          }
   16327          break;
   16328       }
   16329       case 0x0B: {  /* TLTIU */
   16330          DIP("tltiu r%d, %d %d", rs, imm, trap_code);
   16331          if (mode64) {
   16332             stmt (IRStmt_Exit (binop (Iop_CmpLT64U, getIReg (rs),
   16333                                       mkU64 (extend_s_16to64 (imm))),
   16334                              Ijk_SigTRAP,
   16335                              IRConst_U64(guest_PC_curr_instr + 4),
   16336                              OFFB_PC));
   16337          } else {
   16338             stmt (IRStmt_Exit (binop (Iop_CmpLT32U, getIReg (rs),
   16339                                       mkU32 (extend_s_16to32 (imm))),
   16340                                Ijk_SigTRAP,
   16341                                IRConst_U32(guest_PC_curr_instr + 4),
   16342                                OFFB_PC));
   16343          }
   16344          break;
   16345       }
   16346       case 0x0C: {  /* TEQI */
   16347           DIP("teqi r%d, %d %d", rs, imm, trap_code);
   16348          if (mode64) {
   16349             stmt (IRStmt_Exit (binop (Iop_CmpEQ64, getIReg (rs),
   16350                                       mkU64 (extend_s_16to64 (imm))),
   16351                                Ijk_SigTRAP,
   16352                                IRConst_U64(guest_PC_curr_instr + 4),
   16353                                OFFB_PC));
   16354          } else {
   16355             stmt (IRStmt_Exit (binop (Iop_CmpEQ32, getIReg (rs),
   16356                                       mkU32 (extend_s_16to32 (imm))),
   16357                                Ijk_SigTRAP,
   16358                                IRConst_U32(guest_PC_curr_instr + 4),
   16359                                OFFB_PC));
   16360          }
   16361          break;
   16362       }
   16363       case 0x0E: {  /* TNEI */
   16364          DIP("tnei r%d, %d %d", rs, imm, trap_code);
   16365          if (mode64) {
   16366             stmt (IRStmt_Exit (binop (Iop_CmpNE64, getIReg (rs),
   16367                                       mkU64 (extend_s_16to64 (imm))),
   16368                                Ijk_SigTRAP,
   16369                                IRConst_U64(guest_PC_curr_instr + 4),
   16370                                OFFB_PC));
   16371          } else {
   16372             stmt (IRStmt_Exit (binop (Iop_CmpNE32, getIReg (rs),
   16373                                       mkU32 (extend_s_16to32 (imm))),
   16374                                Ijk_SigTRAP,
   16375                                IRConst_U32(guest_PC_curr_instr + 4),
   16376                                OFFB_PC));
   16377          }
   16378          break;
   16379       }
   16380       case 0x1C: {  /* BPOSGE32 */
   16381          DIP("bposge32 %d", imm);
   16382          vassert(!mode64);
   16383          t0 = newTemp(Ity_I32);
   16384          /* Get pos field from DSPControl register. */
   16385          assign(t0, binop(Iop_And32, getDSPControl(), mkU32(0x3f)));
   16386          dis_branch(False, unop(Iop_Not1, binop(Iop_CmpLT32U, mkexpr(t0),
   16387                                 mkU32(32))), imm, &bstmt);
   16388       }
   16389       case 0x1F:
   16390          /* SYNCI */
   16391          /* Just ignore it */
   16392          break;
   16393 
   16394       default:
   16395          goto decode_failure;
   16396       }
   16397       break;
   16398 
   16399    case 0x04:
   16400       DIP("beq r%d, r%d, %d", rs, rt, imm);
   16401       if (mode64)
   16402          dis_branch(False, binop(Iop_CmpEQ64, getIReg(rs), getIReg(rt)),
   16403                                  imm, &bstmt);
   16404       else
   16405          dis_branch(False, binop(Iop_CmpEQ32, getIReg(rs), getIReg(rt)),
   16406                                  imm, &bstmt);
   16407       break;
   16408 
   16409    case 0x14:
   16410       DIP("beql r%d, r%d, %d", rs, rt, imm);
   16411       lastn = dis_branch_likely(binop(mode64 ? Iop_CmpNE64 : Iop_CmpNE32,
   16412                                 getIReg(rs), getIReg(rt)), imm);
   16413       break;
   16414 
   16415    case 0x05:
   16416       DIP("bne r%d, r%d, %d", rs, rt, imm);
   16417       if (mode64)
   16418          dis_branch(False, binop(Iop_CmpNE64, getIReg(rs), getIReg(rt)),
   16419                                  imm, &bstmt);
   16420       else
   16421          dis_branch(False, binop(Iop_CmpNE32, getIReg(rs), getIReg(rt)),
   16422                                  imm, &bstmt);
   16423       break;
   16424 
   16425    case 0x15:
   16426       DIP("bnel r%d, r%d, %d", rs, rt, imm);
   16427       lastn = dis_branch_likely(binop(mode64 ? Iop_CmpEQ64 : Iop_CmpEQ32,
   16428                                       getIReg(rs), getIReg(rt)), imm);
   16429       break;
   16430 
   16431    case 0x07:  /* BGTZ */
   16432       DIP("bgtz r%d, %d", rs, imm);
   16433       if (mode64)
   16434          dis_branch(False, unop(Iop_Not1, binop(Iop_CmpLE64S, getIReg(rs),
   16435                                 mkU64(0x00))), imm, &bstmt);
   16436       else
   16437          dis_branch(False, unop(Iop_Not1, binop(Iop_CmpLE32S, getIReg(rs),
   16438                                 mkU32(0x00))), imm, &bstmt);
   16439       break;
   16440 
   16441    case 0x17:  /* BGTZL */
   16442       DIP("bgtzl r%d, %d", rs, imm);
   16443       if (mode64)
   16444          lastn = dis_branch_likely(binop(Iop_CmpLE64S, getIReg(rs),
   16445                                          mkU64(0x00)), imm);
   16446       else
   16447          lastn = dis_branch_likely(binop(Iop_CmpLE32S, getIReg(rs),
   16448                                          mkU32(0x00)), imm);
   16449       break;
   16450 
   16451    case 0x06:  /* BLEZ */
   16452       DIP("blez r%d, %d", rs, imm);
   16453       if (mode64)
   16454          dis_branch(False, binop(Iop_CmpLE64S, getIReg(rs), mkU64(0x0)),
   16455                                 imm, &bstmt);
   16456       else
   16457          dis_branch(False,binop(Iop_CmpLE32S, getIReg(rs), mkU32(0x0)), imm,
   16458                                 &bstmt);
   16459       break;
   16460 
   16461    case 0x16:  /* BLEZL */
   16462       DIP("blezl r%d, %d", rs, imm);
   16463       lastn = dis_branch_likely(unop(Iop_Not1, (binop(mode64 ? Iop_CmpLE64S :
   16464                                      Iop_CmpLE32S, getIReg(rs), mode64 ?
   16465                                      mkU64(0x0) : mkU32(0x0)))), imm);
   16466       break;
   16467 
   16468    case 0x08: {  /* ADDI */
   16469       DIP("addi r%d, r%d, %d", rt, rs, imm);
   16470       IRTemp tmpRs32 = newTemp(Ity_I32);
   16471       assign(tmpRs32, mkNarrowTo32(ty, getIReg(rs)));
   16472 
   16473       t0 = newTemp(Ity_I32);
   16474       t1 = newTemp(Ity_I32);
   16475       t2 = newTemp(Ity_I32);
   16476       t3 = newTemp(Ity_I32);
   16477       t4 = newTemp(Ity_I32);
   16478       /* dst = src0 + sign(imm)
   16479          if(sign(src0 ) != sign(imm ))
   16480          goto no overflow;
   16481          if(sign(dst) == sign(src0 ))
   16482          goto no overflow;
   16483          we have overflow! */
   16484 
   16485       assign(t0, binop(Iop_Add32, mkexpr(tmpRs32),
   16486                        mkU32(extend_s_16to32(imm))));
   16487       assign(t1, binop(Iop_Xor32, mkexpr(tmpRs32),
   16488                        mkU32(extend_s_16to32(imm))));
   16489       assign(t2, unop(Iop_1Sto32, binop(Iop_CmpEQ32, binop(Iop_And32,
   16490                       mkexpr(t1), mkU32(0x80000000)), mkU32(0x80000000))));
   16491 
   16492       assign(t3, binop(Iop_Xor32, mkexpr(t0), mkexpr(tmpRs32)));
   16493       assign(t4, unop(Iop_1Sto32, binop(Iop_CmpNE32, binop(Iop_And32,
   16494                       mkexpr(t3), mkU32(0x80000000)), mkU32(0x80000000))));
   16495 
   16496       stmt(IRStmt_Exit(binop(Iop_CmpEQ32, binop(Iop_Or32, mkexpr(t2),
   16497                              mkexpr(t4)), mkU32(0)), Ijk_SigFPE_IntOvf,
   16498                        mode64 ? IRConst_U64(guest_PC_curr_instr + 4) :
   16499                                 IRConst_U32(guest_PC_curr_instr + 4),
   16500                        OFFB_PC));
   16501 
   16502       putIReg(rt,  mkWidenFrom32(ty, mkexpr(t0), True));
   16503       break;
   16504    }
   16505    case 0x09:  /* ADDIU */
   16506       DIP("addiu r%d, r%d, %d", rt, rs, imm);
   16507       if (mode64) {
   16508          putIReg(rt, mkWidenFrom32(ty, binop(Iop_Add32,
   16509                      mkNarrowTo32(ty, getIReg(rs)),mkU32(extend_s_16to32(imm))),
   16510                      True));
   16511       } else
   16512          putIReg(rt, binop(Iop_Add32, getIReg(rs),mkU32(extend_s_16to32(imm))));
   16513       break;
   16514 
   16515    case 0x0C:  /* ANDI */
   16516       DIP("andi r%d, r%d, %d", rt, rs, imm);
   16517       if (mode64) {
   16518          ALUI_PATTERN64(Iop_And64);
   16519       } else {
   16520          ALUI_PATTERN(Iop_And32);
   16521       }
   16522       break;
   16523 
   16524    case 0x0E:  /* XORI */
   16525       DIP("xori r%d, r%d, %d", rt, rs, imm);
   16526       if (mode64) {
   16527          ALUI_PATTERN64(Iop_Xor64);
   16528       } else {
   16529          ALUI_PATTERN(Iop_Xor32);
   16530       }
   16531       break;
   16532 
   16533    case 0x0D:  /* ORI */
   16534       DIP("ori r%d, r%d, %d", rt, rs, imm);
   16535       if (mode64) {
   16536          ALUI_PATTERN64(Iop_Or64);
   16537       } else {
   16538          ALUI_PATTERN(Iop_Or32);
   16539       }
   16540       break;
   16541 
   16542    case 0x0A:  /* SLTI */
   16543       DIP("slti r%d, r%d, %d", rt, rs, imm);
   16544       if (mode64)
   16545          putIReg(rt, unop(Iop_1Uto64, binop(Iop_CmpLT64S, getIReg(rs),
   16546                                             mkU64(extend_s_16to64(imm)))));
   16547       else
   16548          putIReg(rt, unop(Iop_1Uto32, binop(Iop_CmpLT32S, getIReg(rs),
   16549                                             mkU32(extend_s_16to32(imm)))));
   16550       break;
   16551 
   16552    case 0x0B:  /* SLTIU */
   16553       DIP("sltiu r%d, r%d, %d", rt, rs, imm);
   16554       if (mode64)
   16555          putIReg(rt, unop(Iop_1Uto64, binop(Iop_CmpLT64U, getIReg(rs),
   16556                                             mkU64(extend_s_16to64(imm)))));
   16557       else
   16558          putIReg(rt, unop(Iop_1Uto32, binop(Iop_CmpLT32U, getIReg(rs),
   16559                                             mkU32(extend_s_16to32(imm)))));
   16560       break;
   16561 
   16562    case 0x18: {  /* Doubleword Add Immidiate - DADD; MIPS64 */
   16563       DIP("daddi r%d, r%d, %d", rt, rs, imm);
   16564       IRTemp tmpRs64 = newTemp(Ity_I64);
   16565       assign(tmpRs64, getIReg(rs));
   16566 
   16567       t0 = newTemp(Ity_I64);
   16568       t1 = newTemp(Ity_I64);
   16569       t2 = newTemp(Ity_I64);
   16570       t3 = newTemp(Ity_I64);
   16571       t4 = newTemp(Ity_I64);
   16572       /* dst = src0 + sign(imm)
   16573          if(sign(src0 ) != sign(imm ))
   16574          goto no overflow;
   16575          if(sign(dst) == sign(src0 ))
   16576          goto no overflow;
   16577          we have overflow! */
   16578 
   16579       assign(t0, binop(Iop_Add64, mkexpr(tmpRs64),
   16580                        mkU64(extend_s_16to64(imm))));
   16581       assign(t1, binop(Iop_Xor64, mkexpr(tmpRs64),
   16582                        mkU64(extend_s_16to64(imm))));
   16583       assign(t2, unop(Iop_1Sto64, binop(Iop_CmpEQ64, binop(Iop_And64,
   16584                       mkexpr(t1), mkU64(0x8000000000000000ULL)),
   16585                                         mkU64(0x8000000000000000ULL))));
   16586 
   16587       assign(t3, binop(Iop_Xor64, mkexpr(t0), mkexpr(tmpRs64)));
   16588       assign(t4, unop(Iop_1Sto64, binop(Iop_CmpNE64, binop(Iop_And64,
   16589                       mkexpr(t3), mkU64(0x8000000000000000ULL)),
   16590                                         mkU64(0x8000000000000000ULL))));
   16591 
   16592       stmt(IRStmt_Exit(binop(Iop_CmpEQ64, binop(Iop_Or64, mkexpr(t2),
   16593                              mkexpr(t4)), mkU64(0)), Ijk_SigFPE_IntOvf,
   16594                        IRConst_U64(guest_PC_curr_instr + 4),
   16595                        OFFB_PC));
   16596 
   16597       putIReg(rt,  mkexpr(t0));
   16598       break;
   16599    }
   16600 
   16601    case 0x19:  /* Doubleword Add Immidiate Unsigned - DADDIU; MIPS64 */
   16602       DIP("daddiu r%d, r%d, %d", rt, rs, imm);
   16603       putIReg(rt, binop(Iop_Add64, getIReg(rs), mkU64(extend_s_16to64(imm))));
   16604       break;
   16605 
   16606    case 0x1A: {
   16607       /* Load Doubleword Left - LDL; MIPS64 */
   16608       vassert(mode64);
   16609       DIP("ldl r%u, %d(r%u)", rt, imm, rs);
   16610       /* t1 = addr */
   16611 #if defined (_MIPSEL)
   16612       t1 = newTemp(Ity_I64);
   16613       assign(t1, binop(Iop_Add64, getIReg(rs), mkU64(extend_s_16to64(imm))));
   16614 #elif defined (_MIPSEB)
   16615       t1 = newTemp(Ity_I64);
   16616       assign(t1, binop(Iop_Xor64, mkU64(0x7), binop(Iop_Add64, getIReg(rs),
   16617                                   mkU64(extend_s_16to64(imm)))));
   16618 #endif
   16619       /* t2 = word addr */
   16620       /* t4 = addr mod 8 */
   16621       LWX_SWX_PATTERN64_1;
   16622 
   16623       /* t3 = word content - shifted */
   16624       t3 = newTemp(Ity_I64);
   16625       assign(t3, binop(Iop_Shl64, load(Ity_I64, mkexpr(t2)),
   16626                  narrowTo(Ity_I8, binop(Iop_Shl64, binop(Iop_Sub64, mkU64(0x07),
   16627                  mkexpr(t4)), mkU8(3)))));
   16628 
   16629       /* rt content  - adjusted */
   16630       t5 = newTemp(Ity_I64);
   16631       t6 = newTemp(Ity_I64);
   16632       t7 = newTemp(Ity_I64);
   16633 
   16634       assign(t5, binop(Iop_Mul64, mkexpr(t4), mkU64(0x8)));
   16635 
   16636       assign(t6, binop(Iop_Shr64, mkU64(0x00FFFFFFFFFFFFFFULL),
   16637                        narrowTo(Ity_I8, mkexpr(t5))));
   16638 
   16639       assign(t7, binop(Iop_And64, getIReg(rt), mkexpr(t6)));
   16640 
   16641       putIReg(rt, binop(Iop_Or64, mkexpr(t7), mkexpr(t3)));
   16642       break;
   16643    }
   16644 
   16645    case 0x1B: {
   16646       /* Load Doubleword Right - LDR; MIPS64 */
   16647       vassert(mode64);
   16648       DIP("ldr r%u,%d(r%u)", rt, imm, rs);
   16649       /* t1 = addr */
   16650 #if defined (_MIPSEL)
   16651       t1 = newTemp(Ity_I64);
   16652       assign(t1, binop(Iop_Add64, getIReg(rs), mkU64(extend_s_16to64(imm))));
   16653 #elif defined (_MIPSEB)
   16654       t1 = newTemp(Ity_I64);
   16655       assign(t1, binop(Iop_Xor64, mkU64(0x7), binop(Iop_Add64, getIReg(rs),
   16656                                   mkU64(extend_s_16to64(imm)))));
   16657 #endif
   16658       /* t2 = word addr */
   16659       /* t4 = addr mod 8 */
   16660       LWX_SWX_PATTERN64_1;
   16661 
   16662       /* t3 = word content - shifted */
   16663       t3 = newTemp(Ity_I64);
   16664       assign(t3, binop(Iop_Shr64, load(Ity_I64, mkexpr(t2)),
   16665                  narrowTo(Ity_I8, binop(Iop_Shl64, mkexpr(t4), mkU8(3)))));
   16666 
   16667       /* rt content  - adjusted */
   16668       t5 = newTemp(Ity_I64);
   16669       assign(t5, binop(Iop_And64, getIReg(rt), unop(Iop_Not64,
   16670                  binop(Iop_Shr64, mkU64(0xFFFFFFFFFFFFFFFFULL),
   16671                  narrowTo(Ity_I8, binop(Iop_Shl64, mkexpr(t4), mkU8(0x3)))))));
   16672 
   16673       putIReg(rt, binop(Iop_Or64, mkexpr(t5), mkexpr(t3)));
   16674       break;
   16675    }
   16676 
   16677    case 0x27:  /* Load Word unsigned - LWU; MIPS64 */
   16678       DIP("lwu r%u,%d(r%u)", rt, imm, rs);
   16679       LOAD_STORE_PATTERN;
   16680 
   16681       putIReg(rt, mkWidenFrom32(ty, load(Ity_I32, mkexpr(t1)), False));
   16682       break;
   16683 
   16684    case 0x30:  /* LL / LWC0 */
   16685       DIP("ll r%d, %d(r%d)", rt, imm, rs);
   16686       LOAD_STORE_PATTERN;
   16687 
   16688       t2 = newTemp(Ity_I32);
   16689 #if defined (_MIPSEL)
   16690       stmt(IRStmt_LLSC(Iend_LE, t2, mkexpr(t1), NULL /* this is a load */ ));
   16691 #elif defined (_MIPSEB)
   16692       stmt(IRStmt_LLSC(Iend_BE, t2, mkexpr(t1), NULL /* this is a load */ ));
   16693 #endif
   16694       if (mode64)
   16695          putIReg(rt, unop(Iop_32Sto64, mkexpr(t2)));
   16696       else
   16697          putIReg(rt, mkexpr(t2));
   16698       break;
   16699 
   16700    case 0x34:  /* Load Linked Doubleword - LLD; MIPS64 */
   16701       DIP("lld r%d, %d(r%d)", rt, imm, rs);
   16702       LOAD_STORE_PATTERN;
   16703 
   16704       t2 = newTemp(Ity_I64);
   16705 #if defined (_MIPSEL)
   16706       stmt(IRStmt_LLSC
   16707            (Iend_LE, t2, mkexpr(t1), NULL /* this is a load */ ));
   16708 #elif defined (_MIPSEB)
   16709       stmt(IRStmt_LLSC
   16710            (Iend_BE, t2, mkexpr(t1), NULL /* this is a load */ ));
   16711 #endif
   16712 
   16713       putIReg(rt, mkexpr(t2));
   16714       break;
   16715 
   16716    case 0x38:  /* SC / SWC0 */
   16717       DIP("sc r%d, %d(r%d)", rt, imm, rs);
   16718       LOAD_STORE_PATTERN;
   16719 
   16720       t2 = newTemp(Ity_I1);
   16721 #if defined (_MIPSEL)
   16722       stmt(IRStmt_LLSC(Iend_LE, t2, mkexpr(t1), mkNarrowTo32(ty, getIReg(rt))));
   16723 #elif defined (_MIPSEB)
   16724       stmt(IRStmt_LLSC(Iend_BE, t2, mkexpr(t1), mkNarrowTo32(ty, getIReg(rt))));
   16725 #endif
   16726 
   16727       putIReg(rt, unop(mode64 ? Iop_1Uto64 : Iop_1Uto32, mkexpr(t2)));
   16728       break;
   16729 
   16730    case 0x3C:  /* Store Conditional Doubleword - SCD; MIPS64 */
   16731       DIP("sdc r%d, %d(r%d)", rt, imm, rs);
   16732       LOAD_STORE_PATTERN;
   16733 
   16734       t2 = newTemp(Ity_I1);
   16735 #if defined (_MIPSEL)
   16736       stmt(IRStmt_LLSC(Iend_LE, t2, mkexpr(t1), getIReg(rt)));
   16737 #elif defined (_MIPSEB)
   16738       stmt(IRStmt_LLSC(Iend_BE, t2, mkexpr(t1), getIReg(rt)));
   16739 #endif
   16740 
   16741       putIReg(rt, unop(Iop_1Uto64, mkexpr(t2)));
   16742       break;
   16743 
   16744    case 0x37:  /* Load Doubleword - LD; MIPS64 */
   16745       DIP("ld r%u, %d(r%u)", rt, imm, rs);
   16746       LOAD_STORE_PATTERN;
   16747       putIReg(rt, load(Ity_I64, mkexpr(t1)));
   16748       break;
   16749 
   16750    case 0x3F:  /* Store Doubleword - SD; MIPS64 */
   16751       DIP("sd r%u, %d(r%u)", rt, imm, rs);
   16752       LOAD_STORE_PATTERN;
   16753       store(mkexpr(t1), getIReg(rt));
   16754       break;
   16755 
   16756    decode_failure_dsp:
   16757       vex_printf("Error occured while trying to decode MIPS32 DSP "
   16758                  "instruction.\nYour platform probably doesn't support "
   16759                  "MIPS32 DSP ASE.\n");
   16760    decode_failure:
   16761       /* All decode failures end up here. */
   16762       if (sigill_diag)
   16763          vex_printf("vex mips->IR: unhandled instruction bytes: "
   16764                     "0x%x 0x%x 0x%x 0x%x\n",
   16765                     (Int) getIByte(delta_start + 0),
   16766                     (Int) getIByte(delta_start + 1),
   16767                     (Int) getIByte(delta_start + 2),
   16768                     (Int) getIByte(delta_start + 3));
   16769 
   16770       /* Tell the dispatcher that this insn cannot be decoded, and so has
   16771          not been executed, and (is currently) the next to be executed.
   16772          EIP should be up-to-date since it made so at the start bnezof each
   16773          insn, but nevertheless be paranoid and update it again right
   16774          now. */
   16775       if (mode64) {
   16776          stmt(IRStmt_Put(offsetof(VexGuestMIPS64State, guest_PC),
   16777               mkU64(guest_PC_curr_instr)));
   16778          jmp_lit64(&dres, Ijk_NoDecode, guest_PC_curr_instr);
   16779       } else {
   16780          stmt(IRStmt_Put(offsetof(VexGuestMIPS32State, guest_PC),
   16781               mkU32(guest_PC_curr_instr)));
   16782          jmp_lit32(&dres, Ijk_NoDecode, guest_PC_curr_instr);
   16783       }
   16784       dres.whatNext = Dis_StopHere;
   16785       dres.len = 0;
   16786       return dres;
   16787    }  /* switch (opc) for the main (primary) opcode switch. */
   16788 
   16789    /* All MIPS insn have 4 bytes */
   16790 
   16791    if (delay_slot_branch) {
   16792       delay_slot_branch = False;
   16793       stmt(bstmt);
   16794       bstmt = NULL;
   16795       if (mode64)
   16796          putPC(mkU64(guest_PC_curr_instr + 4));
   16797       else
   16798          putPC(mkU32(guest_PC_curr_instr + 4));
   16799       dres.jk_StopHere = is_Branch_or_Jump_and_Link(guest_code + delta - 4) ?
   16800                          Ijk_Call : Ijk_Boring;
   16801    }
   16802 
   16803    if (likely_delay_slot) {
   16804       dres.jk_StopHere = Ijk_Boring;
   16805       dres.whatNext = Dis_StopHere;
   16806       putPC(lastn);
   16807       lastn = NULL;
   16808    }
   16809    if (delay_slot_jump) {
   16810       putPC(lastn);
   16811       lastn = NULL;
   16812       dres.jk_StopHere = is_Branch_or_Jump_and_Link(guest_code + delta - 4) ?
   16813                          Ijk_Call : Ijk_Boring;
   16814    }
   16815 
   16816  decode_success:
   16817    /* All decode successes end up here. */
   16818    switch (dres.whatNext) {
   16819       case Dis_Continue:
   16820          if (mode64)
   16821             putPC(mkU64(guest_PC_curr_instr + 4));
   16822          else
   16823             putPC(mkU32(guest_PC_curr_instr + 4));
   16824          break;
   16825       case Dis_ResteerU:
   16826       case Dis_ResteerC:
   16827          putPC(mkU32(dres.continueAt));
   16828          break;
   16829       case Dis_StopHere:
   16830          break;
   16831       default:
   16832          vassert(0);
   16833          break;
   16834    }
   16835 
   16836    /* On MIPS we need to check if the last instruction in block is branch or
   16837       jump. */
   16838    if (((vex_control.guest_max_insns - 1) == (delta + 4) / 4)
   16839        &&  (dres.whatNext != Dis_StopHere))
   16840       if (branch_or_jump(guest_code + delta + 4)) {
   16841          dres.whatNext = Dis_StopHere;
   16842          dres.jk_StopHere = Ijk_Boring;
   16843          if (mode64)
   16844             putPC(mkU64(guest_PC_curr_instr + 4));
   16845          else
   16846             putPC(mkU32(guest_PC_curr_instr + 4));
   16847       }
   16848    dres.len = 4;
   16849 
   16850    DIP("\n");
   16851 
   16852    return dres;
   16853 
   16854 }
   16855 
   16856 /*------------------------------------------------------------*/
   16857 /*--- Top-level fn                                         ---*/
   16858 /*------------------------------------------------------------*/
   16859 
   16860 /* Disassemble a single instruction into IR.  The instruction
   16861    is located in host memory at &guest_code[delta]. */
   16862 DisResult disInstr_MIPS( IRSB*        irsb_IN,
   16863                          Bool         (*resteerOkFn) ( void *, Addr64 ),
   16864                          Bool         resteerCisOk,
   16865                          void*        callback_opaque,
   16866                          UChar*       guest_code_IN,
   16867                          Long         delta,
   16868                          Addr64       guest_IP,
   16869                          VexArch      guest_arch,
   16870                          VexArchInfo* archinfo,
   16871                          VexAbiInfo*  abiinfo,
   16872                          Bool         host_bigendian_IN,
   16873                          Bool         sigill_diag_IN )
   16874 {
   16875    DisResult dres;
   16876    /* Set globals (see top of this file) */
   16877    vassert(guest_arch == VexArchMIPS32 || guest_arch == VexArchMIPS64);
   16878 
   16879    mode64 = guest_arch != VexArchMIPS32;
   16880 #if (__mips_fpr==64)
   16881    fp_mode64 = ((VEX_MIPS_REV(archinfo->hwcaps) == VEX_PRID_CPU_32FPR)
   16882                 || guest_arch == VexArchMIPS64);
   16883 #endif
   16884 
   16885    guest_code = guest_code_IN;
   16886    irsb = irsb_IN;
   16887    host_is_bigendian = host_bigendian_IN;
   16888 #if defined(VGP_mips32_linux)
   16889    guest_PC_curr_instr = (Addr32)guest_IP;
   16890 #elif defined(VGP_mips64_linux)
   16891    guest_PC_curr_instr = (Addr64)guest_IP;
   16892 #endif
   16893 
   16894    dres = disInstr_MIPS_WRK(resteerOkFn, resteerCisOk, callback_opaque,
   16895                             delta, archinfo, abiinfo, sigill_diag_IN);
   16896 
   16897    return dres;
   16898 }
   16899 
   16900 /*--------------------------------------------------------------------*/
   16901 /*--- end                                        guest_mips_toIR.c ---*/
   16902 /*--------------------------------------------------------------------*/
   16903