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: what is the host's endianness?  This has to do with float vs
     53    double register accesses on VFP, but it's complex and not properly
     54    thought out. */
     55 static VexEndness host_endness;
     56 
     57 /* Pointer to the guest code area. */
     58 static const UChar *guest_code;
     59 
     60 /* CONST: The guest address for the instruction currently being
     61    translated. */
     62 #if defined(VGP_mips32_linux)
     63 static Addr32 guest_PC_curr_instr;
     64 #else
     65 static Addr64 guest_PC_curr_instr;
     66 #endif
     67 
     68 /* MOD: The IRSB* into which we're generating code. */
     69 static IRSB *irsb;
     70 
     71 /* Is our guest binary 32 or 64bit? Set at each call to
     72    disInstr_MIPS below. */
     73 static Bool mode64 = False;
     74 
     75 /* CPU has FPU and 32 dbl. prec. FP registers. */
     76 static Bool fp_mode64 = False;
     77 
     78 /* Define 1.0 in single and double precision. */
     79 #define ONE_SINGLE 0x3F800000
     80 #define ONE_DOUBLE 0x3FF0000000000000ULL
     81 
     82 /*------------------------------------------------------------*/
     83 /*---                  Debugging output                    ---*/
     84 /*------------------------------------------------------------*/
     85 
     86 #define DIP(format, args...)           \
     87    if (vex_traceflags & VEX_TRACE_FE)  \
     88       vex_printf(format, ## args)
     89 
     90 /*------------------------------------------------------------*/
     91 /*--- Helper bits and pieces for deconstructing the        ---*/
     92 /*--- mips insn stream.                                    ---*/
     93 /*------------------------------------------------------------*/
     94 
     95 /* ---------------- Integer registers ---------------- */
     96 
     97 static UInt integerGuestRegOffset(UInt iregNo)
     98 {
     99    /* Do we care about endianness here?  We do if sub-parts of integer
    100       registers are accessed, but I don't think that ever happens on
    101       MIPS. */
    102    UInt ret;
    103    if (!mode64)
    104       switch (iregNo) {
    105          case 0:
    106             ret = offsetof(VexGuestMIPS32State, guest_r0); break;
    107          case 1:
    108             ret = offsetof(VexGuestMIPS32State, guest_r1); break;
    109          case 2:
    110             ret = offsetof(VexGuestMIPS32State, guest_r2); break;
    111          case 3:
    112             ret = offsetof(VexGuestMIPS32State, guest_r3); break;
    113          case 4:
    114             ret = offsetof(VexGuestMIPS32State, guest_r4); break;
    115          case 5:
    116             ret = offsetof(VexGuestMIPS32State, guest_r5); break;
    117          case 6:
    118             ret = offsetof(VexGuestMIPS32State, guest_r6); break;
    119          case 7:
    120             ret = offsetof(VexGuestMIPS32State, guest_r7); break;
    121          case 8:
    122             ret = offsetof(VexGuestMIPS32State, guest_r8); break;
    123          case 9:
    124             ret = offsetof(VexGuestMIPS32State, guest_r9); break;
    125          case 10:
    126             ret = offsetof(VexGuestMIPS32State, guest_r10); break;
    127          case 11:
    128             ret = offsetof(VexGuestMIPS32State, guest_r11); break;
    129          case 12:
    130             ret = offsetof(VexGuestMIPS32State, guest_r12); break;
    131          case 13:
    132             ret = offsetof(VexGuestMIPS32State, guest_r13); break;
    133          case 14:
    134             ret = offsetof(VexGuestMIPS32State, guest_r14); break;
    135          case 15:
    136             ret = offsetof(VexGuestMIPS32State, guest_r15); break;
    137          case 16:
    138             ret = offsetof(VexGuestMIPS32State, guest_r16); break;
    139          case 17:
    140             ret = offsetof(VexGuestMIPS32State, guest_r17); break;
    141          case 18:
    142             ret = offsetof(VexGuestMIPS32State, guest_r18); break;
    143          case 19:
    144             ret = offsetof(VexGuestMIPS32State, guest_r19); break;
    145          case 20:
    146             ret = offsetof(VexGuestMIPS32State, guest_r20); break;
    147          case 21:
    148             ret = offsetof(VexGuestMIPS32State, guest_r21); break;
    149          case 22:
    150             ret = offsetof(VexGuestMIPS32State, guest_r22); break;
    151          case 23:
    152             ret = offsetof(VexGuestMIPS32State, guest_r23); break;
    153          case 24:
    154             ret = offsetof(VexGuestMIPS32State, guest_r24); break;
    155          case 25:
    156             ret = offsetof(VexGuestMIPS32State, guest_r25); break;
    157          case 26:
    158             ret = offsetof(VexGuestMIPS32State, guest_r26); break;
    159          case 27:
    160             ret = offsetof(VexGuestMIPS32State, guest_r27); break;
    161          case 28:
    162             ret = offsetof(VexGuestMIPS32State, guest_r28); break;
    163          case 29:
    164             ret = offsetof(VexGuestMIPS32State, guest_r29); break;
    165          case 30:
    166             ret = offsetof(VexGuestMIPS32State, guest_r30); break;
    167          case 31:
    168             ret = offsetof(VexGuestMIPS32State, guest_r31); break;
    169          default:
    170             vassert(0);
    171             break;
    172       }
    173    else
    174       switch (iregNo) {
    175          case 0:
    176             ret = offsetof(VexGuestMIPS64State, guest_r0); break;
    177          case 1:
    178             ret = offsetof(VexGuestMIPS64State, guest_r1); break;
    179          case 2:
    180             ret = offsetof(VexGuestMIPS64State, guest_r2); break;
    181          case 3:
    182             ret = offsetof(VexGuestMIPS64State, guest_r3); break;
    183          case 4:
    184             ret = offsetof(VexGuestMIPS64State, guest_r4); break;
    185          case 5:
    186             ret = offsetof(VexGuestMIPS64State, guest_r5); break;
    187          case 6:
    188             ret = offsetof(VexGuestMIPS64State, guest_r6); break;
    189          case 7:
    190             ret = offsetof(VexGuestMIPS64State, guest_r7); break;
    191          case 8:
    192             ret = offsetof(VexGuestMIPS64State, guest_r8); break;
    193          case 9:
    194             ret = offsetof(VexGuestMIPS64State, guest_r9); break;
    195          case 10:
    196             ret = offsetof(VexGuestMIPS64State, guest_r10); break;
    197          case 11:
    198             ret = offsetof(VexGuestMIPS64State, guest_r11); break;
    199          case 12:
    200             ret = offsetof(VexGuestMIPS64State, guest_r12); break;
    201          case 13:
    202             ret = offsetof(VexGuestMIPS64State, guest_r13); break;
    203          case 14:
    204             ret = offsetof(VexGuestMIPS64State, guest_r14); break;
    205          case 15:
    206             ret = offsetof(VexGuestMIPS64State, guest_r15); break;
    207          case 16:
    208             ret = offsetof(VexGuestMIPS64State, guest_r16); break;
    209          case 17:
    210             ret = offsetof(VexGuestMIPS64State, guest_r17); break;
    211          case 18:
    212             ret = offsetof(VexGuestMIPS64State, guest_r18); break;
    213          case 19:
    214             ret = offsetof(VexGuestMIPS64State, guest_r19); break;
    215          case 20:
    216             ret = offsetof(VexGuestMIPS64State, guest_r20); break;
    217          case 21:
    218             ret = offsetof(VexGuestMIPS64State, guest_r21); break;
    219          case 22:
    220             ret = offsetof(VexGuestMIPS64State, guest_r22); break;
    221          case 23:
    222             ret = offsetof(VexGuestMIPS64State, guest_r23); break;
    223          case 24:
    224             ret = offsetof(VexGuestMIPS64State, guest_r24); break;
    225          case 25:
    226             ret = offsetof(VexGuestMIPS64State, guest_r25); break;
    227          case 26:
    228             ret = offsetof(VexGuestMIPS64State, guest_r26); break;
    229          case 27:
    230             ret = offsetof(VexGuestMIPS64State, guest_r27); break;
    231          case 28:
    232             ret = offsetof(VexGuestMIPS64State, guest_r28); break;
    233          case 29:
    234             ret = offsetof(VexGuestMIPS64State, guest_r29); break;
    235          case 30:
    236             ret = offsetof(VexGuestMIPS64State, guest_r30); break;
    237          case 31:
    238             ret = offsetof(VexGuestMIPS64State, guest_r31); break;
    239          default:
    240             vassert(0);
    241             break;
    242       }
    243    return ret;
    244 }
    245 
    246 #if defined(VGP_mips32_linux)
    247 #define OFFB_PC     offsetof(VexGuestMIPS32State, guest_PC)
    248 #else
    249 #define OFFB_PC     offsetof(VexGuestMIPS64State, guest_PC)
    250 #endif
    251 
    252 /* ---------------- Floating point registers ---------------- */
    253 
    254 static UInt floatGuestRegOffset(UInt fregNo)
    255 {
    256    vassert(fregNo < 32);
    257    UInt ret;
    258    if (!mode64)
    259       switch (fregNo) {
    260          case 0:
    261             ret = offsetof(VexGuestMIPS32State, guest_f0); break;
    262          case 1:
    263             ret = offsetof(VexGuestMIPS32State, guest_f1); break;
    264          case 2:
    265             ret = offsetof(VexGuestMIPS32State, guest_f2); break;
    266          case 3:
    267             ret = offsetof(VexGuestMIPS32State, guest_f3); break;
    268          case 4:
    269             ret = offsetof(VexGuestMIPS32State, guest_f4); break;
    270          case 5:
    271             ret = offsetof(VexGuestMIPS32State, guest_f5); break;
    272          case 6:
    273             ret = offsetof(VexGuestMIPS32State, guest_f6); break;
    274          case 7:
    275             ret = offsetof(VexGuestMIPS32State, guest_f7); break;
    276          case 8:
    277             ret = offsetof(VexGuestMIPS32State, guest_f8); break;
    278          case 9:
    279             ret = offsetof(VexGuestMIPS32State, guest_f9); break;
    280          case 10:
    281             ret = offsetof(VexGuestMIPS32State, guest_f10); break;
    282          case 11:
    283             ret = offsetof(VexGuestMIPS32State, guest_f11); break;
    284          case 12:
    285             ret = offsetof(VexGuestMIPS32State, guest_f12); break;
    286          case 13:
    287             ret = offsetof(VexGuestMIPS32State, guest_f13); break;
    288          case 14:
    289             ret = offsetof(VexGuestMIPS32State, guest_f14); break;
    290          case 15:
    291             ret = offsetof(VexGuestMIPS32State, guest_f15); break;
    292          case 16:
    293             ret = offsetof(VexGuestMIPS32State, guest_f16); break;
    294          case 17:
    295             ret = offsetof(VexGuestMIPS32State, guest_f17); break;
    296          case 18:
    297             ret = offsetof(VexGuestMIPS32State, guest_f18); break;
    298          case 19:
    299             ret = offsetof(VexGuestMIPS32State, guest_f19); break;
    300          case 20:
    301             ret = offsetof(VexGuestMIPS32State, guest_f20); break;
    302          case 21:
    303             ret = offsetof(VexGuestMIPS32State, guest_f21); break;
    304          case 22:
    305             ret = offsetof(VexGuestMIPS32State, guest_f22); break;
    306          case 23:
    307             ret = offsetof(VexGuestMIPS32State, guest_f23); break;
    308          case 24:
    309             ret = offsetof(VexGuestMIPS32State, guest_f24); break;
    310          case 25:
    311             ret = offsetof(VexGuestMIPS32State, guest_f25); break;
    312          case 26:
    313             ret = offsetof(VexGuestMIPS32State, guest_f26); break;
    314          case 27:
    315             ret = offsetof(VexGuestMIPS32State, guest_f27); break;
    316          case 28:
    317             ret = offsetof(VexGuestMIPS32State, guest_f28); break;
    318          case 29:
    319             ret = offsetof(VexGuestMIPS32State, guest_f29); break;
    320          case 30:
    321             ret = offsetof(VexGuestMIPS32State, guest_f30); break;
    322          case 31:
    323             ret = offsetof(VexGuestMIPS32State, guest_f31); break;
    324          default:
    325             vassert(0);
    326             break;
    327       }
    328    else
    329       switch (fregNo) {
    330          case 0:
    331             ret = offsetof(VexGuestMIPS64State, guest_f0); break;
    332          case 1:
    333             ret = offsetof(VexGuestMIPS64State, guest_f1); break;
    334          case 2:
    335             ret = offsetof(VexGuestMIPS64State, guest_f2); break;
    336          case 3:
    337             ret = offsetof(VexGuestMIPS64State, guest_f3); break;
    338          case 4:
    339             ret = offsetof(VexGuestMIPS64State, guest_f4); break;
    340          case 5:
    341             ret = offsetof(VexGuestMIPS64State, guest_f5); break;
    342          case 6:
    343             ret = offsetof(VexGuestMIPS64State, guest_f6); break;
    344          case 7:
    345             ret = offsetof(VexGuestMIPS64State, guest_f7); break;
    346          case 8:
    347             ret = offsetof(VexGuestMIPS64State, guest_f8); break;
    348          case 9:
    349             ret = offsetof(VexGuestMIPS64State, guest_f9); break;
    350          case 10:
    351             ret = offsetof(VexGuestMIPS64State, guest_f10); break;
    352          case 11:
    353             ret = offsetof(VexGuestMIPS64State, guest_f11); break;
    354          case 12:
    355             ret = offsetof(VexGuestMIPS64State, guest_f12); break;
    356          case 13:
    357             ret = offsetof(VexGuestMIPS64State, guest_f13); break;
    358          case 14:
    359             ret = offsetof(VexGuestMIPS64State, guest_f14); break;
    360          case 15:
    361             ret = offsetof(VexGuestMIPS64State, guest_f15); break;
    362          case 16:
    363             ret = offsetof(VexGuestMIPS64State, guest_f16); break;
    364          case 17:
    365             ret = offsetof(VexGuestMIPS64State, guest_f17); break;
    366          case 18:
    367             ret = offsetof(VexGuestMIPS64State, guest_f18); break;
    368          case 19:
    369             ret = offsetof(VexGuestMIPS64State, guest_f19); break;
    370          case 20:
    371             ret = offsetof(VexGuestMIPS64State, guest_f20); break;
    372          case 21:
    373             ret = offsetof(VexGuestMIPS64State, guest_f21); break;
    374          case 22:
    375             ret = offsetof(VexGuestMIPS64State, guest_f22); break;
    376          case 23:
    377             ret = offsetof(VexGuestMIPS64State, guest_f23); break;
    378          case 24:
    379             ret = offsetof(VexGuestMIPS64State, guest_f24); break;
    380          case 25:
    381             ret = offsetof(VexGuestMIPS64State, guest_f25); break;
    382          case 26:
    383             ret = offsetof(VexGuestMIPS64State, guest_f26); break;
    384          case 27:
    385             ret = offsetof(VexGuestMIPS64State, guest_f27); break;
    386          case 28:
    387             ret = offsetof(VexGuestMIPS64State, guest_f28); break;
    388          case 29:
    389             ret = offsetof(VexGuestMIPS64State, guest_f29); break;
    390          case 30:
    391             ret = offsetof(VexGuestMIPS64State, guest_f30); break;
    392          case 31:
    393             ret = offsetof(VexGuestMIPS64State, guest_f31); break;
    394          default:
    395             vassert(0);
    396             break;
    397       }
    398    return ret;
    399 }
    400 
    401 /* ---------------- MIPS32 DSP ASE(r2) accumulators ---------------- */
    402 
    403 static UInt accumulatorGuestRegOffset(UInt acNo)
    404 {
    405    vassert(!mode64);
    406    vassert(acNo <= 3);
    407    UInt ret;
    408    switch (acNo) {
    409       case 0:
    410          ret = offsetof(VexGuestMIPS32State, guest_ac0); break;
    411       case 1:
    412          ret = offsetof(VexGuestMIPS32State, guest_ac1); break;
    413       case 2:
    414          ret = offsetof(VexGuestMIPS32State, guest_ac2); break;
    415       case 3:
    416          ret = offsetof(VexGuestMIPS32State, guest_ac3); break;
    417       default:
    418          vassert(0);
    419     break;
    420    }
    421    return ret;
    422 }
    423 
    424 /* Do a endian load of a 32-bit word, regardless of the endianness of the
    425    underlying host. */
    426 static inline UInt getUInt(const UChar * p)
    427 {
    428    UInt w = 0;
    429 #if defined (_MIPSEL)
    430    w = (w << 8) | p[3];
    431    w = (w << 8) | p[2];
    432    w = (w << 8) | p[1];
    433    w = (w << 8) | p[0];
    434 #elif defined (_MIPSEB)
    435    w = (w << 8) | p[0];
    436    w = (w << 8) | p[1];
    437    w = (w << 8) | p[2];
    438    w = (w << 8) | p[3];
    439 #endif
    440    return w;
    441 }
    442 
    443 #define BITS2(_b1,_b0) \
    444    (((_b1) << 1) | (_b0))
    445 
    446 #define BITS3(_b2,_b1,_b0)                      \
    447   (((_b2) << 2) | ((_b1) << 1) | (_b0))
    448 
    449 #define BITS4(_b3,_b2,_b1,_b0) \
    450    (((_b3) << 3) | ((_b2) << 2) | ((_b1) << 1) | (_b0))
    451 
    452 #define BITS5(_b4,_b3,_b2,_b1,_b0)  \
    453    (((_b4) << 4) | BITS4((_b3),(_b2),(_b1),(_b0)))
    454 
    455 #define BITS6(_b5,_b4,_b3,_b2,_b1,_b0)  \
    456    ((BITS2((_b5),(_b4)) << 4) \
    457     | BITS4((_b3),(_b2),(_b1),(_b0)))
    458 
    459 #define BITS8(_b7,_b6,_b5,_b4,_b3,_b2,_b1,_b0)  \
    460    ((BITS4((_b7),(_b6),(_b5),(_b4)) << 4) \
    461     | BITS4((_b3),(_b2),(_b1),(_b0)))
    462 
    463 #define LOAD_STORE_PATTERN \
    464    t1 = newTemp(mode64 ? Ity_I64 : Ity_I32); \
    465       if(!mode64) \
    466          assign(t1, binop(Iop_Add32, getIReg(rs), \
    467                                      mkU32(extend_s_16to32(imm)))); \
    468       else \
    469          assign(t1, binop(Iop_Add64, getIReg(rs), \
    470                                      mkU64(extend_s_16to64(imm)))); \
    471 
    472 #define LOADX_STORE_PATTERN \
    473    t1 = newTemp(mode64 ? Ity_I64 : Ity_I32); \
    474       if(!mode64) \
    475          assign(t1, binop(Iop_Add32, getIReg(regRs), getIReg(regRt))); \
    476       else \
    477          assign(t1, binop(Iop_Add64, getIReg(regRs), getIReg(regRt)));
    478 
    479 #define LWX_SWX_PATTERN64 \
    480    t2 = newTemp(Ity_I64); \
    481    assign(t2, binop(Iop_And64, mkexpr(t1), mkU64(0xFFFFFFFFFFFFFFFCULL))); \
    482    t4 = newTemp(Ity_I32); \
    483    assign(t4, mkNarrowTo32( ty, binop(Iop_And64, \
    484                                       mkexpr(t1), mkU64(0x3))));
    485 
    486 #define LWX_SWX_PATTERN64_1 \
    487    t2 = newTemp(Ity_I64); \
    488    assign(t2, binop(Iop_And64, mkexpr(t1), mkU64(0xFFFFFFFFFFFFFFF8ULL))); \
    489    t4 = newTemp(Ity_I64); \
    490    assign(t4, binop(Iop_And64, mkexpr(t1), mkU64(0x7)));
    491 
    492 #define LWX_SWX_PATTERN \
    493    t2 = newTemp(Ity_I32); \
    494    assign(t2, binop(Iop_And32, mkexpr(t1), mkU32(0xFFFFFFFC))); \
    495    t4 = newTemp(Ity_I32); \
    496    assign(t4, binop(Iop_And32, mkexpr(t1), mkU32(0x00000003)))
    497 
    498 #define SXXV_PATTERN(op) \
    499    putIReg(rd, binop(op, \
    500          getIReg(rt), \
    501             unop(Iop_32to8, \
    502                binop(Iop_And32, \
    503                   getIReg(rs), \
    504                   mkU32(0x0000001F) \
    505                ) \
    506             ) \
    507          ) \
    508       )
    509 
    510 #define SXXV_PATTERN64(op) \
    511    putIReg(rd, mkWidenFrom32(ty, binop(op, \
    512            mkNarrowTo32(ty, getIReg(rt)), \
    513              unop(Iop_32to8, \
    514                 binop(Iop_And32, \
    515                    mkNarrowTo32(ty, getIReg(rs)), \
    516                    mkU32(0x0000001F) \
    517                 ) \
    518              ) \
    519           ), True \
    520        ))
    521 
    522 #define SXX_PATTERN(op) \
    523    putIReg(rd, binop(op, getIReg(rt), mkU8(sa)));
    524 
    525 #define ALU_PATTERN(op) \
    526    putIReg(rd, binop(op, getIReg(rs), getIReg(rt)));
    527 
    528 #define ALUI_PATTERN(op) \
    529    putIReg(rt, binop(op, getIReg(rs), mkU32(imm)));
    530 
    531 #define ALUI_PATTERN64(op) \
    532    putIReg(rt, binop(op, getIReg(rs), mkU64(imm)));
    533 
    534 #define ALU_PATTERN64(op) \
    535    putIReg(rd, mkWidenFrom32(ty, binop(op, \
    536                              mkNarrowTo32(ty, getIReg(rs)), \
    537                              mkNarrowTo32(ty, getIReg(rt))), True));
    538 
    539 #define FP_CONDITIONAL_CODE \
    540    t3 = newTemp(Ity_I32);   \
    541    assign(t3, binop(Iop_And32, \
    542                  IRExpr_ITE( binop(Iop_CmpEQ32, mkU32(cc), mkU32(0)), \
    543                              binop(Iop_Shr32, getFCSR(), mkU8(23)), \
    544                              binop(Iop_Shr32, getFCSR(), mkU8(24+cc))), \
    545                  mkU32(0x1)));
    546 
    547 #define ILLEGAL_INSTRUCTON \
    548    putPC(mkU32(guest_PC_curr_instr + 4)); \
    549    dres.jk_StopHere = Ijk_SigILL; \
    550    dres.whatNext    = Dis_StopHere;
    551 
    552 /*------------------------------------------------------------*/
    553 /*---                  Field helpers                       ---*/
    554 /*------------------------------------------------------------*/
    555 
    556 static UInt get_opcode(UInt mipsins)
    557 {
    558    return (0xFC000000 & mipsins) >> 26;
    559 }
    560 
    561 static UInt get_rs(UInt mipsins)
    562 {
    563    return (0x03E00000 & mipsins) >> 21;
    564 }
    565 
    566 static UInt get_rt(UInt mipsins)
    567 {
    568    return (0x001F0000 & mipsins) >> 16;
    569 }
    570 
    571 static UInt get_imm(UInt mipsins)
    572 {
    573    return (0x0000FFFF & mipsins);
    574 }
    575 
    576 static UInt get_instr_index(UInt mipsins)
    577 {
    578    return (0x03FFFFFF & mipsins);
    579 }
    580 
    581 static UInt get_rd(UInt mipsins)
    582 {
    583    return (0x0000F800 & mipsins) >> 11;
    584 }
    585 
    586 static UInt get_sa(UInt mipsins)
    587 {
    588    return (0x000007C0 & mipsins) >> 6;
    589 }
    590 
    591 static UInt get_function(UInt mipsins)
    592 {
    593    return (0x0000003F & mipsins);
    594 }
    595 
    596 static UInt get_ft(UInt mipsins)
    597 {
    598    return (0x001F0000 & mipsins) >> 16;
    599 }
    600 
    601 static UInt get_fs(UInt mipsins)
    602 {
    603    return (0x0000F800 & mipsins) >> 11;
    604 }
    605 
    606 static UInt get_fd(UInt mipsins)
    607 {
    608    return (0x000007C0 & mipsins) >> 6;
    609 }
    610 
    611 static UInt get_mov_cc(UInt mipsins)
    612 {
    613    return (0x001C0000 & mipsins) >> 18;
    614 }
    615 
    616 static UInt get_bc1_cc(UInt mipsins)
    617 {
    618    return (0x001C0000 & mipsins) >> 18;
    619 }
    620 
    621 static UInt get_fpc_cc(UInt mipsins)
    622 {
    623    return (0x00000700 & mipsins) >> 8;
    624 }
    625 
    626 static UInt get_tf(UInt mipsins)
    627 {
    628    return (0x00010000 & mipsins) >> 16;
    629 }
    630 
    631 static UInt get_nd(UInt mipsins)
    632 {
    633    return (0x00020000 & mipsins) >> 17;
    634 }
    635 
    636 static UInt get_fmt(UInt mipsins)
    637 {
    638    return (0x03E00000 & mipsins) >> 21;
    639 }
    640 
    641 static UInt get_FC(UInt mipsins)
    642 {
    643    return (0x000000F0 & mipsins) >> 4;
    644 }
    645 
    646 static UInt get_cond(UInt mipsins)
    647 {
    648    return (0x0000000F & mipsins);
    649 }
    650 
    651 /* for break & syscall */
    652 static UInt get_code(UInt mipsins)
    653 {
    654    return (0xFFC0 & mipsins) >> 6;
    655 }
    656 
    657 static UInt get_lsb(UInt mipsins)
    658 {
    659    return (0x7C0 & mipsins) >> 6;
    660 }
    661 
    662 static UInt get_msb(UInt mipsins)
    663 {
    664    return (0x0000F800 & mipsins) >> 11;
    665 }
    666 
    667 static UInt get_rot(UInt mipsins)
    668 {
    669    return (0x00200000 & mipsins) >> 21;
    670 }
    671 
    672 static UInt get_rotv(UInt mipsins)
    673 {
    674    return (0x00000040 & mipsins) >> 6;
    675 }
    676 
    677 static UInt get_sel(UInt mipsins)
    678 {
    679    return (0x00000007 & mipsins);
    680 }
    681 
    682 /* Get acc number for all MIPS32 DSP ASE(r2) instructions that use them,
    683    except for MFHI and MFLO. */
    684 static UInt get_acNo(UInt mipsins)
    685 {
    686    return (0x00001800 & mipsins) >> 11;
    687 }
    688 
    689 /* Get accumulator number for MIPS32 DSP ASEr2 MFHI and MFLO instructions. */
    690 static UInt get_acNo_mfhilo(UInt mipsins)
    691 {
    692    return (0x00600000 & mipsins) >> 21;
    693 }
    694 
    695 /* Get mask field (helper function for wrdsp instruction). */
    696 static UInt get_wrdspMask(UInt mipsins)
    697 {
    698    return (0x001ff800 & mipsins) >> 11;
    699 }
    700 
    701 /* Get mask field (helper function for rddsp instruction). */
    702 static UInt get_rddspMask(UInt mipsins)
    703 {
    704    return (0x03ff0000 & mipsins) >> 16;
    705 }
    706 
    707 /* Get shift field (helper function for DSP ASE instructions). */
    708 static UInt get_shift(UInt mipsins)
    709 {
    710    return (0x03f00000 & mipsins) >> 20;
    711 }
    712 
    713 /* Get immediate field for DSP ASE instructions. */
    714 static UInt get_dspImm(UInt mipsins)
    715 {
    716    return (0x03ff0000 & mipsins) >> 16;
    717 }
    718 
    719 static Bool branch_or_jump(const UChar * addr)
    720 {
    721    UInt fmt;
    722    UInt cins = getUInt(addr);
    723 
    724    UInt opcode = get_opcode(cins);
    725    UInt rt = get_rt(cins);
    726    UInt function = get_function(cins);
    727 
    728    /* bgtz, blez, bne, beq, jal */
    729    if (opcode == 0x07 || opcode == 0x06 || opcode == 0x05 || opcode == 0x04
    730        || opcode == 0x03 || opcode == 0x02) {
    731       return True;
    732    }
    733 
    734    /* bgez */
    735    if (opcode == 0x01 && rt == 0x01) {
    736       return True;
    737    }
    738 
    739    /* bgezal */
    740    if (opcode == 0x01 && rt == 0x11) {
    741       return True;
    742    }
    743 
    744    /* bltzal */
    745    if (opcode == 0x01 && rt == 0x10) {
    746       return True;
    747    }
    748 
    749    /* bltz */
    750    if (opcode == 0x01 && rt == 0x00) {
    751       return True;
    752    }
    753 
    754    /* jalr */
    755    if (opcode == 0x00 && function == 0x09) {
    756       return True;
    757    }
    758 
    759    /* jr */
    760    if (opcode == 0x00 && function == 0x08) {
    761       return True;
    762    }
    763 
    764    if (opcode == 0x11) {
    765       /*bc1f & bc1t */
    766       fmt = get_fmt(cins);
    767       if (fmt == 0x08) {
    768          return True;
    769       }
    770    }
    771 
    772    /* bposge32 */
    773    if (opcode == 0x01 && rt == 0x1c) {
    774       return True;
    775    }
    776 
    777    /* Cavium Specific instructions. */
    778    if (opcode == 0x32 || opcode == 0x3A || opcode == 0x36 || opcode == 0x3E) {
    779        /* BBIT0, BBIT1, BBIT032, BBIT132 */
    780       return True;
    781    }
    782 
    783    return False;
    784 }
    785 
    786 static Bool is_Branch_or_Jump_and_Link(const UChar * addr)
    787 {
    788    UInt cins = getUInt(addr);
    789 
    790    UInt opcode = get_opcode(cins);
    791    UInt rt = get_rt(cins);
    792    UInt function = get_function(cins);
    793 
    794    /* jal */
    795    if (opcode == 0x02) {
    796       return True;
    797    }
    798 
    799    /* bgezal */
    800    if (opcode == 0x01 && rt == 0x11) {
    801       return True;
    802    }
    803 
    804    /* bltzal */
    805    if (opcode == 0x01 && rt == 0x10) {
    806       return True;
    807    }
    808 
    809    /* jalr */
    810    if (opcode == 0x00 && function == 0x09) {
    811       return True;
    812    }
    813 
    814    return False;
    815 }
    816 
    817 static Bool branch_or_link_likely(const UChar * addr)
    818 {
    819    UInt cins = getUInt(addr);
    820    UInt opcode = get_opcode(cins);
    821    UInt rt = get_rt(cins);
    822 
    823    /* bgtzl, blezl, bnel, beql */
    824    if (opcode == 0x17 || opcode == 0x16 || opcode == 0x15 || opcode == 0x14)
    825       return True;
    826 
    827    /* bgezl */
    828    if (opcode == 0x01 && rt == 0x03)
    829       return True;
    830 
    831    /* bgezall */
    832    if (opcode == 0x01 && rt == 0x13)
    833       return True;
    834 
    835    /* bltzall */
    836    if (opcode == 0x01 && rt == 0x12)
    837       return True;
    838 
    839    /* bltzl */
    840    if (opcode == 0x01 && rt == 0x02)
    841       return True;
    842 
    843    return False;
    844 }
    845 
    846 /*------------------------------------------------------------*/
    847 /*--- Helper bits and pieces for creating IR fragments.    ---*/
    848 /*------------------------------------------------------------*/
    849 
    850 static IRExpr *mkU8(UInt i)
    851 {
    852    vassert(i < 256);
    853    return IRExpr_Const(IRConst_U8((UChar) i));
    854 }
    855 
    856 /* Create an expression node for a 16-bit integer constant. */
    857 static IRExpr *mkU16(UInt i)
    858 {
    859    return IRExpr_Const(IRConst_U16(i));
    860 }
    861 
    862 /* Create an expression node for a 32-bit integer constant. */
    863 static IRExpr *mkU32(UInt i)
    864 {
    865    return IRExpr_Const(IRConst_U32(i));
    866 }
    867 
    868 /* Create an expression node for a 64-bit integer constant. */
    869 static IRExpr *mkU64(ULong i)
    870 {
    871    return IRExpr_Const(IRConst_U64(i));
    872 }
    873 
    874 static IRExpr *mkexpr(IRTemp tmp)
    875 {
    876    return IRExpr_RdTmp(tmp);
    877 }
    878 
    879 static IRExpr *unop(IROp op, IRExpr * a)
    880 {
    881    return IRExpr_Unop(op, a);
    882 }
    883 
    884 static IRExpr *binop(IROp op, IRExpr * a1, IRExpr * a2)
    885 {
    886    return IRExpr_Binop(op, a1, a2);
    887 }
    888 
    889 static IRExpr *triop(IROp op, IRExpr * a1, IRExpr * a2, IRExpr * a3)
    890 {
    891    return IRExpr_Triop(op, a1, a2, a3);
    892 }
    893 
    894 static IRExpr *qop ( IROp op, IRExpr * a1, IRExpr * a2, IRExpr * a3,
    895                      IRExpr * a4 )
    896 {
    897    return IRExpr_Qop(op, a1, a2, a3, a4);
    898 }
    899 
    900 static IRExpr *load(IRType ty, IRExpr * addr)
    901 {
    902    IRExpr *load1 = NULL;
    903 #if defined (_MIPSEL)
    904    load1 = IRExpr_Load(Iend_LE, ty, addr);
    905 #elif defined (_MIPSEB)
    906    load1 = IRExpr_Load(Iend_BE, ty, addr);
    907 #endif
    908    return load1;
    909 }
    910 
    911 /* Add a statement to the list held by "irsb". */
    912 static void stmt(IRStmt * st)
    913 {
    914    addStmtToIRSB(irsb, st);
    915 }
    916 
    917 static void assign(IRTemp dst, IRExpr * e)
    918 {
    919    stmt(IRStmt_WrTmp(dst, e));
    920 }
    921 
    922 static void store(IRExpr * addr, IRExpr * data)
    923 {
    924 #if defined (_MIPSEL)
    925    stmt(IRStmt_Store(Iend_LE, addr, data));
    926 #elif defined (_MIPSEB)
    927    stmt(IRStmt_Store(Iend_BE, addr, data));
    928 #endif
    929 }
    930 
    931 /* Generate a new temporary of the given type. */
    932 static IRTemp newTemp(IRType ty)
    933 {
    934    vassert(isPlausibleIRType(ty));
    935    return newIRTemp(irsb->tyenv, ty);
    936 }
    937 
    938 /* Generate an expression for SRC rotated right by ROT. */
    939 static IRExpr *genROR32(IRExpr * src, Int rot)
    940 {
    941    vassert(rot >= 0 && rot < 32);
    942    if (rot == 0)
    943       return src;
    944    return binop(Iop_Or32, binop(Iop_Shl32, src, mkU8(32 - rot)),
    945                           binop(Iop_Shr32, src, mkU8(rot)));
    946 }
    947 
    948 static IRExpr *genRORV32(IRExpr * src, IRExpr * rs)
    949 {
    950    IRTemp t0 = newTemp(Ity_I8);
    951    IRTemp t1 = newTemp(Ity_I8);
    952 
    953    assign(t0, unop(Iop_32to8, binop(Iop_And32, rs, mkU32(0x0000001F))));
    954    assign(t1, binop(Iop_Sub8, mkU8(32), mkexpr(t0)));
    955    return binop(Iop_Or32, binop(Iop_Shl32, src, mkexpr(t1)),
    956                           binop(Iop_Shr32, src, mkexpr(t0)));
    957 }
    958 
    959 static UShort extend_s_10to16(UInt x)
    960 {
    961    return (UShort) ((((Int) x) << 22) >> 22);
    962 }
    963 
    964 static ULong extend_s_10to32(UInt x)
    965 {
    966    return (ULong)((((Long) x) << 22) >> 22);
    967 }
    968 
    969 static ULong extend_s_10to64(UInt x)
    970 {
    971    return (ULong)((((Long) x) << 54) >> 54);
    972 }
    973 
    974 static UInt extend_s_16to32(UInt x)
    975 {
    976    return (UInt) ((((Int) x) << 16) >> 16);
    977 }
    978 
    979 static UInt extend_s_18to32(UInt x)
    980 {
    981    return (UInt) ((((Int) x) << 14) >> 14);
    982 }
    983 
    984 static ULong extend_s_16to64 ( UInt x )
    985 {
    986    return (ULong) ((((Long) x) << 48) >> 48);
    987 }
    988 
    989 static ULong extend_s_18to64 ( UInt x )
    990 {
    991    return (ULong) ((((Long) x) << 46) >> 46);
    992 }
    993 
    994 static ULong extend_s_32to64 ( UInt x )
    995 {
    996    return (ULong) ((((Long) x) << 32) >> 32);
    997 }
    998 
    999 static void jmp_lit32 ( /*MOD*/ DisResult* dres, IRJumpKind kind, Addr32 d32 )
   1000 {
   1001    vassert(dres->whatNext    == Dis_Continue);
   1002    vassert(dres->len         == 0);
   1003    vassert(dres->continueAt  == 0);
   1004    vassert(dres->jk_StopHere == Ijk_INVALID);
   1005    dres->whatNext    = Dis_StopHere;
   1006    dres->jk_StopHere = kind;
   1007    stmt( IRStmt_Put( OFFB_PC, mkU32(d32) ) );
   1008 }
   1009 
   1010 static void jmp_lit64 ( /*MOD*/ DisResult* dres, IRJumpKind kind, Addr64 d64 )
   1011 {
   1012    vassert(dres->whatNext    == Dis_Continue);
   1013    vassert(dres->len         == 0);
   1014    vassert(dres->continueAt  == 0);
   1015    vassert(dres->jk_StopHere == Ijk_INVALID);
   1016    dres->whatNext    = Dis_StopHere;
   1017    dres->jk_StopHere = kind;
   1018    stmt(IRStmt_Put(OFFB_PC, mkU64(d64)));
   1019 }
   1020 
   1021 /* Get value from accumulator (helper function for MIPS32 DSP ASE instructions).
   1022    This function should be called before any other operation if widening
   1023    multiplications are used. */
   1024 static IRExpr *getAcc(UInt acNo)
   1025 {
   1026    vassert(!mode64);
   1027    vassert(acNo <= 3);
   1028    return IRExpr_Get(accumulatorGuestRegOffset(acNo), Ity_I64);
   1029 }
   1030 
   1031 /* Get value from DSPControl register (helper function for MIPS32 DSP ASE
   1032    instructions). */
   1033 static IRExpr *getDSPControl(void)
   1034 {
   1035    vassert(!mode64);
   1036    return IRExpr_Get(offsetof(VexGuestMIPS32State, guest_DSPControl), Ity_I32);
   1037 }
   1038 
   1039 /* Put value to DSPControl register. Expression e is written to DSPControl as
   1040    is. If only certain bits of DSPControl need to be changed, it should be done
   1041    before calling putDSPControl(). It could be done by reading DSPControl and
   1042    ORing it with appropriate mask. */
   1043 static void putDSPControl(IRExpr * e)
   1044 {
   1045    vassert(!mode64);
   1046    stmt(IRStmt_Put(offsetof(VexGuestMIPS32State, guest_DSPControl), e));
   1047 }
   1048 
   1049 /* Fetch a byte from the guest insn stream. */
   1050 static UChar getIByte(Int delta)
   1051 {
   1052    return guest_code[delta];
   1053 }
   1054 
   1055 static IRExpr *getIReg(UInt iregNo)
   1056 {
   1057    if (0 == iregNo) {
   1058       return mode64 ? mkU64(0x0) : mkU32(0x0);
   1059    } else {
   1060       IRType ty = mode64 ? Ity_I64 : Ity_I32;
   1061       vassert(iregNo < 32);
   1062       return IRExpr_Get(integerGuestRegOffset(iregNo), ty);
   1063    }
   1064 }
   1065 
   1066 static IRExpr *getHI(void)
   1067 {
   1068    if (mode64)
   1069       return IRExpr_Get(offsetof(VexGuestMIPS64State, guest_HI), Ity_I64);
   1070    else
   1071       return IRExpr_Get(offsetof(VexGuestMIPS32State, guest_HI), Ity_I32);
   1072 }
   1073 
   1074 static IRExpr *getLO(void)
   1075 {
   1076    if (mode64)
   1077       return IRExpr_Get(offsetof(VexGuestMIPS64State, guest_LO), Ity_I64);
   1078    else
   1079       return IRExpr_Get(offsetof(VexGuestMIPS32State, guest_LO), Ity_I32);
   1080 }
   1081 
   1082 static IRExpr *getFCSR(void)
   1083 {
   1084    if (mode64)
   1085       return IRExpr_Get(offsetof(VexGuestMIPS64State, guest_FCSR), Ity_I32);
   1086    else
   1087       return IRExpr_Get(offsetof(VexGuestMIPS32State, guest_FCSR), Ity_I32);
   1088 }
   1089 
   1090 /* Get byte from register reg, byte pos from 0 to 3 (or 7 for MIPS64) . */
   1091 static IRExpr *getByteFromReg(UInt reg, UInt byte_pos)
   1092 {
   1093   UInt pos = byte_pos * 8;
   1094   if (mode64)
   1095       return unop(Iop_64to8, binop(Iop_And64,
   1096                                    binop(Iop_Shr64, getIReg(reg), mkU8(pos)),
   1097                                    mkU64(0xFF)));
   1098    else
   1099       return unop(Iop_32to8, binop(Iop_And32,
   1100                                    binop(Iop_Shr32, getIReg(reg), mkU8(pos)),
   1101                                    mkU32(0xFF)));
   1102 }
   1103 
   1104 static void putFCSR(IRExpr * e)
   1105 {
   1106    if (mode64)
   1107       stmt(IRStmt_Put(offsetof(VexGuestMIPS64State, guest_FCSR), e));
   1108    else
   1109       stmt(IRStmt_Put(offsetof(VexGuestMIPS32State, guest_FCSR), e));
   1110 }
   1111 
   1112 /* fs   - fpu source register number.
   1113    inst - fpu instruction that needs to be executed.
   1114    sz32 - size of source register.
   1115    opN  - number of operads:
   1116           1 - unary operation.
   1117           2 - binary operation. */
   1118 static void calculateFCSR(UInt fs, UInt ft, UInt inst, Bool sz32, UInt opN)
   1119 {
   1120    IRDirty *d;
   1121    IRTemp fcsr = newTemp(Ity_I32);
   1122    /* IRExpr_BBPTR() => Need to pass pointer to guest state to helper. */
   1123    if (fp_mode64)
   1124       d = unsafeIRDirty_1_N(fcsr, 0,
   1125                             "mips_dirtyhelper_calculate_FCSR_fp64",
   1126                             &mips_dirtyhelper_calculate_FCSR_fp64,
   1127                             mkIRExprVec_4(IRExpr_BBPTR(),
   1128                                           mkU32(fs),
   1129                                           mkU32(ft),
   1130                                           mkU32(inst)));
   1131    else
   1132       d = unsafeIRDirty_1_N(fcsr, 0,
   1133                             "mips_dirtyhelper_calculate_FCSR_fp32",
   1134                             &mips_dirtyhelper_calculate_FCSR_fp32,
   1135                             mkIRExprVec_4(IRExpr_BBPTR(),
   1136                                           mkU32(fs),
   1137                                           mkU32(ft),
   1138                                           mkU32(inst)));
   1139 
   1140    if (opN == 1) {  /* Unary operation. */
   1141       /* Declare we're reading guest state. */
   1142       if (sz32 || fp_mode64)
   1143          d->nFxState = 2;
   1144       else
   1145          d->nFxState = 3;
   1146       vex_bzero(&d->fxState, sizeof(d->fxState));
   1147 
   1148       d->fxState[0].fx     = Ifx_Read;  /* read */
   1149       if (mode64)
   1150          d->fxState[0].offset = offsetof(VexGuestMIPS64State, guest_FCSR);
   1151       else
   1152          d->fxState[0].offset = offsetof(VexGuestMIPS32State, guest_FCSR);
   1153       d->fxState[0].size   = sizeof(UInt);
   1154       d->fxState[1].fx     = Ifx_Read;  /* read */
   1155       d->fxState[1].offset = floatGuestRegOffset(fs);
   1156       d->fxState[1].size   = sizeof(ULong);
   1157 
   1158       if (!(sz32 || fp_mode64)) {
   1159          d->fxState[2].fx     = Ifx_Read;  /* read */
   1160          d->fxState[2].offset = floatGuestRegOffset(fs+1);
   1161          d->fxState[2].size   = sizeof(ULong);
   1162       }
   1163    } else if (opN == 2) {  /* Binary operation. */
   1164       /* Declare we're reading guest state. */
   1165       if (sz32 || fp_mode64)
   1166          d->nFxState = 3;
   1167       else
   1168          d->nFxState = 5;
   1169       vex_bzero(&d->fxState, sizeof(d->fxState));
   1170 
   1171       d->fxState[0].fx     = Ifx_Read;  /* read */
   1172       if (mode64)
   1173          d->fxState[0].offset = offsetof(VexGuestMIPS64State, guest_FCSR);
   1174       else
   1175          d->fxState[0].offset = offsetof(VexGuestMIPS32State, guest_FCSR);
   1176       d->fxState[0].size   = sizeof(UInt);
   1177       d->fxState[1].fx     = Ifx_Read;  /* read */
   1178       d->fxState[1].offset = floatGuestRegOffset(fs);
   1179       d->fxState[1].size   = sizeof(ULong);
   1180       d->fxState[2].fx     = Ifx_Read;  /* read */
   1181       d->fxState[2].offset = floatGuestRegOffset(ft);
   1182       d->fxState[2].size   = sizeof(ULong);
   1183 
   1184       if (!(sz32 || fp_mode64)) {
   1185          d->fxState[3].fx     = Ifx_Read;  /* read */
   1186          d->fxState[3].offset = floatGuestRegOffset(fs+1);
   1187          d->fxState[3].size   = sizeof(ULong);
   1188          d->fxState[4].fx     = Ifx_Read;  /* read */
   1189          d->fxState[4].offset = floatGuestRegOffset(ft+1);
   1190          d->fxState[4].size   = sizeof(ULong);
   1191       }
   1192    }
   1193 
   1194    stmt(IRStmt_Dirty(d));
   1195 
   1196    putFCSR(mkexpr(fcsr));
   1197 }
   1198 
   1199 static IRExpr *getULR(void)
   1200 {
   1201    if (mode64)
   1202       return IRExpr_Get(offsetof(VexGuestMIPS64State, guest_ULR), Ity_I64);
   1203    else
   1204       return IRExpr_Get(offsetof(VexGuestMIPS32State, guest_ULR), Ity_I32);
   1205 }
   1206 
   1207 static void putIReg(UInt archreg, IRExpr * e)
   1208 {
   1209    IRType ty = mode64 ? Ity_I64 : Ity_I32;
   1210    vassert(archreg < 32);
   1211    vassert(typeOfIRExpr(irsb->tyenv, e) == ty);
   1212    if (archreg != 0)
   1213       stmt(IRStmt_Put(integerGuestRegOffset(archreg), e));
   1214 }
   1215 
   1216 static IRExpr *mkNarrowTo32(IRType ty, IRExpr * src)
   1217 {
   1218    vassert(ty == Ity_I32 || ty == Ity_I64);
   1219    return ty == Ity_I64 ? unop(Iop_64to32, src) : src;
   1220 }
   1221 
   1222 static void putLO(IRExpr * e)
   1223 {
   1224    if (mode64) {
   1225       stmt(IRStmt_Put(offsetof(VexGuestMIPS64State, guest_LO), e));
   1226    } else {
   1227       stmt(IRStmt_Put(offsetof(VexGuestMIPS32State, guest_LO), e));
   1228    /* Add value to lower 32 bits of ac0 to maintain compatibility between
   1229       regular MIPS32 instruction set and MIPS DSP ASE. Keep higher 32bits
   1230       unchanged. */
   1231       IRTemp t_lo = newTemp(Ity_I32);
   1232       IRTemp t_hi = newTemp(Ity_I32);
   1233       assign(t_lo, e);
   1234       assign(t_hi, unop(Iop_64HIto32, getAcc(0)));
   1235       stmt(IRStmt_Put(accumulatorGuestRegOffset(0),
   1236            binop(Iop_32HLto64, mkexpr(t_hi), mkexpr(t_lo))));
   1237    }
   1238 }
   1239 
   1240 static void putHI(IRExpr * e)
   1241 {
   1242    if (mode64) {
   1243       stmt(IRStmt_Put(offsetof(VexGuestMIPS64State, guest_HI), e));
   1244    } else {
   1245       stmt(IRStmt_Put(offsetof(VexGuestMIPS32State, guest_HI), e));
   1246    /* Add value to higher 32 bits of ac0 to maintain compatibility between
   1247       regular MIPS32 instruction set and MIPS DSP ASE. Keep lower 32bits
   1248       unchanged. */
   1249       IRTemp t_lo = newTemp(Ity_I32);
   1250       IRTemp t_hi = newTemp(Ity_I32);
   1251       assign(t_hi, e);
   1252       assign(t_lo, unop(Iop_64to32, getAcc(0)));
   1253       stmt(IRStmt_Put(accumulatorGuestRegOffset(0),
   1254            binop(Iop_32HLto64, mkexpr(t_hi), mkexpr(t_lo))));
   1255    }
   1256 }
   1257 
   1258 /* Put value to accumulator(helper function for MIPS32 DSP ASE instructions). */
   1259 static void putAcc(UInt acNo, IRExpr * e)
   1260 {
   1261    vassert(!mode64);
   1262    vassert(acNo <= 3);
   1263    vassert(typeOfIRExpr(irsb->tyenv, e) == Ity_I64);
   1264    stmt(IRStmt_Put(accumulatorGuestRegOffset(acNo), e));
   1265 /* If acNo = 0, split value to HI and LO regs in order to maintain compatibility
   1266    between MIPS32 and MIPS DSP ASE insn sets. */
   1267    if (0 == acNo) {
   1268      putLO(unop(Iop_64to32, e));
   1269      putHI(unop(Iop_64HIto32, e));
   1270    }
   1271 }
   1272 
   1273 static IRExpr *mkNarrowTo8 ( IRType ty, IRExpr * src )
   1274 {
   1275    vassert(ty == Ity_I32 || ty == Ity_I64);
   1276    return ty == Ity_I64 ? unop(Iop_64to8, src) : unop(Iop_32to8, src);
   1277 }
   1278 
   1279 static void putPC(IRExpr * e)
   1280 {
   1281    stmt(IRStmt_Put(OFFB_PC, e));
   1282 }
   1283 
   1284 static IRExpr *mkWidenFrom32(IRType ty, IRExpr * src, Bool sined)
   1285 {
   1286    vassert(ty == Ity_I32 || ty == Ity_I64);
   1287    if (ty == Ity_I32)
   1288       return src;
   1289    return (sined) ? unop(Iop_32Sto64, src) : unop(Iop_32Uto64, src);
   1290 }
   1291 
   1292 /* Narrow 8/16/32 bit int expr to 8/16/32.  Clearly only some
   1293    of these combinations make sense. */
   1294 static IRExpr *narrowTo(IRType dst_ty, IRExpr * e)
   1295 {
   1296    IRType src_ty = typeOfIRExpr(irsb->tyenv, e);
   1297    if (src_ty == dst_ty)
   1298       return e;
   1299    if (src_ty == Ity_I32 && dst_ty == Ity_I16)
   1300       return unop(Iop_32to16, e);
   1301    if (src_ty == Ity_I32 && dst_ty == Ity_I8)
   1302       return unop(Iop_32to8, e);
   1303    if (src_ty == Ity_I64 && dst_ty == Ity_I8) {
   1304       vassert(mode64);
   1305       return unop(Iop_64to8, e);
   1306    }
   1307    if (src_ty == Ity_I64 && dst_ty == Ity_I16) {
   1308       vassert(mode64);
   1309       return unop(Iop_64to16, e);
   1310    }
   1311    vpanic("narrowTo(mips)");
   1312    return 0;
   1313 }
   1314 
   1315 static IRExpr *getLoFromF64(IRType ty, IRExpr * src)
   1316 {
   1317    vassert(ty == Ity_F32 || ty == Ity_F64);
   1318    if (ty == Ity_F64) {
   1319       IRTemp t0, t1;
   1320       t0 = newTemp(Ity_I64);
   1321       t1 = newTemp(Ity_I32);
   1322       assign(t0, unop(Iop_ReinterpF64asI64, src));
   1323       assign(t1, unop(Iop_64to32, mkexpr(t0)));
   1324       return unop(Iop_ReinterpI32asF32, mkexpr(t1));
   1325    } else
   1326       return src;
   1327 }
   1328 
   1329 static IRExpr *mkWidenFromF32(IRType ty, IRExpr * src)
   1330 {
   1331    vassert(ty == Ity_F32 || ty == Ity_F64);
   1332    if (ty == Ity_F64) {
   1333       IRTemp t0 = newTemp(Ity_I32);
   1334       IRTemp t1 = newTemp(Ity_I64);
   1335       assign(t0, unop(Iop_ReinterpF32asI32, src));
   1336       assign(t1, binop(Iop_32HLto64, mkU32(0x0), mkexpr(t0)));
   1337       return unop(Iop_ReinterpI64asF64, mkexpr(t1));
   1338    } else
   1339       return src;
   1340 }
   1341 
   1342 static IRExpr *dis_branch_likely(IRExpr * guard, UInt imm)
   1343 {
   1344    ULong branch_offset;
   1345    IRTemp t0;
   1346 
   1347    /* PC = PC + (SignExtend(signed_immed_24) << 2)
   1348       An 18-bit signed offset (the 16-bit offset field shifted left 2 bits)
   1349       is added to the address of the instruction following
   1350       the branch (not the branch itself), in the branch delay slot, to form
   1351       a PC-relative effective target address. */
   1352    if (mode64)
   1353       branch_offset = extend_s_18to64(imm << 2);
   1354    else
   1355       branch_offset = extend_s_18to32(imm << 2);
   1356 
   1357    t0 = newTemp(Ity_I1);
   1358    assign(t0, guard);
   1359 
   1360    if (mode64)
   1361       stmt(IRStmt_Exit(mkexpr(t0), Ijk_Boring,
   1362                        IRConst_U64(guest_PC_curr_instr + 8), OFFB_PC));
   1363    else
   1364       stmt(IRStmt_Exit(mkexpr(t0), Ijk_Boring,
   1365                        IRConst_U32(guest_PC_curr_instr + 8), OFFB_PC));
   1366 
   1367    irsb->jumpkind = Ijk_Boring;
   1368 
   1369    if (mode64)
   1370       return mkU64(guest_PC_curr_instr + 4 + branch_offset);
   1371    else
   1372       return mkU32(guest_PC_curr_instr + 4 + branch_offset);
   1373 }
   1374 
   1375 static void dis_branch(Bool link, IRExpr * guard, UInt imm, IRStmt ** set)
   1376 {
   1377    ULong branch_offset;
   1378    IRTemp t0;
   1379 
   1380    if (link) {  /* LR (GPR31) = addr of the 2nd instr after branch instr */
   1381       if (mode64)
   1382          putIReg(31, mkU64(guest_PC_curr_instr + 8));
   1383       else
   1384          putIReg(31, mkU32(guest_PC_curr_instr + 8));
   1385    }
   1386 
   1387    /* PC = PC + (SignExtend(signed_immed_24) << 2)
   1388       An 18-bit signed offset (the 16-bit offset field shifted left 2 bits)
   1389       is added to the address of the instruction following
   1390       the branch (not the branch itself), in the branch delay slot, to form
   1391       a PC-relative effective target address. */
   1392 
   1393    if (mode64)
   1394       branch_offset = extend_s_18to64(imm << 2);
   1395    else
   1396       branch_offset = extend_s_18to32(imm << 2);
   1397 
   1398    t0 = newTemp(Ity_I1);
   1399    assign(t0, guard);
   1400    if (mode64)
   1401       *set = IRStmt_Exit(mkexpr(t0), link ? Ijk_Call : Ijk_Boring,
   1402                          IRConst_U64(guest_PC_curr_instr + 4 + branch_offset),
   1403                          OFFB_PC);
   1404    else
   1405       *set = IRStmt_Exit(mkexpr(t0), link ? Ijk_Call : Ijk_Boring,
   1406                          IRConst_U32(guest_PC_curr_instr + 4 +
   1407                                      (UInt) branch_offset), OFFB_PC);
   1408 }
   1409 
   1410 static IRExpr *getFReg(UInt fregNo)
   1411 {
   1412    vassert(fregNo < 32);
   1413    IRType ty = fp_mode64 ? Ity_F64 : Ity_F32;
   1414    return IRExpr_Get(floatGuestRegOffset(fregNo), ty);
   1415 }
   1416 
   1417 static IRExpr *getDReg(UInt dregNo)
   1418 {
   1419    vassert(dregNo < 32);
   1420    if (fp_mode64) {
   1421       return IRExpr_Get(floatGuestRegOffset(dregNo), Ity_F64);
   1422    } else {
   1423       /* Read a floating point register pair and combine their contents into a
   1424          64-bit value */
   1425       IRTemp t0 = newTemp(Ity_F32);
   1426       IRTemp t1 = newTemp(Ity_F32);
   1427       IRTemp t2 = newTemp(Ity_F64);
   1428       IRTemp t3 = newTemp(Ity_I32);
   1429       IRTemp t4 = newTemp(Ity_I32);
   1430       IRTemp t5 = newTemp(Ity_I64);
   1431 
   1432       assign(t0, getFReg(dregNo));
   1433       assign(t1, getFReg(dregNo + 1));
   1434 
   1435       assign(t3, unop(Iop_ReinterpF32asI32, mkexpr(t0)));
   1436       assign(t4, unop(Iop_ReinterpF32asI32, mkexpr(t1)));
   1437       assign(t5, binop(Iop_32HLto64, mkexpr(t4), mkexpr(t3)));
   1438       assign(t2, unop(Iop_ReinterpI64asF64, mkexpr(t5)));
   1439 
   1440       return mkexpr(t2);
   1441    }
   1442 }
   1443 
   1444 static void putFReg(UInt dregNo, IRExpr * e)
   1445 {
   1446    vassert(dregNo < 32);
   1447    IRType ty = fp_mode64 ? Ity_F64 : Ity_F32;
   1448    vassert(typeOfIRExpr(irsb->tyenv, e) == ty);
   1449    stmt(IRStmt_Put(floatGuestRegOffset(dregNo), e));
   1450 }
   1451 
   1452 static void putDReg(UInt dregNo, IRExpr * e)
   1453 {
   1454    if (fp_mode64) {
   1455       vassert(dregNo < 32);
   1456       IRType ty = Ity_F64;
   1457       vassert(typeOfIRExpr(irsb->tyenv, e) == ty);
   1458       stmt(IRStmt_Put(floatGuestRegOffset(dregNo), e));
   1459    } else {
   1460       vassert(dregNo < 32);
   1461       vassert(typeOfIRExpr(irsb->tyenv, e) == Ity_F64);
   1462       IRTemp t1 = newTemp(Ity_F64);
   1463       IRTemp t4 = newTemp(Ity_I32);
   1464       IRTemp t5 = newTemp(Ity_I32);
   1465       IRTemp t6 = newTemp(Ity_I64);
   1466       assign(t1, e);
   1467       assign(t6, unop(Iop_ReinterpF64asI64, mkexpr(t1)));
   1468       assign(t4, unop(Iop_64HIto32, mkexpr(t6)));  /* hi */
   1469       assign(t5, unop(Iop_64to32, mkexpr(t6)));    /* lo */
   1470       putFReg(dregNo, unop(Iop_ReinterpI32asF32, mkexpr(t5)));
   1471       putFReg(dregNo + 1, unop(Iop_ReinterpI32asF32, mkexpr(t4)));
   1472    }
   1473 }
   1474 
   1475 static void setFPUCondCode(IRExpr * e, UInt cc)
   1476 {
   1477    if (cc == 0) {
   1478       putFCSR(binop(Iop_And32, getFCSR(), mkU32(0xFF7FFFFF)));
   1479       putFCSR(binop(Iop_Or32, getFCSR(), binop(Iop_Shl32, e, mkU8(23))));
   1480    } else {
   1481       putFCSR(binop(Iop_And32, getFCSR(), unop(Iop_Not32,
   1482                                binop(Iop_Shl32, mkU32(0x01000000), mkU8(cc)))));
   1483       putFCSR(binop(Iop_Or32, getFCSR(), binop(Iop_Shl32, e, mkU8(24 + cc))));
   1484    }
   1485 }
   1486 
   1487 static IRExpr* get_IR_roundingmode ( void )
   1488 {
   1489 /*
   1490    rounding mode | MIPS | IR
   1491    ------------------------
   1492    to nearest    | 00  | 00
   1493    to zero       | 01  | 11
   1494    to +infinity  | 10  | 10
   1495    to -infinity  | 11  | 01
   1496 */
   1497    IRTemp rm_MIPS = newTemp(Ity_I32);
   1498    /* Last two bits in FCSR are rounding mode. */
   1499 
   1500    if (mode64)
   1501       assign(rm_MIPS, binop(Iop_And32, IRExpr_Get(offsetof(VexGuestMIPS64State,
   1502                                        guest_FCSR), Ity_I32), mkU32(3)));
   1503    else
   1504       assign(rm_MIPS, binop(Iop_And32, IRExpr_Get(offsetof(VexGuestMIPS32State,
   1505                                        guest_FCSR), Ity_I32), mkU32(3)));
   1506 
   1507    /* rm_IR = XOR( rm_MIPS32, (rm_MIPS32 << 1) & 2) */
   1508 
   1509    return binop(Iop_Xor32, mkexpr(rm_MIPS), binop(Iop_And32,
   1510                 binop(Iop_Shl32, mkexpr(rm_MIPS), mkU8(1)), mkU32(2)));
   1511 }
   1512 
   1513 /* sz, ULong -> IRExpr */
   1514 static IRExpr *mkSzImm ( IRType ty, ULong imm64 )
   1515 {
   1516    vassert(ty == Ity_I32 || ty == Ity_I64);
   1517    return ty == Ity_I64 ? mkU64(imm64) : mkU32((UInt) imm64);
   1518 }
   1519 
   1520 static IRConst *mkSzConst ( IRType ty, ULong imm64 )
   1521 {
   1522    vassert(ty == Ity_I32 || ty == Ity_I64);
   1523    return (ty == Ity_I64 ? IRConst_U64(imm64) : IRConst_U32((UInt) imm64));
   1524 }
   1525 
   1526 /* Make sure we get valid 32 and 64bit addresses */
   1527 static Addr64 mkSzAddr ( IRType ty, Addr64 addr )
   1528 {
   1529    vassert(ty == Ity_I32 || ty == Ity_I64);
   1530    return (ty == Ity_I64 ? (Addr64) addr :
   1531                            (Addr64) extend_s_32to64(toUInt(addr)));
   1532 }
   1533 
   1534 /* Shift and Rotate instructions for MIPS64 */
   1535 static Bool dis_instr_shrt ( UInt theInstr )
   1536 {
   1537    UInt opc2 = get_function(theInstr);
   1538    UChar regRs = get_rs(theInstr);
   1539    UChar regRt = get_rt(theInstr);
   1540    UChar regRd = get_rd(theInstr);
   1541    UChar uImmsa = get_sa(theInstr);
   1542    Long sImmsa = extend_s_16to64(uImmsa);
   1543    IRType ty = mode64 ? Ity_I64 : Ity_I32;
   1544    IRTemp tmp = newTemp(ty);
   1545    IRTemp tmpOr = newTemp(ty);
   1546    IRTemp tmpRt = newTemp(ty);
   1547    IRTemp tmpRs = newTemp(ty);
   1548    IRTemp tmpRd = newTemp(ty);
   1549 
   1550    assign(tmpRs, getIReg(regRs));
   1551    assign(tmpRt, getIReg(regRt));
   1552 
   1553    switch (opc2) {
   1554       case 0x3A:
   1555          if ((regRs & 0x01) == 0) {
   1556             /* Doubleword Shift Right Logical - DSRL; MIPS64 */
   1557             DIP("dsrl r%u, r%u, %d", regRd, regRt, (Int)sImmsa);
   1558             assign(tmpRd, binop(Iop_Shr64, mkexpr(tmpRt), mkU8(uImmsa)));
   1559             putIReg(regRd, mkexpr(tmpRd));
   1560          } else if ((regRs & 0x01) == 1) {
   1561             /* Doubleword Rotate Right - DROTR; MIPS64r2 */
   1562             vassert(mode64);
   1563             DIP("drotr r%u, r%u, %d", regRd, regRt, (Int)sImmsa);
   1564             IRTemp tmpL = newTemp(ty);
   1565             IRTemp tmpR = newTemp(ty);
   1566             assign(tmpR, binop(Iop_Shr64, mkexpr(tmpRt), mkU8(uImmsa)));
   1567             assign(tmp, binop(Iop_Shl64, mkexpr(tmpRt), mkU8(63 - uImmsa)));
   1568             assign(tmpL, binop(Iop_Shl64, mkexpr(tmp), mkU8(1)));
   1569             assign(tmpRd, binop(Iop_Or64, mkexpr(tmpL), mkexpr(tmpR)));
   1570             putIReg(regRd, mkexpr(tmpRd));
   1571          } else
   1572             return False;
   1573          break;
   1574 
   1575       case 0x3E:
   1576          if ((regRs & 0x01) == 0) {
   1577             /* Doubleword Shift Right Logical Plus 32 - DSRL32; MIPS64 */
   1578             DIP("dsrl32 r%u, r%u, %d", regRd, regRt, (Int)(sImmsa + 32));
   1579             assign(tmpRd, binop(Iop_Shr64, mkexpr(tmpRt), mkU8(uImmsa + 32)));
   1580             putIReg(regRd, mkexpr(tmpRd));
   1581          } else if ((regRs & 0x01) == 1) {
   1582             /* Doubleword Rotate Right Plus 32 - DROTR32; MIPS64r2 */
   1583             DIP("drotr32 r%u, r%u, %d", regRd, regRt, (Int)sImmsa);
   1584             vassert(mode64);
   1585             IRTemp tmpL = newTemp(ty);
   1586             IRTemp tmpR = newTemp(ty);
   1587             /* (tmpRt >> sa) | (tmpRt << (64 - sa)) */
   1588             assign(tmpR, binop(Iop_Shr64, mkexpr(tmpRt), mkU8(uImmsa + 32)));
   1589             assign(tmp, binop(Iop_Shl64, mkexpr(tmpRt),
   1590                               mkU8(63 - (uImmsa + 32))));
   1591             assign(tmpL, binop(Iop_Shl64, mkexpr(tmp), mkU8(1)));
   1592             assign(tmpRd, binop(Iop_Or64, mkexpr(tmpL), mkexpr(tmpR)));
   1593             putIReg(regRd, mkexpr(tmpRd));
   1594          } else
   1595             return False;
   1596          break;
   1597 
   1598       case 0x16:
   1599          if ((uImmsa & 0x01) == 0) {
   1600             /* Doubleword Shift Right Logical Variable - DSRLV; MIPS64 */
   1601             DIP("dsrlv r%u, r%u, r%u", regRd, regRt, regRs);
   1602             IRTemp tmpRs8 = newTemp(Ity_I8);
   1603             /* s = tmpRs[5..0] */
   1604             assign(tmp, binop(Iop_And64, mkexpr(tmpRs), mkU64(63)));
   1605             assign(tmpRs8, mkNarrowTo8(ty, mkexpr(tmp)));
   1606             assign(tmpRd, binop(Iop_Shr64, mkexpr(tmpRt), mkexpr(tmpRs8)));
   1607             putIReg(regRd, mkexpr(tmpRd));
   1608          } else if ((uImmsa & 0x01) == 1) {
   1609             /* Doubleword Rotate Right Variable - DROTRV; MIPS64r2 */
   1610             DIP("drotrv r%u, r%u, r%u", regRd, regRt, regRs);
   1611             IRTemp tmpL = newTemp(ty);
   1612             IRTemp tmpR = newTemp(ty);
   1613             IRTemp tmpRs8 = newTemp(Ity_I8);
   1614             IRTemp tmpLs8 = newTemp(Ity_I8);
   1615             IRTemp tmp64 = newTemp(ty);
   1616             /* s = tmpRs[5...0]
   1617                m = 64 - s
   1618                (tmpRt << s) | (tmpRt >> m) */
   1619 
   1620             assign(tmp64, binop(Iop_And64, mkexpr(tmpRs), mkSzImm(ty, 63)));
   1621             assign(tmp, binop(Iop_Sub64, mkU64(63), mkexpr(tmp64)));
   1622 
   1623             assign(tmpLs8, mkNarrowTo8(ty, mkexpr(tmp)));
   1624             assign(tmpRs8, mkNarrowTo8(ty, mkexpr(tmp64)));
   1625 
   1626             assign(tmpR, binop(Iop_Shr64, mkexpr(tmpRt), mkexpr(tmpRs8)));
   1627             assign(tmpL, binop(Iop_Shl64, mkexpr(tmpRt), mkexpr(tmpLs8)));
   1628             assign(tmpRd, binop(Iop_Shl64, mkexpr(tmpL), mkU8(1)));
   1629             assign(tmpOr, binop(Iop_Or64, mkexpr(tmpRd), mkexpr(tmpR)));
   1630 
   1631             putIReg(regRd, mkexpr(tmpOr));
   1632          } else
   1633             return False;
   1634          break;
   1635 
   1636       case 0x38:  /* Doubleword Shift Left Logical - DSLL; MIPS64 */
   1637          DIP("dsll r%u, r%u, %d", regRd, regRt, (Int)sImmsa);
   1638          vassert(mode64);
   1639          assign(tmpRd, binop(Iop_Shl64, mkexpr(tmpRt), mkU8(uImmsa)));
   1640          putIReg(regRd, mkexpr(tmpRd));
   1641          break;
   1642 
   1643       case 0x3C:  /* Doubleword Shift Left Logical Plus 32 - DSLL32; MIPS64 */
   1644          DIP("dsll32 r%u, r%u, %d", regRd, regRt, (Int)sImmsa);
   1645          assign(tmpRd, binop(Iop_Shl64, mkexpr(tmpRt), mkU8(uImmsa + 32)));
   1646          putIReg(regRd, mkexpr(tmpRd));
   1647          break;
   1648 
   1649       case 0x14: {  /* Doubleword Shift Left Logical Variable - DSLLV; MIPS64 */
   1650          DIP("dsllv r%u, r%u, r%u", regRd, regRt, regRs);
   1651          IRTemp tmpRs8 = newTemp(Ity_I8);
   1652 
   1653          assign(tmp, binop(Iop_And64, mkexpr(tmpRs), mkSzImm(ty, 63)));
   1654          assign(tmpRs8, mkNarrowTo8(ty, mkexpr(tmp)));
   1655          assign(tmpRd, binop(Iop_Shl64, mkexpr(tmpRt), mkexpr(tmpRs8)));
   1656          putIReg(regRd, mkexpr(tmpRd));
   1657          break;
   1658       }
   1659 
   1660       case 0x3B:  /* Doubleword Shift Right Arithmetic - DSRA; MIPS64 */
   1661          DIP("dsra r%u, r%u, %d", regRd, regRt, (Int)sImmsa);
   1662          assign(tmpRd, binop(Iop_Sar64, mkexpr(tmpRt), mkU8(uImmsa)));
   1663          putIReg(regRd, mkexpr(tmpRd));
   1664          break;
   1665 
   1666       case 0x3F:  /* Doubleword Shift Right Arithmetic Plus 32 - DSRA32;
   1667                      MIPS64 */
   1668          DIP("dsra32 r%u, r%u, %d", regRd, regRt, (Int)sImmsa);
   1669          assign(tmpRd, binop(Iop_Sar64, mkexpr(tmpRt), mkU8(uImmsa + 32)));
   1670          putIReg(regRd, mkexpr(tmpRd));
   1671          break;
   1672 
   1673       case 0x17: {  /* Doubleword Shift Right Arithmetic Variable - DSRAV;
   1674                        MIPS64 */
   1675          DIP("dsrav r%u, r%u, r%u", regRd, regRt, regRs);
   1676          IRTemp tmpRs8 = newTemp(Ity_I8);
   1677          assign(tmp, binop(Iop_And64, mkexpr(tmpRs), mkSzImm(ty, 63)));
   1678          assign(tmpRs8, mkNarrowTo8(ty, mkexpr(tmp)));
   1679          assign(tmpRd, binop(Iop_Sar64, mkexpr(tmpRt), mkexpr(tmpRs8)));
   1680          putIReg(regRd, mkexpr(tmpRd));
   1681          break;
   1682 
   1683       }
   1684 
   1685       default:
   1686          return False;
   1687 
   1688    }
   1689    return True;
   1690 }
   1691 
   1692 static IROp mkSzOp ( IRType ty, IROp op8 )
   1693 {
   1694    Int adj;
   1695    vassert(ty == Ity_I8 || ty == Ity_I16 || ty == Ity_I32 || ty == Ity_I64);
   1696    vassert(op8 == Iop_Add8 || op8 == Iop_Sub8 || op8 == Iop_Mul8
   1697            || op8 == Iop_Or8 || op8 == Iop_And8 || op8 == Iop_Xor8
   1698            || op8 == Iop_Shl8 || op8 == Iop_Shr8 || op8 == Iop_Sar8
   1699            || op8 == Iop_CmpEQ8 || op8 == Iop_CmpNE8 || op8 == Iop_Not8);
   1700    adj = ty == Ity_I8 ? 0 : (ty == Ity_I16 ? 1 : (ty == Ity_I32 ? 2 : 3));
   1701    return adj + op8;
   1702 }
   1703 
   1704 /*********************************************************/
   1705 /*---             Floating Point Compare              ---*/
   1706 /*********************************************************/
   1707 /* Function that returns a string that represent mips cond
   1708    mnemonic for the input code. */
   1709 static const HChar* showCondCode(UInt code) {
   1710    const HChar* ret;
   1711    switch (code) {
   1712       case 0: ret = "f"; break;
   1713       case 1: ret = "un"; break;
   1714       case 2: ret = "eq"; break;
   1715       case 3: ret = "ueq"; break;
   1716       case 4: ret = "olt"; break;
   1717       case 5: ret = "ult"; break;
   1718       case 6: ret = "ole"; break;
   1719       case 7: ret = "ule"; break;
   1720       case 8: ret = "sf"; break;
   1721       case 9: ret = "ngle"; break;
   1722       case 10: ret = "seq"; break;
   1723       case 11: ret = "ngl"; break;
   1724       case 12: ret = "lt"; break;
   1725       case 13: ret = "nge"; break;
   1726       case 14: ret = "le"; break;
   1727       case 15: ret = "ngt"; break;
   1728       default: vpanic("showCondCode"); break;
   1729    }
   1730    return ret;
   1731 }
   1732 
   1733 static Bool dis_instr_CCondFmt ( UInt cins )
   1734 {
   1735    IRTemp t0, t1, t2, t3, tmp5, tmp6;
   1736    IRTemp ccIR = newTemp(Ity_I32);
   1737    IRTemp ccMIPS = newTemp(Ity_I32);
   1738    UInt FC = get_FC(cins);
   1739    UInt fmt = get_fmt(cins);
   1740    UInt fs = get_fs(cins);
   1741    UInt ft = get_ft(cins);
   1742    UInt cond = get_cond(cins);
   1743 
   1744    if (FC == 0x3) {  /* C.cond.fmt */
   1745       UInt fpc_cc = get_fpc_cc(cins);
   1746       switch (fmt) {
   1747          case 0x10: {  /* C.cond.S */
   1748             DIP("c.%s.s %d, f%d, f%d", showCondCode(cond), fpc_cc, fs, ft);
   1749             if (fp_mode64) {
   1750                t0 = newTemp(Ity_I32);
   1751                t1 = newTemp(Ity_I32);
   1752                t2 = newTemp(Ity_I32);
   1753                t3 = newTemp(Ity_I32);
   1754 
   1755                tmp5 = newTemp(Ity_F64);
   1756                tmp6 = newTemp(Ity_F64);
   1757 
   1758                assign(tmp5, unop(Iop_F32toF64, getLoFromF64(Ity_F64,
   1759                                  getFReg(fs))));
   1760                assign(tmp6, unop(Iop_F32toF64, getLoFromF64(Ity_F64,
   1761                                  getFReg(ft))));
   1762 
   1763                assign(ccIR, binop(Iop_CmpF64, mkexpr(tmp5), mkexpr(tmp6)));
   1764                putHI(mkWidenFrom32(mode64 ? Ity_I64: Ity_I32,
   1765                                    mkexpr(ccIR), True));
   1766                /* Map compare result from IR to MIPS
   1767                   FP cmp result | MIPS | IR
   1768                   --------------------------
   1769                   UN            | 0x1 | 0x45
   1770                   EQ            | 0x2 | 0x40
   1771                   GT            | 0x4 | 0x00
   1772                   LT            | 0x8 | 0x01
   1773                 */
   1774 
   1775                /* ccMIPS = Shl(1, (~(ccIR>>5) & 2) | ((ccIR ^ (ccIR>>6)) & 1) */
   1776                assign(ccMIPS, binop(Iop_Shl32, mkU32(1), unop(Iop_32to8,
   1777                               binop(Iop_Or32, binop(Iop_And32, unop(Iop_Not32,
   1778                               binop(Iop_Shr32, mkexpr(ccIR),mkU8(5))),mkU32(2)),
   1779                               binop(Iop_And32, binop(Iop_Xor32, mkexpr(ccIR),
   1780                               binop(Iop_Shr32, mkexpr(ccIR), mkU8(6))),
   1781                               mkU32(1))))));
   1782                putLO(mkWidenFrom32(mode64 ? Ity_I64: Ity_I32,
   1783                                    mkexpr(ccMIPS), True));
   1784 
   1785                /* UN */
   1786                assign(t0, binop(Iop_And32, mkexpr(ccMIPS), mkU32(0x1)));
   1787                /* EQ */
   1788                assign(t1, binop(Iop_And32, binop(Iop_Shr32, mkexpr(ccMIPS),
   1789                                                  mkU8(0x1)), mkU32(0x1)));
   1790                /* NGT */
   1791                assign(t2, binop(Iop_And32, unop(Iop_Not32, binop(Iop_Shr32,
   1792                                  mkexpr(ccMIPS), mkU8(0x2))),mkU32(0x1)));
   1793                /* LT */
   1794                assign(t3, binop(Iop_And32, binop(Iop_Shr32, mkexpr(ccMIPS),
   1795                                                  mkU8(0x3)), mkU32(0x1)));
   1796                switch (cond) {
   1797                   case 0x0:
   1798                      setFPUCondCode(mkU32(0), fpc_cc);
   1799                      break;
   1800                   case 0x1:
   1801                      setFPUCondCode(mkexpr(t0), fpc_cc);
   1802                      break;
   1803                   case 0x2:
   1804                      setFPUCondCode(mkexpr(t1), fpc_cc);
   1805                      break;
   1806                   case 0x3:
   1807                      setFPUCondCode(binop(Iop_Or32, mkexpr(t0), mkexpr(t1)),
   1808                                           fpc_cc);
   1809                      break;
   1810                   case 0x4:
   1811                      setFPUCondCode(mkexpr(t3), fpc_cc);
   1812                      break;
   1813                   case 0x5:
   1814                      setFPUCondCode(binop(Iop_Or32, mkexpr(t0), mkexpr(t3)),
   1815                                           fpc_cc);
   1816                      break;
   1817                   case 0x6:
   1818                      setFPUCondCode(binop(Iop_Or32, mkexpr(t3), mkexpr(t1)),
   1819                                           fpc_cc);
   1820                      break;
   1821                   case 0x7:
   1822                      setFPUCondCode(mkexpr(t2), fpc_cc);
   1823                      break;
   1824                   case 0x8:
   1825                      setFPUCondCode(mkU32(0), fpc_cc);
   1826                      break;
   1827                   case 0x9:
   1828                      setFPUCondCode(mkexpr(t0), fpc_cc);
   1829                      break;
   1830                   case 0xA:
   1831                      setFPUCondCode(mkexpr(t1), fpc_cc);
   1832                      break;
   1833                   case 0xB:
   1834                      setFPUCondCode(binop(Iop_Or32, mkexpr(t0), mkexpr(t1)),
   1835                                           fpc_cc);
   1836                      break;
   1837                   case 0xC:
   1838                      setFPUCondCode(mkexpr(t3), fpc_cc);
   1839                      break;
   1840                   case 0xD:
   1841                      setFPUCondCode(binop(Iop_Or32, mkexpr(t0), mkexpr(t3)),
   1842                                           fpc_cc);
   1843                      break;
   1844                   case 0xE:
   1845                      setFPUCondCode(binop(Iop_Or32, mkexpr(t3), mkexpr(t1)),
   1846                                           fpc_cc);
   1847                      break;
   1848                   case 0xF:
   1849                      setFPUCondCode(mkexpr(t2), fpc_cc);
   1850                      break;
   1851 
   1852                   default:
   1853                      return False;
   1854                }
   1855 
   1856             } else {
   1857                t0 = newTemp(Ity_I32);
   1858                t1 = newTemp(Ity_I32);
   1859                t2 = newTemp(Ity_I32);
   1860                t3 = newTemp(Ity_I32);
   1861 
   1862                assign(ccIR, binop(Iop_CmpF64, unop(Iop_F32toF64, getFReg(fs)),
   1863                                   unop(Iop_F32toF64, getFReg(ft))));
   1864                /* Map compare result from IR to MIPS
   1865                   FP cmp result | MIPS | IR
   1866                   --------------------------
   1867                   UN            | 0x1 | 0x45
   1868                   EQ            | 0x2 | 0x40
   1869                   GT            | 0x4 | 0x00
   1870                   LT            | 0x8 | 0x01
   1871                 */
   1872 
   1873                /* ccMIPS = Shl(1, (~(ccIR>>5) & 2) | ((ccIR ^ (ccIR>>6)) & 1) */
   1874                assign(ccMIPS, binop(Iop_Shl32, mkU32(1), unop(Iop_32to8,
   1875                               binop(Iop_Or32, binop(Iop_And32, unop(Iop_Not32,
   1876                               binop(Iop_Shr32, mkexpr(ccIR), mkU8(5))),
   1877                                     mkU32(2)), binop(Iop_And32,
   1878                               binop(Iop_Xor32, mkexpr(ccIR),
   1879                               binop(Iop_Shr32, mkexpr(ccIR), mkU8(6))),
   1880                               mkU32(1))))));
   1881                /* UN */
   1882                assign(t0, binop(Iop_And32, mkexpr(ccMIPS), mkU32(0x1)));
   1883                /* EQ */
   1884                assign(t1, binop(Iop_And32, binop(Iop_Shr32, mkexpr(ccMIPS),
   1885                       mkU8(0x1)), mkU32(0x1)));
   1886                /* NGT */
   1887                assign(t2, binop(Iop_And32, unop(Iop_Not32, binop(Iop_Shr32,
   1888                       mkexpr(ccMIPS), mkU8(0x2))), mkU32(0x1)));
   1889                /* LT */
   1890                assign(t3, binop(Iop_And32, binop(Iop_Shr32, mkexpr(ccMIPS),
   1891                       mkU8(0x3)), mkU32(0x1)));
   1892 
   1893                switch (cond) {
   1894                   case 0x0:
   1895                      setFPUCondCode(mkU32(0), fpc_cc);
   1896                      break;
   1897                   case 0x1:
   1898                      setFPUCondCode(mkexpr(t0), fpc_cc);
   1899                      break;
   1900                   case 0x2:
   1901                      setFPUCondCode(mkexpr(t1), fpc_cc);
   1902                      break;
   1903                   case 0x3:
   1904                      setFPUCondCode(binop(Iop_Or32, mkexpr(t0), mkexpr(t1)),
   1905                                           fpc_cc);
   1906                      break;
   1907                   case 0x4:
   1908                      setFPUCondCode(mkexpr(t3), fpc_cc);
   1909                      break;
   1910                   case 0x5:
   1911                      setFPUCondCode(binop(Iop_Or32, mkexpr(t0), mkexpr(t3)),
   1912                                           fpc_cc);
   1913                      break;
   1914                   case 0x6:
   1915                      setFPUCondCode(binop(Iop_Or32, mkexpr(t3), mkexpr(t1)),
   1916                                           fpc_cc);
   1917                      break;
   1918                   case 0x7:
   1919                      setFPUCondCode(mkexpr(t2), fpc_cc);
   1920                      break;
   1921                   case 0x8:
   1922                      setFPUCondCode(mkU32(0), fpc_cc);
   1923                      break;
   1924                   case 0x9:
   1925                      setFPUCondCode(mkexpr(t0), fpc_cc);
   1926                      break;
   1927                   case 0xA:
   1928                      setFPUCondCode(mkexpr(t1), fpc_cc);
   1929                      break;
   1930                   case 0xB:
   1931                      setFPUCondCode(binop(Iop_Or32, mkexpr(t0), mkexpr(t1)),
   1932                                           fpc_cc);
   1933                      break;
   1934                   case 0xC:
   1935                      setFPUCondCode(mkexpr(t3), fpc_cc);
   1936                      break;
   1937                   case 0xD:
   1938                      setFPUCondCode(binop(Iop_Or32, mkexpr(t0), mkexpr(t3)),
   1939                                           fpc_cc);
   1940                      break;
   1941                   case 0xE:
   1942                      setFPUCondCode(binop(Iop_Or32, mkexpr(t3), mkexpr(t1)),
   1943                                           fpc_cc);
   1944                      break;
   1945                   case 0xF:
   1946                      setFPUCondCode(mkexpr(t2), fpc_cc);
   1947                      break;
   1948 
   1949                   default:
   1950                      return False;
   1951                }
   1952             }
   1953          }
   1954             break;
   1955 
   1956          case 0x11: {  /* C.cond.D */
   1957             DIP("c.%s.d %d, f%d, f%d", showCondCode(cond), fpc_cc, fs, ft);
   1958             t0 = newTemp(Ity_I32);
   1959             t1 = newTemp(Ity_I32);
   1960             t2 = newTemp(Ity_I32);
   1961             t3 = newTemp(Ity_I32);
   1962             assign(ccIR, binop(Iop_CmpF64, getDReg(fs), getDReg(ft)));
   1963             /* Map compare result from IR to MIPS
   1964                FP cmp result | MIPS | IR
   1965                --------------------------
   1966                UN            | 0x1 | 0x45
   1967                EQ            | 0x2 | 0x40
   1968                GT            | 0x4 | 0x00
   1969                LT            | 0x8 | 0x01
   1970              */
   1971 
   1972             /* ccMIPS = Shl(1, (~(ccIR>>5) & 2) | ((ccIR ^ (ccIR>>6)) & 1) */
   1973             assign(ccMIPS, binop(Iop_Shl32, mkU32(1), unop(Iop_32to8,
   1974                            binop(Iop_Or32, binop(Iop_And32, unop(Iop_Not32,
   1975                            binop(Iop_Shr32, mkexpr(ccIR), mkU8(5))), mkU32(2)),
   1976                            binop(Iop_And32, binop(Iop_Xor32, mkexpr(ccIR),
   1977                            binop(Iop_Shr32, mkexpr(ccIR), mkU8(6))),
   1978                            mkU32(1))))));
   1979 
   1980             /* UN */
   1981             assign(t0, binop(Iop_And32, mkexpr(ccMIPS), mkU32(0x1)));
   1982             /* EQ */
   1983             assign(t1, binop(Iop_And32, binop(Iop_Shr32, mkexpr(ccMIPS),
   1984                    mkU8(0x1)), mkU32(0x1)));
   1985             /* NGT */
   1986             assign(t2, binop(Iop_And32, unop(Iop_Not32, binop(Iop_Shr32,
   1987                    mkexpr(ccMIPS), mkU8(0x2))), mkU32(0x1)));
   1988             /* LT */
   1989             assign(t3, binop(Iop_And32, binop(Iop_Shr32, mkexpr(ccMIPS),
   1990                    mkU8(0x3)), mkU32(0x1)));
   1991 
   1992             switch (cond) {
   1993                case 0x0:
   1994                   setFPUCondCode(mkU32(0), fpc_cc);
   1995                   break;
   1996                case 0x1:
   1997                   setFPUCondCode(mkexpr(t0), fpc_cc);
   1998                   break;
   1999                case 0x2:
   2000                   setFPUCondCode(mkexpr(t1), fpc_cc);
   2001                   break;
   2002                case 0x3:
   2003                   setFPUCondCode(binop(Iop_Or32, mkexpr(t0), mkexpr(t1)),
   2004                                        fpc_cc);
   2005                   break;
   2006                case 0x4:
   2007                   setFPUCondCode(mkexpr(t3), fpc_cc);
   2008                   break;
   2009                case 0x5:
   2010                   setFPUCondCode(binop(Iop_Or32, mkexpr(t0), mkexpr(t3)),
   2011                                        fpc_cc);
   2012                   break;
   2013                case 0x6:
   2014                   setFPUCondCode(binop(Iop_Or32, mkexpr(t3), mkexpr(t1)),
   2015                                        fpc_cc);
   2016                   break;
   2017                case 0x7:
   2018                   setFPUCondCode(mkexpr(t2), fpc_cc);
   2019                   break;
   2020                case 0x8:
   2021                   setFPUCondCode(mkU32(0), fpc_cc);
   2022                   break;
   2023                case 0x9:
   2024                   setFPUCondCode(mkexpr(t0), fpc_cc);
   2025                   break;
   2026                case 0xA:
   2027                   setFPUCondCode(mkexpr(t1), fpc_cc);
   2028                   break;
   2029                case 0xB:
   2030                   setFPUCondCode(binop(Iop_Or32, mkexpr(t0), mkexpr(t1)),
   2031                                        fpc_cc);
   2032                   break;
   2033                case 0xC:
   2034                   setFPUCondCode(mkexpr(t3), fpc_cc);
   2035                   break;
   2036                case 0xD:
   2037                   setFPUCondCode(binop(Iop_Or32, mkexpr(t0), mkexpr(t3)),
   2038                                        fpc_cc);
   2039                   break;
   2040                case 0xE:
   2041                   setFPUCondCode(binop(Iop_Or32, mkexpr(t3), mkexpr(t1)),
   2042                                        fpc_cc);
   2043                   break;
   2044                case 0xF:
   2045                   setFPUCondCode(mkexpr(t2), fpc_cc);
   2046                   break;
   2047                default:
   2048                   return False;
   2049             }
   2050          }
   2051          break;
   2052 
   2053          default:
   2054             return False;
   2055       }
   2056    } else {
   2057       return False;
   2058    }
   2059 
   2060    return True;
   2061 }
   2062 
   2063 /*********************************************************/
   2064 /*---        Branch Instructions for mips64           ---*/
   2065 /*********************************************************/
   2066 static Bool dis_instr_branch ( UInt theInstr, DisResult * dres,
   2067                                Bool(*resteerOkFn) (void *, Addr),
   2068                                void *callback_opaque, IRStmt ** set )
   2069 {
   2070    UInt jmpKind = 0;
   2071    UChar opc1 = get_opcode(theInstr);
   2072    UChar regRs = get_rs(theInstr);
   2073    UChar regRt = get_rt(theInstr);
   2074    UInt offset = get_imm(theInstr);
   2075    Long sOffset = extend_s_16to64(offset);
   2076    IRType ty = mode64 ? Ity_I64 : Ity_I32;
   2077    IROp opSlt = mode64 ? Iop_CmpLT64S : Iop_CmpLT32S;
   2078 
   2079    IRTemp tmp = newTemp(ty);
   2080    IRTemp tmpRs = newTemp(ty);
   2081    IRTemp tmpRt = newTemp(ty);
   2082    IRTemp tmpLt = newTemp(ty);
   2083    IRTemp tmpReg0 = newTemp(ty);
   2084 
   2085    UChar regLnk = 31;   /* reg 31 is link reg in MIPS */
   2086    Addr64 addrTgt = 0;
   2087    Addr64 cia = guest_PC_curr_instr;
   2088 
   2089    IRExpr *eConst0 = mkSzImm(ty, (UInt) 0);
   2090    IRExpr *eNia = mkSzImm(ty, cia + 8);
   2091    IRExpr *eCond = NULL;
   2092 
   2093    assign(tmpRs, getIReg(regRs));
   2094    assign(tmpRt, getIReg(regRt));
   2095    assign(tmpReg0, getIReg(0));
   2096 
   2097    eCond = binop(mkSzOp(ty, Iop_CmpNE8), mkexpr(tmpReg0), mkexpr(tmpReg0));
   2098 
   2099    switch (opc1) {
   2100       case 0x01:
   2101          switch (regRt) {
   2102             case 0x00: {  /* BLTZ rs, offset */
   2103                addrTgt = mkSzAddr(ty, cia + 4 + (sOffset << 2));
   2104                IRTemp tmpLtRes = newTemp(Ity_I1);
   2105 
   2106                assign(tmp, eConst0);
   2107                assign(tmpLtRes, binop(opSlt, mkexpr(tmpRs), mkexpr(tmp)));
   2108                assign(tmpLt, mode64 ? unop(Iop_1Uto64, mkexpr(tmpLtRes)) :
   2109                       unop(Iop_1Uto32, mkexpr(tmpLtRes)));
   2110 
   2111                eCond = binop(mkSzOp(ty, Iop_CmpNE8), mkexpr(tmpLt),
   2112                              mkexpr(tmpReg0));
   2113 
   2114                jmpKind = Ijk_Boring;
   2115                break;
   2116             }
   2117 
   2118             case 0x01: {  /* BGEZ rs, offset */
   2119                IRTemp tmpLtRes = newTemp(Ity_I1);
   2120                addrTgt = mkSzAddr(ty, cia + 4 + (sOffset << 2));
   2121 
   2122                assign(tmp, eConst0);
   2123                assign(tmpLtRes, binop(opSlt, mkexpr(tmpRs), mkexpr(tmp)));
   2124                assign(tmpLt, mode64 ? unop(Iop_1Uto64, mkexpr(tmpLtRes)) :
   2125                                       unop(Iop_1Uto32, mkexpr(tmpLtRes)));
   2126                eCond = binop(mkSzOp(ty, Iop_CmpEQ8), mkexpr(tmpLt),
   2127                                     mkexpr(tmpReg0));
   2128 
   2129                jmpKind = Ijk_Boring;
   2130                break;
   2131             }
   2132 
   2133             case 0x11: {  /* BGEZAL rs, offset */
   2134                addrTgt = mkSzAddr(ty, cia + 4 + (sOffset << 2));
   2135                putIReg(regLnk, eNia);
   2136                IRTemp tmpLtRes = newTemp(Ity_I1);
   2137 
   2138                assign(tmpLtRes, binop(opSlt, mkexpr(tmpRs), eConst0));
   2139                assign(tmpLt, mode64 ? unop(Iop_1Uto64, mkexpr(tmpLtRes)) :
   2140                                       unop(Iop_1Uto32, mkexpr(tmpLtRes)));
   2141 
   2142                eCond = binop(mkSzOp(ty, Iop_CmpEQ8), mkexpr(tmpLt),
   2143                                     mkexpr(tmpReg0));
   2144 
   2145                jmpKind = Ijk_Call;
   2146                break;
   2147             }
   2148 
   2149             case 0x10: {  /* BLTZAL rs, offset */
   2150                IRTemp tmpLtRes = newTemp(Ity_I1);
   2151                IRTemp tmpRes = newTemp(ty);
   2152 
   2153                addrTgt = mkSzAddr(ty, cia + 4 + (sOffset << 2));
   2154                putIReg(regLnk, eNia);
   2155 
   2156                assign(tmp, eConst0);
   2157                assign(tmpLtRes, binop(opSlt, mkexpr(tmpRs), mkexpr(tmp)));
   2158                assign(tmpRes, mode64 ? unop(Iop_1Uto64,
   2159                       mkexpr(tmpLtRes)) : unop(Iop_1Uto32, mkexpr(tmpLtRes)));
   2160                eCond = binop(mkSzOp(ty, Iop_CmpNE8), mkexpr(tmpRes),
   2161                                                      mkexpr(tmpReg0));
   2162 
   2163                jmpKind = Ijk_Call;
   2164                break;
   2165             }
   2166 
   2167          }
   2168          break;
   2169       default:
   2170          return False;
   2171       }
   2172    *set = IRStmt_Exit(eCond, jmpKind, mkSzConst(ty, addrTgt), OFFB_PC);
   2173    return True;
   2174 }
   2175 
   2176 /*********************************************************/
   2177 /*---         Cavium Specific Instructions            ---*/
   2178 /*********************************************************/
   2179 
   2180 /* Convenience function to yield to thread scheduler */
   2181 static void jump_back(IRExpr *condition)
   2182 {
   2183    stmt( IRStmt_Exit(condition,
   2184                      Ijk_Yield,
   2185                      IRConst_U64( guest_PC_curr_instr ),
   2186                      OFFB_PC) );
   2187 }
   2188 
   2189 /* Based on s390_irgen_load_and_add32. */
   2190 static void mips_irgen_load_and_add32(IRTemp op1addr, IRTemp new_val,
   2191                                       UChar rd, Bool putIntoRd)
   2192 {
   2193    IRCAS *cas;
   2194    IRTemp old_mem = newTemp(Ity_I32);
   2195    IRTemp expd    = newTemp(Ity_I32);
   2196 
   2197    assign(expd, load(Ity_I32, mkexpr(op1addr)));
   2198 
   2199    cas = mkIRCAS(IRTemp_INVALID, old_mem,
   2200                  Iend_LE, mkexpr(op1addr),
   2201                  NULL, mkexpr(expd), /* expected value */
   2202                  NULL, mkexpr(new_val)  /* new value */);
   2203    stmt(IRStmt_CAS(cas));
   2204 
   2205    /* If old_mem contains the expected value, then the CAS succeeded.
   2206       Otherwise, it did not */
   2207    jump_back(binop(Iop_CmpNE32, mkexpr(old_mem), mkexpr(expd)));
   2208    if (putIntoRd)
   2209       putIReg(rd, mkWidenFrom32(Ity_I64, mkexpr(old_mem), True));
   2210 }
   2211 
   2212 /* Based on s390_irgen_load_and_add64. */
   2213 static void mips_irgen_load_and_add64(IRTemp op1addr, IRTemp new_val,
   2214                                       UChar rd, Bool putIntoRd)
   2215 {
   2216    IRCAS *cas;
   2217    IRTemp old_mem = newTemp(Ity_I64);
   2218    IRTemp expd    = newTemp(Ity_I64);
   2219 
   2220    assign(expd, load(Ity_I64, mkexpr(op1addr)));
   2221 
   2222    cas = mkIRCAS(IRTemp_INVALID, old_mem,
   2223                  Iend_LE, mkexpr(op1addr),
   2224                  NULL, mkexpr(expd), /* expected value */
   2225                  NULL, mkexpr(new_val)  /* new value */);
   2226    stmt(IRStmt_CAS(cas));
   2227 
   2228    /* If old_mem contains the expected value, then the CAS succeeded.
   2229       Otherwise, it did not */
   2230    jump_back(binop(Iop_CmpNE64, mkexpr(old_mem), mkexpr(expd)));
   2231    if (putIntoRd)
   2232       putIReg(rd, mkexpr(old_mem));
   2233 }
   2234 
   2235 static Bool dis_instr_CVM ( UInt theInstr )
   2236 {
   2237    UChar  opc2     = get_function(theInstr);
   2238    UChar  opc1     = get_opcode(theInstr);
   2239    UChar  regRs    = get_rs(theInstr);
   2240    UChar  regRt    = get_rt(theInstr);
   2241    UChar  regRd    = get_rd(theInstr);
   2242    /* MIPS trap instructions extract code from theInstr[15:6].
   2243       Cavium OCTEON instructions SNEI, SEQI extract immediate operands
   2244       from the same bit field [15:6]. */
   2245    UInt   imm      = get_code(theInstr);
   2246    UChar  lenM1    = get_msb(theInstr);
   2247    UChar  p        = get_lsb(theInstr);
   2248    IRType ty       = mode64? Ity_I64 : Ity_I32;
   2249    IRTemp tmp      = newTemp(ty);
   2250    IRTemp tmpRs    = newTemp(ty);
   2251    IRTemp tmpRt    = newTemp(ty);
   2252    IRTemp t1       = newTemp(ty);
   2253    UInt size;
   2254    assign(tmpRs, getIReg(regRs));
   2255 
   2256    switch(opc1) {
   2257       case 0x1C: {
   2258          switch(opc2) {
   2259             case 0x03: {  /* DMUL rd, rs, rt */
   2260                DIP("dmul r%d, r%d, r%d", regRd, regRs, regRt);
   2261                IRTemp t0 = newTemp(Ity_I128);
   2262                assign(t0, binop(Iop_MullU64, getIReg(regRs), getIReg(regRt)));
   2263                putIReg(regRd, unop(Iop_128to64, mkexpr(t0)));
   2264                break;
   2265             }
   2266 
   2267             case 0x18: {  /* Store Atomic Add Word - SAA; Cavium OCTEON */
   2268                DIP("saa r%u, (r%u)", regRt, regRs);
   2269                IRTemp addr = newTemp(Ity_I64);
   2270                IRTemp new  = newTemp(Ity_I32);
   2271                assign (addr, getIReg(regRs));
   2272                assign(new, binop(Iop_Add32,
   2273                                  load(Ity_I32, mkexpr(addr)),
   2274                                  mkNarrowTo32(ty, getIReg(regRt))));
   2275                mips_irgen_load_and_add32(addr, new, 0, False);
   2276                break;
   2277             }
   2278 
   2279             /* Store Atomic Add Doubleword - SAAD; Cavium OCTEON */
   2280             case 0x19: {
   2281                DIP( "saad r%u, (r%u)", regRt, regRs);
   2282                IRTemp addr = newTemp(Ity_I64);
   2283                IRTemp new  = newTemp(Ity_I64);
   2284                assign (addr, getIReg(regRs));
   2285                assign(new, binop(Iop_Add64,
   2286                                  load(Ity_I64, mkexpr(addr)),
   2287                                  getIReg(regRt)));
   2288                mips_irgen_load_and_add64(addr, new, 0, False);
   2289                break;
   2290             }
   2291 
   2292             /* LAI, LAID, LAD, LADD, LAS, LASD,
   2293                LAC, LACD, LAA, LAAD, LAW, LAWD */
   2294             case 0x1f: {
   2295                UInt opc3 = get_sa(theInstr);
   2296                IRTemp addr = newTemp(Ity_I64);
   2297                switch (opc3) {
   2298                   /* Load Atomic Increment Word - LAI; Cavium OCTEON2 */
   2299                   case 0x02: {
   2300                      DIP("lai r%u,(r%u)\n", regRd, regRs);
   2301                      IRTemp new  = newTemp(Ity_I32);
   2302                      assign(addr, getIReg(regRs));
   2303                      assign(new, binop(Iop_Add32,
   2304                                        load(Ity_I32, mkexpr(addr)),
   2305                                        mkU32(1)));
   2306                      mips_irgen_load_and_add32(addr, new, regRd, True);
   2307                      break;
   2308                   }
   2309                   /* Load Atomic Increment Doubleword - LAID; Cavium OCTEON2 */
   2310                   case 0x03: {
   2311                      DIP("laid r%u,(r%u)\n", regRd, regRs);
   2312                      IRTemp new  = newTemp(Ity_I64);
   2313                      assign(addr, getIReg(regRs));
   2314                      assign(new, binop(Iop_Add64,
   2315                                        load(Ity_I64, mkexpr(addr)),
   2316                                        mkU64(1)));
   2317                      mips_irgen_load_and_add64(addr, new, regRd, True);
   2318                      break;
   2319                   }
   2320                   /* Load Atomic Decrement Word - LAD; Cavium OCTEON2 */
   2321                   case 0x06: {
   2322                      DIP("lad r%u,(r%u)\n", regRd, regRs);
   2323                      IRTemp new  = newTemp(Ity_I32);
   2324                      assign(addr, getIReg(regRs));
   2325                      assign(new, binop(Iop_Sub32,
   2326                                        load(Ity_I32, mkexpr(addr)),
   2327                                        mkU32(1)));
   2328                      mips_irgen_load_and_add32(addr, new, regRd, True);
   2329                      break;
   2330                   }
   2331                   /* Load Atomic Decrement Doubleword - LADD; Cavium OCTEON2 */
   2332                   case 0x07: {
   2333                      DIP("ladd r%u,(r%u)\n", regRd, regRs);
   2334                      IRTemp new  = newTemp(Ity_I64);
   2335                      assign (addr, getIReg(regRs));
   2336                      assign(new, binop(Iop_Sub64,
   2337                                        load(Ity_I64, mkexpr(addr)),
   2338                                        mkU64(1)));
   2339                      mips_irgen_load_and_add64(addr, new, regRd, True);
   2340                      break;
   2341                   }
   2342                   /* Load Atomic Set Word - LAS; Cavium OCTEON2 */
   2343                   case 0x0a: {
   2344                      DIP("las r%u,(r%u)\n", regRd, regRs);
   2345                      IRTemp new  = newTemp(Ity_I32);
   2346                      assign(addr, getIReg(regRs));
   2347                      assign(new, mkU32(0xffffffff));
   2348                      mips_irgen_load_and_add32(addr, new, regRd, True);
   2349                      break;
   2350                   }
   2351                   /* Load Atomic Set Doubleword - LASD; Cavium OCTEON2 */
   2352                   case 0x0b: {
   2353                      DIP("lasd r%u,(r%u)\n", regRd, regRs);
   2354                      IRTemp new  = newTemp(Ity_I64);
   2355                      assign (addr, getIReg(regRs));
   2356                      assign(new, mkU64(0xffffffffffffffffULL));
   2357                      mips_irgen_load_and_add64(addr, new, regRd, True);
   2358                      break;
   2359                   }
   2360                   /* Load Atomic Clear Word - LAC; Cavium OCTEON2 */
   2361                   case 0x0e: {
   2362                      DIP("lac r%u,(r%u)\n", regRd, regRs);
   2363                      IRTemp new  = newTemp(Ity_I32);
   2364                      assign (addr, getIReg(regRs));
   2365                      assign(new, mkU32(0));
   2366                      mips_irgen_load_and_add32(addr, new, regRd, True);
   2367                      break;
   2368                   }
   2369                   /* Load Atomic Clear Doubleword - LACD; Cavium OCTEON2 */
   2370                   case 0x0f: {
   2371                      DIP("lacd r%u,(r%u)\n", regRd, regRs);
   2372                      IRTemp new  = newTemp(Ity_I64);
   2373                      assign(addr, getIReg(regRs));
   2374                      assign(new, mkU64(0));
   2375                      mips_irgen_load_and_add64(addr, new, regRd, True);
   2376                      break;
   2377                   }
   2378                   /* Load Atomic Add Word - LAA; Cavium OCTEON2 */
   2379                   case 0x12: {
   2380                      DIP("laa r%u,(r%u),r%u\n", regRd, regRs, regRt);
   2381                      IRTemp new  = newTemp(Ity_I32);
   2382                      assign(addr, getIReg(regRs));
   2383                      assign(new, binop(Iop_Add32,
   2384                                        load(Ity_I32, mkexpr(addr)),
   2385                                        mkNarrowTo32(ty, getIReg(regRt))));
   2386                      mips_irgen_load_and_add32(addr, new, regRd, True);
   2387                      break;
   2388                   }
   2389                   /* Load Atomic Add Doubleword - LAAD; Cavium OCTEON2 */
   2390                   case 0x13: {
   2391                      DIP("laad r%u,(r%u),r%u\n", regRd, regRs, regRt);
   2392                      IRTemp new  = newTemp(Ity_I64);
   2393                      assign (addr, getIReg(regRs));
   2394                      assign(new, binop(Iop_Add64,
   2395                                        load(Ity_I64, mkexpr(addr)),
   2396                                        getIReg(regRt)));
   2397                      mips_irgen_load_and_add64(addr, new, regRd, True);
   2398                      break;
   2399                   }
   2400                   /* Load Atomic Swap Word - LAW; Cavium OCTEON2 */
   2401                   case 0x16: {
   2402                      DIP("law r%u,(r%u)\n", regRd, regRs);
   2403                      IRTemp new  = newTemp(Ity_I32);
   2404                      assign(addr, getIReg(regRs));
   2405                      assign(new, mkNarrowTo32(ty, getIReg(regRt)));
   2406                      mips_irgen_load_and_add32(addr, new, regRd, True);
   2407                      break;
   2408                   }
   2409                   /* Load Atomic Swap Doubleword - LAWD; Cavium OCTEON2 */
   2410                   case 0x17: {
   2411                      DIP("lawd r%u,(r%u)\n", regRd, regRs);
   2412                      IRTemp new  = newTemp(Ity_I64);
   2413                      assign(addr, getIReg(regRs));
   2414                      assign(new, getIReg(regRt));
   2415                      mips_irgen_load_and_add64(addr, new, regRd, True);
   2416                      break;
   2417                   }
   2418                   default:
   2419                      vex_printf("Unknown laxx instruction, opc3=0x%x\n", opc3);
   2420                      vex_printf("Instruction=0x%08x\n", theInstr);
   2421                      return False;
   2422                }
   2423                break;
   2424             }
   2425 
   2426             /* Unsigned Byte Add - BADDU rd, rs, rt; Cavium OCTEON */
   2427             case 0x28: {
   2428                DIP("BADDU r%d, r%d, r%d", regRs, regRt, regRd);
   2429                IRTemp t0 = newTemp(Ity_I8);
   2430 
   2431                assign(t0, binop(Iop_Add8,
   2432                                 mkNarrowTo8(ty, getIReg(regRs)),
   2433                                 mkNarrowTo8(ty, getIReg(regRt))));
   2434 
   2435                if (mode64)
   2436                   putIReg(regRd, binop(mkSzOp(ty, Iop_And8),
   2437                                        unop(Iop_8Uto64, mkexpr(t0)),
   2438                                        mkSzImm(ty, 0xFF)));
   2439                else
   2440                   putIReg(regRd, binop(mkSzOp(ty, Iop_And8),
   2441                                        unop(Iop_8Uto32, mkexpr(t0)),
   2442                                        mkSzImm(ty, 0xFF)));
   2443                break;
   2444             }
   2445 
   2446             case 0x2c: {  /* Count Ones in a Word - POP; Cavium OCTEON */
   2447                int i, shift[5];
   2448                IRTemp mask[5];
   2449                IRTemp old = newTemp(ty);
   2450                IRTemp nyu = IRTemp_INVALID;
   2451                assign(old, getIReg(regRs));
   2452                DIP("pop r%d, r%d", regRd, regRs);
   2453 
   2454                for (i = 0; i < 5; i++) {
   2455                   mask[i] = newTemp(ty);
   2456                   shift[i] = 1 << i;
   2457                }
   2458                if(mode64) {
   2459                   assign(mask[0], mkU64(0x0000000055555555));
   2460                   assign(mask[1], mkU64(0x0000000033333333));
   2461                   assign(mask[2], mkU64(0x000000000F0F0F0F));
   2462                   assign(mask[3], mkU64(0x0000000000FF00FF));
   2463                   assign(mask[4], mkU64(0x000000000000FFFF));
   2464 
   2465                   for (i = 0; i < 5; i++) {
   2466                      nyu = newTemp(ty);
   2467                      assign(nyu,
   2468                             binop(Iop_Add64,
   2469                                   binop(Iop_And64,
   2470                                         mkexpr(old), mkexpr(mask[i])),
   2471                                   binop(Iop_And64,
   2472                                         binop(Iop_Shr64,
   2473                                               mkexpr(old), mkU8(shift[i])),
   2474                                         mkexpr(mask[i]))));
   2475                      old = nyu;
   2476                   }
   2477                } else {
   2478                   assign(mask[0], mkU32(0x55555555));
   2479                   assign(mask[1], mkU32(0x33333333));
   2480                   assign(mask[2], mkU32(0x0F0F0F0F));
   2481                   assign(mask[3], mkU32(0x00FF00FF));
   2482                   assign(mask[4], mkU32(0x0000FFFF));
   2483                   assign(old, getIReg(regRs));
   2484 
   2485                   for (i = 0; i < 5; i++) {
   2486                      nyu = newTemp(ty);
   2487                      assign(nyu,
   2488                             binop(Iop_Add32,
   2489                                   binop(Iop_And32,
   2490                                         mkexpr(old), mkexpr(mask[i])),
   2491                                   binop(Iop_And32,
   2492                                         binop(Iop_Shr32,
   2493                                               mkexpr(old), mkU8(shift[i])),
   2494                                         mkexpr(mask[i]))));
   2495                      old = nyu;
   2496                   }
   2497                }
   2498                putIReg(regRd, mkexpr(nyu));
   2499                break;
   2500             }
   2501 
   2502             /* Count Ones in a Doubleword - DPOP; Cavium OCTEON */
   2503             case 0x2d: {
   2504                int i, shift[6];
   2505                IRTemp mask[6];
   2506                IRTemp old = newTemp(ty);
   2507                IRTemp nyu = IRTemp_INVALID;
   2508                DIP("dpop r%d, r%d", regRd, regRs);
   2509 
   2510                for (i = 0; i < 6; i++) {
   2511                   mask[i] = newTemp(ty);
   2512                   shift[i] = 1 << i;
   2513                }
   2514                vassert(mode64); /*Caution! Only for Mode 64*/
   2515                assign(mask[0], mkU64(0x5555555555555555ULL));
   2516                assign(mask[1], mkU64(0x3333333333333333ULL));
   2517                assign(mask[2], mkU64(0x0F0F0F0F0F0F0F0FULL));
   2518                assign(mask[3], mkU64(0x00FF00FF00FF00FFULL));
   2519                assign(mask[4], mkU64(0x0000FFFF0000FFFFULL));
   2520                assign(mask[5], mkU64(0x00000000FFFFFFFFULL));
   2521                assign(old, getIReg(regRs));
   2522                for (i = 0; i < 6; i++) {
   2523                   nyu = newTemp(Ity_I64);
   2524                   assign(nyu,
   2525                          binop(Iop_Add64,
   2526                                binop(Iop_And64,
   2527                                      mkexpr(old), mkexpr(mask[i])),
   2528                                binop(Iop_And64,
   2529                                      binop(Iop_Shr64,
   2530                                            mkexpr(old), mkU8(shift[i])),
   2531                                      mkexpr(mask[i]))));
   2532                   old = nyu;
   2533                }
   2534                putIReg(regRd, mkexpr(nyu));
   2535                break;
   2536             }
   2537 
   2538             case 0x32:  /* 5. CINS rd, rs, p, lenm1 */
   2539                DIP("cins r%u, r%u, %d, %d\n", regRt, regRs, p, lenM1);
   2540                assign ( tmp  , binop(Iop_Shl64, mkexpr(tmpRs),
   2541                                      mkU8(64-( lenM1+1 ))));
   2542                assign ( tmpRt, binop(Iop_Shr64, mkexpr( tmp ),
   2543                                      mkU8(64-(p+lenM1+1))));
   2544                putIReg( regRt, mkexpr(tmpRt));
   2545                break;
   2546 
   2547             case 0x33:  /* 6. CINS32 rd, rs, p+32, lenm1 */
   2548                DIP("cins32 r%u, r%u, %d, %d\n", regRt, regRs, p+32, lenM1);
   2549                assign ( tmp  , binop(Iop_Shl64, mkexpr(tmpRs),
   2550                                      mkU8(64-( lenM1+1 ))));
   2551                assign ( tmpRt, binop(Iop_Shr64, mkexpr( tmp ),
   2552                                      mkU8(32-(p+lenM1+1))));
   2553                putIReg( regRt, mkexpr(tmpRt));
   2554                break;
   2555 
   2556             case 0x3A:  /* 3. EXTS rt, rs, p len */
   2557                DIP("exts r%u, r%u, %d, %d\n", regRt, regRs, p, lenM1);
   2558                size = lenM1 + 1;  /* lenm1+1 */
   2559                UChar lsAmt = 64 - (p + size);  /* p+lenm1+1 */
   2560                UChar rsAmt = 64 - size;  /* lenm1+1 */
   2561                tmp = newTemp(Ity_I64);
   2562                assign(tmp, binop(Iop_Shl64, mkexpr(tmpRs), mkU8(lsAmt)));
   2563                putIReg(regRt, binop(Iop_Sar64, mkexpr(tmp), mkU8(rsAmt)));
   2564                break;
   2565 
   2566             case 0x3B:  /* 4. EXTS32 rt, rs, p len */
   2567                DIP("exts32 r%u, r%u, %d, %d\n", regRt, regRs, p, lenM1);
   2568                assign ( tmp  , binop(Iop_Shl64, mkexpr(tmpRs),
   2569                                      mkU8(32-(p+lenM1+1))));
   2570                assign ( tmpRt, binop(Iop_Sar64, mkexpr(tmp),
   2571                                      mkU8(64-(lenM1+1))) );
   2572                putIReg( regRt, mkexpr(tmpRt));
   2573                break;
   2574 
   2575             case 0x2B:  /* 20. SNE rd, rs, rt */
   2576                DIP("sne r%d, r%d, r%d", regRd,regRs, regRt);
   2577                if (mode64)
   2578                   putIReg(regRd, unop(Iop_1Uto64, binop(Iop_CmpNE64,
   2579                                                         getIReg(regRs),
   2580                                                         getIReg(regRt))));
   2581                else
   2582                   putIReg(regRd,unop(Iop_1Uto32, binop(Iop_CmpNE32,
   2583                                                        getIReg(regRs),
   2584                                                        getIReg(regRt))));
   2585                break;
   2586 
   2587             case 0x2A:  /* Set Equals - SEQ; Cavium OCTEON */
   2588                DIP("seq r%d, r%d, %d", regRd, regRs, regRt);
   2589                if (mode64)
   2590                   putIReg(regRd, unop(Iop_1Uto64,
   2591                                       binop(Iop_CmpEQ64, getIReg(regRs),
   2592                                             getIReg(regRt))));
   2593                else
   2594                   putIReg(regRd, unop(Iop_1Uto32,
   2595                                       binop(Iop_CmpEQ32, getIReg(regRs),
   2596                                             getIReg(regRt))));
   2597                break;
   2598 
   2599             case 0x2E:  /* Set Equals Immediate - SEQI; Cavium OCTEON */
   2600                DIP("seqi r%d, r%d, %d", regRt, regRs, imm);
   2601                if (mode64)
   2602                   putIReg(regRt, unop(Iop_1Uto64,
   2603                                       binop(Iop_CmpEQ64, getIReg(regRs),
   2604                                             mkU64(extend_s_10to64(imm)))));
   2605                else
   2606                   putIReg(regRt, unop(Iop_1Uto32,
   2607                                       binop(Iop_CmpEQ32, getIReg(regRs),
   2608                                             mkU32(extend_s_10to32(imm)))));
   2609                break;
   2610 
   2611             case 0x2F:  /* Set Not Equals Immediate - SNEI; Cavium OCTEON */
   2612                DIP("snei r%d, r%d, %d", regRt, regRs, imm);
   2613                if (mode64)
   2614                   putIReg(regRt, unop(Iop_1Uto64,
   2615                                    binop(Iop_CmpNE64,
   2616                                          getIReg(regRs),
   2617                                          mkU64(extend_s_10to64(imm)))));
   2618                else
   2619                   putIReg(regRt, unop(Iop_1Uto32,
   2620                                    binop(Iop_CmpNE32,
   2621                                          getIReg(regRs),
   2622                                          mkU32(extend_s_10to32(imm)))));
   2623                break;
   2624 
   2625             default:
   2626                return False;
   2627          }
   2628          break;
   2629       } /* opc1 0x1C ends here*/
   2630       case 0x1F: {
   2631          switch(opc2) {
   2632             case 0x0A: {  // lx - Load indexed instructions
   2633                switch (get_sa(theInstr)) {
   2634                   case 0x00: {  // LWX rd, index(base)
   2635                      DIP("lwx r%d, r%d(r%d)", regRd, regRt, regRs);
   2636                      LOADX_STORE_PATTERN;
   2637                      putIReg(regRd, mkWidenFrom32(ty, load(Ity_I32, mkexpr(t1)),
   2638                                                   True));
   2639                      break;
   2640                   }
   2641                   case 0x08: {  // LDX rd, index(base)
   2642                      DIP("ldx r%d, r%d(r%d)", regRd, regRt, regRs);
   2643                      vassert(mode64); /* Currently Implemented only for n64 */
   2644                      LOADX_STORE_PATTERN;
   2645                      putIReg(regRd, load(Ity_I64, mkexpr(t1)));
   2646                      break;
   2647                   }
   2648                   case 0x06: {  // LBUX rd, index(base)
   2649                      DIP("lbux r%d, r%d(r%d)", regRd, regRt, regRs);
   2650                      LOADX_STORE_PATTERN;
   2651                      if (mode64)
   2652                         putIReg(regRd, unop(Iop_8Uto64, load(Ity_I8,
   2653                                                              mkexpr(t1))));
   2654                      else
   2655                         putIReg(regRd, unop(Iop_8Uto32, load(Ity_I8,
   2656                                                              mkexpr(t1))));
   2657                      break;
   2658                   }
   2659                   case 0x10: {  // LWUX rd, index(base) (Cavium OCTEON)
   2660                      DIP("lwux r%d, r%d(r%d)", regRd, regRt, regRs);
   2661                      LOADX_STORE_PATTERN; /* same for both 32 and 64 modes*/
   2662                      putIReg(regRd, mkWidenFrom32(ty, load(Ity_I32, mkexpr(t1)),
   2663                                                   False));
   2664                      break;
   2665                   }
   2666                   case 0x14: {  // LHUX rd, index(base) (Cavium OCTEON)
   2667                      DIP("lhux r%d, r%d(r%d)", regRd, regRt, regRs);
   2668                      LOADX_STORE_PATTERN;
   2669                      if (mode64)
   2670                         putIReg(regRd,
   2671                                 unop(Iop_16Uto64, load(Ity_I16, mkexpr(t1))));
   2672                      else
   2673                         putIReg(regRd,
   2674                                 unop(Iop_16Uto32, load(Ity_I16, mkexpr(t1))));
   2675                      break;
   2676                   }
   2677                   case 0x16: {  // LBX rd, index(base) (Cavium OCTEON)
   2678                      DIP("lbx r%d, r%d(r%d)", regRd, regRs, regRt);
   2679                      LOADX_STORE_PATTERN;
   2680                      if (mode64)
   2681                         putIReg(regRd,
   2682                                 unop(Iop_8Sto64, load(Ity_I8, mkexpr(t1))));
   2683                      else
   2684                         putIReg(regRd,
   2685                                 unop(Iop_8Sto32, load(Ity_I8, mkexpr(t1))));
   2686                      break;
   2687                   }
   2688                   default:
   2689                      vex_printf("\nUnhandled LX instruction opc3 = %x\n",
   2690                                 get_sa(theInstr));
   2691                      return False;
   2692                }
   2693                break;
   2694             }
   2695          } /* opc1 = 0x1F & opc2 = 0xA (LX) ends here*/
   2696          break;
   2697       } /* opc1 = 0x1F ends here*/
   2698       default:
   2699          return False;
   2700    } /* main opc1 switch ends here */
   2701    return True;
   2702 }
   2703 
   2704 /*------------------------------------------------------------*/
   2705 /*---       Disassemble a single DSP ASE instruction       ---*/
   2706 /*------------------------------------------------------------*/
   2707 
   2708 static UInt disDSPInstr_MIPS_WRK ( UInt cins )
   2709 {
   2710    IRTemp t0, t1 = 0, t2, t3, t4, t5, t6, t7, t8, t9, t10, t11, t12, t13, t14,
   2711           t15, t16, t17;
   2712    UInt opcode, rs, rt, rd, sa, function, ac, ac_mfhilo, rddsp_mask,
   2713         wrdsp_mask, dsp_imm, shift;
   2714 
   2715    opcode = get_opcode(cins);
   2716    rs = get_rs(cins);
   2717    rt = get_rt(cins);
   2718    rd = get_rd(cins);
   2719    sa = get_sa(cins);
   2720    function = get_function(cins);
   2721    ac = get_acNo(cins);
   2722    ac_mfhilo = get_acNo_mfhilo(cins);
   2723    rddsp_mask = get_rddspMask(cins);
   2724    wrdsp_mask = get_wrdspMask(cins);
   2725    dsp_imm = get_dspImm(cins);
   2726    shift = get_shift(cins);
   2727 
   2728    switch (opcode) {
   2729       case 0x00: {  /* Special */
   2730          switch (function) {
   2731             case 0x10: {  /* MFHI */
   2732                DIP("mfhi ac%d r%d", ac_mfhilo, rd);
   2733                putIReg(rd, unop(Iop_64HIto32, getAcc(ac_mfhilo)));
   2734                break;
   2735             }
   2736 
   2737             case 0x11: {  /* MTHI */
   2738                DIP("mthi ac%d r%d", ac, rs);
   2739                t1 = newTemp(Ity_I32);
   2740                assign(t1, unop(Iop_64to32, getAcc(ac)));
   2741                putAcc(ac, binop(Iop_32HLto64, getIReg(rs), mkexpr(t1)));
   2742                break;
   2743             }
   2744 
   2745             case 0x12: {  /* MFLO */
   2746                DIP("mflo ac%d r%d", ac_mfhilo, rd);
   2747                putIReg(rd, unop(Iop_64to32, getAcc(ac_mfhilo)));
   2748                break;
   2749             }
   2750 
   2751             case 0x13: {  /* MTLO */
   2752                DIP("mtlo ac%d r%d", ac, rs);
   2753                t1 = newTemp(Ity_I32);
   2754                assign(t1, unop(Iop_64HIto32, getAcc(ac)));
   2755                putAcc(ac, binop(Iop_32HLto64, mkexpr(t1), getIReg(rs)));
   2756                break;
   2757             }
   2758 
   2759             case 0x18: {  /* MULT */
   2760                DIP("mult ac%d r%d, r%d", ac, rs, rt);
   2761                t1 = newTemp(Ity_I64);
   2762                assign(t1, binop(Iop_MullS32, mkNarrowTo32(Ity_I32, getIReg(rs)),
   2763                                 mkNarrowTo32(Ity_I32, getIReg(rt))));
   2764                putAcc(ac, mkexpr(t1));
   2765                break;
   2766             }
   2767 
   2768             case 0x19: {  /* MULTU */
   2769                DIP("multu ac%d r%d, r%d", ac, rs, rt);
   2770                t1 = newTemp(Ity_I64);
   2771                assign(t1, binop(Iop_MullU32, mkNarrowTo32(Ity_I32, getIReg(rs)),
   2772                                              mkNarrowTo32(Ity_I32,
   2773                                                           getIReg(rt))));
   2774                putAcc(ac, mkexpr(t1));
   2775             break;
   2776             }
   2777          }
   2778          break;
   2779       }
   2780       case 0x1C: {  /* Special2 */
   2781          switch (function) {
   2782             case 0x00: {  /* MADD */
   2783                DIP("madd ac%d, r%d, r%d", ac, rs, rt);
   2784                t1 = newTemp(Ity_I64);
   2785                t2 = newTemp(Ity_I64);
   2786                t3 = newTemp(Ity_I64);
   2787 
   2788                assign(t1, getAcc(ac));
   2789                assign(t2, binop(Iop_MullS32, getIReg(rs), getIReg(rt)));
   2790                assign(t3, binop(Iop_Add64, mkexpr(t1), mkexpr(t2)));
   2791 
   2792                putAcc(ac, mkexpr(t3));
   2793                break;
   2794             }
   2795             case 0x01: {  /* MADDU */
   2796                DIP("maddu ac%d r%d, r%d", ac, rs, rt);
   2797                t1 = newTemp(Ity_I64);
   2798                t2 = newTemp(Ity_I64);
   2799                t3 = newTemp(Ity_I64);
   2800 
   2801                assign(t1, getAcc(ac));
   2802                assign(t2, binop(Iop_MullU32, getIReg(rs), getIReg(rt)));
   2803                assign(t3, binop(Iop_Add64, mkexpr(t2), mkexpr(t1)));
   2804 
   2805                putAcc(ac, mkexpr(t3));
   2806                break;
   2807             }
   2808             case 0x04: {  /* MSUB */
   2809                DIP("msub ac%d r%d, r%d", ac, rs, rt);
   2810                t1 = newTemp(Ity_I64);
   2811                t2 = newTemp(Ity_I64);
   2812                t3 = newTemp(Ity_I64);
   2813 
   2814                assign(t1, getAcc(ac));
   2815                assign(t2, binop(Iop_MullS32, getIReg(rs), getIReg(rt)));
   2816                assign(t3, binop(Iop_Sub64, mkexpr(t1), mkexpr(t2)));
   2817 
   2818                putAcc(ac, mkexpr(t3));
   2819                break;
   2820             }
   2821             case 0x05: {  /* MSUBU */
   2822                DIP("msubu ac%d r%d, r%d", ac, rs, rt);
   2823                t1 = newTemp(Ity_I64);
   2824                t2 = newTemp(Ity_I64);
   2825                t3 = newTemp(Ity_I64);
   2826 
   2827                assign(t1, getAcc(ac));
   2828                assign(t2, binop(Iop_MullU32, getIReg(rs), getIReg(rt)));
   2829                assign(t3, binop(Iop_Sub64, mkexpr(t1), mkexpr(t2)));
   2830 
   2831                putAcc(ac, mkexpr(t3));
   2832                break;
   2833             }
   2834          }
   2835          break;
   2836       }
   2837       case 0x1F: {  /* Special3 */
   2838          switch (function) {
   2839             case 0x12: {  /* ABSQ_S.PH */
   2840                switch (sa) {
   2841                   case 0x1: {  /* ABSQ_S.QB */
   2842                      DIP("absq_s.qb r%d, r%d", rd, rt);
   2843                      vassert(!mode64);
   2844                      t0 = newTemp(Ity_I8);
   2845                      t1 = newTemp(Ity_I1);
   2846                      t2 = newTemp(Ity_I1);
   2847                      t3 = newTemp(Ity_I8);
   2848                      t4 = newTemp(Ity_I8);
   2849                      t5 = newTemp(Ity_I1);
   2850                      t6 = newTemp(Ity_I1);
   2851                      t7 = newTemp(Ity_I8);
   2852                      t8 = newTemp(Ity_I8);
   2853                      t9 = newTemp(Ity_I1);
   2854                      t10 = newTemp(Ity_I1);
   2855                      t11 = newTemp(Ity_I8);
   2856                      t12 = newTemp(Ity_I8);
   2857                      t13 = newTemp(Ity_I1);
   2858                      t14 = newTemp(Ity_I1);
   2859                      t15 = newTemp(Ity_I8);
   2860                      t16 = newTemp(Ity_I32);
   2861                      t17 = newTemp(Ity_I32);
   2862 
   2863                      /* Absolute value of the rightmost byte (bits 7-0). */
   2864                      /* t0 - rightmost byte. */
   2865                      assign(t0, unop(Iop_16to8, unop(Iop_32to16, getIReg(rt))));
   2866                      /* t1 holds 1 if t0 is equal to 0x80, or 0 otherwise. */
   2867                      assign(t1, binop(Iop_CmpEQ32,
   2868                                       unop(Iop_8Uto32, mkexpr(t0)),
   2869                                       mkU32(0x00000080)));
   2870                      /* t2 holds 1 if value in t0 is negative, 0 otherwise. */
   2871                      assign(t2, unop(Iop_32to1,
   2872                                      binop(Iop_Shr32,
   2873                                            binop(Iop_And32,
   2874                                                  getIReg(rt),
   2875                                                  mkU32(0x00000080)),
   2876                                            mkU8(0x7))));
   2877                      /* t3 holds abs(t0). */
   2878                      assign(t3, IRExpr_ITE(mkexpr(t1),
   2879                                            mkU8(0x7F),
   2880                                            IRExpr_ITE(mkexpr(t2),
   2881                                                       binop(Iop_Add8,
   2882                                                             unop(Iop_Not8,
   2883                                                                  mkexpr(t0)),
   2884                                                             mkU8(0x1)),
   2885                                                       mkexpr(t0))));
   2886 
   2887                      /* Absolute value of bits 15-8. */
   2888                      /* t4 - input byte. */
   2889                      assign(t4,
   2890                             unop(Iop_16HIto8, unop(Iop_32to16, getIReg(rt))));
   2891                      /* t5 holds 1 if t4 is equal to 0x80, or 0 otherwise. */
   2892                      assign(t5, binop(Iop_CmpEQ32,
   2893                                       unop(Iop_8Uto32, mkexpr(t4)),
   2894                                       mkU32(0x00000080)));
   2895                      /* t6 holds 1 if value in t4 is negative, 0 otherwise. */
   2896                      assign(t6, unop(Iop_32to1,
   2897                                      binop(Iop_Shr32,
   2898                                            binop(Iop_And32,
   2899                                                  getIReg(rt),
   2900                                                  mkU32(0x00008000)),
   2901                                            mkU8(15))));
   2902                      /* t3 holds abs(t4). */
   2903                      assign(t7, IRExpr_ITE(mkexpr(t5),
   2904                                            mkU8(0x7F),
   2905                                            IRExpr_ITE(mkexpr(t6),
   2906                                                       binop(Iop_Add8,
   2907                                                             unop(Iop_Not8,
   2908                                                                  mkexpr(t4)),
   2909                                                             mkU8(0x1)),
   2910                                                       mkexpr(t4))));
   2911 
   2912                      /* Absolute value of bits 23-15. */
   2913                      /* t8 - input byte. */
   2914                      assign(t8,
   2915                             unop(Iop_16to8, unop(Iop_32HIto16, getIReg(rt))));
   2916                      /* t9 holds 1 if t8 is equal to 0x80, or 0 otherwise. */
   2917                      assign(t9, binop(Iop_CmpEQ32,
   2918                                       unop(Iop_8Uto32, mkexpr(t8)),
   2919                                       mkU32(0x00000080)));
   2920                      /* t6 holds 1 if value in t8 is negative, 0 otherwise. */
   2921                      assign(t10, unop(Iop_32to1,
   2922                                       binop(Iop_Shr32,
   2923                                             binop(Iop_And32,
   2924                                                   getIReg(rt),
   2925                                                   mkU32(0x00800000)),
   2926                                             mkU8(23))));
   2927                      /* t3 holds abs(t8). */
   2928                      assign(t11, IRExpr_ITE(mkexpr(t9),
   2929                                             mkU8(0x7F),
   2930                                             IRExpr_ITE(mkexpr(t10),
   2931                                                        binop(Iop_Add8,
   2932                                                              unop(Iop_Not8,
   2933                                                                   mkexpr(t8)),
   2934                                                              mkU8(0x1)),
   2935                                                        mkexpr(t8))));
   2936 
   2937                      /* Absolute value of bits 31-24. */
   2938                      /* t12 - input byte. */
   2939                      assign(t12,
   2940                             unop(Iop_16HIto8, unop(Iop_32HIto16, getIReg(rt))));
   2941                      /* t13 holds 1 if t12 is equal to 0x80, or 0 otherwise. */
   2942                      assign(t13, binop(Iop_CmpEQ32,
   2943                                        unop(Iop_8Uto32, mkexpr(t12)),
   2944                                        mkU32(0x00000080)));
   2945                      /* t14 holds 1 if value in t12 is negative, 0 otherwise. */
   2946                      assign(t14, unop(Iop_32to1,
   2947                                       binop(Iop_Shr32,
   2948                                             binop(Iop_And32,
   2949                                                   getIReg(rt),
   2950                                                   mkU32(0x80000000)),
   2951                                             mkU8(31))));
   2952                      /* t15 holds abs(t12). */
   2953                      assign(t15, IRExpr_ITE(mkexpr(t13),
   2954                                             mkU8(0x7F),
   2955                                             IRExpr_ITE(mkexpr(t14),
   2956                                                        binop(Iop_Add8,
   2957                                                              unop(Iop_Not8,
   2958                                                                   mkexpr(t12)),
   2959                                                              mkU8(0x1)),
   2960                                                        mkexpr(t12))));
   2961 
   2962                      /* t16 holds !0 if any of input bytes is 0x80 or 0
   2963                         otherwise. */
   2964                      assign(t16,
   2965                             binop(Iop_Or32,
   2966                                   binop(Iop_Or32,
   2967                                         binop(Iop_Or32,
   2968                                               unop(Iop_1Sto32, mkexpr(t13)),
   2969                                               unop(Iop_1Sto32, mkexpr(t9))),
   2970                                         unop(Iop_1Sto32, mkexpr(t5))),
   2971                                   unop(Iop_1Sto32, mkexpr(t1))));
   2972 
   2973                      putDSPControl(IRExpr_ITE(binop(Iop_CmpEQ32,
   2974                                                     mkexpr(t16),
   2975                                                     mkU32(0x0)),
   2976                                               getDSPControl(),
   2977                                               binop(Iop_Or32,
   2978                                                     getDSPControl(),
   2979                                                     mkU32(0x00100000))));
   2980 
   2981                      /* t17 = t15|t11|t7|t3 */
   2982                      assign(t17,
   2983                             binop(Iop_16HLto32,
   2984                                   binop(Iop_8HLto16, mkexpr(t15), mkexpr(t11)),
   2985                                   binop(Iop_8HLto16, mkexpr(t7), mkexpr(t3))));
   2986 
   2987                      putIReg(rd, mkexpr(t17));
   2988                      break;
   2989                   }
   2990                   case 0x2: {  /* REPL.QB */
   2991                      DIP("repl.qb r%d, %d", rd, dsp_imm);
   2992                      vassert(!mode64);
   2993 
   2994                      putIReg(rd, mkU32((dsp_imm << 24) | (dsp_imm << 16) |
   2995                                        (dsp_imm << 8) | (dsp_imm)));
   2996                      break;
   2997                   }
   2998                   case 0x3: {  /* REPLV.QB */
   2999                      DIP("replv.qb r%d, r%d", rd, rt);
   3000                      vassert(!mode64);
   3001                      t0 = newTemp(Ity_I8);
   3002 
   3003                      assign(t0, unop(Iop_32to8,
   3004                                 binop(Iop_And32, getIReg(rt), mkU32(0xff))));
   3005                      putIReg(rd,
   3006                              binop(Iop_16HLto32,
   3007                                    binop(Iop_8HLto16, mkexpr(t0), mkexpr(t0)),
   3008                                    binop(Iop_8HLto16, mkexpr(t0), mkexpr(t0))));
   3009                      break;
   3010                   }
   3011                   case 0x4: {  /* PRECEQU.PH.QBL */
   3012                      DIP("precequ.ph.qbl r%d, r%d", rd, rt);
   3013                      vassert(!mode64);
   3014 
   3015                      putIReg(rd, binop(Iop_Or32,
   3016                                        binop(Iop_Shr32,
   3017                                              binop(Iop_And32,
   3018                                                    getIReg(rt),
   3019                                                    mkU32(0xff000000)),
   3020                                              mkU8(1)),
   3021                                        binop(Iop_Shr32,
   3022                                              binop(Iop_And32,
   3023                                                    getIReg(rt),
   3024                                                    mkU32(0x00ff0000)),
   3025                                              mkU8(9))));
   3026                      break;
   3027                   }
   3028                   case 0x5: {  /* PRECEQU.PH.QBR */
   3029                      DIP("precequ.ph.qbr r%d, r%d", rd, rt);
   3030                      vassert(!mode64);
   3031 
   3032                      putIReg(rd, binop(Iop_Or32,
   3033                                        binop(Iop_Shl32,
   3034                                              binop(Iop_And32,
   3035                                                    getIReg(rt),
   3036                                                    mkU32(0x0000ff00)),
   3037                                              mkU8(15)),
   3038                                        binop(Iop_Shl32,
   3039                                              binop(Iop_And32,
   3040                                                    getIReg(rt),
   3041                                                    mkU32(0x000000ff)),
   3042                                              mkU8(7))));
   3043                      break;
   3044                   }
   3045                   case 0x6: {  /* PRECEQU.PH.QBLA */
   3046                      DIP("precequ.ph.qbla r%d, r%d", rd, rt);
   3047                      vassert(!mode64);
   3048 
   3049                      putIReg(rd, binop(Iop_Or32,
   3050                                        binop(Iop_Shr32,
   3051                                              binop(Iop_And32,
   3052                                                    getIReg(rt),
   3053                                                    mkU32(0xff000000)),
   3054                                              mkU8(1)),
   3055                                        binop(Iop_Shr32,
   3056                                              binop(Iop_And32,
   3057                                                    getIReg(rt),
   3058                                                    mkU32(0x0000ff00)),
   3059                                              mkU8(1))));
   3060                      break;
   3061                   }
   3062                   case 0x7: {  /* PRECEQU.PH.QBRA */
   3063                      DIP("precequ.ph.qbra r%d, r%d", rd, rt);
   3064                      vassert(!mode64);
   3065 
   3066                      putIReg(rd, binop(Iop_Or32,
   3067                                        binop(Iop_Shl32,
   3068                                              binop(Iop_And32,
   3069                                                    getIReg(rt),
   3070                                                    mkU32(0x00ff0000)),
   3071                                              mkU8(7)),
   3072                                        binop(Iop_Shl32,
   3073                                              binop(Iop_And32,
   3074                                                    getIReg(rt),
   3075                                                    mkU32(0x000000ff)),
   3076                                              mkU8(7))));
   3077                      break;
   3078                   }
   3079                   case 0x9: {  /* ABSQ_S.PH */
   3080                      DIP("absq_s.ph r%d, r%d", rd, rt);
   3081                      vassert(!mode64);
   3082                      t0 = newTemp(Ity_I16);
   3083                      t1 = newTemp(Ity_I1);
   3084                      t2 = newTemp(Ity_I1);
   3085                      t3 = newTemp(Ity_I16);
   3086                      t4 = newTemp(Ity_I16);
   3087                      t5 = newTemp(Ity_I1);
   3088                      t6 = newTemp(Ity_I1);
   3089                      t7 = newTemp(Ity_I16);
   3090                      t8 = newTemp(Ity_I32);
   3091                      t9 = newTemp(Ity_I32);
   3092 
   3093                      /* t0 holds lower 16 bits of value in rt. */
   3094                      assign(t0, unop(Iop_32to16, getIReg(rt)));
   3095                      /* t1 holds 1 if t0 is equal to 0x8000. */
   3096                      assign(t1, binop(Iop_CmpEQ32,
   3097                                       unop(Iop_16Uto32, mkexpr(t0)),
   3098                                       mkU32(0x00008000)));
   3099                      /* t2 holds 1 if value in t0 is negative, 0 otherwise. */
   3100                      assign(t2, unop(Iop_32to1,
   3101                                      binop(Iop_Shr32,
   3102                                            binop(Iop_And32,
   3103                                                  getIReg(rt),
   3104                                                  mkU32(0x00008000)),
   3105                                            mkU8(15))));
   3106                      /* t3 holds abs(t0). */
   3107                      assign(t3, IRExpr_ITE(mkexpr(t1),
   3108                                            mkU16(0x7FFF),
   3109                                            IRExpr_ITE(mkexpr(t2),
   3110                                                       binop(Iop_Add16,
   3111                                                             unop(Iop_Not16,
   3112                                                                  mkexpr(t0)),
   3113                                                             mkU16(0x1)),
   3114                                                       mkexpr(t0))));
   3115 
   3116                      /* t4 holds lower 16 bits of value in rt. */
   3117                      assign(t4, unop(Iop_32HIto16, getIReg(rt)));
   3118                      /* t5 holds 1 if t4 is equal to 0x8000. */
   3119                      assign(t5, binop(Iop_CmpEQ32,
   3120                                       unop(Iop_16Uto32, mkexpr(t4)),
   3121                                       mkU32(0x00008000)));
   3122                      /* t6 holds 1 if value in t4 is negative, 0 otherwise. */
   3123                      assign(t6, unop(Iop_32to1,
   3124                                      binop(Iop_Shr32,
   3125                                            binop(Iop_And32,
   3126                                                  getIReg(rt),
   3127                                                  mkU32(0x80000000)),
   3128                                            mkU8(31))));
   3129                      /* t7 holds abs(t4). */
   3130                      assign(t7, IRExpr_ITE(mkexpr(t5),
   3131                                            mkU16(0x7FFF),
   3132                                            IRExpr_ITE(mkexpr(t6),
   3133                                                       binop(Iop_Add16,
   3134                                                             unop(Iop_Not16,
   3135                                                                  mkexpr(t4)),
   3136                                                             mkU16(0x1)),
   3137                                                       mkexpr(t4))));
   3138                      /* If any of the two input halfwords is equal 0x8000,
   3139                         set bit 20 in DSPControl register. */
   3140                      assign(t8, binop(Iop_Or32,
   3141                                       unop(Iop_1Sto32, mkexpr(t5)),
   3142                                       unop(Iop_1Sto32, mkexpr(t1))));
   3143 
   3144                      putDSPControl(IRExpr_ITE(binop(Iop_CmpEQ32,
   3145                                                     mkexpr(t8),
   3146                                                     mkU32(0x0)),
   3147                                               getDSPControl(),
   3148                                               binop(Iop_Or32,
   3149                                                     getDSPControl(),
   3150                                                     mkU32(0x00100000))));
   3151 
   3152                      /* t9 = t7|t3 */
   3153                      assign(t9, binop(Iop_16HLto32, mkexpr(t7), mkexpr(t3)));
   3154 
   3155                      putIReg(rd, mkexpr(t9));
   3156                      break;
   3157                   }
   3158                   case 0xA: {  /* REPL.PH */
   3159                      DIP("repl.ph r%d, %d", rd, dsp_imm);
   3160                      vassert(!mode64);
   3161                      UShort immediate = extend_s_10to16(dsp_imm);
   3162 
   3163                      putIReg(rd, mkU32(immediate << 16 | immediate));
   3164                      break;
   3165                   }
   3166                   case 0xB: {  /* REPLV.PH */
   3167                      DIP("replv.ph r%d, r%d", rd, rt);
   3168                      vassert(!mode64);
   3169 
   3170                      putIReg(rd, binop(Iop_16HLto32,
   3171                                        unop(Iop_32to16, getIReg(rt)),
   3172                                        unop(Iop_32to16, getIReg(rt))));
   3173                      break;
   3174                   }
   3175                   case 0xC: {  /* PRECEQ.W.PHL */
   3176                      DIP("preceq.w.phl r%d, r%d", rd, rt);
   3177                      vassert(!mode64);
   3178                      putIReg(rd, binop(Iop_And32,
   3179                                        getIReg(rt),
   3180                                        mkU32(0xffff0000)));
   3181                      break;
   3182                   }
   3183                   case 0xD: {  /* PRECEQ.W.PHR */
   3184                      DIP("preceq.w.phr r%d, r%d", rd, rt);
   3185                      vassert(!mode64);
   3186                      putIReg(rd, binop(Iop_16HLto32,
   3187                                        unop(Iop_32to16, getIReg(rt)),
   3188                                        mkU16(0x0)));
   3189                      break;
   3190                   }
   3191                   case 0x11: {  /* ABSQ_S.W */
   3192                      DIP("absq_s.w r%d, r%d", rd, rt);
   3193                      vassert(!mode64);
   3194                      t0 = newTemp(Ity_I1);
   3195                      t1 = newTemp(Ity_I1);
   3196                      t2 = newTemp(Ity_I32);
   3197 
   3198                      assign(t0,
   3199                             binop(Iop_CmpEQ32, getIReg(rt), mkU32(0x80000000)));
   3200 
   3201                      putDSPControl(IRExpr_ITE(mkexpr(t0),
   3202                                               binop(Iop_Or32,
   3203                                                     getDSPControl(),
   3204                                                     mkU32(0x00100000)),
   3205                                               getDSPControl()));
   3206 
   3207                      assign(t1, binop(Iop_CmpLT32S, getIReg(rt), mkU32(0x0)));
   3208 
   3209                      assign(t2, IRExpr_ITE(mkexpr(t0),
   3210                                            mkU32(0x7FFFFFFF),
   3211                                            IRExpr_ITE(mkexpr(t1),
   3212                                                       binop(Iop_Add32,
   3213                                                             unop(Iop_Not32,
   3214                                                                  getIReg(rt)),
   3215                                                             mkU32(0x1)),
   3216                                                       getIReg(rt))));
   3217                      putIReg(rd, mkexpr(t2));
   3218                      break;
   3219                   }
   3220                   case 0x1B: {  /* BITREV */
   3221                      DIP("bitrev r%d, r%d", rd, rt);
   3222                      vassert(!mode64);
   3223                      /* 32bit reversal as seen on Bit Twiddling Hacks site
   3224                         http://graphics.stanford.edu/~seander/bithacks.html
   3225                         section ReverseParallel */
   3226                      t1 = newTemp(Ity_I32);
   3227                      t2 = newTemp(Ity_I32);
   3228                      t3 = newTemp(Ity_I32);
   3229                      t4 = newTemp(Ity_I32);
   3230                      t5 = newTemp(Ity_I32);
   3231 
   3232                      assign(t1, binop(Iop_Or32,
   3233                                       binop(Iop_Shr32,
   3234                                             binop(Iop_And32,
   3235                                                   getIReg(rt),
   3236                                                   mkU32(0xaaaaaaaa)),
   3237                                             mkU8(0x1)),
   3238                                       binop(Iop_Shl32,
   3239                                             binop(Iop_And32,
   3240                                                   getIReg(rt),
   3241                                                   mkU32(0x55555555)),
   3242                                             mkU8(0x1))));
   3243                      assign(t2, binop(Iop_Or32,
   3244                                       binop(Iop_Shr32,
   3245                                             binop(Iop_And32,
   3246                                                   mkexpr(t1),
   3247                                                   mkU32(0xcccccccc)),
   3248                                             mkU8(0x2)),
   3249                                       binop(Iop_Shl32,
   3250                                             binop(Iop_And32,
   3251                                                   mkexpr(t1),
   3252                                                   mkU32(0x33333333)),
   3253                                             mkU8(0x2))));
   3254                      assign(t3, binop(Iop_Or32,
   3255                                       binop(Iop_Shr32,
   3256                                             binop(Iop_And32,
   3257                                                   mkexpr(t2),
   3258                                                   mkU32(0xf0f0f0f0)),
   3259                                             mkU8(0x4)),
   3260                                       binop(Iop_Shl32,
   3261                                             binop(Iop_And32,
   3262                                                   mkexpr(t2),
   3263                                                   mkU32(0x0f0f0f0f)),
   3264                                             mkU8(0x4))));
   3265                      assign(t4, binop(Iop_Or32,
   3266                                       binop(Iop_Shr32,
   3267                                             binop(Iop_And32,
   3268                                                   mkexpr(t3),
   3269                                                   mkU32(0xff00ff00)),
   3270                                             mkU8(0x8)),
   3271                                       binop(Iop_Shl32,
   3272                                             binop(Iop_And32,
   3273                                                   mkexpr(t3),
   3274                                                   mkU32(0x00ff00ff)),
   3275                                             mkU8(0x8))));
   3276                      assign(t5, binop(Iop_Or32,
   3277                                       binop(Iop_Shr32,
   3278                                             mkexpr(t4),
   3279                                             mkU8(0x10)),
   3280                                       binop(Iop_Shl32,
   3281                                             mkexpr(t4),
   3282                                             mkU8(0x10))));
   3283                      putIReg(rd, binop(Iop_Shr32,
   3284                                        mkexpr(t5),
   3285                                        mkU8(16)));
   3286                      break;
   3287                   }
   3288                   case 0x1C: {  /* PRECEU.PH.QBL */
   3289                      DIP("preceu.ph.qbl r%d, r%d", rd, rt);
   3290                      vassert(!mode64);
   3291 
   3292                      putIReg(rd, binop(Iop_Or32,
   3293                                        binop(Iop_Shr32,
   3294                                              binop(Iop_And32,
   3295                                                    getIReg(rt),
   3296                                                    mkU32(0xff000000)),
   3297                                              mkU8(8)),
   3298                                        binop(Iop_Shr32,
   3299                                              binop(Iop_And32,
   3300                                                    getIReg(rt),
   3301                                                    mkU32(0x00ff0000)),
   3302                                              mkU8(16))));
   3303                      break;
   3304                   }
   3305                   case 0x1E: {  /* PRECEU.PH.QBLA */
   3306                      DIP("preceu.ph.qbla r%d, r%d", rd, rt);
   3307                      vassert(!mode64);
   3308 
   3309                      putIReg(rd, binop(Iop_Or32,
   3310                                        binop(Iop_Shr32,
   3311                                              binop(Iop_And32,
   3312                                                    getIReg(rt),
   3313                                                    mkU32(0xff000000)),
   3314                                              mkU8(8)),
   3315                                        binop(Iop_Shr32,
   3316                                              binop(Iop_And32,
   3317                                                    getIReg(rt),
   3318                                                    mkU32(0x0000ff00)),
   3319                                              mkU8(8))));
   3320                      break;
   3321                   }
   3322                   case 0x1D: {  /* PRECEU.PH.QBR */
   3323                      DIP("preceu.ph.qbr r%d, r%d", rd, rt);
   3324                      vassert(!mode64);
   3325 
   3326                      putIReg(rd, binop(Iop_Or32,
   3327                                        binop(Iop_Shl32,
   3328                                              binop(Iop_And32,
   3329                                                    getIReg(rt),
   3330                                                    mkU32(0x0000ff00)),
   3331                                              mkU8(8)),
   3332                                        binop(Iop_And32,
   3333                                              getIReg(rt),
   3334                                              mkU32(0x000000ff))));
   3335                      break;
   3336                   }
   3337                   case 0x1F: {  /* PRECEU.PH.QBRA */
   3338                      DIP("preceu.ph.qbra r%d, r%d", rd, rt);
   3339                      vassert(!mode64);
   3340 
   3341                      putIReg(rd, binop(Iop_Or32,
   3342                                        binop(Iop_And32,
   3343                                              getIReg(rt),
   3344                                              mkU32(0x00ff0000)),
   3345                                        binop(Iop_And32,
   3346                                              getIReg(rt),
   3347                                              mkU32(0x000000ff))));
   3348                      break;
   3349                   }
   3350                   default:
   3351                      return -1;
   3352                }
   3353                break;  /* end of ABSQ_S.PH */
   3354             }
   3355             case 0x38: {  /* EXTR.W */
   3356                switch(sa) {
   3357                   case 0x0: {  /* EXTR.W */
   3358                      DIP("extr.w r%d, ac%d, %d", rt, ac, rs);
   3359                      vassert(!mode64);
   3360                      t0 = newTemp(Ity_I64);
   3361                      t1 = newTemp(Ity_I64);
   3362                      t2 = newTemp(Ity_I32);
   3363                      t3 = newTemp(Ity_I1);
   3364                      t4 = newTemp(Ity_I1);
   3365                      t5 = newTemp(Ity_I1);
   3366                      t6 = newTemp(Ity_I1);
   3367                      t7 = newTemp(Ity_I32);
   3368                      t8 = newTemp(Ity_I64);
   3369                      t9 = newTemp(Ity_I64);
   3370                      t10 = newTemp(Ity_I1);
   3371                      t11 = newTemp(Ity_I1);
   3372                      t12 = newTemp(Ity_I1);
   3373                      t13 = newTemp(Ity_I1);
   3374                      t14 = newTemp(Ity_I32);
   3375 
   3376                      assign(t0, getAcc(ac));
   3377                      if (0 == rs) {
   3378                         assign(t1, mkexpr(t0));
   3379                      } else {
   3380                         assign(t1, binop(Iop_Sar64, mkexpr(t0), mkU8(rs)));
   3381                      }
   3382                      /* Check if bits 63..31 of the result in t1 aren't 0. */
   3383                      assign(t3, binop(Iop_CmpNE32,
   3384                                       unop(Iop_64HIto32,
   3385                                            mkexpr(t1)),
   3386                                       mkU32(0)));
   3387                      assign(t4, binop(Iop_CmpNE32,
   3388                                       binop(Iop_And32,
   3389                                             unop(Iop_64to32,
   3390                                                  mkexpr(t1)),
   3391                                             mkU32(0x80000000)),
   3392                                       mkU32(0)));
   3393                      /* Check if bits 63..31 of the result in t1 aren't
   3394                         0x1ffffffff. */
   3395                      assign(t5, binop(Iop_CmpNE32,
   3396                                       unop(Iop_64HIto32,
   3397                                            mkexpr(t1)),
   3398                                       mkU32(0xffffffff)));
   3399                      assign(t6, binop(Iop_CmpNE32,
   3400                                       binop(Iop_And32,
   3401                                             unop(Iop_64to32,
   3402                                                  mkexpr(t1)),
   3403                                             mkU32(0x80000000)),
   3404                                       mkU32(0x80000000)));
   3405                      /* If bits 63..31 aren't 0 nor 0x1ffffffff, set DSP
   3406                         control register. */
   3407                      assign(t7, binop(Iop_And32,
   3408                                       binop(Iop_Or32,
   3409                                             unop(Iop_1Sto32, mkexpr(t3)),
   3410                                             unop(Iop_1Sto32, mkexpr(t4))),
   3411                                       binop(Iop_Or32,
   3412                                             unop(Iop_1Sto32, mkexpr(t5)),
   3413                                             unop(Iop_1Sto32, mkexpr(t6)))));
   3414                      putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32,
   3415                                                     mkexpr(t7),
   3416                                                     mkU32(0)),
   3417                                               binop(Iop_Or32,
   3418                                                     getDSPControl(),
   3419                                                     mkU32(0x00800000)),
   3420                                               getDSPControl()));
   3421 
   3422                      /* If the last discarded bit is 1, there would be carry
   3423                         when rounding, otherwise there wouldn't. We use that
   3424                         fact and just add the value of the last discarded bit
   3425                         to the least sifgnificant bit of the shifted value
   3426                         from acc. */
   3427                      if (0 == rs) {
   3428                         assign(t8, mkU64(0x0ULL));
   3429                      } else {
   3430                         assign(t8, binop(Iop_And64,
   3431                                          binop(Iop_Shr64,
   3432                                                mkexpr(t0),
   3433                                                mkU8(rs-1)),
   3434                                          mkU64(0x1ULL)));
   3435                      }
   3436                      assign(t9, binop(Iop_Add64, mkexpr(t1), mkexpr(t8)));
   3437 
   3438                      /* Repeat previous steps for the rounded value. */
   3439                      assign(t10, binop(Iop_CmpNE32,
   3440                                       unop(Iop_64HIto32,
   3441                                            mkexpr(t9)),
   3442                                       mkU32(0)));
   3443                      assign(t11, binop(Iop_CmpNE32,
   3444                                       binop(Iop_And32,
   3445                                             unop(Iop_64to32,
   3446                                                  mkexpr(t9)),
   3447                                             mkU32(0x80000000)),
   3448                                       mkU32(0)));
   3449 
   3450                      assign(t12, binop(Iop_CmpNE32,
   3451                                       unop(Iop_64HIto32,
   3452                                            mkexpr(t9)),
   3453                                       mkU32(0xffffffff)));
   3454                      assign(t13, binop(Iop_CmpNE32,
   3455                                       binop(Iop_And32,
   3456                                             unop(Iop_64to32,
   3457                                                  mkexpr(t9)),
   3458                                             mkU32(0x80000000)),
   3459                                       mkU32(0x80000000)));
   3460 
   3461                      assign(t14, binop(Iop_And32,
   3462                                       binop(Iop_Or32,
   3463                                             unop(Iop_1Sto32, mkexpr(t10)),
   3464                                             unop(Iop_1Sto32, mkexpr(t11))),
   3465                                       binop(Iop_Or32,
   3466                                             unop(Iop_1Sto32, mkexpr(t12)),
   3467                                             unop(Iop_1Sto32, mkexpr(t13)))));
   3468                      putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32,
   3469                                                     mkexpr(t14),
   3470                                                     mkU32(0)),
   3471                                               binop(Iop_Or32,
   3472                                                     getDSPControl(),
   3473                                                     mkU32(0x00800000)),
   3474                                               getDSPControl()));
   3475                      if (0 == rs) {
   3476                         putIReg(rt, unop(Iop_64to32, mkexpr(t0)));
   3477                      } else {
   3478                         putIReg(rt, unop(Iop_64to32, mkexpr(t1)));
   3479                      }
   3480                      break;
   3481                   }
   3482                   case 0x1: {  /* EXTRV.W */
   3483                      DIP("extrv.w r%d, ac%d, r%d", rt, ac, rs);
   3484                      vassert(!mode64);
   3485                      t0 = newTemp(Ity_I64);
   3486                      t1 = newTemp(Ity_I64);
   3487                      t2 = newTemp(Ity_I32);
   3488                      t3 = newTemp(Ity_I1);
   3489                      t4 = newTemp(Ity_I1);
   3490                      t5 = newTemp(Ity_I1);
   3491                      t6 = newTemp(Ity_I1);
   3492                      t7 = newTemp(Ity_I32);
   3493                      t8 = newTemp(Ity_I64);
   3494                      t9 = newTemp(Ity_I64);
   3495                      t10 = newTemp(Ity_I1);
   3496                      t11 = newTemp(Ity_I1);
   3497                      t12 = newTemp(Ity_I1);
   3498                      t13 = newTemp(Ity_I1);
   3499                      t14 = newTemp(Ity_I32);
   3500                      t15 = newTemp(Ity_I8);
   3501 
   3502                      assign(t15, unop(Iop_32to8,
   3503                                       binop(Iop_And32,
   3504                                             getIReg(rs),
   3505                                             mkU32(0x1f))));
   3506                      assign(t0, getAcc(ac));
   3507                      assign(t1, binop(Iop_Sar64, mkexpr(t0), mkexpr(t15)));
   3508                      putIReg(rt, IRExpr_ITE(binop(Iop_CmpEQ32,
   3509                                                         unop(Iop_8Uto32,
   3510                                                              mkexpr(t15)),
   3511                                                         mkU32(0)),
   3512                                                   unop(Iop_64to32, mkexpr(t0)),
   3513                                                   unop(Iop_64to32, mkexpr(t1))));
   3514 
   3515                      /* Check if bits 63..31 of the result in t1 aren't 0. */
   3516                      assign(t3, binop(Iop_CmpNE32,
   3517                                       unop(Iop_64HIto32,
   3518                                            mkexpr(t1)),
   3519                                       mkU32(0)));
   3520                      assign(t4, binop(Iop_CmpNE32,
   3521                                       binop(Iop_And32,
   3522                                             unop(Iop_64to32,
   3523                                                  mkexpr(t1)),
   3524                                             mkU32(0x80000000)),
   3525                                       mkU32(0)));
   3526                      /* Check if bits 63..31 of the result in t1 aren't
   3527                         0x1ffffffff. */
   3528                      assign(t5, binop(Iop_CmpNE32,
   3529                                       unop(Iop_64HIto32,
   3530                                            mkexpr(t1)),
   3531                                       mkU32(0xffffffff)));
   3532                      assign(t6, binop(Iop_CmpNE32,
   3533                                       binop(Iop_And32,
   3534                                             unop(Iop_64to32,
   3535                                                  mkexpr(t1)),
   3536                                             mkU32(0x80000000)),
   3537                                       mkU32(0x80000000)));
   3538                      /* If bits 63..31 aren't 0 nor 0x1ffffffff, set DSP
   3539                         control register. */
   3540                      assign(t7, binop(Iop_And32,
   3541                                       binop(Iop_Or32,
   3542                                             unop(Iop_1Sto32, mkexpr(t3)),
   3543                                             unop(Iop_1Sto32, mkexpr(t4))),
   3544                                       binop(Iop_Or32,
   3545                                             unop(Iop_1Sto32, mkexpr(t5)),
   3546                                             unop(Iop_1Sto32, mkexpr(t6)))));
   3547                      putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32,
   3548                                                     mkexpr(t7),
   3549                                                     mkU32(0)),
   3550                                               binop(Iop_Or32,
   3551                                                     getDSPControl(),
   3552                                                     mkU32(0x00800000)),
   3553                                               getDSPControl()));
   3554 
   3555                      /* If the last discarded bit is 1, there would be carry
   3556                         when rounding, otherwise there wouldn't. We use that
   3557                         fact and just add the value of the last discarded bit
   3558                         to the least sifgnificant bit of the shifted value
   3559                         from acc. */
   3560                      assign(t8,
   3561                             IRExpr_ITE(binop(Iop_CmpEQ32,
   3562                                              unop(Iop_8Uto32,
   3563                                                   mkexpr(t15)),
   3564                                              mkU32(0)),
   3565                                        mkU64(0x0ULL),
   3566                                        binop(Iop_And64,
   3567                                              binop(Iop_Shr64,
   3568                                                    mkexpr(t0),
   3569                                                    unop(Iop_32to8,
   3570                                                         binop(Iop_Sub32,
   3571                                                               unop(Iop_8Uto32,
   3572                                                                    mkexpr(t15)),
   3573                                                                    mkU32(1)))),
   3574                                              mkU64(0x1ULL))));
   3575 
   3576                      assign(t9, binop(Iop_Add64, mkexpr(t1), mkexpr(t8)));
   3577 
   3578                      /* Repeat previous steps for the rounded value. */
   3579                      assign(t10, binop(Iop_CmpNE32,
   3580                                       unop(Iop_64HIto32,
   3581                                            mkexpr(t9)),
   3582                                       mkU32(0)));
   3583                      assign(t11, binop(Iop_CmpNE32,
   3584                                       binop(Iop_And32,
   3585                                             unop(Iop_64to32,
   3586                                                  mkexpr(t9)),
   3587                                             mkU32(0x80000000)),
   3588                                       mkU32(0)));
   3589 
   3590                      assign(t12, binop(Iop_CmpNE32,
   3591                                       unop(Iop_64HIto32,
   3592                                            mkexpr(t9)),
   3593                                       mkU32(0xffffffff)));
   3594                      assign(t13, binop(Iop_CmpNE32,
   3595                                       binop(Iop_And32,
   3596                                             unop(Iop_64to32,
   3597                                                  mkexpr(t9)),
   3598                                             mkU32(0x80000000)),
   3599                                       mkU32(0x80000000)));
   3600 
   3601                      assign(t14, binop(Iop_And32,
   3602                                       binop(Iop_Or32,
   3603                                             unop(Iop_1Sto32, mkexpr(t10)),
   3604                                             unop(Iop_1Sto32, mkexpr(t11))),
   3605                                       binop(Iop_Or32,
   3606                                             unop(Iop_1Sto32, mkexpr(t12)),
   3607                                             unop(Iop_1Sto32, mkexpr(t13)))));
   3608                      putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32,
   3609                                                     mkexpr(t14),
   3610                                                     mkU32(0)),
   3611                                               binop(Iop_Or32,
   3612                                                     getDSPControl(),
   3613                                                     mkU32(0x00800000)),
   3614                                               getDSPControl()));
   3615                      break;
   3616                   }
   3617                   case 0x2: {  /* EXTP */
   3618                      DIP("extp r%d, ac%d, %d", rt, ac, rs);
   3619                      vassert(!mode64);
   3620                      t0 = newTemp(Ity_I64);
   3621                      t1 = newTemp(Ity_I32);
   3622                      t2 = newTemp(Ity_I1);
   3623                      t3 = newTemp(Ity_I1);
   3624                      t4 = newTemp(Ity_I8);
   3625                      t5 = newTemp(Ity_I64);
   3626                      t6 = newTemp(Ity_I64);
   3627                      t7 = newTemp(Ity_I32);
   3628 
   3629                      assign(t0, getAcc(ac));
   3630                      /* Extract pos field of DSPControl register. */
   3631                      assign(t1, binop(Iop_And32, getDSPControl(), mkU32(0x3f)));
   3632 
   3633                      /* Check if (pos - size) >= 0 [size <= pos]
   3634                         if (pos < size)
   3635                            put 1 to EFI field of DSPControl register
   3636                         else
   3637                            extract bits from acc and put 0 to EFI field of
   3638                            DSPCtrl */
   3639                      assign(t2, binop(Iop_CmpLT32U, mkexpr(t1), mkU32(rs)));
   3640 
   3641                      putDSPControl(IRExpr_ITE(mkexpr(t2),
   3642                                               binop(Iop_Or32,
   3643                                                     binop(Iop_And32,
   3644                                                           getDSPControl(),
   3645                                                           mkU32(0xffffbfff)),
   3646                                                     mkU32(0x4000)),
   3647                                               binop(Iop_And32,
   3648                                                     getDSPControl(),
   3649                                                     mkU32(0xffffbfff))));
   3650 
   3651                      /* If pos <= 31, shift right the value from the acc
   3652                         (pos-size) times and take (size+1) bits from the least
   3653                         significant positions. Otherwise, shift left the value
   3654                         (63-pos) times, take (size+1) bits from the most
   3655                         significant positions and shift right (31-size) times.*/
   3656                      assign(t3, binop(Iop_CmpLE32U, mkexpr(t1), mkU32(31)));
   3657 
   3658                      assign(t4,
   3659                            IRExpr_ITE(mkexpr(t3),
   3660                                       unop(Iop_32to8,
   3661                                            binop(Iop_Sub32,
   3662                                                  mkexpr(t1), mkU32(rs))),
   3663                                       unop(Iop_32to8,
   3664                                            binop(Iop_Sub32,
   3665                                                  mkU32(63), mkexpr(t1)))));
   3666 
   3667                      assign(t5, IRExpr_ITE(mkexpr(t3),
   3668                                            binop(Iop_Shr64,
   3669                                                  mkexpr(t0), mkexpr(t4)),
   3670                                            binop(Iop_Shl64,
   3671                                                  mkexpr(t0), mkexpr(t4))));
   3672 
   3673                      /* t6 holds a mask for bit extraction */
   3674                      assign(t6,
   3675                             IRExpr_ITE(mkexpr(t3),
   3676                                        unop(Iop_Not64,
   3677                                             binop(Iop_Shl64,
   3678                                                   mkU64(0xffffffffffffffffULL),
   3679                                                   mkU8(rs+1))),
   3680                                        unop(Iop_Not64,
   3681                                             binop(Iop_Shr64,
   3682                                                   mkU64(0xffffffffffffffffULL),
   3683                                                   mkU8(rs+1)))));
   3684 
   3685                      assign(t7, IRExpr_ITE(mkexpr(t3),
   3686                                            unop(Iop_64to32,
   3687                                                 binop(Iop_And64,
   3688                                                       mkexpr(t5),
   3689                                                       mkexpr(t6))),
   3690                                            binop(Iop_Shr32,
   3691                                                  unop(Iop_64HIto32,
   3692                                                       binop(Iop_And64,
   3693                                                             mkexpr(t5),
   3694                                                             mkexpr(t6))),
   3695                                                  mkU8(31-rs))));
   3696 
   3697                      putIReg(rt, mkexpr(t7));
   3698                      break;
   3699                   }
   3700                   case 0x3: {  /* EXTPV */
   3701                      DIP("extpv r%d, ac%d, r%d", rt, ac, rs);
   3702                      vassert(!mode64);
   3703                      t0 = newTemp(Ity_I64);
   3704                      t1 = newTemp(Ity_I32);
   3705                      t2 = newTemp(Ity_I1);
   3706                      t3 = newTemp(Ity_I1);
   3707                      t4 = newTemp(Ity_I8);
   3708                      t5 = newTemp(Ity_I64);
   3709                      t6 = newTemp(Ity_I64);
   3710                      t7 = newTemp(Ity_I32);
   3711                      t8 = newTemp(Ity_I32);
   3712 
   3713                      assign(t8, binop(Iop_And32, getIReg(rs), mkU32(0x1f)));
   3714                      assign(t0, getAcc(ac));
   3715                      /* Extract pos field of DSPControl register. */
   3716                      assign(t1, binop(Iop_And32, getDSPControl(), mkU32(0x3f)));
   3717 
   3718                      /* Check if (pos - size) >= 0 [size <= pos]
   3719                         if (pos < size)
   3720                            put 1 to EFI field of DSPControl register
   3721                         else
   3722                            extract bits from acc and put 0 to EFI field of
   3723                            DSPCtrl */
   3724                      assign(t2, binop(Iop_CmpLT32U, mkexpr(t1), mkexpr(t8)));
   3725 
   3726                      putDSPControl(IRExpr_ITE(mkexpr(t2),
   3727                                               binop(Iop_Or32,
   3728                                                     binop(Iop_And32,
   3729                                                           getDSPControl(),
   3730                                                           mkU32(0xffffbfff)),
   3731                                                     mkU32(0x4000)),
   3732                                               binop(Iop_And32,
   3733                                                     getDSPControl(),
   3734                                                     mkU32(0xffffbfff))));
   3735 
   3736                      /* If pos <= 31, shift right the value from the acc
   3737                         (pos-size) times and take (size+1) bits from the least
   3738                         significant positions. Otherwise, shift left the value
   3739                         (63-pos) times, take (size+1) bits from the most
   3740                         significant positions and shift right (31-size)
   3741                         times. */
   3742                      assign(t3, binop(Iop_CmpLE32U, mkexpr(t1), mkU32(31)));
   3743 
   3744                      assign(t4,
   3745                            IRExpr_ITE(mkexpr(t3),
   3746                                       unop(Iop_32to8,
   3747                                            binop(Iop_Sub32,
   3748                                                  mkexpr(t1), mkexpr(t8))),
   3749                                       unop(Iop_32to8,
   3750                                            binop(Iop_Sub32,
   3751                                                  mkU32(63), mkexpr(t1)))));
   3752 
   3753                      assign(t5, IRExpr_ITE(mkexpr(t3),
   3754                                            binop(Iop_Shr64,
   3755                                                  mkexpr(t0), mkexpr(t4)),
   3756                                            binop(Iop_Shl64,
   3757                                                  mkexpr(t0), mkexpr(t4))));
   3758 
   3759                      /* t6 holds a mask for bit extraction. */
   3760                      assign(t6,
   3761                             IRExpr_ITE(mkexpr(t3),
   3762                                        unop(Iop_Not64,
   3763                                             binop(Iop_Shl64,
   3764                                                   mkU64(0xffffffffffffffffULL),
   3765                                                   unop(Iop_32to8,
   3766                                                        binop(Iop_Add32,
   3767                                                              mkexpr(t8),
   3768                                                              mkU32(1))))),
   3769                                        unop(Iop_Not64,
   3770                                             binop(Iop_Shr64,
   3771                                                   mkU64(0xffffffffffffffffULL),
   3772                                                   unop(Iop_32to8,
   3773                                                        binop(Iop_Add32,
   3774                                                              mkexpr(t8),
   3775                                                              mkU32(1)))))));
   3776 
   3777                      assign(t7, IRExpr_ITE(mkexpr(t3),
   3778                                            unop(Iop_64to32,
   3779                                                 binop(Iop_And64,
   3780                                                       mkexpr(t5),
   3781                                                       mkexpr(t6))),
   3782                                            binop(Iop_Shr32,
   3783                                                  unop(Iop_64HIto32,
   3784                                                       binop(Iop_And64,
   3785                                                             mkexpr(t5),
   3786                                                             mkexpr(t6))),
   3787                                                  unop(Iop_32to8,
   3788                                                       binop(Iop_Sub32,
   3789                                                             mkU32(31),
   3790                                                             mkexpr(t8))))));
   3791 
   3792                      putIReg(rt, mkexpr(t7));
   3793                      break;
   3794                   }
   3795                   case 0x4: {  /* EXTR_R.W */
   3796                      DIP("extr_r.w r%d, ac%d, %d", rt, ac, rs);
   3797                      vassert(!mode64);
   3798                      t0 = newTemp(Ity_I64);
   3799                      t1 = newTemp(Ity_I64);
   3800                      t2 = newTemp(Ity_I32);
   3801                      t3 = newTemp(Ity_I1);
   3802                      t4 = newTemp(Ity_I1);
   3803                      t5 = newTemp(Ity_I1);
   3804                      t6 = newTemp(Ity_I1);
   3805                      t7 = newTemp(Ity_I32);
   3806                      t8 = newTemp(Ity_I64);
   3807                      t9 = newTemp(Ity_I64);
   3808                      t10 = newTemp(Ity_I1);
   3809                      t11 = newTemp(Ity_I1);
   3810                      t12 = newTemp(Ity_I1);
   3811                      t13 = newTemp(Ity_I1);
   3812                      t14 = newTemp(Ity_I32);
   3813                      t15 = newTemp(Ity_I64);
   3814                      t16 = newTemp(Ity_I1);
   3815 
   3816                      assign(t0, getAcc(ac));
   3817                      assign(t16, binop(Iop_CmpEQ32,
   3818                                        mkU32(rs),
   3819                                        mkU32(0)));
   3820                      assign(t1, IRExpr_ITE(mkexpr(t16),
   3821                                            mkexpr(t0),
   3822                                            binop(Iop_Sar64,
   3823                                                  mkexpr(t0),
   3824                                                  mkU8(rs))));
   3825                      /* If the last discarded bit is 1, there would be carry
   3826                         when rounding, otherwise there wouldn't. We use that
   3827                         fact and just add the value of the last discarded bit
   3828                         to the least significant bit of the shifted value
   3829                         from acc. */
   3830                      assign(t15, binop(Iop_Shr64,
   3831                                        mkexpr(t0),
   3832                                        unop(Iop_32to8,
   3833                                             binop(Iop_Sub32,
   3834                                                   binop(Iop_And32,
   3835                                                         mkU32(rs),
   3836                                                         mkU32(0x1f)),
   3837                                                   mkU32(1)))));
   3838 
   3839                      assign(t8,
   3840                             IRExpr_ITE(mkexpr(t16),
   3841                                        mkU64(0x0ULL),
   3842                                        binop(Iop_And64,
   3843                                              mkexpr(t15),
   3844                                              mkU64(0x0000000000000001ULL))));
   3845                      assign(t9, binop(Iop_Add64, mkexpr(t1), mkexpr(t8)));
   3846                      putIReg(rt, unop(Iop_64to32, mkexpr(t9)));
   3847 
   3848                      /* Check if bits 63..31 of the result in t1 aren't 0. */
   3849                      assign(t3, binop(Iop_CmpNE32,
   3850                                       unop(Iop_64HIto32,
   3851                                            mkexpr(t1)),
   3852                                       mkU32(0)));
   3853                      assign(t4, binop(Iop_CmpNE32,
   3854                                       binop(Iop_And32,
   3855                                             unop(Iop_64to32,
   3856                                                  mkexpr(t1)),
   3857                                             mkU32(0x80000000)),
   3858                                       mkU32(0)));
   3859 
   3860                      /* Check if bits 63..31 of the result in t1 aren't
   3861                         0x1ffffffff. */
   3862                      assign(t5, binop(Iop_CmpNE32,
   3863                                       unop(Iop_64HIto32,
   3864                                            mkexpr(t1)),
   3865                                       mkU32(0xffffffff)));
   3866                      assign(t6, binop(Iop_CmpNE32,
   3867                                       binop(Iop_And32,
   3868                                             unop(Iop_64to32,
   3869                                                  mkexpr(t1)),
   3870                                             mkU32(0x80000000)),
   3871                                       mkU32(0x80000000)));
   3872                      /* If bits 63..31 aren't 0 nor 0x1ffffffff, set DSP
   3873                         control register. */
   3874                      assign(t7, binop(Iop_And32,
   3875                                       binop(Iop_Or32,
   3876                                             unop(Iop_1Sto32, mkexpr(t3)),
   3877                                             unop(Iop_1Sto32, mkexpr(t4))),
   3878                                       binop(Iop_Or32,
   3879                                             unop(Iop_1Sto32, mkexpr(t5)),
   3880                                             unop(Iop_1Sto32, mkexpr(t6)))));
   3881                      putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32,
   3882                                                     mkexpr(t7),
   3883                                                     mkU32(0)),
   3884                                               binop(Iop_Or32,
   3885                                                     getDSPControl(),
   3886                                                     mkU32(0x00800000)),
   3887                                               getDSPControl()));
   3888 
   3889                      /* Repeat previous steps for the rounded value. */
   3890                      assign(t10, binop(Iop_CmpNE32,
   3891                                       unop(Iop_64HIto32,
   3892                                            mkexpr(t9)),
   3893                                       mkU32(0)));
   3894                      assign(t11, binop(Iop_CmpNE32,
   3895                                       binop(Iop_And32,
   3896                                             unop(Iop_64to32,
   3897                                                  mkexpr(t9)),
   3898                                             mkU32(0x80000000)),
   3899                                       mkU32(0)));
   3900 
   3901                      assign(t12, binop(Iop_CmpNE32,
   3902                                       unop(Iop_64HIto32,
   3903                                            mkexpr(t9)),
   3904                                       mkU32(0xffffffff)));
   3905                      assign(t13, binop(Iop_CmpNE32,
   3906                                       binop(Iop_And32,
   3907                                             unop(Iop_64to32,
   3908                                                  mkexpr(t9)),
   3909                                             mkU32(0x80000000)),
   3910                                       mkU32(0x80000000)));
   3911 
   3912                      assign(t14, binop(Iop_And32,
   3913                                       binop(Iop_Or32,
   3914                                             unop(Iop_1Sto32, mkexpr(t10)),
   3915                                             unop(Iop_1Sto32, mkexpr(t11))),
   3916                                       binop(Iop_Or32,
   3917                                             unop(Iop_1Sto32, mkexpr(t12)),
   3918                                             unop(Iop_1Sto32, mkexpr(t13)))));
   3919                      putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32,
   3920                                                     mkexpr(t14),
   3921                                                     mkU32(0)),
   3922                                               binop(Iop_Or32,
   3923                                                     getDSPControl(),
   3924                                                     mkU32(0x00800000)),
   3925                                               getDSPControl()));
   3926                      break;
   3927                   }
   3928                   case 0x5: {  /* EXTRV_R.W */
   3929                      DIP("extrv_r.w r%d, ac%d, r%d", rt, ac, rs);
   3930                      vassert(!mode64);
   3931                      t0 = newTemp(Ity_I64);
   3932                      t1 = newTemp(Ity_I64);
   3933                      t2 = newTemp(Ity_I32);
   3934                      t3 = newTemp(Ity_I1);
   3935                      t4 = newTemp(Ity_I1);
   3936                      t5 = newTemp(Ity_I1);
   3937                      t6 = newTemp(Ity_I1);
   3938                      t7 = newTemp(Ity_I32);
   3939                      t8 = newTemp(Ity_I64);
   3940                      t9 = newTemp(Ity_I64);
   3941                      t10 = newTemp(Ity_I1);
   3942                      t11 = newTemp(Ity_I1);
   3943                      t12 = newTemp(Ity_I1);
   3944                      t13 = newTemp(Ity_I1);
   3945                      t14 = newTemp(Ity_I32);
   3946                      t15 = newTemp(Ity_I8);
   3947 
   3948                      assign(t15, unop(Iop_32to8,
   3949                                       binop(Iop_And32,
   3950                                             getIReg(rs),
   3951                                             mkU32(0x1f))));
   3952                      assign(t0, getAcc(ac));
   3953                      assign(t1, binop(Iop_Sar64, mkexpr(t0), mkexpr(t15)));
   3954 
   3955                      /* Check if bits 63..31 of the result in t1 aren't 0. */
   3956                      assign(t3, binop(Iop_CmpNE32,
   3957                                       unop(Iop_64HIto32,
   3958                                            mkexpr(t1)),
   3959                                       mkU32(0)));
   3960                      assign(t4, binop(Iop_CmpNE32,
   3961                                       binop(Iop_And32,
   3962                                             unop(Iop_64to32,
   3963                                                  mkexpr(t1)),
   3964                                             mkU32(0x80000000)),
   3965                                       mkU32(0)));
   3966                      /* Check if bits 63..31 of the result in t1 aren't
   3967                         0x1ffffffff. */
   3968                      assign(t5, binop(Iop_CmpNE32,
   3969                                       unop(Iop_64HIto32,
   3970                                            mkexpr(t1)),
   3971                                       mkU32(0xffffffff)));
   3972                      assign(t6, binop(Iop_CmpNE32,
   3973                                       binop(Iop_And32,
   3974                                             unop(Iop_64to32,
   3975                                                  mkexpr(t1)),
   3976                                             mkU32(0x80000000)),
   3977                                       mkU32(0x80000000)));
   3978                      /* If bits 63..31 aren't 0 nor 0x1ffffffff, set DSP
   3979                         control register. */
   3980                      assign(t7, binop(Iop_And32,
   3981                                       binop(Iop_Or32,
   3982                                             unop(Iop_1Sto32, mkexpr(t3)),
   3983                                             unop(Iop_1Sto32, mkexpr(t4))),
   3984                                       binop(Iop_Or32,
   3985                                             unop(Iop_1Sto32, mkexpr(t5)),
   3986                                             unop(Iop_1Sto32, mkexpr(t6)))));
   3987                      putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32,
   3988                                                     mkexpr(t7),
   3989                                                     mkU32(0)),
   3990                                               binop(Iop_Or32,
   3991                                                     getDSPControl(),
   3992                                                     mkU32(0x00800000)),
   3993                                               getDSPControl()));
   3994 
   3995                      /* If the last discarded bit is 1, there would be carry
   3996                         when rounding, otherwise there wouldn't. We use that
   3997                         fact and just add the value of the last discarded bit
   3998                         to the least sifgnificant bit of the shifted value
   3999                         from acc. */
   4000                      assign(t8,
   4001                             IRExpr_ITE(binop(Iop_CmpEQ32,
   4002                                              unop(Iop_8Uto32,
   4003                                                   mkexpr(t15)),
   4004                                              mkU32(0)),
   4005                                        mkU64(0x0ULL),
   4006                                        binop(Iop_And64,
   4007                                              binop(Iop_Shr64,
   4008                                                    mkexpr(t0),
   4009                                                    unop(Iop_32to8,
   4010                                                         binop(Iop_Sub32,
   4011                                                               unop(Iop_8Uto32,
   4012                                                                    mkexpr(t15)),
   4013                                                                    mkU32(1)))),
   4014                                              mkU64(0x1ULL))));
   4015 
   4016                      assign(t9, binop(Iop_Add64, mkexpr(t1), mkexpr(t8)));
   4017                      /* Put rounded value in destination register. */
   4018                      putIReg(rt, unop(Iop_64to32, mkexpr(t9)));
   4019 
   4020                      /* Repeat previous steps for the rounded value. */
   4021                      assign(t10, binop(Iop_CmpNE32,
   4022                                       unop(Iop_64HIto32,
   4023                                            mkexpr(t9)),
   4024                                       mkU32(0)));
   4025                      assign(t11, binop(Iop_CmpNE32,
   4026                                       binop(Iop_And32,
   4027                                             unop(Iop_64to32,
   4028                                                  mkexpr(t9)),
   4029                                             mkU32(0x80000000)),
   4030                                       mkU32(0)));
   4031 
   4032                      assign(t12, binop(Iop_CmpNE32,
   4033                                       unop(Iop_64HIto32,
   4034                                            mkexpr(t9)),
   4035                                       mkU32(0xffffffff)));
   4036                      assign(t13, binop(Iop_CmpNE32,
   4037                                       binop(Iop_And32,
   4038                                             unop(Iop_64to32,
   4039                                                  mkexpr(t9)),
   4040                                             mkU32(0x80000000)),
   4041                                       mkU32(0x80000000)));
   4042 
   4043                      assign(t14, binop(Iop_And32,
   4044                                       binop(Iop_Or32,
   4045                                             unop(Iop_1Sto32, mkexpr(t10)),
   4046                                             unop(Iop_1Sto32, mkexpr(t11))),
   4047                                       binop(Iop_Or32,
   4048                                             unop(Iop_1Sto32, mkexpr(t12)),
   4049                                             unop(Iop_1Sto32, mkexpr(t13)))));
   4050                      putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32,
   4051                                                     mkexpr(t14),
   4052                                                     mkU32(0)),
   4053                                               binop(Iop_Or32,
   4054                                                     getDSPControl(),
   4055                                                     mkU32(0x00800000)),
   4056                                               getDSPControl()));
   4057                      break;
   4058                   }
   4059                   case 0x6: {  /* EXTR_RS.W */
   4060                      DIP("extr_rs.w r%d, ac%d, %d", rt, ac, rs);
   4061                      vassert(!mode64);
   4062                      t0 = newTemp(Ity_I64);
   4063                      t1 = newTemp(Ity_I64);
   4064                      t2 = newTemp(Ity_I32);
   4065                      t3 = newTemp(Ity_I1);
   4066                      t4 = newTemp(Ity_I1);
   4067                      t5 = newTemp(Ity_I1);
   4068                      t6 = newTemp(Ity_I1);
   4069                      t7 = newTemp(Ity_I32);
   4070                      t8 = newTemp(Ity_I64);
   4071                      t9 = newTemp(Ity_I64);
   4072                      t10 = newTemp(Ity_I1);
   4073                      t11 = newTemp(Ity_I1);
   4074                      t12 = newTemp(Ity_I1);
   4075                      t13 = newTemp(Ity_I1);
   4076                      t14 = newTemp(Ity_I32);
   4077                      t16 = newTemp(Ity_I32);
   4078 
   4079                      assign(t0, getAcc(ac));
   4080                      if (0 == rs) {
   4081                         assign(t1, mkexpr(t0));
   4082                      } else {
   4083                         assign(t1, binop(Iop_Sar64, mkexpr(t0), mkU8(rs)));
   4084                      }
   4085 
   4086                      /* Check if bits 63..31 of the result in t1 aren't 0. */
   4087                      assign(t3, binop(Iop_CmpNE32,
   4088                                       unop(Iop_64HIto32,
   4089                                            mkexpr(t1)),
   4090                                       mkU32(0)));
   4091                      assign(t4, binop(Iop_CmpNE32,
   4092                                       binop(Iop_And32,
   4093                                             unop(Iop_64to32,
   4094                                                  mkexpr(t1)),
   4095                                             mkU32(0x80000000)),
   4096                                       mkU32(0)));
   4097                      /* Check if bits 63..31 of the result in t1 aren't
   4098                         0x1ffffffff. */
   4099                      assign(t5, binop(Iop_CmpNE32,
   4100                                       unop(Iop_64HIto32,
   4101                                            mkexpr(t1)),
   4102                                       mkU32(0xffffffff)));
   4103                      assign(t6, binop(Iop_CmpNE32,
   4104                                       binop(Iop_And32,
   4105                                             unop(Iop_64to32,
   4106                                                  mkexpr(t1)),
   4107                                             mkU32(0x80000000)),
   4108                                       mkU32(0x80000000)));
   4109                      /* If bits 63..31 aren't 0 nor 0x1ffffffff, set DSP
   4110                         control register. */
   4111                      assign(t7, binop(Iop_And32,
   4112                                       binop(Iop_Or32,
   4113                                             unop(Iop_1Sto32, mkexpr(t3)),
   4114                                             unop(Iop_1Sto32, mkexpr(t4))),
   4115                                       binop(Iop_Or32,
   4116                                             unop(Iop_1Sto32, mkexpr(t5)),
   4117                                             unop(Iop_1Sto32, mkexpr(t6)))));
   4118                      putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32,
   4119                                                     mkexpr(t7),
   4120                                                     mkU32(0)),
   4121                                               binop(Iop_Or32,
   4122                                                     getDSPControl(),
   4123                                                     mkU32(0x00800000)),
   4124                                               getDSPControl()));
   4125 
   4126                      /* If the last discarded bit is 1, there would be carry
   4127                         when rounding, otherwise there wouldn't. We use that
   4128                         fact and just add the value of the last discarded bit
   4129                         to the least sifgnificant bit of the shifted value
   4130                         from acc. */
   4131                      if (0 == rs) {
   4132                         assign(t8, mkU64(0x0ULL));
   4133                      } else {
   4134                         assign(t8, binop(Iop_And64,
   4135                                          binop(Iop_Shr64,
   4136                                                mkexpr(t0),
   4137                                                mkU8(rs-1)),
   4138                                          mkU64(0x1ULL)));
   4139                      }
   4140 
   4141                      assign(t9, binop(Iop_Add64, mkexpr(t1), mkexpr(t8)));
   4142 
   4143                      /* Repeat previous steps for the rounded value. */
   4144                      assign(t10, binop(Iop_CmpNE32,
   4145                                       unop(Iop_64HIto32,
   4146                                            mkexpr(t9)),
   4147                                       mkU32(0)));
   4148                      assign(t11, binop(Iop_CmpNE32,
   4149                                       binop(Iop_And32,
   4150                                             unop(Iop_64to32,
   4151                                                  mkexpr(t9)),
   4152                                             mkU32(0x80000000)),
   4153                                       mkU32(0)));
   4154 
   4155                      assign(t12, binop(Iop_CmpNE32,
   4156                                       unop(Iop_64HIto32,
   4157                                            mkexpr(t9)),
   4158                                       mkU32(0xffffffff)));
   4159                      assign(t13, binop(Iop_CmpNE32,
   4160                                       binop(Iop_And32,
   4161                                             unop(Iop_64to32,
   4162                                                  mkexpr(t9)),
   4163                                             mkU32(0x80000000)),
   4164                                       mkU32(0x80000000)));
   4165 
   4166                      assign(t14, binop(Iop_And32,
   4167                                       binop(Iop_Or32,
   4168                                             unop(Iop_1Sto32, mkexpr(t10)),
   4169                                             unop(Iop_1Sto32, mkexpr(t11))),
   4170                                       binop(Iop_Or32,
   4171                                             unop(Iop_1Sto32, mkexpr(t12)),
   4172                                             unop(Iop_1Sto32, mkexpr(t13)))));
   4173                      putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32,
   4174                                                     mkexpr(t14),
   4175                                                     mkU32(0)),
   4176                                               binop(Iop_Or32,
   4177                                                     getDSPControl(),
   4178                                                     mkU32(0x00800000)),
   4179                                               getDSPControl()));
   4180 
   4181                      assign(t16, binop(Iop_And32,
   4182                                        unop(Iop_64HIto32,
   4183                                             mkexpr(t9)),
   4184                                        mkU32(0x80000000)));
   4185                      putIReg(rt, IRExpr_ITE(binop(Iop_CmpNE32,
   4186                                                   mkexpr(t14),
   4187                                                   mkU32(0)),
   4188                                             IRExpr_ITE(binop(Iop_CmpEQ32,
   4189                                                              mkexpr(t16),
   4190                                                              mkU32(0)),
   4191                                                        mkU32(0x7fffffff),
   4192                                                        mkU32(0x80000000)),
   4193                                             unop(Iop_64to32, mkexpr(t9))));
   4194                      break;
   4195                   }
   4196                   case 0x7: {  /* EXTRV_RS.W */
   4197                      DIP("extrv_rs.w r%d, ac%d, r%d", rt, ac, rs);
   4198                      vassert(!mode64);
   4199                      t0 = newTemp(Ity_I64);
   4200                      t1 = newTemp(Ity_I64);
   4201                      t2 = newTemp(Ity_I32);
   4202                      t3 = newTemp(Ity_I1);
   4203                      t4 = newTemp(Ity_I1);
   4204                      t5 = newTemp(Ity_I1);
   4205                      t6 = newTemp(Ity_I1);
   4206                      t7 = newTemp(Ity_I32);
   4207                      t8 = newTemp(Ity_I64);
   4208                      t9 = newTemp(Ity_I64);
   4209                      t10 = newTemp(Ity_I1);
   4210                      t11 = newTemp(Ity_I1);
   4211                      t12 = newTemp(Ity_I1);
   4212                      t13 = newTemp(Ity_I1);
   4213                      t14 = newTemp(Ity_I32);
   4214                      t15 = newTemp(Ity_I32);
   4215                      t16 = newTemp(Ity_I32);
   4216                      t17 = newTemp(Ity_I1);
   4217 
   4218                      assign(t15, binop(Iop_And32,
   4219                                        getIReg(rs),
   4220                                        mkU32(0x1f)));
   4221                      assign(t17, binop(Iop_CmpEQ32,
   4222                                        mkexpr(t15),
   4223                                        mkU32(0)));
   4224                      assign(t0, getAcc(ac));
   4225                      assign(t1, IRExpr_ITE(mkexpr(t17),
   4226                                            mkexpr(t0),
   4227                                            binop(Iop_Sar64,
   4228                                                  mkexpr(t0),
   4229                                                  unop(Iop_32to8,
   4230                                                       mkexpr(t15)))));
   4231 
   4232                      /* Check if bits 63..31 of the result in t1 aren't 0. */
   4233                      assign(t3, binop(Iop_CmpNE32,
   4234                                       unop(Iop_64HIto32,
   4235                                            mkexpr(t1)),
   4236                                       mkU32(0)));
   4237                      assign(t4, binop(Iop_CmpNE32,
   4238                                       binop(Iop_And32,
   4239                                             unop(Iop_64to32,
   4240                                                  mkexpr(t1)),
   4241                                             mkU32(0x80000000)),
   4242                                       mkU32(0)));
   4243                      /* Check if bits 63..31 of the result in t1 aren't
   4244                         0x1ffffffff. */
   4245                      assign(t5, binop(Iop_CmpNE32,
   4246                                       unop(Iop_64HIto32,
   4247                                            mkexpr(t1)),
   4248                                       mkU32(0xffffffff)));
   4249                      assign(t6, binop(Iop_CmpNE32,
   4250                                       binop(Iop_And32,
   4251                                             unop(Iop_64to32,
   4252                                                  mkexpr(t1)),
   4253                                             mkU32(0x80000000)),
   4254                                       mkU32(0x80000000)));
   4255                      /* If bits 63..31 aren't 0 nor 0x1ffffffff, set DSP
   4256                         control register. */
   4257                      assign(t7, binop(Iop_And32,
   4258                                       binop(Iop_Or32,
   4259                                             unop(Iop_1Sto32, mkexpr(t3)),
   4260                                             unop(Iop_1Sto32, mkexpr(t4))),
   4261                                       binop(Iop_Or32,
   4262                                             unop(Iop_1Sto32, mkexpr(t5)),
   4263                                             unop(Iop_1Sto32, mkexpr(t6)))));
   4264                      putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32,
   4265                                                     mkexpr(t7),
   4266                                                     mkU32(0)),
   4267                                               binop(Iop_Or32,
   4268                                                     getDSPControl(),
   4269                                                     mkU32(0x00800000)),
   4270                                               getDSPControl()));
   4271 
   4272                      /* If the last discarded bit is 1, there would be carry
   4273                         when rounding, otherwise there wouldn't. We use that
   4274                         fact and just add the value of the last discarded bit
   4275                         to the least sifgnificant bit of the shifted value
   4276                         from acc. */
   4277                      assign(t8,
   4278                             IRExpr_ITE(mkexpr(t17),
   4279                                        mkU64(0x0ULL),
   4280                                        binop(Iop_And64,
   4281                                              binop(Iop_Shr64,
   4282                                                    mkexpr(t0),
   4283                                                    unop(Iop_32to8,
   4284                                                         binop(Iop_Sub32,
   4285                                                               mkexpr(t15),
   4286                                                               mkU32(1)))),
   4287                                              mkU64(0x1ULL))));
   4288 
   4289                      assign(t9, binop(Iop_Add64, mkexpr(t1), mkexpr(t8)));
   4290 
   4291                      /* Repeat previous steps for the rounded value. */
   4292                      assign(t10, binop(Iop_CmpNE32,
   4293                                       unop(Iop_64HIto32,
   4294                                            mkexpr(t9)),
   4295                                       mkU32(0)));
   4296                      assign(t11, binop(Iop_CmpNE32,
   4297                                       binop(Iop_And32,
   4298                                             unop(Iop_64to32,
   4299                                                  mkexpr(t9)),
   4300                                             mkU32(0x80000000)),
   4301                                       mkU32(0)));
   4302 
   4303                      assign(t12, binop(Iop_CmpNE32,
   4304                                       unop(Iop_64HIto32,
   4305                                            mkexpr(t9)),
   4306                                       mkU32(0xffffffff)));
   4307                      assign(t13, binop(Iop_CmpNE32,
   4308                                       binop(Iop_And32,
   4309                                             unop(Iop_64to32,
   4310                                                  mkexpr(t9)),
   4311                                             mkU32(0x80000000)),
   4312                                       mkU32(0x80000000)));
   4313 
   4314                      assign(t14, binop(Iop_And32,
   4315                                       binop(Iop_Or32,
   4316                                             unop(Iop_1Sto32, mkexpr(t10)),
   4317                                             unop(Iop_1Sto32, mkexpr(t11))),
   4318                                       binop(Iop_Or32,
   4319                                             unop(Iop_1Sto32, mkexpr(t12)),
   4320                                             unop(Iop_1Sto32, mkexpr(t13)))));
   4321                      putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32,
   4322                                                     mkexpr(t14),
   4323                                                     mkU32(0)),
   4324                                               binop(Iop_Or32,
   4325                                                     getDSPControl(),
   4326                                                     mkU32(0x00800000)),
   4327                                               getDSPControl()));
   4328 
   4329                      assign(t16, binop(Iop_And32,
   4330                                        unop(Iop_64HIto32,
   4331                                             mkexpr(t9)),
   4332                                        mkU32(0x80000000)));
   4333                      putIReg(rt, IRExpr_ITE(binop(Iop_CmpNE32,
   4334                                                   mkexpr(t14),
   4335                                                   mkU32(0)),
   4336                                             IRExpr_ITE(binop(Iop_CmpEQ32,
   4337                                                              mkexpr(t16),
   4338                                                              mkU32(0)),
   4339                                                        mkU32(0x7fffffff),
   4340                                                        mkU32(0x80000000)),
   4341                                             unop(Iop_64to32, mkexpr(t9))));
   4342                      break;
   4343                   }
   4344                   case 0xA: {  /* EXTPDP */
   4345                      DIP("extpdp r%d, ac%d, %d", rt, ac, rs);
   4346                      vassert(!mode64);
   4347                      t0 = newTemp(Ity_I64);
   4348                      t1 = newTemp(Ity_I32);
   4349                      t2 = newTemp(Ity_I1);
   4350                      t3 = newTemp(Ity_I1);
   4351                      t4 = newTemp(Ity_I8);
   4352                      t5 = newTemp(Ity_I64);
   4353                      t6 = newTemp(Ity_I64);
   4354                      t7 = newTemp(Ity_I32);
   4355                      t8 = newTemp(Ity_I32);
   4356 
   4357                      assign(t0, getAcc(ac));
   4358                      /* Extract pos field of DSPControl register. */
   4359                      assign(t1, binop(Iop_And32, getDSPControl(), mkU32(0x3f)));
   4360 
   4361                      /* Check if (pos - size) >= 0 [size <= pos]
   4362                         if (pos < size)
   4363                            put 1 to EFI field of DSPControl register
   4364                         else
   4365                            extract bits from acc and put 0 to EFI field of
   4366                            DSPCtrl */
   4367                      assign(t2, binop(Iop_CmpLT32U, mkexpr(t1), mkU32(rs)));
   4368 
   4369                      assign(t8, binop(Iop_Or32,
   4370                                       binop(Iop_And32,
   4371                                             getDSPControl(),
   4372                                             mkU32(0xffffbfc0)),
   4373                                       binop(Iop_And32,
   4374                                             binop(Iop_Sub32,
   4375                                                   binop(Iop_And32,
   4376                                                         getDSPControl(),
   4377                                                         mkU32(0x3f)),
   4378                                                   mkU32(rs+1)),
   4379                                             mkU32(0x3f))));
   4380                      putDSPControl(IRExpr_ITE(mkexpr(t2),
   4381                                               binop(Iop_Or32,
   4382                                                      binop(Iop_And32,
   4383                                                            getDSPControl(),
   4384                                                            mkU32(0xffffbfff)),
   4385                                                      mkU32(0x4000)),
   4386                                               mkexpr(t8)));
   4387 
   4388                      /* If pos <= 31, shift right the value from the acc
   4389                         (pos-size) times and take (size+1) bits from the least
   4390                         significant positions. Otherwise, shift left the value
   4391                         (63-pos) times, take (size+1) bits from the most
   4392                         significant positions and shift right (31-size) times.
   4393                      */
   4394                      assign(t3, binop(Iop_CmpLE32U, mkexpr(t1), mkU32(31)));
   4395 
   4396                      assign(t4,
   4397                             IRExpr_ITE(mkexpr(t3),
   4398                                        unop(Iop_32to8,
   4399                                             binop(Iop_Sub32,
   4400                                                   mkexpr(t1), mkU32(rs))),
   4401                                        unop(Iop_32to8,
   4402                                             binop(Iop_Sub32,
   4403                                                   mkU32(63), mkexpr(t1)))));
   4404 
   4405                      assign(t5, IRExpr_ITE(mkexpr(t3),
   4406                                            binop(Iop_Shr64,
   4407                                                  mkexpr(t0), mkexpr(t4)),
   4408                                            binop(Iop_Shl64,
   4409                                                  mkexpr(t0), mkexpr(t4))));
   4410 
   4411                      /* t6 holds a mask for bit extraction. */
   4412                      assign(t6,
   4413                             IRExpr_ITE(mkexpr(t3),
   4414                                        unop(Iop_Not64,
   4415                                             binop(Iop_Shl64,
   4416                                                   mkU64(0xffffffffffffffffULL),
   4417                                                   mkU8(rs+1))),
   4418                                        unop(Iop_Not64,
   4419                                             binop(Iop_Shr64,
   4420                                                   mkU64(0xffffffffffffffffULL),
   4421                                                   mkU8(rs+1)))));
   4422 
   4423                      assign(t7, IRExpr_ITE(mkexpr(t3),
   4424                                            unop(Iop_64to32,
   4425                                                 binop(Iop_And64,
   4426                                                       mkexpr(t5),
   4427                                                       mkexpr(t6))),
   4428                                            binop(Iop_Shr32,
   4429                                                  unop(Iop_64HIto32,
   4430                                                       binop(Iop_And64,
   4431                                                             mkexpr(t5),
   4432                                                             mkexpr(t6))),
   4433                                                  mkU8(31-rs))));
   4434 
   4435                      putIReg(rt, mkexpr(t7));
   4436                      break;
   4437                   }
   4438                   case 0xB: {  /* EXTPDPV */
   4439                      DIP("extpdpv r%d, ac%d, r%d", rt, ac, rs);
   4440                      vassert(!mode64);
   4441                      t0 = newTemp(Ity_I64);
   4442                      t1 = newTemp(Ity_I32);
   4443                      t2 = newTemp(Ity_I1);
   4444                      t3 = newTemp(Ity_I1);
   4445                      t4 = newTemp(Ity_I8);
   4446                      t5 = newTemp(Ity_I64);
   4447                      t6 = newTemp(Ity_I64);
   4448                      t7 = newTemp(Ity_I32);
   4449                      t8 = newTemp(Ity_I32);
   4450                      t9 = newTemp(Ity_I32);
   4451 
   4452                      assign(t8, binop(Iop_And32, getIReg(rs), mkU32(0x1f)));
   4453                      assign(t0, getAcc(ac));
   4454                      /* Extract pos field of DSPControl register. */
   4455                      assign(t1, binop(Iop_And32, getDSPControl(), mkU32(0x3f)));
   4456 
   4457                      /* Check if (pos - size) >= 0 [size <= pos]
   4458                         if (pos < size)
   4459                            put 1 to EFI field of DSPControl register
   4460                         else
   4461                            extract bits from acc and put 0 to EFI field of
   4462                            DSPCtrl */
   4463                      assign(t2, binop(Iop_CmpLT32U, mkexpr(t1), mkexpr(t8)));
   4464 
   4465                      assign(t9, binop(Iop_Or32,
   4466                                       binop(Iop_And32,
   4467                                             getDSPControl(),
   4468                                             mkU32(0xffffbfc0)),
   4469                                       binop(Iop_And32,
   4470                                             binop(Iop_Sub32,
   4471                                                   binop(Iop_And32,
   4472                                                         getDSPControl(),
   4473                                                         mkU32(0x3f)),
   4474                                                   binop(Iop_Add32,
   4475                                                         mkexpr(t8),
   4476                                                         mkU32(0x1))),
   4477                                             mkU32(0x3f))));
   4478                      putDSPControl(IRExpr_ITE(mkexpr(t2),
   4479                                               binop(Iop_Or32,
   4480                                                     binop(Iop_And32,
   4481                                                           getDSPControl(),
   4482                                                           mkU32(0xffffbfff)),
   4483                                                     mkU32(0x4000)),
   4484                                               mkexpr(t9)));
   4485 
   4486                      /* If pos <= 31, shift right the value from the acc
   4487                         (pos-size) times and take (size+1) bits from the least
   4488                         significant positions. Otherwise, shift left the value
   4489                         (63-pos) times, take (size+1) bits from the most
   4490                         significant positions and shift right (31-size) times.
   4491                      */
   4492                      assign(t3, binop(Iop_CmpLE32U, mkexpr(t1), mkU32(31)));
   4493 
   4494                      assign(t4,
   4495                             IRExpr_ITE(mkexpr(t3),
   4496                                       unop(Iop_32to8,
   4497                                            binop(Iop_Sub32,
   4498                                                  mkexpr(t1), mkexpr(t8))),
   4499                                       unop(Iop_32to8,
   4500                                            binop(Iop_Sub32,
   4501                                                  mkU32(63), mkexpr(t1)))));
   4502 
   4503                      assign(t5, IRExpr_ITE(mkexpr(t3),
   4504                                            binop(Iop_Shr64,
   4505                                                  mkexpr(t0), mkexpr(t4)),
   4506                                            binop(Iop_Shl64,
   4507                                                  mkexpr(t0), mkexpr(t4))));
   4508 
   4509                      /* t6 holds a mask for bit extraction. */
   4510                      assign(t6,
   4511                             IRExpr_ITE(mkexpr(t3),
   4512                                        unop(Iop_Not64,
   4513                                             binop(Iop_Shl64,
   4514                                                   mkU64(0xffffffffffffffffULL),
   4515                                                   unop(Iop_32to8,
   4516                                                        binop(Iop_Add32,
   4517                                                              mkexpr(t8),
   4518                                                              mkU32(1))))),
   4519                                        unop(Iop_Not64,
   4520                                             binop(Iop_Shr64,
   4521                                                   mkU64(0xffffffffffffffffULL),
   4522                                                   unop(Iop_32to8,
   4523                                                        binop(Iop_Add32,
   4524                                                              mkexpr(t8),
   4525                                                              mkU32(1)))))));
   4526 
   4527                      assign(t7, IRExpr_ITE(mkexpr(t3),
   4528                                            unop(Iop_64to32,
   4529                                                 binop(Iop_And64,
   4530                                                       mkexpr(t5),
   4531                                                       mkexpr(t6))),
   4532                                            binop(Iop_Shr32,
   4533                                                  unop(Iop_64HIto32,
   4534                                                       binop(Iop_And64,
   4535                                                             mkexpr(t5),
   4536                                                             mkexpr(t6))),
   4537                                                  unop(Iop_32to8,
   4538                                                       binop(Iop_Sub32,
   4539                                                             mkU32(31),
   4540                                                             mkexpr(t8))))));
   4541 
   4542                      putIReg(rt, mkexpr(t7));
   4543                      break;
   4544                   }
   4545                   case 0xE: {  /* EXTR_S.H */
   4546                      DIP("extr_s.h r%d, ac%d, %d", rt, ac, rs);
   4547                      vassert(!mode64);
   4548                      t0 = newTemp(Ity_I64);
   4549                      t1 = newTemp(Ity_I64);
   4550                      t2 = newTemp(Ity_I32);
   4551                      t3 = newTemp(Ity_I64);
   4552                      t4 = newTemp(Ity_I32);
   4553                      t5 = newTemp(Ity_I32);
   4554                      t6 = newTemp(Ity_I64);
   4555                      t7 = newTemp(Ity_I32);
   4556                      t9 = newTemp(Ity_I32);
   4557 
   4558                      assign(t0, getAcc(ac));
   4559 
   4560                      assign(t1, binop(Iop_Sar64, mkexpr(t0), mkU8(rs)));
   4561 
   4562                      assign(t2, binop(Iop_Or32,
   4563                                       getDSPControl(), mkU32(0x00800000)));
   4564 
   4565                      assign(t9, binop(Iop_And32,
   4566                                       unop(Iop_64to32,
   4567                                            mkexpr(t1)),
   4568                                       mkU32(0x80000000)));
   4569                      putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32,
   4570                                                     mkexpr(t9),
   4571                                                     binop(Iop_And32,
   4572                                                           unop(Iop_64HIto32,
   4573                                                                mkexpr(t0)),
   4574                                                           mkU32(0x80000000))),
   4575                                               mkexpr(t2),
   4576                                               getDSPControl()));
   4577 
   4578                      /* Check if t1 > 0x7fff ((t1 - 0x7fff) > 0)
   4579                         1. subtract 0x7fff from t1
   4580                         2. if the resulting number is positive (sign bit = 0)
   4581                            and any of the other bits is 1, the value is > 0. */
   4582                      assign(t3, binop(Iop_Sub64,
   4583                                       mkexpr(t1),
   4584                                       mkU64(0x0000000000007fffULL)));
   4585                      assign(t4, binop(Iop_And32,
   4586                                        binop(Iop_Or32,
   4587                                             unop(Iop_1Sto32,
   4588                                                  binop(Iop_CmpNE32,
   4589                                                        mkU32(0),
   4590                                                        binop(Iop_And32,
   4591                                                              unop(Iop_64HIto32,
   4592                                                                   mkexpr(t3)),
   4593                                                              mkU32(0x7fffffff)))),
   4594                                             unop(Iop_1Sto32,
   4595                                                  binop(Iop_CmpNE32,
   4596                                                        mkU32(0),
   4597                                                        unop(Iop_64to32,
   4598                                                             mkexpr(t3))))),
   4599                                        unop(Iop_1Sto32,
   4600                                             binop(Iop_CmpEQ32,
   4601                                                   binop(Iop_And32,
   4602                                                         unop(Iop_64HIto32,
   4603                                                                   mkexpr(t3)),
   4604                                                              mkU32(0x80000000)),
   4605                                                   mkU32(0)))));
   4606                      putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32,
   4607                                                     mkU32(0),
   4608                                                     mkexpr(t4)),
   4609                                               binop(Iop_Or32,
   4610                                                     getDSPControl(),
   4611                                                     mkU32(0x00800000)),
   4612                                               getDSPControl()));
   4613                      /* Check if t1<0xffffffffffff8000 (0xffffffffffff8000-t1)>0
   4614                         1. subtract t1 from 0xffffffffffff8000
   4615                         2. if the resulting number is positive (sign bit = 0)
   4616                             and any of the other bits is 1, the value is > 0 */
   4617                      assign(t6, binop(Iop_Sub64,
   4618                                        mkU64(0xffffffffffff8000ULL),
   4619                                        mkexpr(t1)));
   4620                      assign(t7, binop(Iop_And32,
   4621                                       binop(Iop_Or32,
   4622                                             unop(Iop_1Sto32,
   4623                                                  binop(Iop_CmpNE32,
   4624                                                        mkU32(0),
   4625                                                        binop(Iop_And32,
   4626                                                              unop(Iop_64HIto32,
   4627                                                                   mkexpr(t6)),
   4628                                                              mkU32(0x7fffffff)))),
   4629                                             unop(Iop_1Sto32,
   4630                                                  binop(Iop_CmpNE32,
   4631                                                        mkU32(0),
   4632                                                        unop(Iop_64to32,
   4633                                                             mkexpr(t6))))),
   4634                                       unop(Iop_1Sto32,
   4635                                             binop(Iop_CmpEQ32,
   4636                                                   binop(Iop_And32,
   4637                                                         unop(Iop_64HIto32,
   4638                                                                   mkexpr(t6)),
   4639                                                              mkU32(0x80000000)),
   4640                                                   mkU32(0)))));
   4641                      putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32,
   4642                                                     mkU32(0),
   4643                                                     mkexpr(t7)),
   4644                                               binop(Iop_Or32,
   4645                                                     getDSPControl(),
   4646                                                     mkU32(0x00800000)),
   4647                                               getDSPControl()));
   4648                      putIReg(rt, IRExpr_ITE(binop(Iop_CmpNE32,
   4649                                                     mkU32(0),
   4650                                                     mkexpr(t4)),
   4651                                             mkU32(0x00007fff),
   4652                                             IRExpr_ITE(binop(Iop_CmpNE32,
   4653                                                              mkU32(0),
   4654                                                              mkexpr(t7)),
   4655                                                        mkU32(0xffff8000),
   4656                                                        unop(Iop_64to32,
   4657                                                             mkexpr(t1)))));
   4658                      break;
   4659                   }
   4660                   case 0xF: {  /* EXTRV_S.H */
   4661                      DIP("extrv_s.h r%d, ac%d, %d", rt, ac, rs);
   4662                      vassert(!mode64);
   4663                      t0 = newTemp(Ity_I64);
   4664                      t1 = newTemp(Ity_I64);
   4665                      t2 = newTemp(Ity_I32);
   4666                      t3 = newTemp(Ity_I64);
   4667                      t4 = newTemp(Ity_I32);
   4668                      t5 = newTemp(Ity_I32);
   4669                      t6 = newTemp(Ity_I64);
   4670                      t7 = newTemp(Ity_I32);
   4671                      t9 = newTemp(Ity_I32);
   4672 
   4673                      assign(t0, getAcc(ac));
   4674 
   4675                      assign(t1, binop(Iop_Sar64,
   4676                                       mkexpr(t0),
   4677                                       unop(Iop_32to8,
   4678                                            binop(Iop_And32,
   4679                                                  getIReg(rs),
   4680                                                  mkU32(0x1f)))));
   4681 
   4682                      assign(t2, binop(Iop_Or32,
   4683                                       getDSPControl(), mkU32(0x00800000)));
   4684 
   4685                      assign(t9, binop(Iop_And32,
   4686                                       unop(Iop_64to32,
   4687                                            mkexpr(t1)),
   4688                                       mkU32(0x80000000)));
   4689                      putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32,
   4690                                                     mkexpr(t9),
   4691                                                     binop(Iop_And32,
   4692                                                           unop(Iop_64HIto32,
   4693                                                                mkexpr(t0)),
   4694                                                           mkU32(0x80000000))),
   4695                                               mkexpr(t2),
   4696                                               getDSPControl()));
   4697 
   4698                      /* Check if t1 > 0x7fff ((t1 - 0x7fff) > 0)
   4699                         1. subtract 0x7fff from t1
   4700                         2. if the resulting number is positive (sign bit = 0)
   4701                            and any of the other bits is 1, the value is > 0. */
   4702                      assign(t3, binop(Iop_Sub64,
   4703                                       mkexpr(t1),
   4704                                       mkU64(0x0000000000007fffULL)));
   4705                      assign(t4, binop(Iop_And32,
   4706                                        binop(Iop_Or32,
   4707                                             unop(Iop_1Sto32,
   4708                                                  binop(Iop_CmpNE32,
   4709                                                        mkU32(0),
   4710                                                        binop(Iop_And32,
   4711                                                              unop(Iop_64HIto32,
   4712                                                                   mkexpr(t3)),
   4713                                                              mkU32(0x7fffffff)))),
   4714                                             unop(Iop_1Sto32,
   4715                                                  binop(Iop_CmpNE32,
   4716                                                        mkU32(0),
   4717                                                        unop(Iop_64to32,
   4718                                                             mkexpr(t3))))),
   4719                                        unop(Iop_1Sto32,
   4720                                             binop(Iop_CmpEQ32,
   4721                                                   binop(Iop_And32,
   4722                                                         unop(Iop_64HIto32,
   4723                                                                   mkexpr(t3)),
   4724                                                              mkU32(0x80000000)),
   4725                                                   mkU32(0)))));
   4726                      putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32,
   4727                                                     mkU32(0),
   4728                                                     mkexpr(t4)),
   4729                                               binop(Iop_Or32,
   4730                                                     getDSPControl(),
   4731                                                     mkU32(0x00800000)),
   4732                                               getDSPControl()));
   4733                      /* Check if t1<0xffffffffffff8000 (0xffffffffffff8000-t1)>0
   4734                         1. subtract t1 from 0xffffffffffff8000
   4735                         2. if the resulting number is positive (sign bit = 0)
   4736                             and any of the other bits is 1, the value is > 0 */
   4737                      assign(t6, binop(Iop_Sub64,
   4738                                        mkU64(0xffffffffffff8000ULL),
   4739                                        mkexpr(t1)));
   4740                      assign(t7, binop(Iop_And32,
   4741                                       binop(Iop_Or32,
   4742                                             unop(Iop_1Sto32,
   4743                                                  binop(Iop_CmpNE32,
   4744                                                        mkU32(0),
   4745                                                        binop(Iop_And32,
   4746                                                              unop(Iop_64HIto32,
   4747                                                                   mkexpr(t6)),
   4748                                                              mkU32(0x7fffffff)))),
   4749                                             unop(Iop_1Sto32,
   4750                                                  binop(Iop_CmpNE32,
   4751                                                        mkU32(0),
   4752                                                        unop(Iop_64to32,
   4753                                                             mkexpr(t6))))),
   4754                                       unop(Iop_1Sto32,
   4755                                             binop(Iop_CmpEQ32,
   4756                                                   binop(Iop_And32,
   4757                                                         unop(Iop_64HIto32,
   4758                                                                   mkexpr(t6)),
   4759                                                              mkU32(0x80000000)),
   4760                                                   mkU32(0)))));
   4761                      putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32,
   4762                                                     mkU32(0),
   4763                                                     mkexpr(t7)),
   4764                                               binop(Iop_Or32,
   4765                                                     getDSPControl(),
   4766                                                     mkU32(0x00800000)),
   4767                                               getDSPControl()));
   4768                      putIReg(rt, IRExpr_ITE(binop(Iop_CmpNE32,
   4769                                                     mkU32(0),
   4770                                                     mkexpr(t4)),
   4771                                             mkU32(0x00007fff),
   4772                                             IRExpr_ITE(binop(Iop_CmpNE32,
   4773                                                              mkU32(0),
   4774                                                              mkexpr(t7)),
   4775                                                        mkU32(0xffff8000),
   4776                                                        unop(Iop_64to32,
   4777                                                             mkexpr(t1)))));
   4778                      break;
   4779                   }
   4780                   case 0x12: {  /* RDDSP*/
   4781                      DIP("rddsp r%d, mask 0x%x", rd, rddsp_mask);
   4782                      vassert(!mode64);
   4783 
   4784                      putIReg(rd, mkU32(0x0));
   4785 
   4786                      if ((rddsp_mask & 0x1) == 0x1) {
   4787                         /* Read pos field (bits 5-0) of DSPControl register. */
   4788                         putIReg(rd, binop(Iop_Or32,
   4789                                           getIReg(rd),
   4790                                           binop(Iop_And32,
   4791                                                 getDSPControl(),
   4792                                                 mkU32(0x0000003F))));
   4793                      }
   4794 
   4795                      if ((rddsp_mask & 0x2) == 0x2) {
   4796                         /* Read scount field (bits 12-7) of DSPControl
   4797                            register. */
   4798                         putIReg(rd, binop(Iop_Or32,
   4799                                           getIReg(rd),
   4800                                           binop(Iop_And32,
   4801                                                 getDSPControl(),
   4802                                                 mkU32(0x00001F80))));
   4803                      }
   4804 
   4805                      if ((rddsp_mask & 0x4) == 0x4) {
   4806                         /* Read C field (bit 13) of DSPControl register. */
   4807                         putIReg(rd, binop(Iop_Or32,
   4808                                           getIReg(rd),
   4809                                           binop(Iop_And32,
   4810                                                 getDSPControl(),
   4811                                                 mkU32(0x00002000))));
   4812                      }
   4813 
   4814                      if ((rddsp_mask & 0x8) == 0x8) {
   4815                         /* Read outflag field (bit s 23-16) of DSPControl
   4816                            register. */
   4817                         putIReg(rd, binop(Iop_Or32,
   4818                                           getIReg(rd),
   4819                                           binop(Iop_And32,
   4820                                                 getDSPControl(),
   4821                                                 mkU32(0x00FF0000))));
   4822                      }
   4823 
   4824                      if ((rddsp_mask & 0x10) == 0x10) {
   4825                         /* Read ccond field (bits 31-24) of DSPControl
   4826                            register. */
   4827                         putIReg(rd, binop(Iop_Or32,
   4828                                           getIReg(rd),
   4829                                           binop(Iop_And32,
   4830                                                 getDSPControl(),
   4831                                                 mkU32(0xFF000000))));
   4832                      }
   4833 
   4834                      if ((rddsp_mask & 0x20) == 0x20) {
   4835                         /* Read EFI field (bit 14) of DSPControl register. */
   4836                         putIReg(rd, binop(Iop_Or32,
   4837                                           getIReg(rd),
   4838                                           binop(Iop_And32,
   4839                                                 getDSPControl(),
   4840                                                 mkU32(0x00004000))));
   4841                      }
   4842 
   4843                      if ((rddsp_mask & 0x3f) == 0x3f) {
   4844                         /* Read all fields of DSPControl register. */
   4845                         putIReg(rd, getDSPControl());
   4846                      }
   4847                      break;
   4848                   }
   4849                   case 0x13: {  /* WRDSP */
   4850                      DIP("wrdsp r%d, mask 0x%x", rs, wrdsp_mask);
   4851                      vassert(!mode64);
   4852 
   4853                      if ((wrdsp_mask & 0x3f) == 0x3f) {
   4854                         /* If mips64 put all fields of rs, except bit 15 and bit
   4855                            6, to DSPControl register, otherwise put all except
   4856                            bits 15, 6 and bits 31..28. */
   4857                         putDSPControl(mode64 ?
   4858                                       binop(Iop_And32,
   4859                                             getIReg(rs),
   4860                                             mkU32(0xffff7fbf)) :
   4861                                       binop(Iop_And32,
   4862                                             getIReg(rs),
   4863                                             mkU32(0x0fff7fbf)));
   4864                      } else {
   4865                         if ((wrdsp_mask & 0x1) == 0x1) {
   4866                            /* Put bits 5-0 of rs to DSPControl register pos
   4867                               field. */
   4868                            putDSPControl(binop(Iop_Or32,
   4869                                                binop(Iop_And32,
   4870                                                      getDSPControl(),
   4871                                                      mkU32(0xFFFF7F40)),
   4872                                                binop(Iop_And32,
   4873                                                      getIReg(rs),
   4874                                                      mkU32(0x0000003F))));
   4875                         }
   4876 
   4877                         if ((wrdsp_mask & 0x2) == 0x2) {
   4878                            /* Put bits 12-7 of rs to DSPControl scount field. */
   4879                            putDSPControl(binop(Iop_Or32,
   4880                                                binop(Iop_And32,
   4881                                                      getDSPControl(),
   4882                                                      mkU32(0xFFFFE03F)),
   4883                                                binop(Iop_And32,
   4884                                                      getIReg(rs),
   4885                                                      mkU32(0x00001F80))));
   4886                         }
   4887 
   4888                         if ((wrdsp_mask & 0x4) == 0x4) {
   4889                            /* Put bit 13 of rs to DSPControl register C
   4890                               field. */
   4891                            putDSPControl(binop(Iop_Or32,
   4892                                                binop(Iop_And32,
   4893                                                      getDSPControl(),
   4894                                                      mkU32(0xFFFF5FBF)),
   4895                                                binop(Iop_And32,
   4896                                                      getIReg(rs),
   4897                                                      mkU32(0x00002000))));
   4898                         }
   4899 
   4900                         if ((wrdsp_mask & 0x8) == 0x8) {
   4901                            /* Put bits 23-16 of rs to DSPControl reg outflag
   4902                               field. */
   4903                            putDSPControl(binop(Iop_Or32,
   4904                                                binop(Iop_And32,
   4905                                                      getDSPControl(),
   4906                                                      mkU32(0xFF007FBF)),
   4907                                                binop(Iop_And32,
   4908                                                      getIReg(rs),
   4909                                                      mkU32(0x00FF0000))));
   4910                         }
   4911 
   4912                         if ((wrdsp_mask & 0x10) == 0x10) {
   4913                            /* Put bits 31-24 of rs to DSPControl reg ccond
   4914                               field. */
   4915                            putDSPControl(binop(Iop_Or32,
   4916                                                binop(Iop_And32,
   4917                                                      getDSPControl(),
   4918                                                      mkU32(0x00FF7FBF)),
   4919                                                binop(Iop_And32,
   4920                                                      getIReg(rs),
   4921                                                      mode64 ? mkU32(0xFF000000)
   4922                                                             : mkU32(0x0F000000))
   4923                                                )
   4924                                         );
   4925                         }
   4926 
   4927                         if ((wrdsp_mask & 0x20) == 0x20) {
   4928                            /* Put bit 14 of rs to DSPControl register EFI
   4929                               field. */
   4930                            putDSPControl(binop(Iop_Or32,
   4931                                                binop(Iop_And32,
   4932                                                      getDSPControl(),
   4933                                                      mkU32(0xFFFF3FBF)),
   4934                                                binop(Iop_And32,
   4935                                                      getIReg(rs),
   4936                                                      mkU32(0x00004000))));
   4937                         }
   4938                      }
   4939                      break;
   4940                   }
   4941                   case 0x1A: {  /* SHILO */
   4942                      DIP("shilo ac%d, %d", ac, shift);
   4943                      vassert(!mode64);
   4944                      t0 = newTemp(Ity_I64);
   4945                      t1 = newTemp(Ity_I64);
   4946 
   4947                      assign(t0, getAcc(ac));
   4948 
   4949                      putAcc(ac, mkexpr(t0));
   4950 
   4951                      if (0x20 == (shift & 0x3f)) {
   4952                         putAcc(ac, binop(Iop_32HLto64,
   4953                                          unop(Iop_64to32, mkexpr(t0)),
   4954                                          mkU32(0x0)));
   4955                      } else if (0x20 == (shift & 0x20)) {
   4956                         assign(t1, binop(Iop_Shl64,
   4957                                          mkexpr(t0),
   4958                                          unop(Iop_32to8,
   4959                                               binop(Iop_Add32,
   4960                                                     unop(Iop_Not32,
   4961                                                          mkU32(shift)),
   4962                                                     mkU32(0x1)))));
   4963 
   4964                         putAcc(ac, mkexpr(t1));
   4965                      } else {
   4966                         assign(t1, binop(Iop_Shr64, mkexpr(t0), mkU8(shift)));
   4967 
   4968                         putAcc(ac, mkexpr(t1));
   4969                      }
   4970                      break;
   4971                   }
   4972                   case 0x1B: {  /* SHILOV */
   4973                      DIP("shilov ac%d, r%d", ac, rs);
   4974                      vassert(!mode64);
   4975                      t0 = newTemp(Ity_I64);
   4976                      t1 = newTemp(Ity_I32);
   4977                      t2 = newTemp(Ity_I1);
   4978                      t3 = newTemp(Ity_I64);
   4979                      t4 = newTemp(Ity_I64);
   4980 
   4981                      assign(t0, getAcc(ac));
   4982                      assign(t1, binop(Iop_And32, getIReg(rs), mkU32(0x3f)));
   4983                      assign(t2, binop(Iop_CmpEQ32, mkexpr(t1), mkU32(0x20)));
   4984                      assign(t3, binop(Iop_Shl64,
   4985                                       mkexpr(t0),
   4986                                       unop(Iop_32to8,
   4987                                            binop(Iop_Add32,
   4988                                                  unop(Iop_Not32,
   4989                                                       mkexpr(t1)),
   4990                                                  mkU32(0x1)))));
   4991                      assign(t4, binop(Iop_Shr64,
   4992                                       mkexpr(t0),
   4993                                       unop(Iop_32to8,
   4994                                            mkexpr(t1))));
   4995 
   4996                      putAcc(ac,
   4997                             IRExpr_ITE(mkexpr(t2),
   4998                                        binop(Iop_32HLto64,
   4999                                              unop(Iop_64to32, mkexpr(t0)),
   5000                                              mkU32(0x0)),
   5001                                        IRExpr_ITE(binop(Iop_CmpEQ32,
   5002                                                         binop(Iop_And32,
   5003                                                               mkexpr(t1),
   5004                                                               mkU32(0x20)),
   5005                                                         mkU32(0x20)),
   5006                                                   mkexpr(t3),
   5007                                                   mkexpr(t4))));
   5008                      break;
   5009                   }
   5010                   case 0x1F: {  /* MTHLIP */
   5011                      DIP("mthlip r%d, ac%d", rs, ac);
   5012                      vassert(!mode64);
   5013                      t0 = newTemp(Ity_I64);
   5014                      t1 = newTemp(Ity_I32);
   5015                      t2 = newTemp(Ity_I32);
   5016                      t3 = newTemp(Ity_I1);
   5017 
   5018                      assign(t0, getAcc(ac));
   5019                      putAcc(ac, binop(Iop_32HLto64,
   5020                                       unop(Iop_64to32, mkexpr(t0)),
   5021                                       getIReg(rs)));
   5022                      assign(t1, binop(Iop_And32, getDSPControl(), mkU32(0x3f)));
   5023                      putDSPControl(IRExpr_ITE(binop(Iop_CmpLE32U,
   5024                                                     mkU32(32),
   5025                                                     mkexpr(t1)),
   5026                                               binop(Iop_Or32,
   5027                                                     binop(Iop_Sub32,
   5028                                                           mkexpr(t1),
   5029                                                           mkU32(32)),
   5030                                                    binop(Iop_And32,
   5031                                                          getDSPControl(),
   5032                                                          mkU32(0xffffffc0))),
   5033                                               binop(Iop_Or32,
   5034                                                     binop(Iop_Add32,
   5035                                                           mkexpr(t1),
   5036                                                           mkU32(32)),
   5037                                                     binop(Iop_And32,
   5038                                                           getDSPControl(),
   5039                                                           mkU32(0xffffffc0)))));
   5040                      break;
   5041                   }
   5042                   default:
   5043                      return -1;
   5044                }
   5045                break;  /* end of EXTR.W */
   5046             }
   5047             case 0xA: {  /* LX */
   5048                switch(sa) {
   5049                   case 0x0: {  /* LWX */
   5050                      DIP("lwx r%d, r%d(r%d)", rd, rt, rs);
   5051                      vassert(!mode64);
   5052                      t0 = newTemp(Ity_I32);
   5053 
   5054                      assign(t0, binop(Iop_Add32, getIReg(rt), getIReg(rs)));
   5055 
   5056                      putIReg(rd, load(Ity_I32, mkexpr(t0)));
   5057                      break;
   5058                   }
   5059                   case 0x4: {  /* LHX */
   5060                      DIP("lhx r%d, r%d(r%d)", rd, rt, rs);
   5061                      vassert(!mode64);
   5062                      t0 = newTemp(Ity_I32);
   5063 
   5064                      assign(t0, binop(Iop_Add32, getIReg(rt), getIReg(rs)));
   5065 
   5066                      putIReg(rd, unop(Iop_16Sto32, load(Ity_I16, mkexpr(t0))));
   5067                      break;
   5068                   }
   5069                   case 0x6: {  /* LBUX */
   5070                      DIP("lbux r%d, r%d(r%d)", rd, rt, rs);
   5071                      vassert(!mode64);
   5072                      t0 = newTemp(Ity_I32);
   5073 
   5074                      assign(t0, binop(Iop_Add32, getIReg(rt), getIReg(rs)));
   5075 
   5076                      putIReg(rd, unop(Iop_8Uto32, load(Ity_I8, mkexpr(t0))));
   5077                      break;
   5078                   }
   5079                   default:
   5080                      return -1;
   5081                }
   5082                break;  /* end of LX */
   5083             }
   5084             case 0xC: {  /* INSV */
   5085                switch(sa) {
   5086                   case 0x0: {  /* INSV */
   5087                      DIP("insv r%d, r%d", rt, rs);
   5088                      vassert(!mode64);
   5089 
   5090                      t0 = newTemp(Ity_I32);
   5091                      t1 = newTemp(Ity_I32);
   5092                      t2 = newTemp(Ity_I8);
   5093                      t3 = newTemp(Ity_I8);
   5094                      t4 = newTemp(Ity_I32);
   5095                      t5 = newTemp(Ity_I1);
   5096                      t6 = newTemp(Ity_I32);
   5097                      t7 = newTemp(Ity_I32);
   5098                      t8 = newTemp(Ity_I32);
   5099                      t9 = newTemp(Ity_I32);
   5100 
   5101                      /* t0 <- pos field of DSPControl register. */
   5102                      assign(t0, binop(Iop_And32, getDSPControl(), mkU32(0x3f)));
   5103                      /* t1 <- scount field of DSPControl register. */
   5104                      assign(t1, binop(Iop_Shr32,
   5105                                       binop(Iop_And32,
   5106                                             getDSPControl(),
   5107                                             mkU32(0x1f80)),
   5108                                       mkU8(7)));
   5109 
   5110                      assign(t2, unop(Iop_32to8,
   5111                                      binop(Iop_Add32,
   5112                                            mkexpr(t1),
   5113                                            mkexpr(t0))));
   5114 
   5115                      /* 32-(pos+size) most significant bits of rt. */
   5116                      assign(t6, binop(Iop_Shl32,
   5117                                       binop(Iop_Shr32,
   5118                                             getIReg(rt),
   5119                                             mkexpr(t2)),
   5120                                       mkexpr(t2)));
   5121 
   5122                      assign(t3, unop(Iop_32to8,
   5123                                      binop(Iop_Sub32,
   5124                                            mkU32(32),
   5125                                            mkexpr(t0))));
   5126                      /* Pos least significant bits of rt. */
   5127                      assign(t7, binop(Iop_Shr32,
   5128                                       binop(Iop_Shl32,
   5129                                             getIReg(rt),
   5130                                             mkexpr(t3)),
   5131                                       mkexpr(t3)));
   5132 
   5133                      /* Size least significant bits of rs,
   5134                         shifted to appropriate position. */
   5135                      assign(t8, binop(Iop_Shl32,
   5136                                       binop(Iop_And32,
   5137                                             getIReg(rs),
   5138                                             unop(Iop_Not32,
   5139                                                  binop(Iop_Shl32,
   5140                                                        mkU32(0xffffffff),
   5141                                                        unop(Iop_32to8,
   5142                                                             mkexpr(t1))))),
   5143                                       unop(Iop_32to8,
   5144                                            mkexpr(t0))));
   5145 
   5146                      putIReg(rt, IRExpr_ITE(binop(Iop_CmpEQ32,
   5147                                                   mkexpr(t0),
   5148                                                   mkU32(0)),
   5149                                             IRExpr_ITE(binop(Iop_CmpEQ32,
   5150                                                              mkexpr(t1),
   5151                                                              mkU32(32)),
   5152                                                        getIReg(rs),
   5153                                                        binop(Iop_Or32,
   5154                                                              mkexpr(t6),
   5155                                                              mkexpr(t8))),
   5156                                             IRExpr_ITE(binop(Iop_CmpEQ32,
   5157                                                              unop(Iop_8Uto32,
   5158                                                                   mkexpr(t2)),
   5159                                                              mkU32(32)),
   5160                                                        binop(Iop_Or32,
   5161                                                              mkexpr(t7),
   5162                                                              mkexpr(t8)),
   5163                                                        binop(Iop_Or32,
   5164                                                              binop(Iop_Or32,
   5165                                                                    mkexpr(t6),
   5166                                                                    mkexpr(t7)),
   5167                                                              mkexpr(t8)))));
   5168                      break;
   5169                   }
   5170                   default:
   5171                      return -1;
   5172                }
   5173                break;  /* enf of INSV */
   5174             }
   5175             case 0x10: {  /* ADDU.QB */
   5176                switch(sa) {
   5177                   case 0x00: {  /* ADDU.QB */
   5178                      DIP("addu.qb r%d, r%d, r%d", rd, rs, rt);
   5179                      vassert(!mode64);
   5180                      t0 = newTemp(Ity_I32);
   5181                      t1 = newTemp(Ity_I1);
   5182                      t2 = newTemp(Ity_I32);
   5183                      t3 = newTemp(Ity_I1);
   5184                      t4 = newTemp(Ity_I32);
   5185                      t5 = newTemp(Ity_I1);
   5186                      t6 = newTemp(Ity_I32);
   5187                      t7 = newTemp(Ity_I1);
   5188                      t8 = newTemp(Ity_I32);
   5189 
   5190                      /* Add rightmost bytes of rs and rt. */
   5191                      assign(t0,
   5192                             binop(Iop_Add32,
   5193                                   unop(Iop_8Uto32,
   5194                                        unop(Iop_16to8,
   5195                                             unop(Iop_32to16, getIReg(rs)))),
   5196                                   unop(Iop_8Uto32,
   5197                                        unop(Iop_16to8,
   5198                                             unop(Iop_32to16, getIReg(rt))))));
   5199                      /* t1 will be 1 if there is overflow, 0 otherwise. */
   5200                      assign(t1, binop(Iop_CmpEQ32,
   5201                                       binop(Iop_And32,
   5202                                             mkexpr(t0),
   5203                                             mkU32(0x00000100)),
   5204                                       mkU32(0x00000100)));
   5205 
   5206                      /* Add bits 15-8 of rs and rt. */
   5207                      assign(t2,
   5208                             binop(Iop_Add32,
   5209                                   unop(Iop_8Uto32,
   5210                                        unop(Iop_16HIto8,
   5211                                             unop(Iop_32to16, getIReg(rs)))),
   5212                                   unop(Iop_8Uto32,
   5213                                        unop(Iop_16HIto8,
   5214                                             unop(Iop_32to16, getIReg(rt))))));
   5215                      /* t3 will be 1 if there is overflow, 0 otherwise. */
   5216                      assign(t3, binop(Iop_CmpEQ32,
   5217                                       binop(Iop_And32,
   5218                                             mkexpr(t2),
   5219                                             mkU32(0x00000100)),
   5220                                       mkU32(0x00000100)));
   5221 
   5222                      /* Add bits 15-8 of rs and rt. */
   5223                      assign(t4,
   5224                             binop(Iop_Add32,
   5225                                   unop(Iop_8Uto32,
   5226                                        unop(Iop_16to8,
   5227                                             unop(Iop_32HIto16, getIReg(rs)))),
   5228                                   unop(Iop_8Uto32,
   5229                                        unop(Iop_16to8,
   5230                                             unop(Iop_32HIto16, getIReg(rt))))));
   5231                      /* t5 will be 1 if there is overflow, 0 otherwise. */
   5232                      assign(t5, binop(Iop_CmpEQ32,
   5233                                       binop(Iop_And32,
   5234                                             mkexpr(t4),
   5235                                             mkU32(0x00000100)),
   5236                                       mkU32(0x00000100)));
   5237 
   5238                      /* Add bits 15-8 of rs and rt. */
   5239                      assign(t6,
   5240                             binop(Iop_Add32,
   5241                                   unop(Iop_8Uto32,
   5242                                        unop(Iop_16HIto8,
   5243                                             unop(Iop_32HIto16, getIReg(rs)))),
   5244                                   unop(Iop_8Uto32,
   5245                                        unop(Iop_16HIto8,
   5246                                             unop(Iop_32HIto16, getIReg(rt))))));
   5247                      /* t7 will be 1 if there is overflow, 0 otherwise. */
   5248                      assign(t7, binop(Iop_CmpEQ32,
   5249                                       binop(Iop_And32,
   5250                                             mkexpr(t6),
   5251                                             mkU32(0x00000100)),
   5252                                       mkU32(0x00000100)));
   5253 
   5254                      assign(t8,
   5255                             binop(Iop_Or32,
   5256                                   binop(Iop_Or32,
   5257                                         binop(Iop_Or32,
   5258                                               unop(Iop_1Sto32, mkexpr(t7)),
   5259                                               unop(Iop_1Sto32,  mkexpr(t5))),
   5260                                         unop(Iop_1Sto32, mkexpr(t3))),
   5261                                   unop(Iop_1Sto32, mkexpr(t1))));
   5262 
   5263                      putDSPControl(IRExpr_ITE(binop(Iop_CmpEQ32,
   5264                                                     mkexpr(t8),
   5265                                                     mkU32(0x0)),
   5266                                               getDSPControl(),
   5267                                               binop(Iop_Or32,
   5268                                                     getDSPControl(),
   5269                                                     mkU32(0x00100000))));
   5270 
   5271                      putIReg(rd, binop(Iop_16HLto32,
   5272                                        binop(Iop_8HLto16,
   5273                                              unop(Iop_32to8, mkexpr(t6)),
   5274                                              unop(Iop_32to8, mkexpr(t4))),
   5275                                        binop(Iop_8HLto16,
   5276                                              unop(Iop_32to8, mkexpr(t2)),
   5277                                              unop(Iop_32to8, mkexpr(t0)))));
   5278                      break;
   5279                   }
   5280                   case 0x1: {  /* SUBU.QB */
   5281                      DIP("subu.qb r%d, r%d, r%d", rd, rs, rt);
   5282                      vassert(!mode64);
   5283                      t0 = newTemp(Ity_I32);
   5284                      t1 = newTemp(Ity_I1);
   5285                      t2 = newTemp(Ity_I32);
   5286                      t3 = newTemp(Ity_I1);
   5287                      t4 = newTemp(Ity_I32);
   5288                      t5 = newTemp(Ity_I1);
   5289                      t6 = newTemp(Ity_I32);
   5290                      t7 = newTemp(Ity_I1);
   5291                      t8 = newTemp(Ity_I32);
   5292 
   5293                      /* Subtract rightmost bytes of rs and rt. */
   5294                      assign(t0,
   5295                             binop(Iop_Sub32,
   5296                                   unop(Iop_8Uto32,
   5297                                        unop(Iop_16to8,
   5298                                             unop(Iop_32to16, getIReg(rs)))),
   5299                                   unop(Iop_8Uto32,
   5300                                        unop(Iop_16to8,
   5301                                             unop(Iop_32to16, getIReg(rt))))));
   5302                      /* t1 will be 1 if there is overflow, 0 otherwise. */
   5303                      assign(t1, binop(Iop_CmpEQ32,
   5304                                       binop(Iop_And32,
   5305                                             mkexpr(t0),
   5306                                             mkU32(0x00000100)),
   5307                                       mkU32(0x00000100)));
   5308 
   5309                      /* Subtract bits 15-8 of rs and rt. */
   5310                      assign(t2,
   5311                             binop(Iop_Sub32,
   5312                                   unop(Iop_8Uto32,
   5313                                        unop(Iop_16HIto8,
   5314                                             unop(Iop_32to16, getIReg(rs)))),
   5315                                   unop(Iop_8Uto32,
   5316                                        unop(Iop_16HIto8,
   5317                                             unop(Iop_32to16, getIReg(rt))))));
   5318                      /* t3 will be 1 if there is overflow, 0 otherwise. */
   5319                      assign(t3, binop(Iop_CmpEQ32,
   5320                                       binop(Iop_And32,
   5321                                             mkexpr(t2),
   5322                                             mkU32(0x00000100)),
   5323                                       mkU32(0x00000100)));
   5324 
   5325                      /* Subtract bits 15-8 of rs and rt. */
   5326                      assign(t4,
   5327                             binop(Iop_Sub32,
   5328                                   unop(Iop_8Uto32,
   5329                                        unop(Iop_16to8,
   5330                                             unop(Iop_32HIto16, getIReg(rs)))),
   5331                                   unop(Iop_8Uto32,
   5332                                        unop(Iop_16to8,
   5333                                             unop(Iop_32HIto16, getIReg(rt))))));
   5334                      /* t5 will be 1 if there is overflow, 0 otherwise. */
   5335                      assign(t5, binop(Iop_CmpEQ32,
   5336                                       binop(Iop_And32,
   5337                                             mkexpr(t4),
   5338                                             mkU32(0x00000100)),
   5339                                       mkU32(0x00000100)));
   5340 
   5341                      /* Subtract bits 15-8 of rs and rt. */
   5342                      assign(t6,
   5343                             binop(Iop_Sub32,
   5344                                   unop(Iop_8Uto32,
   5345                                        unop(Iop_16HIto8,
   5346                                             unop(Iop_32HIto16, getIReg(rs)))),
   5347                                   unop(Iop_8Uto32,
   5348                                        unop(Iop_16HIto8,
   5349                                             unop(Iop_32HIto16, getIReg(rt))))));
   5350                      /* t7 will be 1 if there is overflow, 0 otherwise. */
   5351                      assign(t7, binop(Iop_CmpEQ32,
   5352                                       binop(Iop_And32,
   5353                                             mkexpr(t6),
   5354                                             mkU32(0x00000100)),
   5355                                       mkU32(0x00000100)));
   5356 
   5357                      assign(t8, binop(Iop_Or32,
   5358                                       binop(Iop_Or32,
   5359                                             binop(Iop_Or32,
   5360                                                   unop(Iop_1Sto32, mkexpr(t7)),
   5361                                                   unop(Iop_1Sto32, mkexpr(t5))),
   5362                                             unop(Iop_1Sto32, mkexpr(t3))),
   5363                                       unop(Iop_1Sto32, mkexpr(t1))));
   5364 
   5365                      putDSPControl(IRExpr_ITE(binop(Iop_CmpEQ32,
   5366                                                      mkexpr(t8),
   5367                                                      mkU32(0x0)),
   5368                                               getDSPControl(),
   5369                                               binop(Iop_Or32,
   5370                                                     getDSPControl(),
   5371                                                     mkU32(0x00100000))));
   5372 
   5373                      putIReg(rd, binop(Iop_16HLto32,
   5374                                        binop(Iop_8HLto16,
   5375                                              unop(Iop_32to8, mkexpr(t6)),
   5376                                              unop(Iop_32to8, mkexpr(t4))),
   5377                                        binop(Iop_8HLto16,
   5378                                              unop(Iop_32to8, mkexpr(t2)),
   5379                                              unop(Iop_32to8, mkexpr(t0)))));
   5380                      break;
   5381                   }
   5382                   case 0x04: {  /* ADDU_S.QB */
   5383                      DIP("addu_s.qb r%d, r%d, r%d", rd, rs, rt);
   5384                      vassert(!mode64);
   5385                      t0 = newTemp(Ity_I32);
   5386                      t1 = newTemp(Ity_I1);
   5387                      t2 = newTemp(Ity_I8);
   5388                      t3 = newTemp(Ity_I32);
   5389                      t4 = newTemp(Ity_I1);
   5390                      t5 = newTemp(Ity_I8);
   5391                      t6 = newTemp(Ity_I32);
   5392                      t7 = newTemp(Ity_I1);
   5393                      t8 = newTemp(Ity_I8);
   5394                      t9 = newTemp(Ity_I32);
   5395                      t10 = newTemp(Ity_I1);
   5396                      t11 = newTemp(Ity_I8);
   5397                      t12 = newTemp(Ity_I32);
   5398 
   5399                      /* Add rightmost bytes of rs and rt. */
   5400                      assign(t0,
   5401                             binop(Iop_Add32,
   5402                                   unop(Iop_8Uto32,
   5403                                        unop(Iop_16to8,
   5404                                             unop(Iop_32to16, getIReg(rs)))),
   5405                                   unop(Iop_8Uto32,
   5406                                        unop(Iop_16to8,
   5407                                             unop(Iop_32to16, getIReg(rt))))));
   5408                      /* t1 will be 1 if there is overflow, 0 otherwise. */
   5409                      assign(t1, binop(Iop_CmpEQ32,
   5410                                       binop(Iop_And32,
   5411                                             mkexpr(t0),
   5412                                             mkU32(0x00000100)),
   5413                                       mkU32(0x00000100)));
   5414                      /* Saturate if necessary. */
   5415                      assign(t2, IRExpr_ITE(mkexpr(t1),
   5416                                            mkU8(0xff),
   5417                                            unop(Iop_32to8, mkexpr(t0))));
   5418 
   5419                      /* Add bits 15-8 of rs and rt. */
   5420                      assign(t3,
   5421                             binop(Iop_Add32,
   5422                                   unop(Iop_8Uto32,
   5423                                        unop(Iop_16HIto8,
   5424                                             unop(Iop_32to16, getIReg(rs)))),
   5425                                   unop(Iop_8Uto32,
   5426                                        unop(Iop_16HIto8,
   5427                                             unop(Iop_32to16, getIReg(rt))))));
   5428                      /* t4 will be 1 if there is overflow, 0 otherwise. */
   5429                      assign(t4, binop(Iop_CmpEQ32,
   5430                                       binop(Iop_And32,
   5431                                             mkexpr(t3),
   5432                                             mkU32(0x00000100)),
   5433                                       mkU32(0x00000100)));
   5434                      /* Saturate if necessary. */
   5435                      assign(t5, IRExpr_ITE(mkexpr(t4),
   5436                                            mkU8(0xff),
   5437                                            unop(Iop_32to8, mkexpr(t3))));
   5438 
   5439                      /* Add bits 15-8 of rs and rt. */
   5440                      assign(t6,
   5441                             binop(Iop_Add32,
   5442                                   unop(Iop_8Uto32,
   5443                                        unop(Iop_16to8,
   5444                                             unop(Iop_32HIto16, getIReg(rs)))),
   5445                                   unop(Iop_8Uto32,
   5446                                        unop(Iop_16to8,
   5447                                             unop(Iop_32HIto16, getIReg(rt))))));
   5448                      /* t7 will be 1 if there is overflow, 0 otherwise. */
   5449                      assign(t7, binop(Iop_CmpEQ32,
   5450                                       binop(Iop_And32,
   5451                                             mkexpr(t6),
   5452                                             mkU32(0x00000100)),
   5453                                       mkU32(0x00000100)));
   5454                      /* Saturate if necessary. */
   5455                      assign(t8, IRExpr_ITE(mkexpr(t7),
   5456                                            mkU8(0xff),
   5457                                            unop(Iop_32to8, mkexpr(t6))));
   5458 
   5459                      /* Add bits 15-8 of rs and rt. */
   5460                      assign(t9,
   5461                             binop(Iop_Add32,
   5462                                   unop(Iop_8Uto32,
   5463                                        unop(Iop_16HIto8,
   5464                                             unop(Iop_32HIto16, getIReg(rs)))),
   5465                                   unop(Iop_8Uto32,
   5466                                        unop(Iop_16HIto8,
   5467                                             unop(Iop_32HIto16, getIReg(rt))))));
   5468                      /* t10 will be 1 if there is overflow, 0 otherwise. */
   5469                      assign(t10, binop(Iop_CmpEQ32,
   5470                                        binop(Iop_And32,
   5471                                              mkexpr(t9),
   5472                                              mkU32(0x00000100)),
   5473                                        mkU32(0x00000100)));
   5474                      /* Saturate if necessary. */
   5475                      assign(t11, IRExpr_ITE(mkexpr(t10),
   5476                                             mkU8(0xff),
   5477                                             unop(Iop_32to8, mkexpr(t9))));
   5478 
   5479                      assign(t12,
   5480                             binop(Iop_Or32,
   5481                                   binop(Iop_Or32,
   5482                                         binop(Iop_Or32,
   5483                                               unop(Iop_1Sto32, mkexpr(t10)),
   5484                                               unop(Iop_1Sto32, mkexpr(t7))),
   5485                                         unop(Iop_1Sto32, mkexpr(t4))),
   5486                                   unop(Iop_1Sto32, mkexpr(t1))));
   5487 
   5488                      putDSPControl(IRExpr_ITE(binop(Iop_CmpEQ32,
   5489                                                     mkexpr(t12),
   5490                                                     mkU32(0x0)),
   5491                                               getDSPControl(),
   5492                                               binop(Iop_Or32,
   5493                                                     getDSPControl(),
   5494                                                     mkU32(0x00100000))));
   5495 
   5496                      putIReg(rd,
   5497                              binop(Iop_16HLto32,
   5498                                    binop(Iop_8HLto16, mkexpr(t11), mkexpr(t8)),
   5499                                    binop(Iop_8HLto16, mkexpr(t5), mkexpr(t2))));
   5500                      break;
   5501                   }
   5502                   case 0x05: {  /* SUBU_S.QB */
   5503                      DIP("subu_s.qb r%d, r%d, r%d", rd, rs, rt);
   5504                      vassert(!mode64);
   5505                      t1 = newTemp(Ity_I32);
   5506                      t2 = newTemp(Ity_I1);
   5507                      t3 = newTemp(Ity_I1);
   5508                      t4 = newTemp(Ity_I1);
   5509                      t5 = newTemp(Ity_I1);
   5510                      t6 = newTemp(Ity_I32);
   5511                      t7 = newTemp(Ity_I32);
   5512                      t8 = newTemp(Ity_I32);
   5513                      t9 = newTemp(Ity_I32);
   5514 
   5515                      /* Use C function to easily calculate the result
   5516                         and write it in the register more conveniently
   5517                         Underflow is checked using step by step subtraction. */
   5518                      assign(t1, binop(Iop_QSub8Ux4, getIReg(rs), getIReg(rt)));
   5519 
   5520                      /* Subtract each byte of rs and rt. */
   5521                      assign(t6,
   5522                             binop(Iop_Sub32,
   5523                                   unop(Iop_8Uto32,
   5524                                        unop(Iop_16to8,
   5525                                             unop(Iop_32to16, getIReg(rs)))),
   5526                                   unop(Iop_8Uto32,
   5527                                        unop(Iop_16to8,
   5528                                             unop(Iop_32to16, getIReg(rt))))));
   5529                      assign(t7,
   5530                             binop(Iop_Sub32,
   5531                                   unop(Iop_8Uto32,
   5532                                        unop(Iop_16HIto8,
   5533                                             unop(Iop_32to16, getIReg(rs)))),
   5534                                   unop(Iop_8Uto32,
   5535                                        unop(Iop_16HIto8,
   5536                                             unop(Iop_32to16, getIReg(rt))))));
   5537                      assign(t8,
   5538                             binop(Iop_Sub32,
   5539                                   unop(Iop_8Uto32,
   5540                                        unop(Iop_16to8,
   5541                                             unop(Iop_32HIto16, getIReg(rs)))),
   5542                                   unop(Iop_8Uto32,
   5543                                        unop(Iop_16to8,
   5544                                             unop(Iop_32HIto16, getIReg(rt))))));
   5545                      assign(t9,
   5546                             binop(Iop_Sub32,
   5547                                   unop(Iop_8Uto32,
   5548                                        unop(Iop_16HIto8,
   5549                                             unop(Iop_32HIto16, getIReg(rs)))),
   5550                                   unop(Iop_8Uto32,
   5551                                        unop(Iop_16HIto8,
   5552                                             unop(Iop_32HIto16, getIReg(rt))))));
   5553 
   5554                      /* Put 1 to bit 20 in DSPControl if there is underflow
   5555                         in either byte. */
   5556                      assign(t2, binop(Iop_CmpEQ32,
   5557                                       binop(Iop_And32,
   5558                                             mkexpr(t6),
   5559                                             mkU32(0x00000100)),
   5560                                       mkU32(0x00000100)));
   5561                      putDSPControl(IRExpr_ITE(mkexpr(t2),
   5562                                               binop(Iop_Or32,
   5563                                                     getDSPControl(),
   5564                                                     mkU32(0x00100000)),
   5565                                               getDSPControl()));
   5566                      assign(t3, binop(Iop_CmpEQ32,
   5567                                       binop(Iop_And32,
   5568                                             mkexpr(t7),
   5569                                             mkU32(0x00000100)),
   5570                                       mkU32(0x00000100)));
   5571                      putDSPControl(IRExpr_ITE(mkexpr(t3),
   5572                                               binop(Iop_Or32,
   5573                                                     getDSPControl(),
   5574                                                     mkU32(0x00100000)),
   5575                                               getDSPControl()));
   5576                      assign(t4, binop(Iop_CmpEQ32,
   5577                                       binop(Iop_And32,
   5578                                             mkexpr(t8),
   5579                                             mkU32(0x00000100)),
   5580                                       mkU32(0x00000100)));
   5581                      putDSPControl(IRExpr_ITE(mkexpr(t4),
   5582                                               binop(Iop_Or32,
   5583                                                     getDSPControl(),
   5584                                                     mkU32(0x00100000)),
   5585                                               getDSPControl()));
   5586                      assign(t5, binop(Iop_CmpEQ32,
   5587                                       binop(Iop_And32,
   5588                                             mkexpr(t9),
   5589                                             mkU32(0x00000100)),
   5590                                       mkU32(0x00000100)));
   5591                      putDSPControl(IRExpr_ITE(mkexpr(t5),
   5592                                               binop(Iop_Or32,
   5593                                                     getDSPControl(),
   5594                                                     mkU32(0x00100000)),
   5595                                               getDSPControl()));
   5596                      putIReg(rd, mkexpr(t1));
   5597                      break;
   5598                   }
   5599                   case 0x6: {  /* MULEU_S.PH.QBL */
   5600                      DIP("muleu_s.ph.qbl r%d, r%d, r%d", rd, rs, rt);
   5601                      vassert(!mode64);
   5602                      t0 = newTemp(Ity_I32);
   5603                      t1 = newTemp(Ity_I32);
   5604                      t2 = newTemp(Ity_I1);
   5605                      t3 = newTemp(Ity_I1);
   5606 
   5607                      assign(t0,
   5608                             unop(Iop_64to32,
   5609                                  binop(Iop_MullU32,
   5610                                        unop(Iop_8Uto32,
   5611                                             unop(Iop_16HIto8,
   5612                                                  unop(Iop_32HIto16,
   5613                                                       getIReg(rs)))),
   5614                                        unop(Iop_16Uto32,
   5615                                             unop(Iop_32HIto16, getIReg(rt))))));
   5616                      assign(t1,
   5617                             unop(Iop_64to32,
   5618                                  binop(Iop_MullU32,
   5619                                        unop(Iop_8Uto32,
   5620                                             unop(Iop_16to8,
   5621                                                  unop(Iop_32HIto16,
   5622                                                       getIReg(rs)))),
   5623                                        unop(Iop_16Uto32,
   5624                                             unop(Iop_32to16, getIReg(rt))))));
   5625 
   5626                      assign(t2, binop(Iop_CmpNE32,
   5627                                       mkU32(0x0),
   5628                                       binop(Iop_And32,
   5629                                             mkexpr(t0),
   5630                                             mkU32(0x03ff0000))));
   5631                      assign(t3, binop(Iop_CmpNE32,
   5632                                       mkU32(0x0),
   5633                                       binop(Iop_And32,
   5634                                             mkexpr(t1),
   5635                                             mkU32(0x03ff0000))));
   5636                      putDSPControl(IRExpr_ITE(mkexpr(t2),
   5637                                               binop(Iop_Or32,
   5638                                                     getDSPControl(),
   5639                                                     mkU32(0x200000)),
   5640                                               IRExpr_ITE(mkexpr(t3),
   5641                                                          binop(Iop_Or32,
   5642                                                                getDSPControl(),
   5643                                                                mkU32(0x200000)),
   5644                                                          getDSPControl())));
   5645                      putIReg(rd,
   5646                              binop(Iop_16HLto32,
   5647                                    IRExpr_ITE(mkexpr(t2),
   5648                                               mkU16(0xffff),
   5649                                               unop(Iop_32to16, mkexpr(t0))),
   5650                                    IRExpr_ITE(mkexpr(t3),
   5651                                               mkU16(0xffff),
   5652                                               unop(Iop_32to16, mkexpr(t1)))));
   5653                      break;
   5654                   }
   5655                   case 0x7: {  /* MULEU_S.PH.QBR */
   5656                      DIP("muleu_s.ph.qbr r%d, r%d, r%d", rd, rs, rt);
   5657                      vassert(!mode64);
   5658                      t0 = newTemp(Ity_I32);
   5659                      t1 = newTemp(Ity_I32);
   5660                      t2 = newTemp(Ity_I1);
   5661                      t3 = newTemp(Ity_I1);
   5662 
   5663                      assign(t0, unop(Iop_64to32,
   5664                                      binop(Iop_MullU32,
   5665                                            unop(Iop_8Uto32,
   5666                                                 unop(Iop_16HIto8,
   5667                                                      unop(Iop_32to16,
   5668                                                           getIReg(rs)))),
   5669                                            unop(Iop_16Uto32,
   5670                                                 unop(Iop_32HIto16,
   5671                                                      getIReg(rt))))));
   5672                      assign(t1, unop(Iop_64to32,
   5673                                      binop(Iop_MullU32,
   5674                                            unop(Iop_8Uto32,
   5675                                                 unop(Iop_16to8,
   5676                                                      unop(Iop_32to16,
   5677                                                           getIReg(rs)))),
   5678                                            unop(Iop_16Uto32,
   5679                                                 unop(Iop_32to16,
   5680                                                      getIReg(rt))))));
   5681 
   5682                      assign(t2, binop(Iop_CmpNE32,
   5683                                       mkU32(0x0),
   5684                                       binop(Iop_And32,
   5685                                             mkexpr(t0),
   5686                                             mkU32(0x03ff0000))));
   5687                      assign(t3, binop(Iop_CmpNE32,
   5688                                       mkU32(0x0),
   5689                                       binop(Iop_And32,
   5690                                             mkexpr(t1),
   5691                                             mkU32(0x03ff0000))));
   5692                      putDSPControl(IRExpr_ITE(mkexpr(t2),
   5693                                               binop(Iop_Or32,
   5694                                                     getDSPControl(),
   5695                                                     mkU32(0x200000)),
   5696                                               IRExpr_ITE(mkexpr(t3),
   5697                                                          binop(Iop_Or32,
   5698                                                                getDSPControl(),
   5699                                                                mkU32(0x200000)),
   5700                                                          getDSPControl())));
   5701                      putIReg(rd, binop(Iop_16HLto32,
   5702                                        IRExpr_ITE(mkexpr(t2),
   5703                                                   mkU16(0xffff),
   5704                                                   unop(Iop_32to16,
   5705                                                        mkexpr(t0))),
   5706                                        IRExpr_ITE(mkexpr(t3),
   5707                                                   mkU16(0xffff),
   5708                                                   unop(Iop_32to16,
   5709                                                        mkexpr(t1)))));
   5710                      break;
   5711                   }
   5712                   case 0x08: {  /* ADDU.PH */
   5713                      DIP("addu.ph r%d, r%d, r%d", rd, rs, rt);
   5714                      vassert(!mode64);
   5715                      t0 = newTemp(Ity_I32);
   5716                      t1 = newTemp(Ity_I1);
   5717                      t2 = newTemp(Ity_I32);
   5718                      t3 = newTemp(Ity_I1);
   5719 
   5720                      /* Add lower halves. */
   5721                      assign(t0, binop(Iop_Add32,
   5722                                       unop(Iop_16Uto32,
   5723                                            unop(Iop_32to16, getIReg(rs))),
   5724                                       unop(Iop_16Uto32,
   5725                                            unop(Iop_32to16, getIReg(rt)))));
   5726 
   5727                      /* Detect overflow. */
   5728                      assign(t1, binop(Iop_CmpLT32U,
   5729                                       unop(Iop_16Uto32,
   5730                                            unop(Iop_32to16, mkexpr(t0))),
   5731                                       unop(Iop_16Uto32,
   5732                                            unop(Iop_32to16, getIReg(rs)))));
   5733 
   5734                      putDSPControl(IRExpr_ITE(mkexpr(t1),
   5735                                               binop(Iop_Or32,
   5736                                                     getDSPControl(),
   5737                                                     mkU32(0x00100000)),
   5738                                               getDSPControl()));
   5739 
   5740                      /* Add higher halves. */
   5741                      assign(t2, binop(Iop_Add32,
   5742                                       unop(Iop_16Uto32,
   5743                                            unop(Iop_32HIto16, getIReg(rs))),
   5744                                       unop(Iop_16Uto32,
   5745                                            unop(Iop_32HIto16, getIReg(rt)))));
   5746 
   5747                      /* Detect overflow. */
   5748                      assign(t3, binop(Iop_CmpLT32U,
   5749                                       unop(Iop_16Uto32,
   5750                                            unop(Iop_32to16, mkexpr(t2))),
   5751                                       unop(Iop_16Uto32,
   5752                                            unop(Iop_32HIto16,
   5753                                                 getIReg(rs)))));
   5754 
   5755                      putDSPControl(IRExpr_ITE(mkexpr(t3),
   5756                                               binop(Iop_Or32,
   5757                                                     getDSPControl(),
   5758                                                     mkU32(0x00100000)),
   5759                                               getDSPControl()));
   5760 
   5761                      putIReg(rd, binop(Iop_16HLto32,
   5762                                        unop(Iop_32to16, mkexpr(t2)),
   5763                                        unop(Iop_32to16, mkexpr(t0))));
   5764                      break;
   5765                   }
   5766                   case 0x9: {  /* SUBU.PH */
   5767                      DIP("subu.ph r%d, r%d, r%d", rd, rs, rt);
   5768                      vassert(!mode64);
   5769                      t0 = newTemp(Ity_I32);
   5770                      t1 = newTemp(Ity_I1);
   5771                      t2 = newTemp(Ity_I32);
   5772                      t3 = newTemp(Ity_I1);
   5773 
   5774                      /* Substract lower halves. */
   5775                      assign(t0, binop(Iop_Sub32,
   5776                                       unop(Iop_16Uto32,
   5777                                            unop(Iop_32to16, getIReg(rs))),
   5778                                       unop(Iop_16Uto32,
   5779                                            unop(Iop_32to16, getIReg(rt)))));
   5780 
   5781                      /* Detect underflow. */
   5782                      assign(t1, binop(Iop_CmpNE32,
   5783                                       binop(Iop_And32,
   5784                                             mkexpr(t0),
   5785                                             mkU32(0x00010000)),
   5786                                       mkU32(0x0)));
   5787 
   5788                      putDSPControl(IRExpr_ITE(mkexpr(t1),
   5789                                               binop(Iop_Or32,
   5790                                                     getDSPControl(),
   5791                                                     mkU32(0x00100000)),
   5792                                               getDSPControl()));
   5793 
   5794                      /* Subtract higher halves. */
   5795                      assign(t2, binop(Iop_Sub32,
   5796                                       unop(Iop_16Uto32,
   5797                                            unop(Iop_32HIto16, getIReg(rs))),
   5798                                       unop(Iop_16Uto32,
   5799                                            unop(Iop_32HIto16, getIReg(rt)))));
   5800 
   5801                      /* Detect underflow. */
   5802                      assign(t3, binop(Iop_CmpNE32,
   5803                                       binop(Iop_And32,
   5804                                             mkexpr(t2),
   5805                                             mkU32(0x00010000)),
   5806                                       mkU32(0x0)));
   5807 
   5808                      putDSPControl(IRExpr_ITE(mkexpr(t3),
   5809                                               binop(Iop_Or32,
   5810                                                     getDSPControl(),
   5811                                                     mkU32(0x00100000)),
   5812                                               getDSPControl()));
   5813 
   5814                      putIReg(rd, binop(Iop_16HLto32,
   5815                                        unop(Iop_32to16, mkexpr(t2)),
   5816                                        unop(Iop_32to16, mkexpr(t0))));
   5817                      break;
   5818                   }
   5819                   case 0xA: {  /* ADDQ.PH */
   5820                      DIP("addq.ph r%d, r%d, r%d", rd, rs, rt);
   5821                      vassert(!mode64);
   5822                      t0 = newTemp(Ity_I32);
   5823                      t1 = newTemp(Ity_I1);
   5824                      t2 = newTemp(Ity_I32);
   5825                      t3 = newTemp(Ity_I1);
   5826                      t6 = newTemp(Ity_I32);
   5827                      t7 = newTemp(Ity_I32);
   5828 
   5829                      /* Add lower halves. */
   5830                      assign(t0, binop(Iop_Add32,
   5831                                       unop(Iop_16Sto32,
   5832                                            unop(Iop_32to16, getIReg(rs))),
   5833                                       unop(Iop_16Sto32,
   5834                                            unop(Iop_32to16, getIReg(rt)))));
   5835 
   5836                      /* Bit 16 of the result. */
   5837                      assign(t6, binop(Iop_And32,
   5838                                       unop(Iop_16Uto32,
   5839                                            unop(Iop_32HIto16, mkexpr(t0))),
   5840                                       mkU32(0x1)));
   5841                      /* Detect overflow. */
   5842                      assign(t1, binop(Iop_CmpNE32,
   5843                                       binop(Iop_Shr32,
   5844                                             binop(Iop_And32,
   5845                                                   mkexpr(t0),
   5846                                                   mkU32(0x8000)),
   5847                                             mkU8(15)),
   5848                                       mkexpr(t6)));
   5849 
   5850                      putDSPControl(IRExpr_ITE(mkexpr(t1),
   5851                                               binop(Iop_Or32,
   5852                                                     getDSPControl(),
   5853                                                     mkU32(0x00100000)),
   5854                                               getDSPControl()));
   5855 
   5856                      /* Add higher halves. */
   5857                      assign(t2, binop(Iop_Add32,
   5858                                       unop(Iop_16Sto32,
   5859                                            unop(Iop_32HIto16, getIReg(rs))),
   5860                                       unop(Iop_16Sto32,
   5861                                            unop(Iop_32HIto16, getIReg(rt)))));
   5862 
   5863                      /* Bit 16 of the result. */
   5864                      assign(t7, binop(Iop_And32,
   5865                                       unop(Iop_16Uto32,
   5866                                            unop(Iop_32HIto16, mkexpr(t2))),
   5867                                       mkU32(0x1)));
   5868                      /* Detect overflow. */
   5869                      assign(t3, binop(Iop_CmpNE32,
   5870                                       binop(Iop_Shr32,
   5871                                             binop(Iop_And32,
   5872                                                   mkexpr(t2),
   5873                                                   mkU32(0x00008000)),
   5874                                             mkU8(15)),
   5875                                       mkexpr(t7)));
   5876 
   5877                      putDSPControl(IRExpr_ITE(mkexpr(t3),
   5878                                               binop(Iop_Or32,
   5879                                                     getDSPControl(),
   5880                                                     mkU32(0x00100000)),
   5881                                               getDSPControl()));
   5882 
   5883                      putIReg(rd, binop(Iop_16HLto32,
   5884                                        unop(Iop_32to16, mkexpr(t2)),
   5885                                        unop(Iop_32to16, mkexpr(t0))));
   5886                      break;
   5887                   }
   5888                   case 0xB: {  /* SUBQ.PH */
   5889                      DIP("subq.ph r%d, r%d, r%d", rd, rs, rt);
   5890                      vassert(!mode64);
   5891                      t0 = newTemp(Ity_I32);
   5892                      t1 = newTemp(Ity_I1);
   5893                      t2 = newTemp(Ity_I32);
   5894                      t3 = newTemp(Ity_I1);
   5895                      t6 = newTemp(Ity_I32);
   5896                      t7 = newTemp(Ity_I32);
   5897 
   5898                      /* Subtract lower halves. */
   5899                      assign(t0, binop(Iop_Sub32,
   5900                                       unop(Iop_16Sto32,
   5901                                            unop(Iop_32to16, getIReg(rs))),
   5902                                       unop(Iop_16Sto32,
   5903                                            unop(Iop_32to16, getIReg(rt)))));
   5904 
   5905                      /* Bit 16 of the result. */
   5906                      assign(t6, binop(Iop_And32,
   5907                                       unop(Iop_16Uto32,
   5908                                            unop(Iop_32HIto16, mkexpr(t0))),
   5909                                       mkU32(0x1)));
   5910                      /* Compare the signs of input value and the result. */
   5911                      assign(t1, binop(Iop_CmpNE32,
   5912                                       binop(Iop_Shr32,
   5913                                             binop(Iop_And32,
   5914                                                   mkexpr(t0),
   5915                                                   mkU32(0x8000)),
   5916                                             mkU8(15)),
   5917                                       mkexpr(t6)));
   5918 
   5919                      putDSPControl(IRExpr_ITE(mkexpr(t1),
   5920                                               binop(Iop_Or32,
   5921                                                     getDSPControl(),
   5922                                                     mkU32(0x00100000)),
   5923                                               getDSPControl()));
   5924 
   5925                      /* Subtract higher halves. */
   5926                      assign(t2, binop(Iop_Sub32,
   5927                                       unop(Iop_16Sto32,
   5928                                            unop(Iop_32HIto16, getIReg(rs))),
   5929                                       unop(Iop_16Sto32,
   5930                                            unop(Iop_32HIto16, getIReg(rt)))));
   5931 
   5932                      /* Bit 16 of the result. */
   5933                      assign(t7, binop(Iop_And32,
   5934                                       unop(Iop_16Uto32,
   5935                                            unop(Iop_32HIto16, mkexpr(t2))),
   5936                                       mkU32(0x1)));
   5937                      /* Compare the signs of input value and the result. */
   5938                      assign(t3, binop(Iop_CmpNE32,
   5939                                       binop(Iop_Shr32,
   5940                                             binop(Iop_And32,
   5941                                                   mkexpr(t2),
   5942                                                   mkU32(0x00008000)),
   5943                                             mkU8(15)),
   5944                                       mkexpr(t7)));
   5945 
   5946                      putDSPControl(IRExpr_ITE(mkexpr(t3),
   5947                                               binop(Iop_Or32,
   5948                                                     getDSPControl(),
   5949                                                     mkU32(0x00100000)),
   5950                                               getDSPControl()));
   5951 
   5952                      putIReg(rd, binop(Iop_16HLto32,
   5953                                        unop(Iop_32to16, mkexpr(t2)),
   5954                                        unop(Iop_32to16, mkexpr(t0))));
   5955                      break;
   5956                   }
   5957                   case 0xC: {  /* ADDU_S.PH */
   5958                      DIP("addu_s.ph r%d, r%d, r%d", rd, rs, rt);
   5959                      vassert(!mode64);
   5960                      t0 = newTemp(Ity_I32);
   5961                      t1 = newTemp(Ity_I1);
   5962                      t2 = newTemp(Ity_I32);
   5963                      t3 = newTemp(Ity_I1);
   5964 
   5965                      /* Add lower halves. */
   5966                      assign(t0, binop(Iop_Add32,
   5967                                       unop(Iop_16Uto32,
   5968                                            unop(Iop_32to16, getIReg(rs))),
   5969                                       unop(Iop_16Uto32,
   5970                                            unop(Iop_32to16, getIReg(rt)))));
   5971 
   5972                      /* Detect overflow. */
   5973                      assign(t1, binop(Iop_CmpLT32U,
   5974                                       unop(Iop_16Uto32,
   5975                                            unop(Iop_32to16, mkexpr(t0))),
   5976                                       unop(Iop_16Uto32,
   5977                                            unop(Iop_32to16, getIReg(rs)))));
   5978 
   5979                      putDSPControl(IRExpr_ITE(mkexpr(t1),
   5980                                               binop(Iop_Or32,
   5981                                                     getDSPControl(),
   5982                                                     mkU32(0x00100000)),
   5983                                               getDSPControl()));
   5984 
   5985                      /* Add higher halves. */
   5986                      assign(t2, binop(Iop_Add32,
   5987                                       unop(Iop_16Uto32,
   5988                                            unop(Iop_32HIto16, getIReg(rs))),
   5989                                       unop(Iop_16Uto32,
   5990                                            unop(Iop_32HIto16, getIReg(rt)))));
   5991 
   5992                      /* Detect overflow. */
   5993                      assign(t3, binop(Iop_CmpLT32U,
   5994                                       unop(Iop_16Uto32,
   5995                                            unop(Iop_32to16, mkexpr(t2))),
   5996                                       unop(Iop_16Uto32,
   5997                                            unop(Iop_32HIto16, getIReg(rs)))));
   5998 
   5999                      putDSPControl(IRExpr_ITE(mkexpr(t3),
   6000                                               binop(Iop_Or32,
   6001                                                     getDSPControl(),
   6002                                                     mkU32(0x00100000)),
   6003                                               getDSPControl()));
   6004 
   6005                      putIReg(rd, binop(Iop_16HLto32,
   6006                                        IRExpr_ITE(mkexpr(t3),
   6007                                                   mkU16(0xffff),
   6008                                                   unop(Iop_32to16,
   6009                                                        mkexpr(t2))),
   6010                                        IRExpr_ITE(mkexpr(t1),
   6011                                                   mkU16(0xffff),
   6012                                                   unop(Iop_32to16,
   6013                                                        mkexpr(t0)))));
   6014                      break;
   6015                   }
   6016                   case 0xD: {  /* SUBU_S.PH */
   6017                      DIP("subu_s.ph r%d, r%d, r%d", rd, rs, rt);
   6018                      vassert(!mode64);
   6019                      t0 = newTemp(Ity_I32);
   6020                      t1 = newTemp(Ity_I1);
   6021                      t2 = newTemp(Ity_I32);
   6022                      t3 = newTemp(Ity_I1);
   6023 
   6024                      /* Subtract lower halves. */
   6025                      assign(t0, binop(Iop_Sub32,
   6026                                       unop(Iop_16Uto32,
   6027                                            unop(Iop_32to16, getIReg(rs))),
   6028                                       unop(Iop_16Uto32,
   6029                                            unop(Iop_32to16, getIReg(rt)))));
   6030 
   6031                      /* Detect underflow. */
   6032                      assign(t1, binop(Iop_CmpNE32,
   6033                                       binop(Iop_And32,
   6034                                             mkexpr(t0), mkU32(0x00010000)),
   6035                                       mkU32(0x0)));
   6036 
   6037                      putDSPControl(IRExpr_ITE(mkexpr(t1),
   6038                                               binop(Iop_Or32,
   6039                                                     getDSPControl(),
   6040                                                     mkU32(0x00100000)),
   6041                                               getDSPControl()));
   6042 
   6043                      /* Subtract higher halves. */
   6044                      assign(t2, binop(Iop_Sub32,
   6045                                       unop(Iop_16Uto32,
   6046                                            unop(Iop_32HIto16, getIReg(rs))),
   6047                                       unop(Iop_16Uto32,
   6048                                            unop(Iop_32HIto16, getIReg(rt)))));
   6049 
   6050                      /* Detect underflow. */
   6051                      assign(t3, binop(Iop_CmpNE32,
   6052                                       binop(Iop_And32,
   6053                                             mkexpr(t2), mkU32(0x00010000)),
   6054                                       mkU32(0x0)));
   6055 
   6056                      putDSPControl(IRExpr_ITE(mkexpr(t3),
   6057                                               binop(Iop_Or32,
   6058                                                     getDSPControl(),
   6059                                                     mkU32(0x00100000)),
   6060                                               getDSPControl()));
   6061 
   6062                      putIReg(rd,
   6063                              binop(Iop_16HLto32,
   6064                                    IRExpr_ITE(mkexpr(t3),
   6065                                               mkU16(0x0000),
   6066                                               unop(Iop_32to16, mkexpr(t2))),
   6067                                    IRExpr_ITE(mkexpr(t1),
   6068                                               mkU16(0x0000),
   6069                                               unop(Iop_32to16, mkexpr(t0)))));
   6070                      break;
   6071                   }
   6072                   case 0xE: {  /* ADDQ_S.PH */
   6073                      DIP("addq_s.ph r%d r%d, r%d", rd, rs, rt);
   6074                      vassert(!mode64);
   6075                      t0 = newTemp(Ity_I32);
   6076                      t1 = newTemp(Ity_I1);
   6077                      t2 = newTemp(Ity_I32);
   6078                      t3 = newTemp(Ity_I1);
   6079                      t4 = newTemp(Ity_I16);
   6080                      t5 = newTemp(Ity_I16);
   6081                      t6 = newTemp(Ity_I32);
   6082                      t7 = newTemp(Ity_I32);
   6083 
   6084                      /* Add lower halves. */
   6085                      assign(t0, binop(Iop_Add32,
   6086                                       unop(Iop_16Sto32,
   6087                                            unop(Iop_32to16, getIReg(rs))),
   6088                                       unop(Iop_16Sto32,
   6089                                            unop(Iop_32to16, getIReg(rt)))));
   6090 
   6091                      /* Bit 16 of the result. */
   6092                      assign(t6, binop(Iop_And32,
   6093                                       unop(Iop_16Uto32,
   6094                                            unop(Iop_32HIto16, mkexpr(t0))),
   6095                                       mkU32(0x1)));
   6096                      /* Detect overflow. */
   6097                      assign(t1, binop(Iop_CmpNE32,
   6098                                       binop(Iop_Shr32,
   6099                                             binop(Iop_And32,
   6100                                                   mkexpr(t0),
   6101                                                   mkU32(0x8000)),
   6102                                             mkU8(15)),
   6103                                       mkexpr(t6)));
   6104 
   6105                      putDSPControl(IRExpr_ITE(mkexpr(t1),
   6106                                               binop(Iop_Or32,
   6107                                                     getDSPControl(),
   6108                                                     mkU32(0x00100000)),
   6109                                               getDSPControl()));
   6110                      /* Saturate if needed. */
   6111                      assign(t4, IRExpr_ITE(mkexpr(t1),
   6112                                            IRExpr_ITE(binop(Iop_CmpEQ32,
   6113                                                             mkexpr(t6),
   6114                                                             mkU32(0x0)),
   6115                                                       mkU16(0x7fff),
   6116                                                       mkU16(0x8000)),
   6117                                            unop(Iop_32to16, mkexpr(t0))));
   6118 
   6119                      /* Add higher halves. */
   6120                      assign(t2, binop(Iop_Add32,
   6121                                       unop(Iop_16Sto32,
   6122                                            unop(Iop_32HIto16, getIReg(rs))),
   6123                                       unop(Iop_16Sto32,
   6124                                            unop(Iop_32HIto16, getIReg(rt)))));
   6125 
   6126                      /* Bit 16 of the result. */
   6127                      assign(t7, binop(Iop_And32,
   6128                                       unop(Iop_16Uto32,
   6129                                            unop(Iop_32HIto16, mkexpr(t2))),
   6130                                       mkU32(0x1)));
   6131                      /* Detect overflow. */
   6132                      assign(t3, binop(Iop_CmpNE32,
   6133                                       binop(Iop_Shr32,
   6134                                             binop(Iop_And32,
   6135                                                   mkexpr(t2),
   6136                                                   mkU32(0x00008000)),
   6137                                             mkU8(15)),
   6138                                       mkexpr(t7)));
   6139 
   6140                      putDSPControl(IRExpr_ITE(mkexpr(t3),
   6141                                               binop(Iop_Or32,
   6142                                                     getDSPControl(),
   6143                                                     mkU32(0x00100000)),
   6144                                               getDSPControl()));
   6145                      /* Saturate if needed. */
   6146                      assign(t5, IRExpr_ITE(mkexpr(t3),
   6147                                            IRExpr_ITE(binop(Iop_CmpEQ32,
   6148                                                             mkexpr(t7),
   6149                                                             mkU32(0x0)),
   6150                                                       mkU16(0x7fff),
   6151                                                       mkU16(0x8000)),
   6152                                            unop(Iop_32to16, mkexpr(t2))));
   6153 
   6154                      putIReg(rd, binop(Iop_16HLto32, mkexpr(t5), mkexpr(t4)));
   6155                      break;
   6156                   }
   6157                   case 0xF: {  /* SUBQ_S.PH */
   6158                      DIP("subq_s.ph r%d r%d, r%d", rd, rs, rt);
   6159                      vassert(!mode64);
   6160                      t0 = newTemp(Ity_I32);
   6161                      t1 = newTemp(Ity_I1);
   6162                      t2 = newTemp(Ity_I32);
   6163                      t3 = newTemp(Ity_I1);
   6164                      t4 = newTemp(Ity_I16);
   6165                      t5 = newTemp(Ity_I16);
   6166                      t6 = newTemp(Ity_I32);
   6167                      t7 = newTemp(Ity_I32);
   6168 
   6169                      /* Subtract lower halves. */
   6170                      assign(t0, binop(Iop_Sub32,
   6171                                       unop(Iop_16Sto32,
   6172                                            unop(Iop_32to16, getIReg(rs))),
   6173                                       unop(Iop_16Sto32,
   6174                                            unop(Iop_32to16, getIReg(rt)))));
   6175 
   6176                      /* Bit 16 of the result. */
   6177                      assign(t6, binop(Iop_And32,
   6178                                       unop(Iop_16Uto32,
   6179                                            unop(Iop_32HIto16, mkexpr(t0))),
   6180                                       mkU32(0x1)));
   6181                      /* Detect overflow or underflow. */
   6182                      assign(t1, binop(Iop_CmpNE32,
   6183                                       binop(Iop_Shr32,
   6184                                             binop(Iop_And32,
   6185                                                   mkexpr(t0),
   6186                                                   mkU32(0x8000)),
   6187                                             mkU8(15)),
   6188                                       mkexpr(t6)));
   6189 
   6190                      putDSPControl(IRExpr_ITE(mkexpr(t1),
   6191                                               binop(Iop_Or32,
   6192                                                     getDSPControl(),
   6193                                                     mkU32(0x00100000)),
   6194                                               getDSPControl()));
   6195                      /* Saturate if needed. */
   6196                      assign(t4, IRExpr_ITE(mkexpr(t1),
   6197                                            IRExpr_ITE(binop(Iop_CmpEQ32,
   6198                                                             mkexpr(t6),
   6199                                                             mkU32(0x0)),
   6200                                                       mkU16(0x7fff),
   6201                                                       mkU16(0x8000)),
   6202                                            unop(Iop_32to16, mkexpr(t0))));
   6203 
   6204                      /* Subtract higher halves. */
   6205                      assign(t2, binop(Iop_Sub32,
   6206                                       unop(Iop_16Sto32,
   6207                                            unop(Iop_32HIto16, getIReg(rs))),
   6208                                       unop(Iop_16Sto32,
   6209                                            unop(Iop_32HIto16, getIReg(rt)))));
   6210 
   6211                      /* Bit 16 of the result. */
   6212                      assign(t7, binop(Iop_And32,
   6213                                       unop(Iop_16Uto32,
   6214                                            unop(Iop_32HIto16, mkexpr(t2))),
   6215                                       mkU32(0x1)));
   6216                      /* Detect overflow or underflow. */
   6217                      assign(t3, binop(Iop_CmpNE32,
   6218                                       binop(Iop_Shr32,
   6219                                             binop(Iop_And32,
   6220                                                   mkexpr(t2),
   6221                                                   mkU32(0x00008000)),
   6222                                             mkU8(15)),
   6223                                       mkexpr(t7)));
   6224 
   6225                      putDSPControl(IRExpr_ITE(mkexpr(t3),
   6226                                               binop(Iop_Or32,
   6227                                                     getDSPControl(),
   6228                                                     mkU32(0x00100000)),
   6229                                               getDSPControl()));
   6230                      /* Saturate if needed. */
   6231                      assign(t5, IRExpr_ITE(mkexpr(t3),
   6232                                            IRExpr_ITE(binop(Iop_CmpEQ32,
   6233                                                             mkexpr(t7),
   6234                                                             mkU32(0x0)),
   6235                                                       mkU16(0x7fff),
   6236                                                       mkU16(0x8000)),
   6237                                            unop(Iop_32to16, mkexpr(t2))));
   6238 
   6239                      putIReg(rd, binop(Iop_16HLto32, mkexpr(t5), mkexpr(t4)));
   6240                      break;
   6241                   }
   6242                   case 0x10: {  /* ADDSC */
   6243                      DIP("addsc r%d, r%d, r%d", rd, rs, rt);
   6244                      vassert(!mode64);
   6245                      t0 = newTemp(Ity_I64);
   6246                      t1 = newTemp(Ity_I1);
   6247 
   6248                      /* The carry bit result out of the addition operation is
   6249                         written to bit 13(the c field) of the DSPControl reg. */
   6250                      assign(t0, binop(Iop_Add64,
   6251                                       unop(Iop_32Uto64, getIReg(rs)),
   6252                                       unop(Iop_32Uto64, getIReg(rt))));
   6253 
   6254                      assign(t1, binop(Iop_CmpEQ32,
   6255                                       binop(Iop_And32,
   6256                                             unop(Iop_64HIto32, mkexpr(t0)),
   6257                                             mkU32(0x1)),
   6258                                       mkU32(0x1)));
   6259                      putDSPControl(IRExpr_ITE(mkexpr(t1),
   6260                                               binop(Iop_Or32,
   6261                                                     getDSPControl(),
   6262                                                     mkU32(0x2000)),
   6263                                               binop(Iop_And32,
   6264                                                     getDSPControl(),
   6265                                                     mkU32(0xffffdfff))));
   6266 
   6267                      putIReg(rd, unop(Iop_64to32, mkexpr(t0)));
   6268                      break;
   6269                   }
   6270                   case 0x11: {  /* ADDWC */
   6271                      DIP("addwc r%d, r%d, r%d", rd, rs, rt);
   6272                      vassert(!mode64);
   6273                      t0 = newTemp(Ity_I32);
   6274                      t1 = newTemp(Ity_I64);
   6275                      t2 = newTemp(Ity_I32);
   6276                      t3 = newTemp(Ity_I32);
   6277                      t4 = newTemp(Ity_I1);
   6278 
   6279                      /* Get carry bit from DSPControl register. */
   6280                      assign(t0, binop(Iop_Shr32,
   6281                                        binop(Iop_And32,
   6282                                              getDSPControl(),
   6283                                              mkU32(0x2000)),
   6284                                        mkU8(0xd)));
   6285                      assign(t1, binop(Iop_Add64,
   6286                                       unop(Iop_32Sto64, getIReg(rs)),
   6287                                       unop(Iop_32Sto64,
   6288                                            binop(Iop_Add32,
   6289                                                  getIReg(rt),
   6290                                                  mkexpr(t0)))));
   6291 
   6292                      /* Extract bits 32 and 31. */
   6293                      assign(t2, binop(Iop_And32,
   6294                                       unop(Iop_64HIto32, mkexpr(t1)),
   6295                                       mkU32(0x1)));
   6296                      assign(t3, binop(Iop_Shr32,
   6297                                       binop(Iop_And32,
   6298                                             unop(Iop_64to32, mkexpr(t1)),
   6299                                             mkU32(0x80000000)),
   6300                                       mkU8(31)));
   6301                      assign(t4, binop(Iop_CmpNE32, mkexpr(t2), mkexpr(t3)));
   6302 
   6303                      putDSPControl(IRExpr_ITE(mkexpr(t4),
   6304                                               binop(Iop_Or32,
   6305                                                     getDSPControl(),
   6306                                                     mkU32(0x00100000)),
   6307                                               getDSPControl()));
   6308                      putIReg(rd, unop(Iop_64to32, mkexpr(t1)));
   6309                      break;
   6310                   }
   6311                   case 0x12: {  /* MODSUB */
   6312                      DIP("modsub r%d, r%d, r%d", rd, rs, rt);
   6313                      vassert(!mode64);
   6314                      t0 = newTemp(Ity_I32);
   6315                      t1 = newTemp(Ity_I32);
   6316                      t2 = newTemp(Ity_I32);
   6317 
   6318                      /* decr_7..0 */
   6319                      assign(t0,
   6320                             unop(Iop_8Uto32,
   6321                                  unop(Iop_16to8,
   6322                                       unop(Iop_32to16, getIReg(rt)))));
   6323 
   6324                      /* lastindex_15..0 */
   6325                      assign(t1,
   6326                             unop(Iop_16Uto32,
   6327                                  binop(Iop_8HLto16,
   6328                                        unop(Iop_16to8,
   6329                                             unop(Iop_32HIto16, getIReg(rt))),
   6330                                        unop(Iop_16HIto8,
   6331                                             unop(Iop_32to16, getIReg(rt))))));
   6332                      /* temp_15..0 */
   6333                      assign(t2,
   6334                             IRExpr_ITE(binop(Iop_CmpEQ32,
   6335                                              getIReg(rs),
   6336                                              mkU32(0x00000000)),
   6337                                        mkexpr(t1),
   6338                                        binop(Iop_Sub32,
   6339                                              getIReg(rs), mkexpr(t0))));
   6340                      putIReg(rd, mkexpr(t2));
   6341                      break;
   6342                   }
   6343                   case 0x14: {  /* RADDU.W.QB */
   6344                      DIP("raddu.w.qb r%d, r%d", rd, rs);
   6345                      vassert(!mode64);
   6346                      putIReg(rd, binop(Iop_Add32,
   6347                                        binop(Iop_Add32,
   6348                                              unop(Iop_8Uto32,
   6349                                                   unop(Iop_16to8,
   6350                                                        unop(Iop_32to16,
   6351                                                             getIReg(rs)))),
   6352                                              unop(Iop_8Uto32,
   6353                                                   unop(Iop_16HIto8,
   6354                                                        unop(Iop_32to16,
   6355                                                             getIReg(rs))))),
   6356                                        binop(Iop_Add32,
   6357                                              unop(Iop_8Uto32,
   6358                                                   unop(Iop_16to8,
   6359                                                        unop(Iop_32HIto16,
   6360                                                             getIReg(rs)))),
   6361                                              unop(Iop_8Uto32,
   6362                                                   unop(Iop_16HIto8,
   6363                                                        unop(Iop_32HIto16,
   6364                                                             getIReg(rs)))))));
   6365                      break;
   6366                   }
   6367                   case 0x16: {  /* ADDQ_S.W */
   6368                      DIP("addq_s.w r%d, r%d, r%d", rd, rs, rt);
   6369                      vassert(!mode64);
   6370                      t0 = newTemp(Ity_I64);
   6371                      t1 = newTemp(Ity_I1);
   6372                      t2 = newTemp(Ity_I32);
   6373                      t3 = newTemp(Ity_I32);
   6374 
   6375                      assign(t0, binop(Iop_Add64,
   6376                                       unop(Iop_32Sto64, getIReg(rs)),
   6377                                       unop(Iop_32Sto64, getIReg(rt))));
   6378 
   6379                      assign(t3, binop(Iop_And32,
   6380                                       unop(Iop_64HIto32, mkexpr(t0)),
   6381                                       mkU32(0x1)));
   6382                      assign(t1, binop(Iop_CmpNE32,
   6383                                       binop(Iop_Shr32,
   6384                                             binop(Iop_And32,
   6385                                                   unop(Iop_64to32, mkexpr(t0)),
   6386                                                   mkU32(0x80000000)),
   6387                                             mkU8(31)),
   6388                                       mkexpr(t3)));
   6389 
   6390                      putDSPControl(IRExpr_ITE(mkexpr(t1),
   6391                                               binop(Iop_Or32,
   6392                                                     getDSPControl(),
   6393                                                     mkU32(0x00100000)),
   6394                                               getDSPControl()));
   6395 
   6396                      putIReg(rd, IRExpr_ITE(mkexpr(t1),
   6397                                             IRExpr_ITE(binop(Iop_CmpEQ32,
   6398                                                              mkexpr(t3),
   6399                                                              mkU32(0x0)),
   6400                                                        mkU32(0x7fffffff),
   6401                                                        mkU32(0x80000000)),
   6402                                             unop(Iop_64to32, mkexpr(t0))));
   6403                      break;
   6404                   }
   6405                   case 0x17: {  /* SUBQ_S.W */
   6406                      DIP("subq_s.w r%d, r%d, r%d", rd, rs, rt);
   6407                      vassert(!mode64);
   6408                      t0 = newTemp(Ity_I64);
   6409                      t1 = newTemp(Ity_I1);
   6410                      t2 = newTemp(Ity_I32);
   6411                      t3 = newTemp(Ity_I32);
   6412 
   6413                      assign(t0, binop(Iop_Sub64,
   6414                                       unop(Iop_32Sto64, getIReg(rs)),
   6415                                       unop(Iop_32Sto64, getIReg(rt))));
   6416 
   6417                      assign(t3, binop(Iop_And32,
   6418                                       unop(Iop_64HIto32, mkexpr(t0)),
   6419                                       mkU32(0x1)));
   6420                      assign(t1, binop(Iop_CmpNE32,
   6421                                       binop(Iop_Shr32,
   6422                                             binop(Iop_And32,
   6423                                                   unop(Iop_64to32, mkexpr(t0)),
   6424                                                   mkU32(0x80000000)),
   6425                                             mkU8(31)),
   6426                                       mkexpr(t3)));
   6427 
   6428                      putDSPControl(IRExpr_ITE(mkexpr(t1),
   6429                                               binop(Iop_Or32,
   6430                                                     getDSPControl(),
   6431                                                     mkU32(0x00100000)),
   6432                                               getDSPControl()));
   6433 
   6434                      putIReg(rd, IRExpr_ITE(mkexpr(t1),
   6435                                             IRExpr_ITE(binop(Iop_CmpEQ32,
   6436                                                              mkexpr(t3),
   6437                                                              mkU32(0x0)),
   6438                                                        mkU32(0x7fffffff),
   6439                                                        mkU32(0x80000000)),
   6440                                             unop(Iop_64to32, mkexpr(t0))));
   6441                      break;
   6442                   }
   6443                   case 0x1C: {  /* MULEQ_S.W.PHL */
   6444                      DIP("muleq_s.w.phl r%d, r%d, r%d", rd, rs, rt);
   6445                      vassert(!mode64);
   6446                      t0 = newTemp(Ity_I32);
   6447                      t1 = newTemp(Ity_I1);
   6448                      t2 = newTemp(Ity_I1);
   6449                      t3 = newTemp(Ity_I32);
   6450 
   6451                      assign(t0,
   6452                             binop(Iop_Shl32,
   6453                                   binop(Iop_Mul32,
   6454                                         unop(Iop_16Sto32,
   6455                                              unop(Iop_32HIto16, getIReg(rt))),
   6456                                         unop(Iop_16Sto32,
   6457                                              unop(Iop_32HIto16, getIReg(rs)))),
   6458                                   mkU8(0x1)));
   6459                      assign(t1, binop(Iop_CmpEQ32,
   6460                                       binop(Iop_And32,
   6461                                             getIReg(rt),
   6462                                             mkU32(0xffff0000)),
   6463                                       mkU32(0x80000000)));
   6464                      assign(t2, binop(Iop_CmpEQ32,
   6465                                       binop(Iop_And32,
   6466                                             getIReg(rs),
   6467                                             mkU32(0xffff0000)),
   6468                                       mkU32(0x80000000)));
   6469                      assign(t3, IRExpr_ITE(mkexpr(t1),
   6470                                            IRExpr_ITE(mkexpr(t2),
   6471                                                       binop(Iop_Or32,
   6472                                                             getDSPControl(),
   6473                                                             mkU32(0x00200000)),
   6474                                                       getDSPControl()),
   6475                                            getDSPControl()));
   6476                      putDSPControl(mkexpr(t3));
   6477 
   6478                      putIReg(rd, IRExpr_ITE(mkexpr(t1),
   6479                                             IRExpr_ITE(mkexpr(t2),
   6480                                                        mkU32(0x7fffffff),
   6481                                                        mkexpr(t0)),
   6482                                             mkexpr(t0)));
   6483                      break;
   6484                   }
   6485                   case 0x1D: {  /* MULEQ_S.W.PHR */
   6486                      DIP("muleq_s.w.phr r%d, r%d, r%d", rd, rs, rt);
   6487                      vassert(!mode64);
   6488                      t0 = newTemp(Ity_I32);
   6489                      t1 = newTemp(Ity_I1);
   6490                      t2 = newTemp(Ity_I1);
   6491 
   6492                      assign(t0,
   6493                             binop(Iop_Shl32,
   6494                                   binop(Iop_Mul32,
   6495                                         unop(Iop_16Sto32,
   6496                                              unop(Iop_32to16, getIReg(rt))),
   6497                                         unop(Iop_16Sto32,
   6498                                              unop(Iop_32to16, getIReg(rs)))),
   6499                                   mkU8(0x1)));
   6500                      assign(t1, binop(Iop_CmpEQ32,
   6501                                       binop(Iop_And32,
   6502                                             getIReg(rt),
   6503                                             mkU32(0xffff)),
   6504                                       mkU32(0x8000)));
   6505                      assign(t2, binop(Iop_CmpEQ32,
   6506                                       binop(Iop_And32,
   6507                                             getIReg(rs),
   6508                                             mkU32(0xffff)),
   6509                                       mkU32(0x8000)));
   6510                      putDSPControl(IRExpr_ITE(mkexpr(t1),
   6511                                               IRExpr_ITE(mkexpr(t2),
   6512                                                          binop(Iop_Or32,
   6513                                                                getDSPControl(),
   6514                                                                mkU32(0x00200000)
   6515                                                               ),
   6516                                                          getDSPControl()),
   6517                                               getDSPControl()));
   6518                      putIReg(rd, IRExpr_ITE(mkexpr(t1),
   6519                                             IRExpr_ITE(mkexpr(t2),
   6520                                                        mkU32(0x7fffffff),
   6521                                                        mkexpr(t0)),
   6522                                             mkexpr(t0)));
   6523                      break;
   6524                   }
   6525                   case 0x1E: {  /* MULQ_S.PH */
   6526                      DIP("mulq_s.ph r%d, r%d, r%d", rd, rs, rt);
   6527                      vassert(!mode64);
   6528                      t0 = newTemp(Ity_I32);
   6529                      t1 = newTemp(Ity_I32);
   6530                      t2 = newTemp(Ity_I16);
   6531                      t3 = newTemp(Ity_I16);
   6532                      t5 = newTemp(Ity_I32);
   6533                      t6 = newTemp(Ity_I32);
   6534                      t7 = newTemp(Ity_I32);
   6535                      t8 = newTemp(Ity_I32);
   6536 
   6537                      assign(t5,
   6538                             unop(Iop_16Sto32, unop(Iop_32to16, getIReg(rs))));
   6539                      assign(t6,
   6540                             unop(Iop_16Sto32, unop(Iop_32to16, getIReg(rt))));
   6541 
   6542                      assign(t7,
   6543                             unop(Iop_16Sto32, unop(Iop_32HIto16, getIReg(rs))));
   6544                      assign(t8,
   6545                             unop(Iop_16Sto32, unop(Iop_32HIto16, getIReg(rt))));
   6546 
   6547                      assign(t0, binop(Iop_And32,
   6548                                       unop(Iop_1Sto32,
   6549                                            binop(Iop_CmpEQ32,
   6550                                                  binop(Iop_And32,
   6551                                                        mkexpr(t5),
   6552                                                        mkU32(0xffff)),
   6553                                                  mkU32(0x8000))),
   6554                                       unop(Iop_1Sto32,
   6555                                            binop(Iop_CmpEQ32,
   6556                                                  binop(Iop_And32,
   6557                                                        mkexpr(t6),
   6558                                                        mkU32(0xffff)),
   6559                                                  mkU32(0x8000)))));
   6560                      assign(t1, binop(Iop_And32,
   6561                                       unop(Iop_1Sto32,
   6562                                            binop(Iop_CmpEQ32,
   6563                                                  binop(Iop_And32,
   6564                                                        mkexpr(t7),
   6565                                                        mkU32(0xffff)),
   6566                                                  mkU32(0x8000))),
   6567                                       unop(Iop_1Sto32,
   6568                                            binop(Iop_CmpEQ32,
   6569                                                  binop(Iop_And32,
   6570                                                        mkexpr(t8),
   6571                                                        mkU32(0xffff)),
   6572                                                  mkU32(0x8000)))));
   6573 
   6574                      putDSPControl(IRExpr_ITE(binop(Iop_CmpEQ32,
   6575                                                     binop(Iop_Or32,
   6576                                                           mkexpr(t0),
   6577                                                           mkexpr(t1)),
   6578                                                     mkU32(0x0)),
   6579                                               getDSPControl(),
   6580                                               binop(Iop_Or32,
   6581                                                     getDSPControl(),
   6582                                                     mkU32(0x200000))));
   6583 
   6584                      assign(t2, unop(Iop_32HIto16,
   6585                                      binop(Iop_Shl32,
   6586                                            unop(Iop_64to32,
   6587                                                 binop(Iop_MullS32,
   6588                                                       mkexpr(t7),
   6589                                                       mkexpr(t8))),
   6590                                            mkU8(0x1))));
   6591                      assign(t3, unop(Iop_32HIto16,
   6592                                      binop(Iop_Shl32,
   6593                                            unop(Iop_64to32,
   6594                                                 binop(Iop_MullS32,
   6595                                                       mkexpr(t5),
   6596                                                       mkexpr(t6))),
   6597                                            mkU8(0x1))));
   6598                      putIReg(rd, binop(Iop_16HLto32,
   6599                                        IRExpr_ITE(binop(Iop_CmpEQ32,
   6600                                                         mkexpr(t1),
   6601                                                         mkU32(0x0)),
   6602                                                   mkexpr(t2),
   6603                                                   mkU16(0x7fff)),
   6604                                        IRExpr_ITE(binop(Iop_CmpEQ32,
   6605                                                         mkexpr(t0),
   6606                                                         mkU32(0x0)),
   6607                                                   mkexpr(t3),
   6608                                                   mkU16(0x7fff))));
   6609                      break;
   6610                   }
   6611                   case 0x1F: {  /* MULQ_RS.PH */
   6612                      DIP("mulq_rs.ph r%d, r%d, r%d", rd, rs, rt);
   6613                      vassert(!mode64);
   6614                      t0 = newTemp(Ity_I32);
   6615                      t1 = newTemp(Ity_I1);
   6616                      t2 = newTemp(Ity_I1);
   6617                      t3 = newTemp(Ity_I16);
   6618                      t4 = newTemp(Ity_I32);
   6619                      t5 = newTemp(Ity_I1);
   6620                      t6 = newTemp(Ity_I1);
   6621                      t7 = newTemp(Ity_I16);
   6622 
   6623                      /* Multiply and round lower halfwords. */
   6624                      assign(t0, binop(Iop_Add32,
   6625                                       binop(Iop_Shl32,
   6626                                             binop(Iop_Mul32,
   6627                                                   unop(Iop_16Sto32,
   6628                                                        unop(Iop_32to16,
   6629                                                             getIReg(rt))),
   6630                                                   unop(Iop_16Sto32,
   6631                                                        unop(Iop_32to16,
   6632                                                             getIReg(rs)))),
   6633                                             mkU8(0x1)),
   6634                                       mkU32(0x00008000)));
   6635                      assign(t1, binop(Iop_CmpEQ32,
   6636                                       binop(Iop_And32,
   6637                                             getIReg(rt), mkU32(0xffff)),
   6638                                       mkU32(0x8000)));
   6639                      assign(t2, binop(Iop_CmpEQ32,
   6640                                       binop(Iop_And32,
   6641                                             getIReg(rs), mkU32(0xffff)),
   6642                                       mkU32(0x8000)));
   6643                      putDSPControl(IRExpr_ITE(mkexpr(t1),
   6644                                               IRExpr_ITE(mkexpr(t2),
   6645                                                          binop(Iop_Or32,
   6646                                                                getDSPControl(),
   6647                                                                mkU32(0x00200000)
   6648                                                               ),
   6649                                                          getDSPControl()),
   6650                                               getDSPControl()));
   6651                      assign(t3, IRExpr_ITE(mkexpr(t1),
   6652                                            IRExpr_ITE(mkexpr(t2),
   6653                                                       mkU16(0x7fff),
   6654                                                       unop(Iop_32HIto16,
   6655                                                            mkexpr(t0))),
   6656                                            unop(Iop_32HIto16, mkexpr(t0))));
   6657 
   6658                      /* Multiply and round higher halfwords. */
   6659                      assign(t4, binop(Iop_Add32,
   6660                                       binop(Iop_Shl32,
   6661                                             binop(Iop_Mul32,
   6662                                                   unop(Iop_16Sto32,
   6663                                                        unop(Iop_32HIto16,
   6664                                                             getIReg(rt))),
   6665                                                   unop(Iop_16Sto32,
   6666                                                        unop(Iop_32HIto16,
   6667                                                             getIReg(rs)))),
   6668                                             mkU8(0x1)),
   6669                                       mkU32(0x00008000)));
   6670                      assign(t5, binop(Iop_CmpEQ32,
   6671                                       binop(Iop_And32,
   6672                                             getIReg(rt),
   6673                                             mkU32(0xffff0000)),
   6674                                       mkU32(0x80000000)));
   6675                      assign(t6, binop(Iop_CmpEQ32,
   6676                                       binop(Iop_And32,
   6677                                             getIReg(rs),
   6678                                             mkU32(0xffff0000)),
   6679                                       mkU32(0x80000000)));
   6680                      putDSPControl(IRExpr_ITE(mkexpr(t5),
   6681                                              IRExpr_ITE(mkexpr(t6),
   6682                                                         binop(Iop_Or32,
   6683                                                              getDSPControl(),
   6684                                                              mkU32(0x00200000)),
   6685                                                         getDSPControl()),
   6686                                              getDSPControl()));
   6687                      assign(t7, IRExpr_ITE(mkexpr(t5),
   6688                                            IRExpr_ITE(mkexpr(t6),
   6689                                                       mkU16(0x7fff),
   6690                                                       unop(Iop_32HIto16,
   6691                                                            mkexpr(t4))),
   6692                                            unop(Iop_32HIto16, mkexpr(t4))));
   6693 
   6694                      putIReg(rd, binop(Iop_16HLto32, mkexpr(t7), mkexpr(t3)));
   6695                      break;
   6696                   }
   6697                   default:
   6698                      return -1;
   6699                }
   6700                break;  /* end of ADDU.QB */
   6701             }
   6702             case 0x11: {  /* CMPU.EQ.QB */
   6703                switch(sa) {
   6704                   case 0x0: {  /* CMPU.EQ.QB */
   6705                      DIP("cmpu.eq.qb r%d, r%d", rs, rt);
   6706                      vassert(!mode64);
   6707                      t1 = newTemp(Ity_I1);
   6708                      t2 = newTemp(Ity_I1);
   6709                      t3 = newTemp(Ity_I1);
   6710                      t4 = newTemp(Ity_I1);
   6711 
   6712                      assign(t1,
   6713                             binop(Iop_CmpEQ32,
   6714                                   binop(Iop_And32, getIReg(rs), mkU32(0xff)),
   6715                                   binop(Iop_And32, getIReg(rt), mkU32(0xff))));
   6716                      putDSPControl(IRExpr_ITE(mkexpr(t1),
   6717                                               binop(Iop_Or32,
   6718                                                     getDSPControl(),
   6719                                                     mkU32(0x01000000)),
   6720                                               binop(Iop_And32,
   6721                                                     getDSPControl(),
   6722                                                     mkU32(0xfeffffff))));
   6723 
   6724                      assign(t2, binop(Iop_CmpEQ32,
   6725                                       unop(Iop_8Uto32,
   6726                                            unop(Iop_16HIto8,
   6727                                                 unop(Iop_32to16,
   6728                                                      getIReg(rs)))),
   6729                                       unop(Iop_8Uto32,
   6730                                            unop(Iop_16HIto8,
   6731                                                 unop(Iop_32to16,
   6732                                                      getIReg(rt))))));
   6733                      putDSPControl(IRExpr_ITE(mkexpr(t2),
   6734                                               binop(Iop_Or32,
   6735                                                     getDSPControl(),
   6736                                                     mkU32(0x02000000)),
   6737                                               binop(Iop_And32,
   6738                                                     getDSPControl(),
   6739                                                     mkU32(0xfdffffff))));
   6740 
   6741                      assign(t3, binop(Iop_CmpEQ32,
   6742                                       unop(Iop_8Uto32,
   6743                                            unop(Iop_16to8,
   6744                                                 unop(Iop_32HIto16,
   6745                                                      getIReg(rs)))),
   6746                                       unop(Iop_8Uto32,
   6747                                            unop(Iop_16to8,
   6748                                                 unop(Iop_32HIto16,
   6749                                                      getIReg(rt))))));
   6750                      putDSPControl(IRExpr_ITE(mkexpr(t3),
   6751                                               binop(Iop_Or32,
   6752                                                     getDSPControl(),
   6753                                                     mkU32(0x04000000)),
   6754                                               binop(Iop_And32,
   6755                                                     getDSPControl(),
   6756                                                     mkU32(0xfbffffff))));
   6757 
   6758                      assign(t4, binop(Iop_CmpEQ32,
   6759                                       unop(Iop_8Uto32,
   6760                                            unop(Iop_16HIto8,
   6761                                                 unop(Iop_32HIto16,
   6762                                                      getIReg(rs)))),
   6763                                       unop(Iop_8Uto32,
   6764                                            unop(Iop_16HIto8,
   6765                                                 unop(Iop_32HIto16,
   6766                                                      getIReg(rt))))));
   6767                      putDSPControl(IRExpr_ITE(mkexpr(t4),
   6768                                               binop(Iop_Or32,
   6769                                                     getDSPControl(),
   6770                                                     mkU32(0x08000000)),
   6771                                               binop(Iop_And32,
   6772                                                     getDSPControl(),
   6773                                                     mkU32(0xf7ffffff))));
   6774                      break;
   6775                   }
   6776                   case 0x1: {  /* CMPU.LT.QB */
   6777                      DIP("cmpu.lt.qb r%d, r%d", rs, rt);
   6778                      vassert(!mode64);
   6779                      t1 = newTemp(Ity_I1);
   6780                      t2 = newTemp(Ity_I1);
   6781                      t3 = newTemp(Ity_I1);
   6782                      t4 = newTemp(Ity_I1);
   6783 
   6784                      assign(t1, binop(Iop_CmpLT32U,
   6785                                       unop(Iop_8Uto32,
   6786                                            unop(Iop_16to8,
   6787                                                 unop(Iop_32to16,
   6788                                                      getIReg(rs)))),
   6789                                       unop(Iop_8Uto32,
   6790                                            unop(Iop_16to8,
   6791                                                 unop(Iop_32to16,
   6792                                                      getIReg(rt))))));
   6793                      putDSPControl(IRExpr_ITE(mkexpr(t1),
   6794                                               binop(Iop_Or32,
   6795                                                     getDSPControl(),
   6796                                                     mkU32(0x01000000)),
   6797                                               binop(Iop_And32,
   6798                                                     getDSPControl(),
   6799                                                     mkU32(0xfeffffff))));
   6800 
   6801                      assign(t2, binop(Iop_CmpLT32U,
   6802                                       unop(Iop_8Uto32,
   6803                                            unop(Iop_16HIto8,
   6804                                                 unop(Iop_32to16,
   6805                                                      getIReg(rs)))),
   6806                                       unop(Iop_8Uto32,
   6807                                            unop(Iop_16HIto8,
   6808                                                 unop(Iop_32to16,
   6809                                                      getIReg(rt))))));
   6810                      putDSPControl(IRExpr_ITE(mkexpr(t2),
   6811                                               binop(Iop_Or32,
   6812                                                     getDSPControl(),
   6813                                                     mkU32(0x02000000)),
   6814                                               binop(Iop_And32,
   6815                                                     getDSPControl(),
   6816                                                     mkU32(0xfdffffff))));
   6817 
   6818                      assign(t3, binop(Iop_CmpLT32U,
   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                      putDSPControl(IRExpr_ITE(mkexpr(t3),
   6828                                               binop(Iop_Or32,
   6829                                                     getDSPControl(),
   6830                                                     mkU32(0x04000000)),
   6831                                               binop(Iop_And32,
   6832                                                     getDSPControl(),
   6833                                                     mkU32(0xfbffffff))));
   6834 
   6835                      assign(t4, binop(Iop_CmpLT32U,
   6836                                       unop(Iop_8Uto32,
   6837                                            unop(Iop_16HIto8,
   6838                                                 unop(Iop_32HIto16,
   6839                                                      getIReg(rs)))),
   6840                                       unop(Iop_8Uto32,
   6841                                            unop(Iop_16HIto8,
   6842                                                 unop(Iop_32HIto16,
   6843                                                      getIReg(rt))))));
   6844                      putDSPControl(IRExpr_ITE(mkexpr(t4),
   6845                                               binop(Iop_Or32,
   6846                                                     getDSPControl(),
   6847                                                     mkU32(0x08000000)),
   6848                                               binop(Iop_And32,
   6849                                                     getDSPControl(),
   6850                                                     mkU32(0xf7ffffff))));
   6851                      break;
   6852                   }
   6853                   case 0x2: {  /* CMPU.LE.QB */
   6854                      DIP("cmpu.le.qb r%d, r%d", rs, rt);
   6855                      vassert(!mode64);
   6856                      t1 = newTemp(Ity_I1);
   6857                      t2 = newTemp(Ity_I1);
   6858                      t3 = newTemp(Ity_I1);
   6859                      t4 = newTemp(Ity_I1);
   6860 
   6861                      assign(t1, binop(Iop_CmpLE32U,
   6862                                       unop(Iop_8Uto32,
   6863                                            unop(Iop_16to8,
   6864                                                 unop(Iop_32to16,
   6865                                                      getIReg(rs)))),
   6866                                       unop(Iop_8Uto32,
   6867                                            unop(Iop_16to8,
   6868                                                 unop(Iop_32to16,
   6869                                                      getIReg(rt))))));
   6870                      putDSPControl(IRExpr_ITE(mkexpr(t1),
   6871                                               binop(Iop_Or32,
   6872                                                     getDSPControl(),
   6873                                                     mkU32(0x01000000)),
   6874                                               binop(Iop_And32,
   6875                                                     getDSPControl(),
   6876                                                     mkU32(0xfeffffff))));
   6877 
   6878                      assign(t2, binop(Iop_CmpLE32U,
   6879                                       unop(Iop_8Uto32,
   6880                                            unop(Iop_16HIto8,
   6881                                                 unop(Iop_32to16,
   6882                                                      getIReg(rs)))),
   6883                                       unop(Iop_8Uto32,
   6884                                            unop(Iop_16HIto8,
   6885                                                 unop(Iop_32to16,
   6886                                                      getIReg(rt))))));
   6887                      putDSPControl(IRExpr_ITE(mkexpr(t2),
   6888                                               binop(Iop_Or32,
   6889                                                     getDSPControl(),
   6890                                                     mkU32(0x02000000)),
   6891                                               binop(Iop_And32,
   6892                                                     getDSPControl(),
   6893                                                     mkU32(0xfdffffff))));
   6894 
   6895                      assign(t3, binop(Iop_CmpLE32U,
   6896                                       unop(Iop_8Uto32,
   6897                                            unop(Iop_16to8,
   6898                                                 unop(Iop_32HIto16,
   6899                                                      getIReg(rs)))),
   6900                                       unop(Iop_8Uto32,
   6901                                            unop(Iop_16to8,
   6902                                                 unop(Iop_32HIto16,
   6903                                                      getIReg(rt))))));
   6904                      putDSPControl(IRExpr_ITE(mkexpr(t3),
   6905                                               binop(Iop_Or32,
   6906                                                     getDSPControl(),
   6907                                                     mkU32(0x04000000)),
   6908                                               binop(Iop_And32,
   6909                                                     getDSPControl(),
   6910                                                     mkU32(0xfbffffff))));
   6911 
   6912                      assign(t4, binop(Iop_CmpLE32U,
   6913                                       unop(Iop_8Uto32,
   6914                                            unop(Iop_16HIto8,
   6915                                                 unop(Iop_32HIto16,
   6916                                                      getIReg(rs)))),
   6917                                       unop(Iop_8Uto32,
   6918                                            unop(Iop_16HIto8,
   6919                                                 unop(Iop_32HIto16,
   6920                                                      getIReg(rt))))));
   6921                      putDSPControl(IRExpr_ITE(mkexpr(t4),
   6922                                               binop(Iop_Or32,
   6923                                                     getDSPControl(),
   6924                                                     mkU32(0x08000000)),
   6925                                               binop(Iop_And32,
   6926                                                     getDSPControl(),
   6927                                                     mkU32(0xf7ffffff))));
   6928                      break;
   6929                   }
   6930                   case 0x3: {  /* PICK.QB */
   6931                      DIP("pick.qb r%d, r%d, r%d", rd, rs, rt);
   6932                      vassert(!mode64);
   6933                      t0 = newTemp(Ity_I32);
   6934                      t1 = newTemp(Ity_I8);
   6935                      t2 = newTemp(Ity_I8);
   6936                      t3 = newTemp(Ity_I8);
   6937                      t4 = newTemp(Ity_I8);
   6938 
   6939                      assign(t0, getDSPControl());
   6940                      assign(t1, IRExpr_ITE(binop(Iop_CmpNE32,
   6941                                                  binop(Iop_And32,
   6942                                                        mkexpr(t0),
   6943                                                        mkU32(0x01000000)),
   6944                                                  mkU32(0x0)),
   6945                                            unop(Iop_16to8,
   6946                                                  unop(Iop_32to16,
   6947                                                       getIReg(rs))),
   6948                                            unop(Iop_16to8,
   6949                                                 unop(Iop_32to16,
   6950                                                      getIReg(rt)))));
   6951                      assign(t2, IRExpr_ITE(binop(Iop_CmpNE32,
   6952                                                  binop(Iop_And32,
   6953                                                        mkexpr(t0),
   6954                                                        mkU32(0x02000000)),
   6955                                                  mkU32(0x0)),
   6956                                            unop(Iop_16HIto8,
   6957                                                 unop(Iop_32to16, getIReg(rs))),
   6958                                            unop(Iop_16HIto8,
   6959                                                 unop(Iop_32to16,
   6960                                                      getIReg(rt)))));
   6961                      assign(t3, IRExpr_ITE(binop(Iop_CmpNE32,
   6962                                                  binop(Iop_And32,
   6963                                                        mkexpr(t0),
   6964                                                        mkU32(0x04000000)),
   6965                                                  mkU32(0x0)),
   6966                                            unop(Iop_16to8,
   6967                                                 unop(Iop_32HIto16,
   6968                                                      getIReg(rs))),
   6969                                            unop(Iop_16to8,
   6970                                                 unop(Iop_32HIto16,
   6971                                                      getIReg(rt)))));
   6972                      assign(t4, IRExpr_ITE(binop(Iop_CmpNE32,
   6973                                                  binop(Iop_And32,
   6974                                                        mkexpr(t0),
   6975                                                        mkU32(0x08000000)),
   6976                                                  mkU32(0x0)),
   6977                                            unop(Iop_16HIto8,
   6978                                                 unop(Iop_32HIto16,
   6979                                                      getIReg(rs))),
   6980                                            unop(Iop_16HIto8,
   6981                                                 unop(Iop_32HIto16,
   6982                                                      getIReg(rt)))));
   6983                      putIReg(rd,
   6984                              binop(Iop_16HLto32,
   6985                                    binop(Iop_8HLto16, mkexpr(t4), mkexpr(t3)),
   6986                                    binop(Iop_8HLto16, mkexpr(t2), mkexpr(t1))));
   6987                      break;
   6988                   }
   6989                   case 0x4: {  /* CMPGU.EQ.QB */
   6990                      DIP("cmpgu.eq.qb r%d, r%d, r%d", rd, rs, rt);
   6991                      vassert(!mode64);
   6992                      t1 = newTemp(Ity_I1);
   6993                      t2 = newTemp(Ity_I1);
   6994                      t3 = newTemp(Ity_I1);
   6995                      t4 = newTemp(Ity_I1);
   6996                      t5 = newTemp(Ity_I32);
   6997                      t6 = newTemp(Ity_I32);
   6998                      t7 = newTemp(Ity_I32);
   6999                      t8 = newTemp(Ity_I32);
   7000 
   7001                      assign(t1, binop(Iop_CmpEQ32,
   7002                                       unop(Iop_8Uto32,
   7003                                            unop(Iop_16to8,
   7004                                                 unop(Iop_32to16, getIReg(rs)))),
   7005                                       unop(Iop_8Uto32,
   7006                                            unop(Iop_16to8,
   7007                                                 unop(Iop_32to16,
   7008                                                      getIReg(rt))))));
   7009                      assign(t5, IRExpr_ITE(mkexpr(t1),
   7010                                            mkU32(0x00000001), mkU32(0)));
   7011 
   7012                      assign(t2, binop(Iop_CmpEQ32,
   7013                                       unop(Iop_8Uto32,
   7014                                            unop(Iop_16HIto8,
   7015                                                 unop(Iop_32to16, getIReg(rs)))),
   7016                                       unop(Iop_8Uto32,
   7017                                            unop(Iop_16HIto8,
   7018                                                 unop(Iop_32to16,
   7019                                                      getIReg(rt))))));
   7020                      assign(t6, IRExpr_ITE(mkexpr(t2),
   7021                                            mkU32(0x00000002), mkU32(0)));
   7022 
   7023                      assign(t3, binop(Iop_CmpEQ32,
   7024                                       unop(Iop_8Uto32,
   7025                                            unop(Iop_16to8,
   7026                                                 unop(Iop_32HIto16,
   7027                                                      getIReg(rs)))),
   7028                                       unop(Iop_8Uto32,
   7029                                            unop(Iop_16to8,
   7030                                                 unop(Iop_32HIto16,
   7031                                                      getIReg(rt))))));
   7032                      assign(t7, IRExpr_ITE(mkexpr(t3),
   7033                                            mkU32(0x00000004), mkU32(0)));
   7034 
   7035                      assign(t4, binop(Iop_CmpEQ32,
   7036                                       unop(Iop_8Uto32,
   7037                                            unop(Iop_16HIto8,
   7038                                                 unop(Iop_32HIto16,
   7039                                                      getIReg(rs)))),
   7040                                       unop(Iop_8Uto32,
   7041                                            unop(Iop_16HIto8,
   7042                                                 unop(Iop_32HIto16,
   7043                                                      getIReg(rt))))));
   7044                      assign(t8, IRExpr_ITE(mkexpr(t4),
   7045                                            mkU32(0x00000008), mkU32(0)));
   7046 
   7047                      putIReg(rd, binop(Iop_Or32,
   7048                                        binop(Iop_Or32,
   7049                                              binop(Iop_Or32,
   7050                                                    mkexpr(t5), mkexpr(t6)),
   7051                                              mkexpr(t7)),
   7052                                        mkexpr(t8)));
   7053                      break;
   7054                   }
   7055                   case 0x5: {  /* CMPGU.LT.QB */
   7056                      DIP("cmpgu.lt.qb r%d, r%d, r%d", rd, rs, rt);
   7057                      vassert(!mode64);
   7058                      t1 = newTemp(Ity_I1);
   7059                      t2 = newTemp(Ity_I1);
   7060                      t3 = newTemp(Ity_I1);
   7061                      t4 = newTemp(Ity_I1);
   7062                      t5 = newTemp(Ity_I32);
   7063                      t6 = newTemp(Ity_I32);
   7064                      t7 = newTemp(Ity_I32);
   7065                      t8 = newTemp(Ity_I32);
   7066 
   7067                      assign(t1, binop(Iop_CmpLT32U,
   7068                                       unop(Iop_8Uto32,
   7069                                            unop(Iop_16to8,
   7070                                                 unop(Iop_32to16, getIReg(rs)))),
   7071                                       unop(Iop_8Uto32,
   7072                                            unop(Iop_16to8,
   7073                                                 unop(Iop_32to16,
   7074                                                      getIReg(rt))))));
   7075                      assign(t5, IRExpr_ITE(mkexpr(t1),
   7076                                            mkU32(0x00000001), mkU32(0)));
   7077 
   7078                      assign(t2, binop(Iop_CmpLT32U,
   7079                                       unop(Iop_8Uto32,
   7080                                            unop(Iop_16HIto8,
   7081                                                 unop(Iop_32to16, getIReg(rs)))),
   7082                                       unop(Iop_8Uto32,
   7083                                            unop(Iop_16HIto8,
   7084                                                 unop(Iop_32to16,
   7085                                                      getIReg(rt))))));
   7086                      assign(t6, IRExpr_ITE(mkexpr(t2),
   7087                                            mkU32(0x00000002), mkU32(0)));
   7088 
   7089                      assign(t3, binop(Iop_CmpLT32U,
   7090                                       unop(Iop_8Uto32,
   7091                                            unop(Iop_16to8,
   7092                                                 unop(Iop_32HIto16,
   7093                                                      getIReg(rs)))),
   7094                                       unop(Iop_8Uto32,
   7095                                            unop(Iop_16to8,
   7096                                                 unop(Iop_32HIto16,
   7097                                                      getIReg(rt))))));
   7098                      assign(t7, IRExpr_ITE(mkexpr(t3),
   7099                                            mkU32(0x00000004), mkU32(0)));
   7100 
   7101                      assign(t4, binop(Iop_CmpLT32U,
   7102                                       unop(Iop_8Uto32,
   7103                                            unop(Iop_16HIto8,
   7104                                                 unop(Iop_32HIto16,
   7105                                                      getIReg(rs)))),
   7106                                       unop(Iop_8Uto32,
   7107                                            unop(Iop_16HIto8,
   7108                                                 unop(Iop_32HIto16,
   7109                                                      getIReg(rt))))));
   7110                      assign(t8, IRExpr_ITE(mkexpr(t4),
   7111                                            mkU32(0x00000008), mkU32(0)));
   7112                      putIReg(rd, binop(Iop_Or32,
   7113                                        binop(Iop_Or32,
   7114                                              binop(Iop_Or32,
   7115                                                    mkexpr(t5), mkexpr(t6)),
   7116                                              mkexpr(t7)),
   7117                                        mkexpr(t8)));
   7118                      break;
   7119                   }
   7120                   case 0x6: {  /* CMPGU.LE.QB */
   7121                      DIP("cmpgu.le.qb r%d, r%d, r%d", rd, rs, rt);
   7122                      vassert(!mode64);
   7123                      t1 = newTemp(Ity_I1);
   7124                      t2 = newTemp(Ity_I1);
   7125                      t3 = newTemp(Ity_I1);
   7126                      t4 = newTemp(Ity_I1);
   7127                      t5 = newTemp(Ity_I32);
   7128                      t6 = newTemp(Ity_I32);
   7129                      t7 = newTemp(Ity_I32);
   7130                      t8 = newTemp(Ity_I32);
   7131 
   7132                      assign(t1, binop(Iop_CmpLE32U,
   7133                                       unop(Iop_8Uto32,
   7134                                            unop(Iop_16to8,
   7135                                                 unop(Iop_32to16, getIReg(rs)))),
   7136                                       unop(Iop_8Uto32,
   7137                                            unop(Iop_16to8,
   7138                                                 unop(Iop_32to16,
   7139                                                      getIReg(rt))))));
   7140                      assign(t5, IRExpr_ITE(mkexpr(t1),
   7141                                            mkU32(0x00000001), mkU32(0)));
   7142 
   7143                      assign(t2, binop(Iop_CmpLE32U,
   7144                                       unop(Iop_8Uto32,
   7145                                            unop(Iop_16HIto8,
   7146                                                 unop(Iop_32to16, getIReg(rs)))),
   7147                                       unop(Iop_8Uto32,
   7148                                            unop(Iop_16HIto8,
   7149                                                 unop(Iop_32to16,
   7150                                                      getIReg(rt))))));
   7151                      assign(t6, IRExpr_ITE(mkexpr(t2),
   7152                                            mkU32(0x00000002), mkU32(0)));
   7153 
   7154                      assign(t3, binop(Iop_CmpLE32U,
   7155                                       unop(Iop_8Uto32,
   7156                                            unop(Iop_16to8,
   7157                                                 unop(Iop_32HIto16,
   7158                                                      getIReg(rs)))),
   7159                                       unop(Iop_8Uto32,
   7160                                            unop(Iop_16to8,
   7161                                                 unop(Iop_32HIto16,
   7162                                                      getIReg(rt))))));
   7163                      assign(t7, IRExpr_ITE(mkexpr(t3),
   7164                                            mkU32(0x00000004), mkU32(0)));
   7165 
   7166                      assign(t4, binop(Iop_CmpLE32U,
   7167                                       unop(Iop_8Uto32,
   7168                                            unop(Iop_16HIto8,
   7169                                                 unop(Iop_32HIto16,
   7170                                                      getIReg(rs)))),
   7171                                       unop(Iop_8Uto32,
   7172                                            unop(Iop_16HIto8,
   7173                                                 unop(Iop_32HIto16,
   7174                                                      getIReg(rt))))));
   7175                      assign(t8, IRExpr_ITE(mkexpr(t4),
   7176                                            mkU32(0x00000008), mkU32(0)));
   7177                      putIReg(rd, binop(Iop_Or32,
   7178                                        binop(Iop_Or32,
   7179                                              binop(Iop_Or32,
   7180                                                    mkexpr(t5), mkexpr(t6)),
   7181                                              mkexpr(t7)),
   7182                                        mkexpr(t8)));
   7183                      break;
   7184                   }
   7185                   case 0x8: {  /* CMP.EQ.PH */
   7186                      DIP("cmp.eq.ph r%d, r%d", rs, rt);
   7187                      vassert(!mode64);
   7188                      t1 = newTemp(Ity_I1);
   7189                      t2 = newTemp(Ity_I1);
   7190 
   7191                      assign(t1, binop(Iop_CmpEQ16,
   7192                                       unop(Iop_32to16, getIReg(rs)),
   7193                                       unop(Iop_32to16, getIReg(rt))));
   7194                      putDSPControl(IRExpr_ITE(mkexpr(t1),
   7195                                               binop(Iop_Or32,
   7196                                                     getDSPControl(),
   7197                                                     mkU32(0x01000000)),
   7198                                               binop(Iop_And32,
   7199                                                     getDSPControl(),
   7200                                                     mkU32(0xfeffffff))));
   7201                      assign(t2, binop(Iop_CmpEQ16,
   7202                                       unop(Iop_32HIto16, getIReg(rs)),
   7203                                       unop(Iop_32HIto16, getIReg(rt))));
   7204                      putDSPControl(IRExpr_ITE(mkexpr(t2),
   7205                                               binop(Iop_Or32,
   7206                                                     getDSPControl(),
   7207                                                     mkU32(0x02000000)),
   7208                                               binop(Iop_And32,
   7209                                                     getDSPControl(),
   7210                                                     mkU32(0xfdffffff))));
   7211                      break;
   7212                   }
   7213                   case 0x9: {  /* CMP.LT.PH */
   7214                      DIP("cmp.lt.ph r%d, r%d", rs, rt);
   7215                      vassert(!mode64);
   7216                      t1 = newTemp(Ity_I1);
   7217                      t2 = newTemp(Ity_I1);
   7218 
   7219                      assign(t1, binop(Iop_CmpLT32S,
   7220                                       unop(Iop_16Sto32,
   7221                                            unop(Iop_32to16, getIReg(rs))),
   7222                                       unop(Iop_16Sto32,
   7223                                            unop(Iop_32to16, getIReg(rt)))));
   7224                      putDSPControl(IRExpr_ITE(mkexpr(t1),
   7225                                               binop(Iop_Or32,
   7226                                                     getDSPControl(),
   7227                                                     mkU32(0x01000000)),
   7228                                               binop(Iop_And32,
   7229                                                     getDSPControl(),
   7230                                                     mkU32(0xfeffffff))));
   7231 
   7232                      assign(t2, binop(Iop_CmpLT32S,
   7233                                       unop(Iop_16Sto32,
   7234                                            unop(Iop_32HIto16, getIReg(rs))),
   7235                                       unop(Iop_16Sto32,
   7236                                            unop(Iop_32HIto16, getIReg(rt)))));
   7237                      putDSPControl(IRExpr_ITE(mkexpr(t2),
   7238                                               binop(Iop_Or32,
   7239                                                     getDSPControl(),
   7240                                                     mkU32(0x02000000)),
   7241                                               binop(Iop_And32,
   7242                                                     getDSPControl(),
   7243                                                     mkU32(0xfdffffff))));
   7244                      break;
   7245                   }
   7246                   case 0xA: {  /* CMP.LE.PH */
   7247                      DIP("cmp.le.ph r%d, r%d", rs, rt);
   7248                      vassert(!mode64);
   7249                      t1 = newTemp(Ity_I1);
   7250                      t2 = newTemp(Ity_I1);
   7251 
   7252                      assign(t1, binop(Iop_CmpLE32S,
   7253                                       unop(Iop_16Sto32,
   7254                                            unop(Iop_32to16, getIReg(rs))),
   7255                                       unop(Iop_16Sto32,
   7256                                            unop(Iop_32to16, getIReg(rt)))));
   7257                      putDSPControl(IRExpr_ITE(mkexpr(t1),
   7258                                               binop(Iop_Or32,
   7259                                                     getDSPControl(),
   7260                                                     mkU32(0x01000000)),
   7261                                               binop(Iop_And32,
   7262                                                     getDSPControl(),
   7263                                                     mkU32(0xfeffffff))));
   7264 
   7265                      assign(t2, binop(Iop_CmpLE32S,
   7266                                       unop(Iop_16Sto32,
   7267                                            unop(Iop_32HIto16, getIReg(rs))),
   7268                                       unop(Iop_16Sto32,
   7269                                            unop(Iop_32HIto16, getIReg(rt)))));
   7270                      putDSPControl(IRExpr_ITE(mkexpr(t2),
   7271                                               binop(Iop_Or32,
   7272                                                     getDSPControl(),
   7273                                                     mkU32(0x02000000)),
   7274                                               binop(Iop_And32,
   7275                                                     getDSPControl(),
   7276                                                     mkU32(0xfdffffff))));
   7277                      break;
   7278                   }
   7279                   case 0xB: {  /* PICK.PH */
   7280                      DIP("pick.qb r%d, r%d, r%d", rd, rs, rt);
   7281                      vassert(!mode64);
   7282                      t0 = newTemp(Ity_I32);
   7283                      t1 = newTemp(Ity_I16);
   7284                      t2 = newTemp(Ity_I16);
   7285 
   7286                      assign(t0, getDSPControl());
   7287 
   7288                      assign(t1, IRExpr_ITE(binop(Iop_CmpNE32,
   7289                                                  binop(Iop_And32,
   7290                                                        mkexpr(t0),
   7291                                                        mkU32(0x01000000)),
   7292                                                  mkU32(0x0)),
   7293                                            unop(Iop_32to16, getIReg(rs)),
   7294                                            unop(Iop_32to16, getIReg(rt))));
   7295 
   7296                      assign(t2, IRExpr_ITE(binop(Iop_CmpNE32,
   7297                                                  binop(Iop_And32,
   7298                                                        mkexpr(t0),
   7299                                                        mkU32(0x02000000)),
   7300                                                  mkU32(0x0)),
   7301                                            unop(Iop_32HIto16, getIReg(rs)),
   7302                                            unop(Iop_32HIto16, getIReg(rt))));
   7303 
   7304                      putIReg(rd, binop(Iop_16HLto32, mkexpr(t2), mkexpr(t1)));
   7305                      break;
   7306                   }
   7307                   case 0xC: {  /* PRECRQ.QB.PH */
   7308                      DIP("precrq.qb.ph r%d, r%d, %d", rd, rs, rt);
   7309                      vassert(!mode64);
   7310                      putIReg(rd,
   7311                              binop(Iop_16HLto32,
   7312                                    binop(Iop_8HLto16,
   7313                                          unop(Iop_16HIto8,
   7314                                               unop(Iop_32HIto16, getIReg(rs))),
   7315                                          unop(Iop_16HIto8,
   7316                                               unop(Iop_32to16, getIReg(rs)))),
   7317                                    binop(Iop_8HLto16,
   7318                                          unop(Iop_16HIto8,
   7319                                               unop(Iop_32HIto16, getIReg(rt))),
   7320                                          unop(Iop_16HIto8,
   7321                                               unop(Iop_32to16, getIReg(rt))))));
   7322                      break;
   7323                   }
   7324                   case 0xD: {  /* PRECR.QB.PH */
   7325                      DIP("precr.qb.ph r%d, r%d, r%d", rd, rs, rt);
   7326                      vassert(!mode64);
   7327 
   7328                      putIReg(rd,
   7329                              binop(Iop_16HLto32,
   7330                                    binop(Iop_8HLto16,
   7331                                          unop(Iop_16to8,
   7332                                               unop(Iop_32HIto16, getIReg(rs))),
   7333                                          unop(Iop_16to8,
   7334                                               unop(Iop_32to16, getIReg(rs)))),
   7335                                    binop(Iop_8HLto16,
   7336                                          unop(Iop_16to8,
   7337                                               unop(Iop_32HIto16, getIReg(rt))),
   7338                                          unop(Iop_16to8,
   7339                                               unop(Iop_32to16, getIReg(rt))))));
   7340                      break;
   7341                   }
   7342                   case 0xF: {  /* PRECRQU_S.QB.PH */
   7343                      DIP("precrqu_s.qb.ph r%d, r%d, %d", rd, rs, rt);
   7344                      vassert(!mode64);
   7345                      t0 = newTemp(Ity_I8);
   7346                      t1 = newTemp(Ity_I8);
   7347                      t2 = newTemp(Ity_I8);
   7348                      t3 = newTemp(Ity_I8);
   7349                      t4 = newTemp(Ity_I8);
   7350                      t5 = newTemp(Ity_I32);
   7351                      t6 = newTemp(Ity_I1);
   7352                      t7 = newTemp(Ity_I8);
   7353                      t8 = newTemp(Ity_I1);
   7354                      t9 = newTemp(Ity_I32);
   7355                      t10 = newTemp(Ity_I8);
   7356                      t11 = newTemp(Ity_I1);
   7357                      t12 = newTemp(Ity_I32);
   7358                      t13 = newTemp(Ity_I8);
   7359                      t14 = newTemp(Ity_I1);
   7360                      t15 = newTemp(Ity_I32);
   7361 
   7362                      assign(t4, IRExpr_ITE(binop(Iop_CmpLT32U,
   7363                                                  mkU32(0x7f80),
   7364                                                  binop(Iop_And32,
   7365                                                        unop(Iop_16Uto32,
   7366                                                             unop(Iop_32to16,
   7367                                                             getIReg(rs))),
   7368                                                        mkU32(0x7fff))),
   7369                                            mkU8(0xff),
   7370                                            unop(Iop_16HIto8,
   7371                                                 unop(Iop_32to16,
   7372                                                      binop(Iop_Shl32,
   7373                                                            getIReg(rs),
   7374                                                            mkU8(1))))));
   7375                      assign(t0, IRExpr_ITE(binop(Iop_CmpEQ32,
   7376                                                  binop(Iop_And32,
   7377                                                        unop(Iop_16Uto32,
   7378                                                             unop(Iop_32to16,
   7379                                                                  getIReg(rs))),
   7380                                                        mkU32(0x00008000)),
   7381                                                  mkU32(0x0)),
   7382                                            mkexpr(t4),
   7383                                            mkU8(0x0)));
   7384                      assign(t5, binop(Iop_And32,
   7385                                       unop(Iop_16Uto32,
   7386                                             unop(Iop_32to16,
   7387                                                  getIReg(rs))),
   7388                                       mkU32(0x00008000)));
   7389                      assign(t6, binop(Iop_CmpLT32U,
   7390                                       mkU32(0x7f80),
   7391                                       binop(Iop_And32,
   7392                                             unop(Iop_16Uto32,
   7393                                                  unop(Iop_32to16,
   7394                                                  getIReg(rs))),
   7395                                             mkU32(0x7fff))));
   7396                      putDSPControl(IRExpr_ITE(binop(Iop_CmpEQ32,
   7397                                                     mkexpr(t5),
   7398                                                     mkU32(0x0)),
   7399                                               IRExpr_ITE(mkexpr(t6),
   7400                                                          binop(Iop_Or32,
   7401                                                                getDSPControl(),
   7402                                                                mkU32(0x00400000)
   7403                                                               ),
   7404                                                          getDSPControl()),
   7405                                               binop(Iop_Or32,
   7406                                                     getDSPControl(),
   7407                                                     mkU32(0x00400000))));
   7408 
   7409                      assign(t7, IRExpr_ITE(binop(Iop_CmpLT32U,
   7410                                                  mkU32(0x7f80),
   7411                                                  binop(Iop_And32,
   7412                                                        unop(Iop_16Uto32,
   7413                                                             unop(Iop_32HIto16,
   7414                                                                  getIReg(rs))),
   7415                                                        mkU32(0x7fff))),
   7416                                            mkU8(0xff),
   7417                                            unop(Iop_16HIto8,
   7418                                                 unop(Iop_32HIto16,
   7419                                                      binop(Iop_Shl32,
   7420                                                            getIReg(rs),
   7421                                                            mkU8(1))))));
   7422                      assign(t1, IRExpr_ITE(binop(Iop_CmpEQ32,
   7423                                                  binop(Iop_And32,
   7424                                                        unop(Iop_16Uto32,
   7425                                                             unop(Iop_32HIto16,
   7426                                                                  getIReg(rs))),
   7427                                                        mkU32(0x00008000)),
   7428                                                  mkU32(0x0)),
   7429                                            mkexpr(t7),
   7430                                            mkU8(0x0)));
   7431                      assign(t8, binop(Iop_CmpEQ32,
   7432                                       binop(Iop_And32,
   7433                                             unop(Iop_16Uto32,
   7434                                                  unop(Iop_32HIto16,
   7435                                                       getIReg(rs))),
   7436                                             mkU32(0x00008000)),
   7437                                       mkU32(0x0)));
   7438                      assign(t9, IRExpr_ITE(binop(Iop_CmpLT32U,
   7439                                                  mkU32(0x7f80),
   7440                                                  binop(Iop_And32,
   7441                                                        unop(Iop_16Uto32,
   7442                                                             unop(Iop_32HIto16,
   7443                                                                  getIReg(rs))),
   7444                                                        mkU32(0x7fff))),
   7445                                            binop(Iop_Or32,
   7446                                                  getDSPControl(),
   7447                                                  mkU32(0x00400000)),
   7448                                            getDSPControl()));
   7449                      putDSPControl(IRExpr_ITE(mkexpr(t8),
   7450                                               mkexpr(t9),
   7451                                               binop(Iop_Or32,
   7452                                                     getDSPControl(),
   7453                                                     mkU32(0x00400000))));
   7454 
   7455                      assign(t10, IRExpr_ITE(binop(Iop_CmpLT32U,
   7456                                                   mkU32(0x7f80),
   7457                                                   binop(Iop_And32,
   7458                                                         unop(Iop_16Uto32,
   7459                                                              unop(Iop_32to16,
   7460                                                              getIReg(rt))),
   7461                                                         mkU32(0x7fff))),
   7462                                             mkU8(0xff),
   7463                                             unop(Iop_16HIto8,
   7464                                                  unop(Iop_32to16,
   7465                                                       binop(Iop_Shl32,
   7466                                                             getIReg(rt),
   7467                                                             mkU8(1))))));
   7468                      assign(t2, IRExpr_ITE(binop(Iop_CmpEQ32,
   7469                                                  binop(Iop_And32,
   7470                                                        unop(Iop_16Uto32,
   7471                                                             unop(Iop_32to16,
   7472                                                                  getIReg(rt))),
   7473                                                        mkU32(0x00008000)),
   7474                                                  mkU32(0x0)),
   7475                                            mkexpr(t10),
   7476                                            mkU8(0x0)));
   7477                      assign(t11, binop(Iop_CmpEQ32,
   7478                                        binop(Iop_And32,
   7479                                              unop(Iop_16Uto32,
   7480                                                   unop(Iop_32to16,
   7481                                                        getIReg(rt))),
   7482                                              mkU32(0x00008000)),
   7483                                        mkU32(0x0)));
   7484                      assign(t12, IRExpr_ITE(binop(Iop_CmpLT32U,
   7485                                                   mkU32(0x7f80),
   7486                                                   binop(Iop_And32,
   7487                                                         unop(Iop_16Uto32,
   7488                                                              unop(Iop_32to16,
   7489                                                              getIReg(rt))),
   7490                                                         mkU32(0x7fff))),
   7491                                             binop(Iop_Or32,
   7492                                                   getDSPControl(),
   7493                                                   mkU32(0x00400000)),
   7494                                             getDSPControl()));
   7495                      putDSPControl(IRExpr_ITE(mkexpr(t11),
   7496                                               mkexpr(t12),
   7497                                               binop(Iop_Or32,
   7498                                                     getDSPControl(),
   7499                                                     mkU32(0x00400000))));
   7500 
   7501                      assign(t13, IRExpr_ITE(binop(Iop_CmpLT32U,
   7502                                                   mkU32(0x7f80),
   7503                                                   binop(Iop_And32,
   7504                                                         unop(Iop_16Uto32,
   7505                                                              unop(Iop_32HIto16,
   7506                                                                   getIReg(rt))),
   7507                                                         mkU32(0x7fff))),
   7508                                             mkU8(0xff),
   7509                                             unop(Iop_16HIto8,
   7510                                                  unop(Iop_32HIto16,
   7511                                                       binop(Iop_Shl32,
   7512                                                             getIReg(rt),
   7513                                                             mkU8(1))))));
   7514                      assign(t3, IRExpr_ITE(binop(Iop_CmpEQ32,
   7515                                                  binop(Iop_And32,
   7516                                                        unop(Iop_16Uto32,
   7517                                                             unop(Iop_32HIto16,
   7518                                                                  getIReg(rt))),
   7519                                                        mkU32(0x00008000)),
   7520                                                  mkU32(0x0)),
   7521                                            mkexpr(t13),
   7522                                            mkU8(0x0)));
   7523                      assign(t14, binop(Iop_CmpEQ32,
   7524                                        binop(Iop_And32,
   7525                                              unop(Iop_16Uto32,
   7526                                                   unop(Iop_32HIto16,
   7527                                                        getIReg(rt))),
   7528                                              mkU32(0x00008000)),
   7529                                        mkU32(0x0)));
   7530                      assign(t15, IRExpr_ITE(binop(Iop_CmpLT32U,
   7531                                                   mkU32(0x7f80),
   7532                                                   binop(Iop_And32,
   7533                                                         unop(Iop_16Uto32,
   7534                                                              unop(Iop_32HIto16,
   7535                                                                   getIReg(rt))),
   7536                                                         mkU32(0x7fff))),
   7537                                             binop(Iop_Or32,
   7538                                                   getDSPControl(),
   7539                                                   mkU32(0x00400000)),
   7540                                             getDSPControl()));
   7541                      putDSPControl(IRExpr_ITE(mkexpr(t14),
   7542                                               mkexpr(t15),
   7543                                               binop(Iop_Or32,
   7544                                                     getDSPControl(),
   7545                                                     mkU32(0x00400000))));
   7546 
   7547                      putIReg(rd, binop(Iop_16HLto32,
   7548                                        binop(Iop_8HLto16,
   7549                                              mkexpr(t1), mkexpr(t0)),
   7550                                        binop(Iop_8HLto16,
   7551                                              mkexpr(t3), mkexpr(t2))));
   7552                      break;
   7553                   }
   7554                   case 0x14: {  /* PRECRQ.PH.W */
   7555                      DIP("precrq.ph.w r%d, r%d, %d", rd, rs, rt);
   7556                      vassert(!mode64);
   7557                      putIReg(rd, binop(Iop_16HLto32,
   7558                                        unop(Iop_32HIto16, getIReg(rs)),
   7559                                        unop(Iop_32HIto16, getIReg(rt))));
   7560                      break;
   7561                   }
   7562                   case 0x15: {  /* PRECRQ_RS.PH.W */
   7563                      DIP("precrq_rs.ph.w r%d, r%d, %d", rd, rs, rt);
   7564                      vassert(!mode64);
   7565                      t0 = newTemp(Ity_I64);
   7566                      t1 = newTemp(Ity_I1);
   7567                      t2 = newTemp(Ity_I32);
   7568                      t3 = newTemp(Ity_I64);
   7569                      t4 = newTemp(Ity_I1);
   7570                      t5 = newTemp(Ity_I32);
   7571 
   7572                      assign(t0, binop(Iop_Add64,
   7573                                       binop(Iop_32HLto64,
   7574                                             binop(Iop_Shr32,
   7575                                                   binop(Iop_And32,
   7576                                                         getIReg(rs),
   7577                                                         mkU32(0x80000000)),
   7578                                                   mkU8(31)),
   7579                                             getIReg(rs)),
   7580                                       mkU64(0x0000000000008000ULL)));
   7581                      assign(t1, binop(Iop_CmpNE32,
   7582                                       binop(Iop_And32,
   7583                                             unop(Iop_64HIto32, mkexpr(t0)),
   7584                                             mkU32(0x1)),
   7585                                       binop(Iop_And32,
   7586                                             binop(Iop_Shr32,
   7587                                                   unop(Iop_64to32, mkexpr(t0)),
   7588                                                   mkU8(31)),
   7589                                             mkU32(0x1))));
   7590                      assign(t2, IRExpr_ITE(mkexpr(t1),
   7591                                            mkU32(0x7fffffff),
   7592                                            unop(Iop_64to32, mkexpr(t0))));
   7593                      putDSPControl(IRExpr_ITE(mkexpr(t1),
   7594                                               binop(Iop_Or32,
   7595                                                     getDSPControl(),
   7596                                                     mkU32(0x400000)),
   7597                                               getDSPControl()));
   7598                      assign(t3, binop(Iop_Add64,
   7599                                       binop(Iop_32HLto64,
   7600                                             binop(Iop_Shr32,
   7601                                                   binop(Iop_And32,
   7602                                                         getIReg(rt),
   7603                                                         mkU32(0x80000000)),
   7604                                                   mkU8(31)),
   7605                                             getIReg(rt)),
   7606                                       mkU64(0x0000000000008000ULL)));
   7607                      assign(t4, binop(Iop_CmpNE32,
   7608                                       binop(Iop_And32,
   7609                                             unop(Iop_64HIto32, mkexpr(t3)),
   7610                                             mkU32(0x1)),
   7611                                       binop(Iop_And32,
   7612                                             binop(Iop_Shr32,
   7613                                                   unop(Iop_64to32, mkexpr(t3)),
   7614                                                   mkU8(31)),
   7615                                             mkU32(0x1))));
   7616                      assign(t5, IRExpr_ITE(mkexpr(t4),
   7617                                            mkU32(0x7fffffff),
   7618                                            unop(Iop_64to32, mkexpr(t3))));
   7619                      putDSPControl(IRExpr_ITE(mkexpr(t4),
   7620                                               binop(Iop_Or32,
   7621                                                     getDSPControl(),
   7622                                                     mkU32(0x400000)),
   7623                                               getDSPControl()));
   7624                      putIReg(rd, binop(Iop_16HLto32,
   7625                                        unop(Iop_32HIto16, mkexpr(t2)),
   7626                                        unop(Iop_32HIto16, mkexpr(t5))));
   7627                      break;
   7628                   }
   7629                   case 0x1E: {  /* PRECR_SRA.PH.W */
   7630                      DIP("precr_sra.ph.w r%d, r%d, %d", rt, rs, rd);
   7631                      vassert(!mode64);
   7632 
   7633                      if (0 == rd) {
   7634                         putIReg(rt, binop(Iop_16HLto32,
   7635                                           unop(Iop_32to16, getIReg(rt)),
   7636                                           unop(Iop_32to16, getIReg(rs))));
   7637                      } else {
   7638                         putIReg(rt, binop(Iop_16HLto32,
   7639                                           unop(Iop_32to16, binop(Iop_Sar32,
   7640                                                                  getIReg(rt),
   7641                                                                  mkU8(rd))),
   7642                                           unop(Iop_32to16, binop(Iop_Sar32,
   7643                                                                  getIReg(rs),
   7644                                                                  mkU8(rd)))));
   7645                      }
   7646                      break;
   7647                   }
   7648                   case 0x1F: {  /* PRECR_SRA_R.PH.W */
   7649                      DIP("precr_sra_r.ph.w r%d, r%d, %d", rt, rs, rd);
   7650                      vassert(!mode64);
   7651 
   7652                      t0 = newTemp(Ity_I32);
   7653                      t1 = newTemp(Ity_I32);
   7654 
   7655                      if (0 == rd) {
   7656                         putIReg(rt, binop(Iop_16HLto32,
   7657                                           unop(Iop_32to16, getIReg(rt)),
   7658                                           unop(Iop_32to16, getIReg(rs))));
   7659                      } else {
   7660                         assign(t0, binop(Iop_Shr32,
   7661                                          binop(Iop_Add32,
   7662                                                binop(Iop_Sar32,
   7663                                                      getIReg(rt),
   7664                                                      mkU8(rd-1)),
   7665                                                mkU32(0x1)),
   7666                                          mkU8(0x1)));
   7667                         assign(t1, binop(Iop_Shr32,
   7668                                          binop(Iop_Add32,
   7669                                                binop(Iop_Sar32,
   7670                                                      getIReg(rs),
   7671                                                      mkU8(rd-1)),
   7672                                                mkU32(0x1)),
   7673                                          mkU8(0x1)));
   7674                         putIReg(rt, binop(Iop_16HLto32,
   7675                                           unop(Iop_32to16, mkexpr(t0)),
   7676                                           unop(Iop_32to16, mkexpr(t1))));
   7677                      };
   7678                      break;
   7679                   }
   7680                   case 0xE: {  /* PACKRL.PH */
   7681                      DIP("packrl.ph r%d, r%d, r%d", rd, rs, rt);
   7682                      vassert(!mode64);
   7683 
   7684                      putIReg(rd, binop(Iop_16HLto32,
   7685                                        unop(Iop_32to16, getIReg(rs)),
   7686                                        unop(Iop_32HIto16, getIReg(rt))));
   7687                      break;
   7688                   }
   7689                   case 0x18: {  /* CMPGDU.EQ.QB */
   7690                      DIP("cmpgdu.eq.qb r%d, r%d, r%d", rd, rs, rt);
   7691                      vassert(!mode64);
   7692                      t1 = newTemp(Ity_I1);
   7693                      t2 = newTemp(Ity_I1);
   7694                      t3 = newTemp(Ity_I1);
   7695                      t4 = newTemp(Ity_I1);
   7696                      t5 = newTemp(Ity_I32);
   7697                      t6 = newTemp(Ity_I32);
   7698                      t7 = newTemp(Ity_I32);
   7699                      t8 = newTemp(Ity_I32);
   7700 
   7701                      assign(t1,
   7702                             binop(Iop_CmpEQ32,
   7703                                   unop(Iop_8Uto32,
   7704                                        unop(Iop_16to8,
   7705                                             unop(Iop_32to16, getIReg(rs)))),
   7706                                   unop(Iop_8Uto32,
   7707                                        unop(Iop_16to8,
   7708                                             unop(Iop_32to16, getIReg(rt))))));
   7709                      assign(t5, IRExpr_ITE(mkexpr(t1),
   7710                                            mkU32(0x00000001), mkU32(0)));
   7711                      putDSPControl(IRExpr_ITE(mkexpr(t1),
   7712                                               binop(Iop_Or32,
   7713                                                     getDSPControl(),
   7714                                                     mkU32(0x01000000)),
   7715                                               binop(Iop_And32,
   7716                                                     getDSPControl(),
   7717                                                     mkU32(0xfeffffff))));
   7718 
   7719                      assign(t2, binop(Iop_CmpEQ32,
   7720                                       unop(Iop_8Uto32,
   7721                                            unop(Iop_16HIto8,
   7722                                                 unop(Iop_32to16, getIReg(rs)))),
   7723                                       unop(Iop_8Uto32,
   7724                                            unop(Iop_16HIto8,
   7725                                                 unop(Iop_32to16,
   7726                                                      getIReg(rt))))));
   7727                      assign(t6, IRExpr_ITE(mkexpr(t2),
   7728                                            mkU32(0x00000002), mkU32(0)));
   7729                      putDSPControl(IRExpr_ITE(mkexpr(t2),
   7730                                               binop(Iop_Or32,
   7731                                                     getDSPControl(),
   7732                                                     mkU32(0x02000000)),
   7733                                               binop(Iop_And32,
   7734                                                     getDSPControl(),
   7735                                                     mkU32(0xfdffffff))));
   7736 
   7737                      assign(t3, binop(Iop_CmpEQ32,
   7738                                       unop(Iop_8Uto32,
   7739                                            unop(Iop_16to8,
   7740                                                 unop(Iop_32HIto16,
   7741                                                      getIReg(rs)))),
   7742                                       unop(Iop_8Uto32,
   7743                                            unop(Iop_16to8,
   7744                                                 unop(Iop_32HIto16,
   7745                                                      getIReg(rt))))));
   7746                      assign(t7, IRExpr_ITE(mkexpr(t3),
   7747                                            mkU32(0x00000004), mkU32(0)));
   7748                      putDSPControl(IRExpr_ITE(mkexpr(t3),
   7749                                               binop(Iop_Or32,
   7750                                                     getDSPControl(),
   7751                                                     mkU32(0x04000000)),
   7752                                               binop(Iop_And32,
   7753                                                     getDSPControl(),
   7754                                                     mkU32(0xfbffffff))));
   7755 
   7756                      assign(t4, binop(Iop_CmpEQ32,
   7757                                       unop(Iop_8Uto32,
   7758                                            unop(Iop_16HIto8,
   7759                                                 unop(Iop_32HIto16,
   7760                                                      getIReg(rs)))),
   7761                                       unop(Iop_8Uto32,
   7762                                            unop(Iop_16HIto8,
   7763                                                 unop(Iop_32HIto16,
   7764                                                      getIReg(rt))))));
   7765                      assign(t8, IRExpr_ITE(mkexpr(t4),
   7766                                            mkU32(0x00000008), mkU32(0)));
   7767                      putDSPControl(IRExpr_ITE(mkexpr(t4),
   7768                                               binop(Iop_Or32,
   7769                                                     getDSPControl(),
   7770                                                     mkU32(0x08000000)),
   7771                                               binop(Iop_And32,
   7772                                                     getDSPControl(),
   7773                                                     mkU32(0xf7ffffff))));
   7774 
   7775                      putIReg(rd, binop(Iop_Or32,
   7776                                        binop(Iop_Or32,
   7777                                              binop(Iop_Or32,
   7778                                                    mkexpr(t5), mkexpr(t6)),
   7779                                              mkexpr(t7)),
   7780                                        mkexpr(t8)));
   7781                      break;
   7782                   }
   7783                   case 0x19: {  /* CMPGDU.LT.QB */
   7784                      DIP("cmpgdu.lt.qb r%d, r%d, r%d", rd, rs, rt);
   7785                      vassert(!mode64);
   7786                      t1 = newTemp(Ity_I1);
   7787                      t2 = newTemp(Ity_I1);
   7788                      t3 = newTemp(Ity_I1);
   7789                      t4 = newTemp(Ity_I1);
   7790                      t5 = newTemp(Ity_I32);
   7791                      t6 = newTemp(Ity_I32);
   7792                      t7 = newTemp(Ity_I32);
   7793                      t8 = newTemp(Ity_I32);
   7794 
   7795                      assign(t1, binop(Iop_CmpLT32U,
   7796                                       unop(Iop_8Uto32,
   7797                                            unop(Iop_16to8,
   7798                                                 unop(Iop_32to16, getIReg(rs)))),
   7799                                       unop(Iop_8Uto32,
   7800                                            unop(Iop_16to8,
   7801                                                 unop(Iop_32to16,
   7802                                                      getIReg(rt))))));
   7803                      assign(t5, IRExpr_ITE(mkexpr(t1),
   7804                                            mkU32(0x00000001), mkU32(0)));
   7805                      putDSPControl(IRExpr_ITE(mkexpr(t1),
   7806                                               binop(Iop_Or32,
   7807                                                     getDSPControl(),
   7808                                                     mkU32(0x01000000)),
   7809                                               binop(Iop_And32,
   7810                                                     getDSPControl(),
   7811                                                     mkU32(0xfeffffff))));
   7812 
   7813                      assign(t2, binop(Iop_CmpLT32U,
   7814                                       unop(Iop_8Uto32,
   7815                                            unop(Iop_16HIto8,
   7816                                                 unop(Iop_32to16, getIReg(rs)))),
   7817                                       unop(Iop_8Uto32,
   7818                                            unop(Iop_16HIto8,
   7819                                                 unop(Iop_32to16,
   7820                                                      getIReg(rt))))));
   7821                      assign(t6, IRExpr_ITE(mkexpr(t2),
   7822                                            mkU32(0x00000002), mkU32(0)));
   7823                      putDSPControl(IRExpr_ITE(mkexpr(t2),
   7824                                               binop(Iop_Or32,
   7825                                                     getDSPControl(),
   7826                                                     mkU32(0x02000000)),
   7827                                               binop(Iop_And32,
   7828                                                     getDSPControl(),
   7829                                                     mkU32(0xfdffffff))));
   7830 
   7831                      assign(t3, binop(Iop_CmpLT32U,
   7832                                       unop(Iop_8Uto32,
   7833                                            unop(Iop_16to8,
   7834                                                 unop(Iop_32HIto16,
   7835                                                      getIReg(rs)))),
   7836                                       unop(Iop_8Uto32,
   7837                                            unop(Iop_16to8,
   7838                                                 unop(Iop_32HIto16,
   7839                                                      getIReg(rt))))));
   7840                      assign(t7, IRExpr_ITE(mkexpr(t3),
   7841                                            mkU32(0x00000004), mkU32(0)));
   7842                      putDSPControl(IRExpr_ITE(mkexpr(t3),
   7843                                               binop(Iop_Or32,
   7844                                                     getDSPControl(),
   7845                                                     mkU32(0x04000000)),
   7846                                               binop(Iop_And32,
   7847                                                     getDSPControl(),
   7848                                                     mkU32(0xfbffffff))));
   7849 
   7850                      assign(t4, binop(Iop_CmpLT32U,
   7851                                       unop(Iop_8Uto32,
   7852                                            unop(Iop_16HIto8,
   7853                                                 unop(Iop_32HIto16,
   7854                                                      getIReg(rs)))),
   7855                                       unop(Iop_8Uto32,
   7856                                            unop(Iop_16HIto8,
   7857                                                 unop(Iop_32HIto16,
   7858                                                      getIReg(rt))))));
   7859                      assign(t8, IRExpr_ITE(mkexpr(t4),
   7860                                            mkU32(0x00000008), mkU32(0)));
   7861                      putDSPControl(IRExpr_ITE(mkexpr(t4),
   7862                                               binop(Iop_Or32,
   7863                                                     getDSPControl(),
   7864                                                     mkU32(0x08000000)),
   7865                                               binop(Iop_And32,
   7866                                                     getDSPControl(),
   7867                                                     mkU32(0xf7ffffff))));
   7868 
   7869                      putIReg(rd, binop(Iop_Or32,
   7870                                        binop(Iop_Or32,
   7871                                              binop(Iop_Or32,
   7872                                                    mkexpr(t5), mkexpr(t6)),
   7873                                              mkexpr(t7)),
   7874                                        mkexpr(t8)));
   7875                      break;
   7876                   }
   7877                   case 0x1A: {  /* CMPGDU.LE.QB */
   7878                      DIP("cmpgdu.le.qb r%d, r%d, r%d", rd, rs, rt);
   7879                      vassert(!mode64);
   7880                      t1 = newTemp(Ity_I1);
   7881                      t2 = newTemp(Ity_I1);
   7882                      t3 = newTemp(Ity_I1);
   7883                      t4 = newTemp(Ity_I1);
   7884                      t5 = newTemp(Ity_I32);
   7885                      t6 = newTemp(Ity_I32);
   7886                      t7 = newTemp(Ity_I32);
   7887                      t8 = newTemp(Ity_I32);
   7888 
   7889                      assign(t1, binop(Iop_CmpLE32U,
   7890                                       unop(Iop_8Uto32,
   7891                                            unop(Iop_16to8,
   7892                                                 unop(Iop_32to16, getIReg(rs)))),
   7893                                       unop(Iop_8Uto32,
   7894                                            unop(Iop_16to8,
   7895                                                 unop(Iop_32to16,
   7896                                                      getIReg(rt))))));
   7897                      assign(t5, IRExpr_ITE(mkexpr(t1),
   7898                                            mkU32(0x00000001),
   7899                                            mkU32(0)));
   7900                      putDSPControl(IRExpr_ITE(mkexpr(t1),
   7901                                               binop(Iop_Or32,
   7902                                                     getDSPControl(),
   7903                                                     mkU32(0x01000000)),
   7904                                               binop(Iop_And32,
   7905                                                     getDSPControl(),
   7906                                                     mkU32(0xfeffffff))));
   7907 
   7908                      assign(t2, binop(Iop_CmpLE32U,
   7909                                       unop(Iop_8Uto32,
   7910                                            unop(Iop_16HIto8,
   7911                                                 unop(Iop_32to16, getIReg(rs)))),
   7912                                       unop(Iop_8Uto32,
   7913                                            unop(Iop_16HIto8,
   7914                                                 unop(Iop_32to16,
   7915                                                      getIReg(rt))))));
   7916                      assign(t6, IRExpr_ITE(mkexpr(t2),
   7917                                            mkU32(0x00000002), mkU32(0)));
   7918                      putDSPControl(IRExpr_ITE(mkexpr(t2),
   7919                                               binop(Iop_Or32,
   7920                                                     getDSPControl(),
   7921                                                     mkU32(0x02000000)),
   7922                                               binop(Iop_And32,
   7923                                                     getDSPControl(),
   7924                                                     mkU32(0xfdffffff))));
   7925 
   7926                      assign(t3, binop(Iop_CmpLE32U,
   7927                                       unop(Iop_8Uto32,
   7928                                            unop(Iop_16to8,
   7929                                                 unop(Iop_32HIto16,
   7930                                                      getIReg(rs)))),
   7931                                       unop(Iop_8Uto32,
   7932                                            unop(Iop_16to8,
   7933                                                 unop(Iop_32HIto16,
   7934                                                      getIReg(rt))))));
   7935                      assign(t7, IRExpr_ITE(mkexpr(t3),
   7936                                            mkU32(0x00000004), mkU32(0)));
   7937                      putDSPControl(IRExpr_ITE(mkexpr(t3),
   7938                                               binop(Iop_Or32,
   7939                                                     getDSPControl(),
   7940                                                     mkU32(0x04000000)),
   7941                                               binop(Iop_And32,
   7942                                                     getDSPControl(),
   7943                                                     mkU32(0xfbffffff))));
   7944 
   7945                      assign(t4, binop(Iop_CmpLE32U,
   7946                                       unop(Iop_8Uto32,
   7947                                            unop(Iop_16HIto8,
   7948                                                 unop(Iop_32HIto16,
   7949                                                      getIReg(rs)))),
   7950                                       unop(Iop_8Uto32,
   7951                                            unop(Iop_16HIto8,
   7952                                                 unop(Iop_32HIto16,
   7953                                                      getIReg(rt))))));
   7954                      assign(t8, IRExpr_ITE(mkexpr(t4),
   7955                                            mkU32(0x00000008), mkU32(0)));
   7956                      putDSPControl(IRExpr_ITE(mkexpr(t4),
   7957                                               binop(Iop_Or32,
   7958                                                     getDSPControl(),
   7959                                                     mkU32(0x08000000)),
   7960                                               binop(Iop_And32,
   7961                                                     getDSPControl(),
   7962                                                     mkU32(0xf7ffffff))));
   7963 
   7964                      putIReg(rd, binop(Iop_Or32,
   7965                                        binop(Iop_Or32,
   7966                                              binop(Iop_Or32,
   7967                                                    mkexpr(t5), mkexpr(t6)),
   7968                                              mkexpr(t7)),
   7969                                        mkexpr(t8)));
   7970                      break;
   7971                   }
   7972                   default:
   7973                      return -1;
   7974                }
   7975                break;  /* end of CMPU.EQ.QB */
   7976             }
   7977             case 0x13: {  /* SHLL.QB */
   7978                switch(sa) {
   7979                   case 0x0: {  /* SHLL.QB */
   7980                      DIP("shll.qb r%d, r%d, %d", rd, rt, rs);
   7981                      vassert(!mode64);
   7982                      t0 = newTemp(Ity_I32);
   7983                      t1 = newTemp(Ity_I1);
   7984                      t2 = newTemp(Ity_I1);
   7985                      t3 = newTemp(Ity_I32);
   7986                      t4 = newTemp(Ity_I1);
   7987                      t5 = newTemp(Ity_I1);
   7988                      t6 = newTemp(Ity_I32);
   7989                      t7 = newTemp(Ity_I1);
   7990                      t8 = newTemp(Ity_I1);
   7991                      t9 = newTemp(Ity_I1);
   7992                      t10 = newTemp(Ity_I1);
   7993 
   7994                      if (0 == rs) {
   7995                         putIReg(rd, getIReg(rt));
   7996                      } else {
   7997                         /* Shift bits 7..0 and 23..16. */
   7998                         assign(t0, binop(Iop_Shl32,
   7999                                          binop(Iop_And32,
   8000                                                getIReg(rt),
   8001                                                mkU32(0x00ff00ff)),
   8002                                          mkU8(rs)));
   8003                         assign(t1, binop(Iop_CmpNE32,
   8004                                         binop(Iop_And32,
   8005                                               mkexpr(t0),
   8006                                               mkU32(0xff000000)),
   8007                                         mkU32(0x00000000)));
   8008                         assign(t2, binop(Iop_CmpNE32,
   8009                                         binop(Iop_And32,
   8010                                               mkexpr(t0),
   8011                                               mkU32(0xff000000)),
   8012                                         mkU32(0xff000000)));
   8013                         assign(t7, binop(Iop_CmpNE32,
   8014                                         binop(Iop_And32,
   8015                                               mkexpr(t0),
   8016                                               mkU32(0x0000ff00)),
   8017                                         mkU32(0x00000000)));
   8018                         assign(t8, binop(Iop_CmpNE32,
   8019                                         binop(Iop_And32,
   8020                                               mkexpr(t0),
   8021                                               mkU32(0x0000ff00)),
   8022                                         mkU32(0x000ff00)));
   8023                         /* Shift bits 15..8 and 31..24. */
   8024                         assign(t3, binop(Iop_Shl32,
   8025                                          binop(Iop_Shr32,
   8026                                                binop(Iop_And32,
   8027                                                      getIReg(rt),
   8028                                                      mkU32(0xff00ff00)),
   8029                                                mkU8(8)),
   8030                                          mkU8(rs)));
   8031                         assign(t4, binop(Iop_CmpNE32,
   8032                                         binop(Iop_And32,
   8033                                               mkexpr(t3),
   8034                                               mkU32(0xff000000)),
   8035                                         mkU32(0x00000000)));
   8036                         assign(t5, binop(Iop_CmpNE32,
   8037                                         binop(Iop_And32,
   8038                                               mkexpr(t3),
   8039                                               mkU32(0xff000000)),
   8040                                         mkU32(0xff000000)));
   8041                         assign(t9, binop(Iop_CmpNE32,
   8042                                         binop(Iop_And32,
   8043                                               mkexpr(t3),
   8044                                               mkU32(0x0000ff00)),
   8045                                         mkU32(0x00000000)));
   8046                         assign(t10, binop(Iop_CmpNE32,
   8047                                         binop(Iop_And32,
   8048                                               mkexpr(t3),
   8049                                               mkU32(0x0000ff00)),
   8050                                         mkU32(0x0000ff00)));
   8051 
   8052                         assign(t6, binop(Iop_Or32,
   8053                                          binop(Iop_Or32,
   8054                                                binop(Iop_And32,
   8055                                                      unop(Iop_1Uto32,
   8056                                                           mkexpr(t1)),
   8057                                                      unop(Iop_1Uto32,
   8058                                                           mkexpr(t2))),
   8059                                                binop(Iop_And32,
   8060                                                      unop(Iop_1Uto32,
   8061                                                           mkexpr(t7)),
   8062                                                      unop(Iop_1Uto32,
   8063                                                           mkexpr(t8)))),
   8064                                          binop(Iop_Or32,
   8065                                                binop(Iop_And32,
   8066                                                      unop(Iop_1Uto32,
   8067                                                           mkexpr(t4)),
   8068                                                      unop(Iop_1Uto32,
   8069                                                           mkexpr(t5))),
   8070                                                binop(Iop_And32,
   8071                                                      unop(Iop_1Uto32,
   8072                                                           mkexpr(t9)),
   8073                                                      unop(Iop_1Uto32,
   8074                                                           mkexpr(t10))))));
   8075 
   8076                         putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32,
   8077                                                        mkexpr(t6),
   8078                                                        mkU32(0x0)),
   8079                                                  binop(Iop_Or32,
   8080                                                        getDSPControl(),
   8081                                                        mkU32(0x400000)),
   8082                                                  getDSPControl()));
   8083                         putIReg(rd, binop(Iop_Or32,
   8084                                           binop(Iop_Shl32,
   8085                                                 binop(Iop_And32,
   8086                                                       mkexpr(t3),
   8087                                                       mkU32(0x00ff00ff)),
   8088                                                 mkU8(8)),
   8089                                           binop(Iop_And32,
   8090                                                 mkexpr(t0),
   8091                                                 mkU32(0x00ff00ff))));
   8092                      }
   8093                      break;
   8094                   }
   8095                   case 0x3: {  /* SHRL.QB */
   8096                      DIP("shrl.qb r%d, r%d, %d", rd, rt, rs);
   8097                      vassert(!mode64);
   8098                      t0 = newTemp(Ity_I32);
   8099                      t1 = newTemp(Ity_I8);
   8100                      t2 = newTemp(Ity_I32);
   8101                      t3 = newTemp(Ity_I8);
   8102                      t4 = newTemp(Ity_I32);
   8103                      t5 = newTemp(Ity_I8);
   8104                      t6 = newTemp(Ity_I32);
   8105                      t7 = newTemp(Ity_I8);
   8106                      t9 = newTemp(Ity_I32);
   8107 
   8108                      assign(t9, binop(Iop_And32, getIReg(rs), mkU32(0x7)));
   8109                      assign(t0, unop(Iop_8Uto32,
   8110                                      unop(Iop_16to8,
   8111                                           unop(Iop_32to16, getIReg(rt)))));
   8112                      assign(t1, unop(Iop_32to8,
   8113                                      binop(Iop_Shr32,
   8114                                            mkexpr(t0),
   8115                                            unop(Iop_32to8, mkexpr(t9)))));
   8116 
   8117                      assign(t2, unop(Iop_8Uto32,
   8118                                      unop(Iop_16HIto8,
   8119                                           unop(Iop_32to16, getIReg(rt)))));
   8120                      assign(t3, unop(Iop_32to8,
   8121                                      binop(Iop_Shr32,
   8122                                            mkexpr(t2),
   8123                                            unop(Iop_32to8, mkexpr(t9)))));
   8124 
   8125                      assign(t4, unop(Iop_8Uto32,
   8126                                      unop(Iop_16to8,
   8127                                           unop(Iop_32HIto16, getIReg(rt)))));
   8128                      assign(t5, unop(Iop_32to8,
   8129                                      binop(Iop_Shr32,
   8130                                            mkexpr(t4),
   8131                                            unop(Iop_32to8, mkexpr(t9)))));
   8132 
   8133                      assign(t6, unop(Iop_8Uto32,
   8134                                      unop(Iop_16HIto8,
   8135                                           unop(Iop_32HIto16, getIReg(rt)))));
   8136                      assign(t7, unop(Iop_32to8,
   8137                                      binop(Iop_Shr32,
   8138                                            mkexpr(t6),
   8139                                            unop(Iop_32to8, mkexpr(t9)))));
   8140                      putIReg(rd, IRExpr_ITE(binop(Iop_CmpEQ32,
   8141                                                   mkexpr(t9),
   8142                                                   mkU32(0x0)),
   8143                                             getIReg(rt),
   8144                                             binop(Iop_16HLto32,
   8145                                                   binop(Iop_8HLto16,
   8146                                                         mkexpr(t7),
   8147                                                         mkexpr(t5)),
   8148                                                   binop(Iop_8HLto16,
   8149                                                         mkexpr(t3),
   8150                                                         mkexpr(t1)))));
   8151                      break;
   8152                   }
   8153                   case 0x2: {  /* SHLLV.QB */
   8154                      DIP("shllv.qb r%d, r%d, r%d", rd, rt, rs);
   8155                      vassert(!mode64);
   8156                      t0 = newTemp(Ity_I32);
   8157                      t1 = newTemp(Ity_I1);
   8158                      t2 = newTemp(Ity_I1);
   8159                      t3 = newTemp(Ity_I32);
   8160                      t4 = newTemp(Ity_I1);
   8161                      t5 = newTemp(Ity_I1);
   8162                      t6 = newTemp(Ity_I32);
   8163                      t7 = newTemp(Ity_I1);
   8164                      t8 = newTemp(Ity_I1);
   8165                      t9 = newTemp(Ity_I1);
   8166                      t10 = newTemp(Ity_I1);
   8167                      t11 = newTemp(Ity_I8);
   8168 
   8169                      assign(t11, unop(Iop_32to8,
   8170                                       binop(Iop_And32,
   8171                                             getIReg(rs),
   8172                                             mkU32(0x7))));
   8173                      /* Shift bits 7..0 and 23..16. */
   8174                      assign(t0, binop(Iop_Shl32,
   8175                                       binop(Iop_And32,
   8176                                             getIReg(rt),
   8177                                             mkU32(0x00ff00ff)),
   8178                                       mkexpr(t11)));
   8179                      assign(t1, binop(Iop_CmpNE32,
   8180                                      binop(Iop_And32,
   8181                                            mkexpr(t0),
   8182                                            mkU32(0xff000000)),
   8183                                      mkU32(0x00000000)));
   8184                      assign(t2, binop(Iop_CmpNE32,
   8185                                      binop(Iop_And32,
   8186                                            mkexpr(t0),
   8187                                            mkU32(0xff000000)),
   8188                                      mkU32(0xff000000)));
   8189                      assign(t7, binop(Iop_CmpNE32,
   8190                                      binop(Iop_And32,
   8191                                            mkexpr(t0),
   8192                                            mkU32(0x0000ff00)),
   8193                                      mkU32(0x00000000)));
   8194                      assign(t8, binop(Iop_CmpNE32,
   8195                                      binop(Iop_And32,
   8196                                            mkexpr(t0),
   8197                                            mkU32(0x0000ff00)),
   8198                                      mkU32(0x000ff00)));
   8199                      /* Shift bits 15..8 and 31..24. */
   8200                      assign(t3, binop(Iop_Shl32,
   8201                                       binop(Iop_Shr32,
   8202                                             binop(Iop_And32,
   8203                                                   getIReg(rt),
   8204                                                   mkU32(0xff00ff00)),
   8205                                             mkU8(8)),
   8206                                       mkexpr(t11)));
   8207                      assign(t4, binop(Iop_CmpNE32,
   8208                                      binop(Iop_And32,
   8209                                            mkexpr(t3),
   8210                                            mkU32(0xff000000)),
   8211                                      mkU32(0x00000000)));
   8212                      assign(t5, binop(Iop_CmpNE32,
   8213                                      binop(Iop_And32,
   8214                                            mkexpr(t3),
   8215                                            mkU32(0xff000000)),
   8216                                      mkU32(0xff000000)));
   8217                      assign(t9, binop(Iop_CmpNE32,
   8218                                      binop(Iop_And32,
   8219                                            mkexpr(t3),
   8220                                            mkU32(0x0000ff00)),
   8221                                      mkU32(0x00000000)));
   8222                      assign(t10, binop(Iop_CmpNE32,
   8223                                      binop(Iop_And32,
   8224                                            mkexpr(t3),
   8225                                            mkU32(0x0000ff00)),
   8226                                      mkU32(0x0000ff00)));
   8227 
   8228                      assign(t6, binop(Iop_Or32,
   8229                                       binop(Iop_Or32,
   8230                                             binop(Iop_And32,
   8231                                                   unop(Iop_1Uto32,
   8232                                                        mkexpr(t1)),
   8233                                                   unop(Iop_1Uto32,
   8234                                                        mkexpr(t2))),
   8235                                             binop(Iop_And32,
   8236                                                   unop(Iop_1Uto32,
   8237                                                        mkexpr(t7)),
   8238                                                   unop(Iop_1Uto32,
   8239                                                        mkexpr(t8)))),
   8240                                       binop(Iop_Or32,
   8241                                             binop(Iop_And32,
   8242                                                   unop(Iop_1Uto32,
   8243                                                        mkexpr(t4)),
   8244                                                   unop(Iop_1Uto32,
   8245                                                        mkexpr(t5))),
   8246                                             binop(Iop_And32,
   8247                                                   unop(Iop_1Uto32,
   8248                                                        mkexpr(t9)),
   8249                                                   unop(Iop_1Uto32,
   8250                                                        mkexpr(t10))))));
   8251 
   8252                      putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32,
   8253                                                     mkexpr(t6),
   8254                                                     mkU32(0x0)),
   8255                                               binop(Iop_Or32,
   8256                                                     getDSPControl(),
   8257                                                     mkU32(0x400000)),
   8258                                               getDSPControl()));
   8259                      putIReg(rd, IRExpr_ITE(binop(Iop_CmpEQ32,
   8260                                                   unop(Iop_8Uto32, mkexpr(t11)),
   8261                                                   mkU32(0)),
   8262                                             getIReg(rt),
   8263                                             binop(Iop_Or32,
   8264                                                   binop(Iop_Shl32,
   8265                                                         binop(Iop_And32,
   8266                                                               mkexpr(t3),
   8267                                                               mkU32(0xff00ff)),
   8268                                                         mkU8(8)),
   8269                                                   binop(Iop_And32,
   8270                                                         mkexpr(t0),
   8271                                                         mkU32(0x00ff00ff)))));
   8272                      break;
   8273                   }
   8274                   case 0x1: {  /* SHRLV.QB */
   8275                      DIP("shrlv.qb r%d, r%d, r%d", rd, rt, rs);
   8276                      vassert(!mode64);
   8277                      t0 = newTemp(Ity_I8);
   8278                      t1 = newTemp(Ity_I8);
   8279                      t2 = newTemp(Ity_I8);
   8280                      t3 = newTemp(Ity_I8);
   8281 
   8282                      assign(t0, unop(Iop_32to8,
   8283                                      binop(Iop_Shr32,
   8284                                            unop(Iop_8Uto32,
   8285                                                 unop(Iop_32to8, getIReg(rt))),
   8286                                            mkU8(rs))));
   8287                      assign(t1, unop(Iop_32to8,
   8288                                      binop(Iop_Shr32,
   8289                                            unop(Iop_8Uto32,
   8290                                                 unop(Iop_16HIto8,
   8291                                                      unop(Iop_32to16,
   8292                                                           getIReg(rt)))),
   8293                                            mkU8(rs))));
   8294                      assign(t2, unop(Iop_32to8,
   8295                                       binop(Iop_Shr32,
   8296                                             unop(Iop_8Uto32,
   8297                                                  unop(Iop_16to8,
   8298                                                       unop(Iop_32HIto16,
   8299                                                            getIReg(rt)))),
   8300                                             mkU8(rs))));
   8301                      assign(t3, unop(Iop_32to8,
   8302                                      binop(Iop_Shr32,
   8303                                            unop(Iop_8Uto32,
   8304                                                 unop(Iop_16HIto8,
   8305                                                      unop(Iop_32HIto16,
   8306                                                           getIReg(rt)))),
   8307                                            mkU8(rs))));
   8308                      putIReg(rd,
   8309                              binop(Iop_16HLto32,
   8310                                    binop(Iop_8HLto16, mkexpr(t3), mkexpr(t2)),
   8311                                    binop(Iop_8HLto16, mkexpr(t1), mkexpr(t0))));
   8312                      break;
   8313                   }
   8314                   case 0x4: {  /* SHRA.QB */
   8315                      DIP("shra.qb r%d, r%d, %d", rd, rt, rs);
   8316                      vassert(!mode64);
   8317                      t0 = newTemp(Ity_I32);
   8318                      t1 = newTemp(Ity_I32);
   8319                      t2 = newTemp(Ity_I32);
   8320                      t3 = newTemp(Ity_I32);
   8321                      t4 = newTemp(Ity_I32);
   8322                      t5 = newTemp(Ity_I32);
   8323                      t6 = newTemp(Ity_I32);
   8324                      t7 = newTemp(Ity_I32);
   8325                      t8 = newTemp(Ity_I32);
   8326                      t9 = newTemp(Ity_I32);
   8327                      t10 = newTemp(Ity_I32);
   8328                      t11 = newTemp(Ity_I32);
   8329 
   8330                      /* ========== GPR[rt]_31..24 ========== */
   8331                      assign(t1,
   8332                             unop(Iop_8Uto32,
   8333                                  unop(Iop_16HIto8,
   8334                                       unop(Iop_32HIto16, getIReg(rt)))));
   8335                      assign(t2,
   8336                             binop(Iop_Shr32, mkexpr(t1), mkU8(rs)));
   8337                      /* tempD_7..0 */
   8338                      assign(t0,
   8339                             binop(Iop_Or32,
   8340                                   mkexpr(t2),
   8341                                   binop(Iop_Shl32,
   8342                                         IRExpr_ITE(binop(Iop_CmpEQ32,
   8343                                                          binop(Iop_And32,
   8344                                                                mkexpr(t1),
   8345                                                                mkU32(0x00000080)
   8346                                                               ),
   8347                                                          mkU32(0x00000080)),
   8348                                                    mkU32(0xFFFFFFFF),
   8349                                                    mkU32(0x00000000)),
   8350                                         binop(Iop_Sub8, mkU8(0x8), mkU8(rs)))));
   8351 
   8352                      /* ========== GPR[rt]_23..16 ========== */
   8353                      assign(t4,
   8354                             unop(Iop_8Uto32,
   8355                                  unop(Iop_16to8,
   8356                                       unop(Iop_32HIto16, getIReg(rt)))));
   8357                      assign(t5, binop(Iop_Shr32, mkexpr(t4), mkU8(rs)));
   8358                      /* tempC_7..0 */
   8359                      assign(t3,
   8360                             binop(Iop_Or32,
   8361                                   mkexpr(t5),
   8362                                   binop(Iop_Shl32,
   8363                                         IRExpr_ITE(binop(Iop_CmpEQ32,
   8364                                                          binop(Iop_And32,
   8365                                                                mkexpr(t4),
   8366                                                                mkU32(0x00000080)
   8367                                                               ),
   8368                                                          mkU32(0x00000080)),
   8369                                                    mkU32(0xFFFFFFFF),
   8370                                                    mkU32(0x00000000)),
   8371                                         binop(Iop_Sub8, mkU8(0x8), mkU8(rs)))));
   8372 
   8373                      /* ========== GPR[rt]_15..8 ========== */
   8374                      assign(t7,
   8375                             unop(Iop_8Uto32,
   8376                                  unop(Iop_16HIto8,
   8377                                       unop(Iop_32to16, getIReg(rt)))));
   8378                      assign(t8, binop(Iop_Shr32, mkexpr(t7), mkU8(rs)));
   8379                      /* tempB_7..0 */
   8380                      assign(t6,
   8381                             binop(Iop_Or32,
   8382                                   mkexpr(t8),
   8383                                   binop(Iop_Shl32,
   8384                                         IRExpr_ITE(binop(Iop_CmpEQ32,
   8385                                                          binop(Iop_And32,
   8386                                                                mkexpr(t7),
   8387                                                                mkU32(0x00000080)
   8388                                                               ),
   8389                                                          mkU32(0x00000080)),
   8390                                                    mkU32(0xFFFFFFFF),
   8391                                                    mkU32(0x00000000)),
   8392                                         binop(Iop_Sub8, mkU8(0x8), mkU8(rs)))));
   8393 
   8394                      /* ========== GPR[rt]_7..0 ========== */
   8395                      assign(t10,
   8396                             unop(Iop_8Uto32,
   8397                                  unop(Iop_16to8,
   8398                                       unop(Iop_32to16, getIReg(rt)))));
   8399                      assign(t11, binop(Iop_Shr32, mkexpr(t10), mkU8(rs)));
   8400                      /* tempB_7..0 */
   8401                      assign(t9,
   8402                             binop(Iop_Or32,
   8403                                   mkexpr(t11),
   8404                                   binop(Iop_Shl32,
   8405                                         IRExpr_ITE(binop(Iop_CmpEQ32,
   8406                                                          binop(Iop_And32,
   8407                                                                mkexpr(t10),
   8408                                                                mkU32(0x00000080)
   8409                                                               ),
   8410                                                          mkU32(0x00000080)),
   8411                                                    mkU32(0xFFFFFFFF),
   8412                                                    mkU32(0x00000000)),
   8413                                         binop(Iop_Sub8, mkU8(0x8), mkU8(rs)))));
   8414 
   8415                      putIReg(rd,
   8416                              binop(Iop_16HLto32,
   8417                                    binop(Iop_8HLto16,
   8418                                          unop(Iop_32to8, mkexpr(t0)),
   8419                                          unop(Iop_32to8, mkexpr(t3))),
   8420                                    binop(Iop_8HLto16,
   8421                                          unop(Iop_32to8, mkexpr(t6)),
   8422                                          unop(Iop_32to8, mkexpr(t9)))));
   8423                      break;
   8424                   }
   8425                   case 0x5: {  /* SHRA_R.QB */
   8426                      DIP("shra_r.qb r%d, r%d, %d", rd, rt, rs);
   8427                      vassert(!mode64);
   8428                      t0 = newTemp(Ity_I32);
   8429                      t1 = newTemp(Ity_I8);
   8430                      t2 = newTemp(Ity_I32);
   8431                      t3 = newTemp(Ity_I8);
   8432                      t4 = newTemp(Ity_I32);
   8433                      t5 = newTemp(Ity_I8);
   8434                      t6 = newTemp(Ity_I32);
   8435                      t7 = newTemp(Ity_I8);
   8436 
   8437                      if (0 == rs) {
   8438                         putIReg(rd, getIReg(rt));
   8439                      } else {
   8440                         assign(t0, unop(Iop_8Sto32,
   8441                                         unop(Iop_16to8,
   8442                                              unop(Iop_32to16, getIReg(rt)))));
   8443                         assign(t1, unop(Iop_32to8,
   8444                                         binop(Iop_Sar32,
   8445                                               binop(Iop_Add32,
   8446                                                     mkexpr(t0),
   8447                                                     binop(Iop_Shl32,
   8448                                                           mkU32(0x1),
   8449                                                           mkU8(rs-1))),
   8450                                               mkU8(rs))));
   8451 
   8452                         assign(t2, unop(Iop_8Sto32,
   8453                                         unop(Iop_16HIto8,
   8454                                              unop(Iop_32to16, getIReg(rt)))));
   8455                         assign(t3, unop(Iop_32to8,
   8456                                         binop(Iop_Sar32,
   8457                                               binop(Iop_Add32,
   8458                                                     mkexpr(t2),
   8459                                                     binop(Iop_Shl32,
   8460                                                           mkU32(0x1),
   8461                                                           mkU8(rs-1))),
   8462                                               mkU8(rs))));
   8463 
   8464                         assign(t4, unop(Iop_8Sto32,
   8465                                         unop(Iop_16to8,
   8466                                              unop(Iop_32HIto16, getIReg(rt)))));
   8467                         assign(t5, unop(Iop_32to8,
   8468                                         binop(Iop_Sar32,
   8469                                               binop(Iop_Add32,
   8470                                                     mkexpr(t4),
   8471                                                     binop(Iop_Shl32,
   8472                                                           mkU32(0x1),
   8473                                                           mkU8(rs-1))),
   8474                                               mkU8(rs))));
   8475 
   8476                         assign(t6, unop(Iop_8Sto32,
   8477                                         unop(Iop_16HIto8,
   8478                                              unop(Iop_32HIto16, getIReg(rt)))));
   8479                         assign(t7, unop(Iop_32to8,
   8480                                         binop(Iop_Sar32,
   8481                                               binop(Iop_Add32,
   8482                                                     mkexpr(t6),
   8483                                                     binop(Iop_Shl32,
   8484                                                           mkU32(0x1),
   8485                                                           mkU8(rs-1))),
   8486                                               mkU8(rs))));
   8487                         putIReg(rd, binop(Iop_16HLto32,
   8488                                          binop(Iop_8HLto16,
   8489                                                mkexpr(t7), mkexpr(t5)),
   8490                                          binop(Iop_8HLto16,
   8491                                                mkexpr(t3), mkexpr(t1))));
   8492                      }
   8493                      break;
   8494                   }
   8495                   case 0x6: {  /* SHRAV.QB */
   8496                      DIP("shrav.qb r%d, r%d, %d", rd, rt, rs);
   8497                      vassert(!mode64);
   8498 
   8499                      t0 = newTemp(Ity_I32);
   8500                      t1 = newTemp(Ity_I32);
   8501                      t2 = newTemp(Ity_I32);
   8502 
   8503                      t3 = newTemp(Ity_I32);
   8504                      t4 = newTemp(Ity_I32);
   8505                      t5 = newTemp(Ity_I32);
   8506 
   8507                      t6 = newTemp(Ity_I32);
   8508                      t7 = newTemp(Ity_I32);
   8509                      t8 = newTemp(Ity_I32);
   8510 
   8511                      t9 = newTemp(Ity_I32);
   8512                      t10 = newTemp(Ity_I32);
   8513                      t11 = newTemp(Ity_I32);
   8514 
   8515                      /* ========== GPR[rt]_31..24 ========== */
   8516                      assign(t1,
   8517                             unop(Iop_8Uto32,
   8518                                  unop(Iop_16HIto8,
   8519                                       unop(Iop_32HIto16, getIReg(rt)))));
   8520                      assign(t2,
   8521                             binop(Iop_Shr32,
   8522                                   mkexpr(t1),
   8523                                   unop(Iop_32to8, binop(Iop_And32,
   8524                                                         getIReg(rs),
   8525                                                         mkU32(0x7)))));
   8526                      /* tempD_7..0 */
   8527                      assign(t0,
   8528                             binop(Iop_Or32,
   8529                                   mkexpr(t2),
   8530                                   binop(Iop_Shl32,
   8531                                         IRExpr_ITE(binop(Iop_CmpEQ32,
   8532                                                          binop(Iop_And32,
   8533                                                                mkexpr(t1),
   8534                                                                mkU32(0x00000080)
   8535                                                               ),
   8536                                                          mkU32(0x00000080)),
   8537                                                    mkU32(0xFFFFFFFF),
   8538                                                    mkU32(0x00000000)),
   8539                                         binop(Iop_Sub8,
   8540                                               mkU8(0x8),
   8541                                               unop(Iop_32to8, binop(Iop_And32,
   8542                                                                     getIReg(rs),
   8543                                                                     mkU32(0x7)))
   8544                                               ))));
   8545 
   8546                      /* ========== GPR[rt]_23..16 ========== */
   8547                      assign(t4,
   8548                             unop(Iop_8Uto32,
   8549                                  unop(Iop_16to8,
   8550                                       unop(Iop_32HIto16, getIReg(rt)))));
   8551                      assign(t5,
   8552                             binop(Iop_Shr32,
   8553                                   mkexpr(t4),
   8554                                   unop(Iop_32to8, binop(Iop_And32,
   8555                                                         getIReg(rs),
   8556                                                         mkU32(0x7)))));
   8557                      /* tempC_7..0 */
   8558                      assign(t3,
   8559                             binop(Iop_Or32,
   8560                                   mkexpr(t5),
   8561                                   binop(Iop_Shl32,
   8562                                         IRExpr_ITE(binop(Iop_CmpEQ32,
   8563                                                          binop(Iop_And32,
   8564                                                                mkexpr(t4),
   8565                                                                mkU32(0x00000080)
   8566                                                               ),
   8567                                                          mkU32(0x00000080)),
   8568                                                    mkU32(0xFFFFFFFF),
   8569                                                    mkU32(0x00000000)),
   8570                                         binop(Iop_Sub8,
   8571                                               mkU8(0x8),
   8572                                               unop(Iop_32to8, binop(Iop_And32,
   8573                                                                     getIReg(rs),
   8574                                                                     mkU32(0x7)))
   8575                                               ))));
   8576 
   8577                      /* ========== GPR[rt]_15..8 ========== */
   8578                      assign(t7,
   8579                             unop(Iop_8Uto32,
   8580                                  unop(Iop_16HIto8,
   8581                                       unop(Iop_32to16, getIReg(rt)))));
   8582                      assign(t8,
   8583                             binop(Iop_Shr32,
   8584                                   mkexpr(t7),
   8585                                   unop(Iop_32to8, binop(Iop_And32,
   8586                                                         getIReg(rs),
   8587                                                         mkU32(0x7)))));
   8588                      /* tempB_7..0 */
   8589                      assign(t6,
   8590                             binop(Iop_Or32,
   8591                                   mkexpr(t8),
   8592                                   binop(Iop_Shl32,
   8593                                         IRExpr_ITE(binop(Iop_CmpEQ32,
   8594                                                          binop(Iop_And32,
   8595                                                                mkexpr(t7),
   8596                                                                mkU32(0x00000080)
   8597                                                               ),
   8598                                                          mkU32(0x00000080)),
   8599                                                    mkU32(0xFFFFFFFF),
   8600                                                    mkU32(0x00000000)),
   8601                                         binop(Iop_Sub8,
   8602                                               mkU8(0x8),
   8603                                               unop(Iop_32to8, binop(Iop_And32,
   8604                                                                     getIReg(rs),
   8605                                                                     mkU32(0x7)))
   8606                                               ))));
   8607 
   8608                      /* ========== GPR[rt]_7..0 ========== */
   8609                      assign(t10,
   8610                             unop(Iop_8Uto32,
   8611                                  unop(Iop_16to8,
   8612                                       unop(Iop_32to16, getIReg(rt)))));
   8613                      assign(t11,
   8614                             binop(Iop_Shr32,
   8615                                   mkexpr(t10),
   8616                                   unop(Iop_32to8, binop(Iop_And32,
   8617                                                         getIReg(rs),
   8618                                                         mkU32(0x7)))));
   8619                      /* tempB_7..0 */
   8620                      assign(t9,
   8621                             binop(Iop_Or32,
   8622                                   mkexpr(t11),
   8623                                   binop(Iop_Shl32,
   8624                                         IRExpr_ITE(binop(Iop_CmpEQ32,
   8625                                                          binop(Iop_And32,
   8626                                                                mkexpr(t10),
   8627                                                                mkU32(0x00000080)
   8628                                                               ),
   8629                                                          mkU32(0x00000080)),
   8630                                                    mkU32(0xFFFFFFFF),
   8631                                                    mkU32(0x00000000)),
   8632                                         binop(Iop_Sub8,
   8633                                               mkU8(0x8),
   8634                                               unop(Iop_32to8, binop(Iop_And32,
   8635                                                                     getIReg(rs),
   8636                                                                     mkU32(0x7)))
   8637                                               ))));
   8638 
   8639                      putIReg(rd,
   8640                              binop(Iop_16HLto32,
   8641                                    binop(Iop_8HLto16,
   8642                                          unop(Iop_32to8,
   8643                                               IRExpr_ITE(binop(Iop_CmpEQ32,
   8644                                                                binop(Iop_And32,
   8645                                                                      mkU32(rs),
   8646                                                                      mkU32(0x7)
   8647                                                                     ),
   8648                                                                mkU32(0x0)),
   8649                                                          mkexpr(t1),
   8650                                                          mkexpr(t0))),
   8651                                          unop(Iop_32to8,
   8652                                               IRExpr_ITE(binop(Iop_CmpEQ32,
   8653                                                                binop(Iop_And32,
   8654                                                                      mkU32(rs),
   8655                                                                      mkU32(0x7)
   8656                                                                     ),
   8657                                                                mkU32(0x0)),
   8658                                                          mkexpr(t2),
   8659                                                          mkexpr(t3)))),
   8660                                    binop(Iop_8HLto16,
   8661                                          unop(Iop_32to8,
   8662                                               IRExpr_ITE(binop(Iop_CmpEQ32,
   8663                                                                binop(Iop_And32,
   8664                                                                      mkU32(rs),
   8665                                                                      mkU32(0x7)
   8666                                                                     ),
   8667                                                                mkU32(0x0)),
   8668                                                          mkexpr(t5),
   8669                                                          mkexpr(t6))),
   8670                                          unop(Iop_32to8,
   8671                                               IRExpr_ITE(binop(Iop_CmpEQ32,
   8672                                                                binop(Iop_And32,
   8673                                                                      mkU32(rs),
   8674                                                                      mkU32(0x7)
   8675                                                                     ),
   8676                                                                mkU32(0x0)),
   8677                                                          mkexpr(t8),
   8678                                                          mkexpr(t9))))));
   8679                      break;
   8680                   }
   8681                   case 0x7: {  /* SHRAV_R.QB */
   8682                      DIP("shrav_r.qb r%d, r%d, r%d", rd, rt, rs);
   8683                      vassert(!mode64);
   8684                      t0 = newTemp(Ity_I32);
   8685                      t1 = newTemp(Ity_I8);
   8686                      t2 = newTemp(Ity_I32);
   8687                      t3 = newTemp(Ity_I8);
   8688                      t4 = newTemp(Ity_I32);
   8689                      t5 = newTemp(Ity_I8);
   8690                      t6 = newTemp(Ity_I32);
   8691                      t7 = newTemp(Ity_I8);
   8692                      t8 = newTemp(Ity_I8);
   8693                      t9 = newTemp(Ity_I32);
   8694 
   8695                      assign(t9, binop(Iop_And32, getIReg(rs), mkU32(0x7)));
   8696                      assign(t8, unop(Iop_32to8,
   8697                                      binop(Iop_Sub32, mkexpr(t9), mkU32(0x1))));
   8698                      assign(t0, unop(Iop_8Sto32,
   8699                                      unop(Iop_16to8,
   8700                                           unop(Iop_32to16, getIReg(rt)))));
   8701                      assign(t1, unop(Iop_32to8,
   8702                                      binop(Iop_Sar32,
   8703                                            binop(Iop_Add32,
   8704                                                  mkexpr(t0),
   8705                                                  binop(Iop_Shl32,
   8706                                                        mkU32(0x1),
   8707                                                        mkexpr(t8))),
   8708                                            unop(Iop_32to8,
   8709                                                 mkexpr(t9)))));
   8710 
   8711                      assign(t2, unop(Iop_8Sto32,
   8712                                      unop(Iop_16HIto8,
   8713                                           unop(Iop_32to16, getIReg(rt)))));
   8714                      assign(t3, unop(Iop_32to8,
   8715                                      binop(Iop_Sar32,
   8716                                            binop(Iop_Add32,
   8717                                                  mkexpr(t2),
   8718                                                  binop(Iop_Shl32,
   8719                                                        mkU32(0x1),
   8720                                                        mkexpr(t8))),
   8721                                            unop(Iop_32to8, mkexpr(t9)))));
   8722 
   8723                      assign(t4, unop(Iop_8Sto32,
   8724                                      unop(Iop_16to8,
   8725                                           unop(Iop_32HIto16, getIReg(rt)))));
   8726                      assign(t5, unop(Iop_32to8,
   8727                                      binop(Iop_Sar32,
   8728                                            binop(Iop_Add32,
   8729                                                  mkexpr(t4),
   8730                                                  binop(Iop_Shl32,
   8731                                                        mkU32(0x1),
   8732                                                        mkexpr(t8))),
   8733                                            unop(Iop_32to8, mkexpr(t9)))));
   8734 
   8735                      assign(t6, unop(Iop_8Sto32,
   8736                                      unop(Iop_16HIto8,
   8737                                           unop(Iop_32HIto16, getIReg(rt)))));
   8738                      assign(t7, unop(Iop_32to8,
   8739                                      binop(Iop_Sar32,
   8740                                            binop(Iop_Add32,
   8741                                                  mkexpr(t6),
   8742                                                  binop(Iop_Shl32,
   8743                                                        mkU32(0x1),
   8744                                                        mkexpr(t8))),
   8745                                            unop(Iop_32to8, mkexpr(t9)))));
   8746                      putIReg(rd, IRExpr_ITE(binop(Iop_CmpEQ32,
   8747                                                   mkexpr(t9),
   8748                                                   mkU32(0x0)),
   8749                                             getIReg(rt),
   8750                                             binop(Iop_16HLto32,
   8751                                                   binop(Iop_8HLto16,
   8752                                                         mkexpr(t7),
   8753                                                         mkexpr(t5)),
   8754                                                   binop(Iop_8HLto16,
   8755                                                         mkexpr(t3),
   8756                                                         mkexpr(t1)))));
   8757                      break;
   8758                   }
   8759                   case 0x8: {  /* SHLL.PH */
   8760                      DIP("shll.ph r%d, r%d, %d", rd, rt, rs);
   8761                      vassert(!mode64);
   8762                      t0 = newTemp(Ity_I32);
   8763                      t1 = newTemp(Ity_I32);
   8764                      t2 = newTemp(Ity_I32);
   8765                      t3 = newTemp(Ity_I32);
   8766                      t4 = newTemp(Ity_I32);
   8767                      t5 = newTemp(Ity_I32);
   8768                      t6 = newTemp(Ity_I32);
   8769                      t7 = newTemp(Ity_I32);
   8770 
   8771                      if (0 == rs) {
   8772                         putIReg(rd, getIReg(rt));
   8773                      } else {
   8774                         /* Shift lower 16 bits. */
   8775                         assign(t0, binop(Iop_Shl32,
   8776                                          unop(Iop_16Sto32,
   8777                                               unop(Iop_32to16, getIReg(rt))),
   8778                                          mkU8(rs)));
   8779 
   8780                         assign(t1, unop(Iop_1Uto32,
   8781                                         binop(Iop_CmpNE32,
   8782                                                binop(Iop_Sar32,
   8783                                                      mkexpr(t0),
   8784                                                      mkU8(16)),
   8785                                                mkU32(0))));
   8786                         assign(t2, unop(Iop_1Uto32,
   8787                                         binop(Iop_CmpNE32,
   8788                                               binop(Iop_Sar32,
   8789                                                     mkexpr(t0),
   8790                                                     mkU8(16)),
   8791                                               mkU32(0xffffffff))));
   8792                         assign(t3, binop(Iop_And32,
   8793                                          mkexpr(t1),
   8794                                          mkexpr(t2)));
   8795                         putDSPControl(IRExpr_ITE(binop(Iop_CmpEQ32,
   8796                                                        mkexpr(t3),
   8797                                                        mkU32(0x1)),
   8798                                                  binop(Iop_Or32,
   8799                                                        getDSPControl(),
   8800                                                        mkU32(0x400000)),
   8801                                                  getDSPControl()));
   8802                         putDSPControl(IRExpr_ITE(binop(Iop_CmpEQ32,
   8803                                                        binop(Iop_And32,
   8804                                                              getIReg(rt),
   8805                                                              mkU32(0x00008000)),
   8806                                                        binop(Iop_And32,
   8807                                                              mkexpr(t0),
   8808                                                              mkU32(0x00008000))
   8809                                                       ),
   8810                                                  getDSPControl(),
   8811                                                  binop(Iop_Or32,
   8812                                                        getDSPControl(),
   8813                                                        mkU32(0x400000))));
   8814                         /* Shift higher 16 bits. */
   8815                         assign(t4, binop(Iop_Shl32,
   8816                                          unop(Iop_16Sto32,
   8817                                               unop(Iop_32HIto16, getIReg(rt))),
   8818                                          mkU8(rs)));
   8819 
   8820                         assign(t5, unop(Iop_1Uto32,
   8821                                         binop(Iop_CmpNE32,
   8822                                                binop(Iop_Sar32,
   8823                                                      mkexpr(t4),
   8824                                                      mkU8(16)),
   8825                                                mkU32(0))));
   8826                         assign(t6, unop(Iop_1Uto32,
   8827                                         binop(Iop_CmpNE32,
   8828                                               binop(Iop_Sar32,
   8829                                                     mkexpr(t4),
   8830                                                     mkU8(16)),
   8831                                               mkU32(0xffffffff))));
   8832                         assign(t7, binop(Iop_And32,
   8833                                          mkexpr(t5),
   8834                                          mkexpr(t6)));
   8835                         putDSPControl(IRExpr_ITE(binop(Iop_CmpEQ32,
   8836                                                        mkexpr(t7),
   8837                                                        mkU32(0x1)),
   8838                                                  binop(Iop_Or32,
   8839                                                        getDSPControl(),
   8840                                                        mkU32(0x400000)),
   8841                                                  getDSPControl()));
   8842                         putDSPControl(IRExpr_ITE(binop(Iop_CmpEQ32,
   8843                                                        mkexpr(t7),
   8844                                                        mkU32(0x1)),
   8845                                                  binop(Iop_Or32,
   8846                                                        getDSPControl(),
   8847                                                        mkU32(0x400000)),
   8848                                                  getDSPControl()));
   8849                         putDSPControl(IRExpr_ITE(binop(Iop_CmpEQ32,
   8850                                                        binop(Iop_And32,
   8851                                                              getIReg(rt),
   8852                                                              mkU32(0x80000000)),
   8853                                                        binop(Iop_Shl32,
   8854                                                              binop(Iop_And32,
   8855                                                                    mkexpr(t4),
   8856                                                                    mkU32(0x00008000)),
   8857                                                              mkU8(16))
   8858                                                       ),
   8859                                                  getDSPControl(),
   8860                                                  binop(Iop_Or32,
   8861                                                        getDSPControl(),
   8862                                                        mkU32(0x400000))));
   8863                         putIReg(rd, binop(Iop_16HLto32,
   8864                                           unop(Iop_32to16, mkexpr(t4)),
   8865                                           unop(Iop_32to16, mkexpr(t0))));
   8866                      }
   8867                      break;
   8868                   }
   8869                   case 0x9: {  /* SHRA.PH */
   8870                      DIP("shra.ph r%d, r%d, %d", rd, rt, rs);
   8871                      vassert(!mode64);
   8872                      t0 = newTemp(Ity_I32);
   8873                      t1 = newTemp(Ity_I32);
   8874                      if (0 == rs) {
   8875                         putIReg(rd, getIReg(rt));
   8876                      } else {
   8877                         assign(t0, binop(Iop_Sar32,
   8878                                          unop(Iop_16Sto32,
   8879                                               unop(Iop_32to16, getIReg(rt))),
   8880                                          mkU8(rs)));
   8881                         assign(t1, binop(Iop_Sar32,
   8882                                          unop(Iop_16Sto32,
   8883                                               unop(Iop_32HIto16, getIReg(rt))),
   8884                                          mkU8(rs)));
   8885                         putIReg(rd, binop(Iop_16HLto32,
   8886                                           unop(Iop_32to16, mkexpr(t1)),
   8887                                           unop(Iop_32to16, mkexpr(t0))));
   8888                      }
   8889                      break;
   8890                   }
   8891                   case 0xA: {  /* SHLLV.PH */
   8892                      DIP("shllv.ph r%d, r%d, r%d", rd, rt, rs);
   8893                      vassert(!mode64);
   8894                      t0 = newTemp(Ity_I32);
   8895                      t2 = newTemp(Ity_I32);
   8896                      t3 = newTemp(Ity_I1);
   8897                      t4 = newTemp(Ity_I1);
   8898                      t5 = newTemp(Ity_I32);
   8899                      t6 = newTemp(Ity_I32);
   8900                      t7 = newTemp(Ity_I1);
   8901                      t8 = newTemp(Ity_I1);
   8902                      t9 = newTemp(Ity_I32);
   8903                      t10 = newTemp(Ity_I32);
   8904                      t11 = newTemp(Ity_I32);
   8905                      t12 = newTemp(Ity_I1);
   8906                      t13 = newTemp(Ity_I1);
   8907 
   8908                      assign(t0, binop(Iop_And32, getIReg(rs), mkU32(0x0f)));
   8909 
   8910                      /* Shift lower 16 bits. */
   8911                      assign(t2, binop(Iop_Shl32,
   8912                                       unop(Iop_16Sto32,
   8913                                            unop(Iop_32to16, getIReg(rt))),
   8914                                       unop(Iop_32to8, mkexpr(t0))));
   8915 
   8916                      assign(t3, binop(Iop_CmpNE32,
   8917                                       unop(Iop_16Sto32,
   8918                                            unop(Iop_32HIto16, mkexpr(t2))),
   8919                                       mkU32(0x00000000)));
   8920                      assign(t4, binop(Iop_CmpNE32,
   8921                                       unop(Iop_16Sto32,
   8922                                            unop(Iop_32HIto16, mkexpr(t2))),
   8923                                       mkU32(0xffffffff)));
   8924                      assign(t10, binop(Iop_And32,
   8925                                        unop(Iop_1Sto32, mkexpr(t3)),
   8926                                        unop(Iop_1Sto32, mkexpr(t4))));
   8927                      assign(t5, binop(Iop_Shr32,
   8928                                       binop(Iop_And32,
   8929                                             getIReg(rt),
   8930                                             mkU32(0x00008000)),
   8931                                       mkU8(15)));
   8932                      assign(t12, binop(Iop_CmpEQ32,
   8933                                        mkexpr(t5),
   8934                                        binop(Iop_Shr32,
   8935                                              binop(Iop_And32,
   8936                                                    mkexpr(t2),
   8937                                                    mkU32(0x00008000)),
   8938                                              mkU8(15))));
   8939 
   8940                      putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32,
   8941                                                     mkexpr(t10),
   8942                                                     mkU32(0x0)),
   8943                                               binop(Iop_Or32,
   8944                                                     getDSPControl(),
   8945                                                     mkU32(0x400000)),
   8946                                               IRExpr_ITE(mkexpr(t12),
   8947                                                          getDSPControl(),
   8948                                                          binop(Iop_Or32,
   8949                                                                getDSPControl(),
   8950                                                                mkU32(0x400000)))
   8951                                              ));
   8952                      /* Shift higher 16 bits. */
   8953                      assign(t6, binop(Iop_Shl32,
   8954                                       unop(Iop_16Sto32,
   8955                                            unop(Iop_32HIto16, getIReg(rt))),
   8956                                       unop(Iop_32to8, mkexpr(t0))));
   8957 
   8958                      assign(t7, binop(Iop_CmpNE32,
   8959                                       unop(Iop_16Sto32,
   8960                                            unop(Iop_32HIto16, mkexpr(t6))),
   8961                                       mkU32(0x00000000)));
   8962                      assign(t8, binop(Iop_CmpNE32,
   8963                                       unop(Iop_16Sto32,
   8964                                            unop(Iop_32HIto16, mkexpr(t6))),
   8965                                       mkU32(0xffffffff)));
   8966                      assign(t11, binop(Iop_And32,
   8967                                        unop(Iop_1Sto32, mkexpr(t7)),
   8968                                        unop(Iop_1Sto32, mkexpr(t8))));
   8969 
   8970                      assign(t9, binop(Iop_Shr32,
   8971                                       binop(Iop_And32,
   8972                                             getIReg(rt),
   8973                                             mkU32(0x80000000)),
   8974                                       mkU8(31)));
   8975                      assign(t13, binop(Iop_CmpEQ32,
   8976                                        mkexpr(t9),
   8977                                        binop(Iop_Shr32,
   8978                                              binop(Iop_And32,
   8979                                                    mkexpr(t6),
   8980                                                    mkU32(0x00008000)),
   8981                                              mkU8(15))));
   8982 
   8983                      putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32,
   8984                                                     mkexpr(t11),
   8985                                                     mkU32(0x0)),
   8986                                               binop(Iop_Or32,
   8987                                                     getDSPControl(),
   8988                                                     mkU32(0x400000)),
   8989                                               IRExpr_ITE(mkexpr(t13),
   8990                                                          getDSPControl(),
   8991                                                          binop(Iop_Or32,
   8992                                                                getDSPControl(),
   8993                                                                mkU32(0x400000)))
   8994                                              ));
   8995 
   8996                      putIReg(rd, binop(Iop_16HLto32,
   8997                                        unop(Iop_32to16, mkexpr(t6)),
   8998                                        unop(Iop_32to16, mkexpr(t2))));
   8999                      break;
   9000                   }
   9001                   case 0xB: {  /* SHRAV.PH */
   9002                      DIP("shrav.ph r%d, r%d, r%d", rd, rt, rs);
   9003                      vassert(!mode64);
   9004                      t0 = newTemp(Ity_I32);
   9005                      t1 = newTemp(Ity_I1);
   9006                      t2 = newTemp(Ity_I32);
   9007                      t3 = newTemp(Ity_I32);
   9008 
   9009                      assign(t0, binop(Iop_And32, getIReg(rs), mkU32(0x0f)));
   9010                      assign(t1, binop(Iop_CmpEQ32, mkexpr(t0), mkU32(0x0)));
   9011                      assign(t2, binop(Iop_Sar32,
   9012                                       unop(Iop_16Sto32,
   9013                                            unop(Iop_32to16, getIReg(rt))),
   9014                                       unop(Iop_32to8, mkexpr(t0))));
   9015                      assign(t3, binop(Iop_Sar32,
   9016                                       unop(Iop_16Sto32,
   9017                                            unop(Iop_32HIto16, getIReg(rt))),
   9018                                       unop(Iop_32to8, mkexpr(t0))));
   9019                      putIReg(rd,
   9020                              binop(Iop_16HLto32,
   9021                                    IRExpr_ITE(mkexpr(t1),
   9022                                               unop(Iop_32HIto16, getIReg(rt)),
   9023                                               unop(Iop_32to16, mkexpr(t3))),
   9024                                    IRExpr_ITE(mkexpr(t1),
   9025                                               unop(Iop_32to16, getIReg(rt)),
   9026                                               unop(Iop_32to16, mkexpr(t2)))));
   9027                      break;
   9028                   }
   9029                   case 0xC: {  /* SHLL_S.PH */
   9030                      DIP("shll_s.ph r%d, r%d, %d", rd, rt, rs);
   9031                      vassert(!mode64);
   9032                      t0 = newTemp(Ity_I32);
   9033                      t1 = newTemp(Ity_I32);
   9034                      t2 = newTemp(Ity_I32);
   9035                      t3 = newTemp(Ity_I32);
   9036                      t4 = newTemp(Ity_I32);
   9037                      t5 = newTemp(Ity_I32);
   9038                      t6 = newTemp(Ity_I32);
   9039                      t7 = newTemp(Ity_I32);
   9040                      t8 = newTemp(Ity_I32);
   9041                      t9 = newTemp(Ity_I32);
   9042                      t10 = newTemp(Ity_I32);
   9043                      t11 = newTemp(Ity_I32);
   9044                      t12 = newTemp(Ity_I32);
   9045                      t13 = newTemp(Ity_I32);
   9046                      t14 = newTemp(Ity_I32);
   9047 
   9048                      if (0 == rs) {
   9049                         putIReg(rd, getIReg(rt));
   9050                      } else {
   9051                         /* Shift lower 16 bits. */
   9052                         assign(t0, binop(Iop_Shl32,
   9053                                          unop(Iop_16Sto32,
   9054                                               unop(Iop_32to16, getIReg(rt))),
   9055                                          mkU8(rs)));
   9056 
   9057                         assign(t1, unop(Iop_1Uto32,
   9058                                         binop(Iop_CmpNE32,
   9059                                                binop(Iop_Sar32,
   9060                                                      mkexpr(t0),
   9061                                                      mkU8(16)),
   9062                                                mkU32(0))));
   9063                         assign(t2, unop(Iop_1Uto32,
   9064                                         binop(Iop_CmpNE32,
   9065                                               binop(Iop_Sar32,
   9066                                                     mkexpr(t0),
   9067                                                     mkU8(16)),
   9068                                               mkU32(0xffffffff))));
   9069                         assign(t3, binop(Iop_And32,
   9070                                          mkexpr(t1),
   9071                                          mkexpr(t2)));
   9072                         putDSPControl(IRExpr_ITE(binop(Iop_CmpEQ32,
   9073                                                        mkexpr(t3),
   9074                                                        mkU32(0x1)),
   9075                                                  binop(Iop_Or32,
   9076                                                        getDSPControl(),
   9077                                                        mkU32(0x400000)),
   9078                                                  getDSPControl()));
   9079                         putDSPControl(IRExpr_ITE(binop(Iop_CmpEQ32,
   9080                                                        binop(Iop_And32,
   9081                                                              getIReg(rt),
   9082                                                              mkU32(0x00008000)),
   9083                                                        binop(Iop_And32,
   9084                                                              mkexpr(t0),
   9085                                                              mkU32(0x00008000))
   9086                                                       ),
   9087                                                  getDSPControl(),
   9088                                                  binop(Iop_Or32,
   9089                                                        getDSPControl(),
   9090                                                        mkU32(0x400000))));
   9091                         assign(t8,
   9092                                IRExpr_ITE(binop(Iop_CmpEQ32,
   9093                                                 mkexpr(t3),
   9094                                                 mkU32(0x1)),
   9095                                           IRExpr_ITE(binop(Iop_CmpEQ32,
   9096                                                            binop(Iop_And32,
   9097                                                                  getIReg(rt),
   9098                                                                  mkU32(0x8000)),
   9099                                                            mkU32(0)),
   9100                                                      mkU32(0x00007fff),
   9101                                                      mkU32(0x00008000)),
   9102                                           binop(Iop_And32,
   9103                                                 mkexpr(t0),
   9104                                                 mkU32(0x0000ffff))));
   9105                         assign(t10,
   9106                                IRExpr_ITE(binop(Iop_CmpEQ32,
   9107                                                 binop(Iop_And32,
   9108                                                       getIReg(rt),
   9109                                                       mkU32(0x00008000)),
   9110                                                 binop(Iop_And32,
   9111                                                       mkexpr(t0),
   9112                                                       mkU32(0x00008000))),
   9113                                           mkexpr(t8),
   9114                                           IRExpr_ITE(binop(Iop_CmpEQ32,
   9115                                                            binop(Iop_And32,
   9116                                                                  getIReg(rt),
   9117                                                                  mkU32(0x8000)),
   9118                                                            mkU32(0)),
   9119                                                      mkU32(0x00007fff),
   9120                                                      mkU32(0x00008000))));
   9121                         /* Shift higher 16 bits. */
   9122                         assign(t4, binop(Iop_Shl32,
   9123                                          unop(Iop_16Sto32,
   9124                                               unop(Iop_32HIto16, getIReg(rt))),
   9125                                          mkU8(rs)));
   9126 
   9127                         assign(t5, unop(Iop_1Uto32,
   9128                                         binop(Iop_CmpNE32,
   9129                                                binop(Iop_Sar32,
   9130                                                      mkexpr(t4),
   9131                                                      mkU8(16)),
   9132                                                mkU32(0))));
   9133                         assign(t6, unop(Iop_1Uto32,
   9134                                         binop(Iop_CmpNE32,
   9135                                               binop(Iop_Sar32,
   9136                                                     mkexpr(t4),
   9137                                                     mkU8(16)),
   9138                                               mkU32(0xffffffff))));
   9139                         assign(t7, binop(Iop_And32,
   9140                                          mkexpr(t5),
   9141                                          mkexpr(t6)));
   9142                         putDSPControl(IRExpr_ITE(binop(Iop_CmpEQ32,
   9143                                                        mkexpr(t7),
   9144                                                        mkU32(0x1)),
   9145                                                  binop(Iop_Or32,
   9146                                                        getDSPControl(),
   9147                                                        mkU32(0x400000)),
   9148                                                  getDSPControl()));
   9149                         putDSPControl(IRExpr_ITE(binop(Iop_CmpEQ32,
   9150                                                        mkexpr(t7),
   9151                                                        mkU32(0x1)),
   9152                                                  binop(Iop_Or32,
   9153                                                        getDSPControl(),
   9154                                                        mkU32(0x400000)),
   9155                                                  getDSPControl()));
   9156                         assign(t12, binop(Iop_Shl32,
   9157                                           binop(Iop_And32,
   9158                                                 mkexpr(t4),
   9159                                                 mkU32(0x8000)),
   9160                                           mkU8(16)));
   9161                         putDSPControl(IRExpr_ITE(binop(Iop_CmpEQ32,
   9162                                                        binop(Iop_And32,
   9163                                                              getIReg(rt),
   9164                                                              mkU32(0x80000000)),
   9165                                                        mkexpr(t12)),
   9166                                                  getDSPControl(),
   9167                                                  binop(Iop_Or32,
   9168                                                        getDSPControl(),
   9169                                                        mkU32(0x400000))));
   9170                         assign(t13, IRExpr_ITE(binop(Iop_CmpEQ32,
   9171                                                      binop(Iop_And32,
   9172                                                            getIReg(rt),
   9173                                                            mkU32(0x80000000)),
   9174                                                      mkU32(0)),
   9175                                                mkU32(0x7fff0000),
   9176                                                mkU32(0x80000000)));
   9177                         assign(t9,
   9178                                IRExpr_ITE(binop(Iop_CmpEQ32,
   9179                                                 mkexpr(t7),
   9180                                                 mkU32(0x1)),
   9181                                           mkexpr(t13),
   9182                                           binop(Iop_Shl32,
   9183                                                 binop(Iop_And32,
   9184                                                       mkexpr(t4),
   9185                                                       mkU32(0x0000ffff)),
   9186                                                 mkU8(16))));
   9187                         assign(t14, IRExpr_ITE(binop(Iop_CmpEQ32,
   9188                                                      binop(Iop_And32,
   9189                                                            getIReg(rt),
   9190                                                            mkU32(0x80000000)),
   9191                                                      mkU32(0)),
   9192                                                mkU32(0x7fff0000),
   9193                                                mkU32(0x80000000)));
   9194                         assign(t11,
   9195                                IRExpr_ITE(binop(Iop_CmpEQ32,
   9196                                                 binop(Iop_And32,
   9197                                                       getIReg(rt),
   9198                                                       mkU32(0x80000000)),
   9199                                                 binop(Iop_Shl32,
   9200                                                       binop(Iop_And32,
   9201                                                             mkexpr(t4),
   9202                                                             mkU32(0x00008000)),
   9203                                                       mkU8(16))),
   9204                                           mkexpr(t9),
   9205                                           mkexpr(t14)));
   9206                         putIReg(rd, binop(Iop_Or32,
   9207                                           mkexpr(t10),
   9208                                           mkexpr(t11)));
   9209                      }
   9210                      break;
   9211                   }
   9212                   case 0xD: {  /* SHRA_R.PH */
   9213                      DIP("shra.ph r%d, r%d, %d", rd, rt, rs);
   9214                      vassert(!mode64);
   9215                      t0 = newTemp(Ity_I32);
   9216                      t1 = newTemp(Ity_I32);
   9217                      if (0 == rs) {
   9218                         putIReg(rd, getIReg(rt));
   9219                      } else {
   9220                         assign(t0, binop(Iop_Sar32,
   9221                                          binop(Iop_Add32,
   9222                                                unop(Iop_16Sto32,
   9223                                                     unop(Iop_32to16,
   9224                                                          getIReg(rt))),
   9225                                                binop(Iop_Shl32,
   9226                                                      mkU32(0x1),
   9227                                                      mkU8(rs-1))),
   9228                                          mkU8(rs)));
   9229                         assign(t1, binop(Iop_Sar32,
   9230                                          binop(Iop_Add32,
   9231                                                unop(Iop_16Sto32,
   9232                                                     unop(Iop_32HIto16,
   9233                                                          getIReg(rt))),
   9234                                                binop(Iop_Shl32,
   9235                                                      mkU32(0x1),
   9236                                                      mkU8(rs-1))),
   9237                                          mkU8(rs)));
   9238                         putIReg(rd, binop(Iop_16HLto32,
   9239                                           unop(Iop_32to16, mkexpr(t1)),
   9240                                           unop(Iop_32to16, mkexpr(t0))));
   9241                      }
   9242                      break;
   9243                   }
   9244                   case 0xE: {  /* SHLLV_S.PH */
   9245                      DIP("shllv_s.ph r%d, r%d, r%d", rd, rt, rs);
   9246                      vassert(!mode64);
   9247                      t0 = newTemp(Ity_I32);
   9248                      t2 = newTemp(Ity_I32);
   9249                      t3 = newTemp(Ity_I1);
   9250                      t4 = newTemp(Ity_I1);
   9251                      t5 = newTemp(Ity_I32);
   9252                      t6 = newTemp(Ity_I32);
   9253                      t7 = newTemp(Ity_I1);
   9254                      t8 = newTemp(Ity_I1);
   9255                      t9 = newTemp(Ity_I32);
   9256                      t10 = newTemp(Ity_I32);
   9257                      t11 = newTemp(Ity_I32);
   9258                      t12 = newTemp(Ity_I1);
   9259                      t13 = newTemp(Ity_I1);
   9260                      t14 = newTemp(Ity_I16);
   9261                      t15 = newTemp(Ity_I16);
   9262                      t16 = newTemp(Ity_I16);
   9263                      t17 = newTemp(Ity_I16);
   9264 
   9265                      assign(t0, binop(Iop_And32, getIReg(rs), mkU32(0x0f)));
   9266 
   9267                      /* Shift lower 16 bits. */
   9268                      assign(t2, binop(Iop_Shl32,
   9269                                       unop(Iop_16Sto32,
   9270                                            unop(Iop_32to16, getIReg(rt))),
   9271                                       unop(Iop_32to8, mkexpr(t0))));
   9272 
   9273                      assign(t3, binop(Iop_CmpNE32,
   9274                                       unop(Iop_16Sto32,
   9275                                            unop(Iop_32HIto16, mkexpr(t2))),
   9276                                       mkU32(0x00000000)));
   9277                      assign(t4, binop(Iop_CmpNE32,
   9278                                       unop(Iop_16Sto32,
   9279                                            unop(Iop_32HIto16, mkexpr(t2))),
   9280                                       mkU32(0xffffffff)));
   9281                      assign(t10, binop(Iop_And32,
   9282                                        unop(Iop_1Sto32, mkexpr(t3)),
   9283                                        unop(Iop_1Sto32, mkexpr(t4))));
   9284                      assign(t5, binop(Iop_Shr32,
   9285                                        binop(Iop_And32,
   9286                                              getIReg(rt),
   9287                                              mkU32(0x00008000)),
   9288                                        mkU8(15)));
   9289                      assign(t12, binop(Iop_CmpEQ32,
   9290                                        mkexpr(t5),
   9291                                        binop(Iop_Shr32,
   9292                                              binop(Iop_And32,
   9293                                                    mkexpr(t2),
   9294                                                    mkU32(0x00008000)),
   9295                                              mkU8(15))));
   9296 
   9297                      putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32,
   9298                                                     mkexpr(t10),
   9299                                                     mkU32(0x0)),
   9300                                               binop(Iop_Or32,
   9301                                                     getDSPControl(),
   9302                                                     mkU32(0x400000)),
   9303                                               IRExpr_ITE(mkexpr(t12),
   9304                                                          getDSPControl(),
   9305                                                          binop(Iop_Or32,
   9306                                                                getDSPControl(),
   9307                                                                mkU32(0x400000)))
   9308                                              ));
   9309                      assign(t14, IRExpr_ITE(binop(Iop_CmpNE32,
   9310                                                   mkexpr(t5),
   9311                                                   mkU32(0x0)),
   9312                                             mkU16(0x8000),
   9313                                             mkU16(0x7fff)));
   9314                      assign(t15, IRExpr_ITE(binop(Iop_CmpNE32,
   9315                                                   mkexpr(t10),
   9316                                                   mkU32(0x0)),
   9317                                             mkexpr(t14),
   9318                                             IRExpr_ITE(mkexpr(t12),
   9319                                                        unop(Iop_32to16,
   9320                                                             mkexpr(t2)),
   9321                                                        mkexpr(t14))));
   9322                      /* Shift higher 16 bits. */
   9323                      assign(t6, binop(Iop_Shl32,
   9324                                       unop(Iop_16Sto32,
   9325                                            unop(Iop_32HIto16, getIReg(rt))),
   9326                                       unop(Iop_32to8, mkexpr(t0))));
   9327 
   9328                      assign(t7, binop(Iop_CmpNE32,
   9329                                       unop(Iop_16Sto32,
   9330                                            unop(Iop_32HIto16, mkexpr(t6))),
   9331                                       mkU32(0x00000000)));
   9332                      assign(t8, binop(Iop_CmpNE32,
   9333                                       unop(Iop_16Sto32,
   9334                                            unop(Iop_32HIto16, mkexpr(t6))),
   9335                                       mkU32(0xffffffff)));
   9336                      assign(t11, binop(Iop_And32,
   9337                                        unop(Iop_1Sto32, mkexpr(t7)),
   9338                                        unop(Iop_1Sto32, mkexpr(t8))));
   9339 
   9340                      assign(t9, binop(Iop_Shr32,
   9341                                       binop(Iop_And32,
   9342                                             getIReg(rt),
   9343                                             mkU32(0x80000000)),
   9344                                       mkU8(31)));
   9345                      assign(t13, binop(Iop_CmpEQ32,
   9346                                        mkexpr(t9),
   9347                                        binop(Iop_Shr32,
   9348                                              binop(Iop_And32,
   9349                                                    mkexpr(t6),
   9350                                                    mkU32(0x00008000)),
   9351                                              mkU8(15))));
   9352 
   9353                      putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32,
   9354                                                     mkexpr(t11),
   9355                                                     mkU32(0x0)),
   9356                                               binop(Iop_Or32,
   9357                                                     getDSPControl(),
   9358                                                     mkU32(0x400000)),
   9359                                               IRExpr_ITE(mkexpr(t13),
   9360                                                          getDSPControl(),
   9361                                                          binop(Iop_Or32,
   9362                                                                getDSPControl(),
   9363                                                                mkU32(0x400000)))
   9364                                              ));
   9365 
   9366                      assign(t16, IRExpr_ITE(binop(Iop_CmpNE32,
   9367                                                   mkexpr(t9),
   9368                                                   mkU32(0x0)),
   9369                                             mkU16(0x8000),
   9370                                             mkU16(0x7fff)));
   9371                      assign(t17, IRExpr_ITE(binop(Iop_CmpNE32,
   9372                                                   mkexpr(t11),
   9373                                                   mkU32(0x0)),
   9374                                             mkexpr(t16),
   9375                                             IRExpr_ITE(mkexpr(t13),
   9376                                                        unop(Iop_32to16,
   9377                                                             mkexpr(t6)),
   9378                                                        mkexpr(t16))));
   9379 
   9380                      putIReg(rd, binop(Iop_16HLto32, mkexpr(t17), mkexpr(t15)));
   9381                      break;
   9382                   }
   9383                   case 0xF: {  /* SHRAV_R.PH */
   9384                      DIP("shrav_r.ph r%d, r%d, r%d", rd, rt, rs);
   9385                      vassert(!mode64);
   9386                      t0 = newTemp(Ity_I32);
   9387                      t1 = newTemp(Ity_I1);
   9388                      t2 = newTemp(Ity_I8);
   9389                      t3 = newTemp(Ity_I32);
   9390                      t4 = newTemp(Ity_I32);
   9391 
   9392                      assign(t0, binop(Iop_And32, getIReg(rs), mkU32(0x0f)));
   9393                      assign(t1, binop(Iop_CmpEQ32, mkexpr(t0), mkU32(0x0)));
   9394                      assign(t2, unop(Iop_32to8,
   9395                                      binop(Iop_Sub32, mkexpr(t0), mkU32(1))));
   9396 
   9397                      assign(t3, binop(Iop_Sar32,
   9398                                       binop(Iop_Add32,
   9399                                             unop(Iop_16Sto32,
   9400                                                  unop(Iop_32to16, getIReg(rt))),
   9401                                             binop(Iop_Shl32,
   9402                                                   mkU32(0x1),
   9403                                                   mkexpr(t2))),
   9404                                       unop(Iop_32to8, mkexpr(t0))));
   9405                      assign(t4, binop(Iop_Sar32,
   9406                                       binop(Iop_Add32,
   9407                                             unop(Iop_16Sto32,
   9408                                                  unop(Iop_32HIto16,
   9409                                                       getIReg(rt))),
   9410                                             binop(Iop_Shl32,
   9411                                                   mkU32(0x1),
   9412                                                   mkexpr(t2))),
   9413                                       unop(Iop_32to8, mkexpr(t0))));
   9414 
   9415                      putIReg(rd, binop(Iop_16HLto32,
   9416                                        IRExpr_ITE(mkexpr(t1),
   9417                                                   unop(Iop_32HIto16,
   9418                                                        getIReg(rt)),
   9419                                                   unop(Iop_32to16,
   9420                                                        mkexpr(t4))),
   9421                                        IRExpr_ITE(mkexpr(t1),
   9422                                                   unop(Iop_32to16, getIReg(rt)),
   9423                                                   unop(Iop_32to16,
   9424                                                        mkexpr(t3)))));
   9425                      break;
   9426                   }
   9427                   case 0x14: {  /* SHLL_S.W */
   9428                      DIP("shll_s.w r%d, r%d, %d", rd, rt, rs);
   9429                      vassert(!mode64);
   9430                      t0 = newTemp(Ity_I32);
   9431                      t1 = newTemp(Ity_I32);
   9432                      t2 = newTemp(Ity_I32);
   9433                      t3 = newTemp(Ity_I32);
   9434                      t4 = newTemp(Ity_I32);
   9435                      t5 = newTemp(Ity_I32);
   9436 
   9437                      if (0 == rs) {
   9438                         putIReg(rd, getIReg(rt));
   9439                      } else {
   9440                         /* t0-bits that will be discarded, sign extended to
   9441                            32bits. */
   9442                         assign(t0, binop(Iop_Sar32,
   9443                                          binop(Iop_And32,
   9444                                                getIReg(rt),
   9445                                                binop(Iop_Sar32,
   9446                                                      mkU32(0x80000000),
   9447                                                      mkU8(rs-1))),
   9448                                          mkU8(32-rs)));
   9449 
   9450                         assign(t1, IRExpr_ITE(binop(Iop_CmpEQ32,
   9451                                                     binop(Iop_And32,
   9452                                                           getIReg(rt),
   9453                                                           mkU32(0x80000000)),
   9454                                                     mkU32(0x0)),
   9455                                               mkU32(0x7fffffff),
   9456                                               mkU32(0x80000000)));
   9457 
   9458                         assign(t2, binop(Iop_Shl32, getIReg(rt), mkU8(rs)));
   9459                         assign(t3, IRExpr_ITE(binop(Iop_CmpEQ32,
   9460                                                     binop(Iop_And32,
   9461                                                           getIReg(rt),
   9462                                                           mkU32(0x80000000)),
   9463                                                     binop(Iop_And32,
   9464                                                           mkexpr(t2),
   9465                                                           mkU32(0x80000000))),
   9466                                               mkexpr(t2),
   9467                                               mkexpr(t1)));
   9468 
   9469                         assign(t4, IRExpr_ITE(binop(Iop_CmpNE32,
   9470                                                     mkexpr(t0),
   9471                                                     mkU32(0x0)),
   9472                                               IRExpr_ITE(binop(Iop_CmpNE32,
   9473                                                                mkexpr(t0),
   9474                                                                mkU32(0xffffffff)
   9475                                                               ),
   9476                                                          mkexpr(t1),
   9477                                                          mkexpr(t3)),
   9478                                               mkexpr(t3)));
   9479                         assign(t5, IRExpr_ITE(binop(Iop_CmpNE32,
   9480                                                     mkexpr(t0),
   9481                                                     mkU32(0xffffffff)),
   9482                                               binop(Iop_Or32,
   9483                                                     getDSPControl(),
   9484                                                     mkU32(0x400000)),
   9485                                               getDSPControl()));
   9486                         putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32,
   9487                                                        mkexpr(t0),
   9488                                                        mkU32(0x0)),
   9489                                                  mkexpr(t5),
   9490                                                  getDSPControl()));
   9491                         putDSPControl(IRExpr_ITE(binop(Iop_CmpEQ32,
   9492                                                        binop(Iop_And32,
   9493                                                              getIReg(rt),
   9494                                                              mkU32(0x80000000)),
   9495                                                        binop(Iop_And32,
   9496                                                              mkexpr(t2),
   9497                                                              mkU32(0x80000000))
   9498                                                             ),
   9499                                                  getDSPControl(),
   9500                                                  binop(Iop_Or32,
   9501                                                        getDSPControl(),
   9502                                                        mkU32(0x400000))));
   9503                         putIReg(rd, mkexpr(t4));
   9504                      }
   9505                      break;
   9506                   }
   9507                   case 0x15: {  /* SHRA_R.W */
   9508                      DIP("shra_r.w r%d, r%d, %d", rd, rt, rs);
   9509                      vassert(!mode64);
   9510                      if (0 == rs) {
   9511                         putIReg(rd, getIReg(rt));
   9512                      } else {
   9513                         putIReg(rd, binop(Iop_Add32,
   9514                                           binop(Iop_Sar32,
   9515                                                 getIReg(rt), mkU8(rs)),
   9516                                           binop(Iop_Shr32,
   9517                                                 binop(Iop_And32,
   9518                                                       getIReg(rt),
   9519                                                       binop(Iop_Shl32,
   9520                                                             mkU32(0x1),
   9521                                                             mkU8(rs-1))),
   9522                                                 mkU8(rs-1))));
   9523                      }
   9524                      break;
   9525                   }
   9526                   case 0x16: {  /* SHLLV_S.W */
   9527                      DIP("shllv_s.w r%d, r%d, r%d", rd, rt, rs);
   9528                      vassert(!mode64);
   9529                      t0 = newTemp(Ity_I32);
   9530                      t1 = newTemp(Ity_I1);
   9531                      t2 = newTemp(Ity_I32);
   9532                      t3 = newTemp(Ity_I64);
   9533                      t4 = newTemp(Ity_I1);
   9534                      t5 = newTemp(Ity_I1);
   9535                      t6 = newTemp(Ity_I32);
   9536                      t7 = newTemp(Ity_I1);
   9537                      t8 = newTemp(Ity_I32);
   9538 
   9539                      /* Check if shift amount is zero. */
   9540                      assign(t0, binop(Iop_And32, getIReg(rs), mkU32(0x1f)));
   9541                      assign(t1, binop(Iop_CmpEQ32, mkexpr(t0), mkU32(0x0)));
   9542 
   9543                      /* t2 = sign of the input value. */
   9544                      assign(t2, binop(Iop_Shr32,
   9545                                       binop(Iop_And32,
   9546                                             getIReg(rt),
   9547                                             mkU32(0x80000000)),
   9548                                       mkU8(31)));
   9549                      /* Shift left input value and check for overflow. */
   9550                      assign(t3, binop(Iop_Shl64,
   9551                                       unop(Iop_32Sto64, getIReg(rt)),
   9552                                       unop(Iop_32to8, mkexpr(t0))));
   9553                      assign(t4, binop(Iop_CmpNE32,
   9554                                       unop(Iop_64HIto32, mkexpr(t3)),
   9555                                       mkU32(0x00000000)));
   9556                      assign(t5, binop(Iop_CmpNE32,
   9557                                       unop(Iop_64HIto32, mkexpr(t3)),
   9558                                       mkU32(0xffffffff)));
   9559                      assign(t6, binop(Iop_And32,
   9560                                       unop(Iop_1Uto32, mkexpr(t4)),
   9561                                       unop(Iop_1Uto32, mkexpr(t5))));
   9562                      assign(t7, binop(Iop_CmpEQ32,
   9563                                       binop(Iop_Shr32,
   9564                                             binop(Iop_And32,
   9565                                                   getIReg(rt),
   9566                                                   mkU32(0x80000000)),
   9567                                             mkU8(31)),
   9568                                       binop(Iop_Shr32,
   9569                                             binop(Iop_And32,
   9570                                                   unop(Iop_64to32, mkexpr(t3)),
   9571                                                   mkU32(0x80000000)),
   9572                                             mkU8(31))));
   9573 
   9574                      putDSPControl(IRExpr_ITE(unop(Iop_32to1, mkexpr(t6)),
   9575                                                    binop(Iop_Or32,
   9576                                                          getDSPControl(),
   9577                                                          mkU32(0x400000)),
   9578                                               IRExpr_ITE(mkexpr(t7),
   9579                                                          getDSPControl(),
   9580                                                          binop(Iop_Or32,
   9581                                                                getDSPControl(),
   9582                                                                mkU32(0x400000)))
   9583                                              ));
   9584 
   9585                      assign(t8, IRExpr_ITE(unop(Iop_32to1,
   9586                                                 mkexpr(t2)),
   9587                                            mkU32(0x80000000),
   9588                                            mkU32(0x7fffffff)));
   9589                      putIReg(rd, IRExpr_ITE(unop(Iop_32to1, mkexpr(t6)),
   9590                                             IRExpr_ITE(unop(Iop_32to1,
   9591                                                             mkexpr(t2)),
   9592                                                        mkU32(0x80000000),
   9593                                                        mkU32(0x7fffffff)),
   9594                                             IRExpr_ITE(mkexpr(t7),
   9595                                                        unop(Iop_64to32,
   9596                                                             mkexpr(t3)),
   9597                                                        mkexpr(t8))));
   9598                      break;
   9599                   }
   9600                   case 0x17: {  /* SHRAV_R.W */
   9601                      DIP("shrav_r.w r%d, r%d, r%d", rd, rt, rs);
   9602                      vassert(!mode64);
   9603                      t0 = newTemp(Ity_I32);
   9604                      t1 = newTemp(Ity_I1);
   9605                      t2 = newTemp(Ity_I8);
   9606                      t3 = newTemp(Ity_I32);
   9607 
   9608                      assign(t0, binop(Iop_And32, getIReg(rs), mkU32(0x1f)));
   9609                      assign(t1, binop(Iop_CmpEQ32, mkexpr(t0), mkU32(0x0)));
   9610                      assign(t2, unop(Iop_32to8,
   9611                                      binop(Iop_Sub32, mkexpr(t0), mkU32(1))));
   9612 
   9613                      putIReg(rd, IRExpr_ITE(mkexpr(t1),
   9614                                             getIReg(rt),
   9615                                             binop(Iop_Sar32,
   9616                                                   binop(Iop_Add32,
   9617                                                         binop(Iop_Sar32,
   9618                                                               getIReg(rt),
   9619                                                               mkexpr(t2)),
   9620                                                         mkU32(0x1)),
   9621                                                   mkU8(1))));
   9622                      break;
   9623                   }
   9624                   case 0x19: {  /* SHRL.PH */
   9625                      DIP("shrl.ph r%d, r%d, %d", rd, rt, rs);
   9626                      vassert(!mode64);
   9627                      t0 = newTemp(Ity_I32);
   9628                      t1 = newTemp(Ity_I32);
   9629                      assign(t0, binop(Iop_Shr32,
   9630                                       unop(Iop_16Uto32,
   9631                                            unop(Iop_32to16, getIReg(rt))),
   9632                                       mkU8(rs)));
   9633                      assign(t1, binop(Iop_Shr32,
   9634                                       unop(Iop_16Uto32,
   9635                                            unop(Iop_32HIto16, getIReg(rt))),
   9636                                       mkU8(rs)));
   9637                      putIReg(rd, binop(Iop_16HLto32,
   9638                                        unop(Iop_32to16, mkexpr(t1)),
   9639                                        unop(Iop_32to16, mkexpr(t0))));
   9640                      break;
   9641                   }
   9642                   case 0x1B: {  /* SHRLV.PH */
   9643                      DIP("shrlv.ph r%d, r%d, r%d", rd, rt, rs);
   9644                      vassert(!mode64);
   9645                      t0 = newTemp(Ity_I32);
   9646                      t1 = newTemp(Ity_I1);
   9647                      t2 = newTemp(Ity_I32);
   9648                      t3 = newTemp(Ity_I32);
   9649                      t4 = newTemp(Ity_I16);
   9650                      t5 = newTemp(Ity_I16);
   9651 
   9652                      /* Get shift amount from lower 5 bits of rs
   9653                         and check if it is zero. */
   9654                      assign(t0, binop(Iop_And32, getIReg(rs), mkU32(0x0f)));
   9655                      assign(t1, binop(Iop_CmpEQ32, mkexpr(t0), mkU32(0x0)));
   9656 
   9657                      assign(t2, binop(Iop_Shr32,
   9658                                       unop(Iop_16Uto32,
   9659                                            unop(Iop_32to16, getIReg(rt))),
   9660                                       unop(Iop_32to8, mkexpr(t0))));
   9661                      assign(t3, binop(Iop_Shr32,
   9662                                       unop(Iop_16Uto32,
   9663                                            unop(Iop_32HIto16, getIReg(rt))),
   9664                                       unop(Iop_32to8, mkexpr(t0))));
   9665 
   9666                      assign(t4, IRExpr_ITE(mkexpr(t1),
   9667                                            unop(Iop_32HIto16, getIReg(rt)),
   9668                                            unop(Iop_32to16, mkexpr(t3))));
   9669                      assign(t5, IRExpr_ITE(mkexpr(t1),
   9670                                            unop(Iop_32to16, getIReg(rt)),
   9671                                            unop(Iop_32to16, mkexpr(t2))));
   9672                      putIReg(rd, binop(Iop_16HLto32, mkexpr(t4), mkexpr(t5)));
   9673                      break;
   9674                   }
   9675                   default:
   9676                      return -1;
   9677                }
   9678                break;  /* end of SHLL.QB */
   9679             }
   9680             case 0x18: {  /* ADDUH.QB/MUL.PH */
   9681                switch(sa) {
   9682                   case 0x00: {  /* ADDUH.QB */
   9683                      DIP("adduh.qb r%d, r%d, r%d", rd, rs, rt);
   9684                      vassert(!mode64);
   9685                      t0 = newTemp(Ity_I32);
   9686 
   9687                      assign(t0, binop(Iop_HAdd8Ux4, getIReg(rs), getIReg(rt)));
   9688 
   9689                      putIReg(rd, mkexpr(t0));
   9690                      break;
   9691                   }
   9692                   case 0x1: {  /* SUBUH.QB */
   9693                      DIP("subuh.qb r%d, r%d, r%d", rd, rs, rt);
   9694                      vassert(!mode64);
   9695                      t0 = newTemp(Ity_I32);
   9696 
   9697                      assign(t0, binop(Iop_HSub8Ux4, getIReg(rs), getIReg(rt)));
   9698 
   9699                      putIReg(rd, mkexpr(t0));
   9700                      break;
   9701                   }
   9702                   case 0x02: {  /* ADDUH_R.QB */
   9703                      DIP("adduh_r.qb r%d, r%d, r%d", rd, rs, rt);
   9704                      vassert(!mode64);
   9705                      t0 = newTemp(Ity_I32);
   9706                      t1 = newTemp(Ity_I32);
   9707                      t2 = newTemp(Ity_I8);
   9708                      t3 = newTemp(Ity_I32);
   9709                      t4 = newTemp(Ity_I32);
   9710                      t5 = newTemp(Ity_I8);
   9711                      t6 = newTemp(Ity_I32);
   9712                      t7 = newTemp(Ity_I32);
   9713                      t8 = newTemp(Ity_I8);
   9714                      t9 = newTemp(Ity_I32);
   9715                      t10 = newTemp(Ity_I32);
   9716                      t11 = newTemp(Ity_I8);
   9717 
   9718                      /* Extract input bytes, add values, add 1 and half the
   9719                         result. */
   9720                      assign(t0, unop(Iop_8Uto32,
   9721                                      unop(Iop_16to8,
   9722                                           unop(Iop_32to16, getIReg(rs)))));
   9723                      assign(t1, unop(Iop_8Uto32,
   9724                                      unop(Iop_16to8,
   9725                                           unop(Iop_32to16, getIReg(rt)))));
   9726                      assign(t2, unop(Iop_16to8,
   9727                                      unop(Iop_32to16,
   9728                                           binop(Iop_Shr32,
   9729                                                 binop(Iop_Add32,
   9730                                                       binop(Iop_Add32,
   9731                                                             mkexpr(t0),
   9732                                                             mkexpr(t1)),
   9733                                                       mkU32(0x00000001)),
   9734                                                 mkU8(0x01)))));
   9735 
   9736                      assign(t3, unop(Iop_8Uto32,
   9737                                      unop(Iop_16HIto8,
   9738                                           unop(Iop_32to16, getIReg(rs)))));
   9739                      assign(t4, unop(Iop_8Uto32,
   9740                                      unop(Iop_16HIto8,
   9741                                           unop(Iop_32to16, getIReg(rt)))));
   9742                      assign(t5, unop(Iop_16to8,
   9743                                      unop(Iop_32to16,
   9744                                           binop(Iop_Shr32,
   9745                                                 binop(Iop_Add32,
   9746                                                       binop(Iop_Add32,
   9747                                                             mkexpr(t3),
   9748                                                             mkexpr(t4)),
   9749                                                       mkU32(0x00000001)),
   9750                                                 mkU8(0x01)))));
   9751 
   9752                      assign(t6, unop(Iop_8Uto32,
   9753                                      unop(Iop_16to8,
   9754                                           unop(Iop_32HIto16, getIReg(rs)))));
   9755                      assign(t7, unop(Iop_8Uto32,
   9756                                      unop(Iop_16to8,
   9757                                           unop(Iop_32HIto16, getIReg(rt)))));
   9758                      assign(t8, unop(Iop_16to8,
   9759                                      unop(Iop_32to16,
   9760                                           binop(Iop_Shr32,
   9761                                                 binop(Iop_Add32,
   9762                                                       binop(Iop_Add32,
   9763                                                             mkexpr(t7),
   9764                                                             mkexpr(t6)),
   9765                                                       mkU32(0x00000001)),
   9766                                                 mkU8(0x01)))));
   9767 
   9768                      assign(t9, unop(Iop_8Uto32,
   9769                                      unop(Iop_16HIto8,
   9770                                           unop(Iop_32HIto16, getIReg(rs)))));
   9771                      assign(t10, unop(Iop_8Uto32,
   9772                                       unop(Iop_16HIto8,
   9773                                            unop(Iop_32HIto16, getIReg(rt)))));
   9774                      assign(t11, unop(Iop_16to8,
   9775                                       unop(Iop_32to16,
   9776                                            binop(Iop_Shr32,
   9777                                                  binop(Iop_Add32,
   9778                                                        binop(Iop_Add32,
   9779                                                              mkexpr(t9),
   9780                                                              mkexpr(t10)),
   9781                                                        mkU32(0x00000001)),
   9782                                                  mkU8(0x01)))));
   9783 
   9784                      putIReg(rd, binop(Iop_16HLto32,
   9785                                        binop(Iop_8HLto16,
   9786                                              mkexpr(t11), mkexpr(t8)),
   9787                                        binop(Iop_8HLto16,
   9788                                              mkexpr(t5), mkexpr(t2))));
   9789                      break;
   9790                   }
   9791                   case 0x3: {  /* SUBUH_R.QB */
   9792                      DIP("subuh_r.qb r%d, r%d, r%d", rd, rs, rt);
   9793                      vassert(!mode64);
   9794                      t1 = newTemp(Ity_I32);
   9795                      t2 = newTemp(Ity_I32);
   9796                      t3 = newTemp(Ity_I32);
   9797                      t4 = newTemp(Ity_I32);
   9798                      t5 = newTemp(Ity_I32);
   9799                      t6 = newTemp(Ity_I32);
   9800                      t7 = newTemp(Ity_I32);
   9801                      t8 = newTemp(Ity_I32);
   9802                      t9 = newTemp(Ity_I8);
   9803                      t10 = newTemp(Ity_I8);
   9804                      t11 = newTemp(Ity_I8);
   9805                      t12 = newTemp(Ity_I8);
   9806 
   9807                      /* Extract each byte of rs and rt. */
   9808                      assign(t1, unop(Iop_8Uto32,
   9809                                      unop(Iop_16to8,
   9810                                           unop(Iop_32to16, getIReg(rs)))));
   9811                      assign(t2, unop(Iop_8Uto32,
   9812                                      unop(Iop_16HIto8,
   9813                                           unop(Iop_32to16, getIReg(rs)))));
   9814                      assign(t3, unop(Iop_8Uto32,
   9815                                      unop(Iop_16to8,
   9816                                           unop(Iop_32HIto16, getIReg(rs)))));
   9817                      assign(t4, unop(Iop_8Uto32,
   9818                                      unop(Iop_16HIto8,
   9819                                           unop(Iop_32HIto16, getIReg(rs)))));
   9820 
   9821                      assign(t5, unop(Iop_8Uto32,
   9822                                      unop(Iop_16to8,
   9823                                           unop(Iop_32to16, getIReg(rt)))));
   9824                      assign(t6, unop(Iop_8Uto32,
   9825                                      unop(Iop_16HIto8,
   9826                                           unop(Iop_32to16, getIReg(rt)))));
   9827                      assign(t7, unop(Iop_8Uto32,
   9828                                      unop(Iop_16to8,
   9829                                           unop(Iop_32HIto16, getIReg(rt)))));
   9830                      assign(t8, unop(Iop_8Uto32,
   9831                                      unop(Iop_16HIto8,
   9832                                           unop(Iop_32HIto16, getIReg(rt)))));
   9833 
   9834                      /* Add 1 to each resulting byte and half the results. */
   9835                      assign(t9, unop(Iop_16to8,
   9836                                      unop(Iop_32to16,
   9837                                           binop(Iop_Shr32,
   9838                                                 binop(Iop_Add32,
   9839                                                       binop(Iop_Sub32,
   9840                                                             mkexpr(t1),
   9841                                                             mkexpr(t5)),
   9842                                                       mkU32(0x00000001)),
   9843                                                 mkU8(0x01)))));
   9844                      assign(t10, unop(Iop_16to8,
   9845                                       unop(Iop_32to16,
   9846                                            binop(Iop_Shr32,
   9847                                                  binop(Iop_Add32,
   9848                                                        binop(Iop_Sub32,
   9849                                                              mkexpr(t2),
   9850                                                              mkexpr(t6)),
   9851                                                        mkU32(0x00000001)),
   9852                                                  mkU8(0x01)))));
   9853                      assign(t11, unop(Iop_16to8,
   9854                                       unop(Iop_32to16,
   9855                                             binop(Iop_Shr32,
   9856                                                   binop(Iop_Add32,
   9857                                                         binop(Iop_Sub32,
   9858                                                               mkexpr(t3),
   9859                                                               mkexpr(t7)),
   9860                                                         mkU32(0x00000001)),
   9861                                                   mkU8(0x01)))));
   9862                      assign(t12, unop(Iop_16to8,
   9863                                       unop(Iop_32to16,
   9864                                            binop(Iop_Shr32,
   9865                                                  binop(Iop_Add32,
   9866                                                        binop(Iop_Sub32,
   9867                                                              mkexpr(t4),
   9868                                                              mkexpr(t8)),
   9869                                                        mkU32(0x00000001)),
   9870                                                  mkU8(0x01)))));
   9871 
   9872                      putIReg(rd, binop(Iop_16HLto32,
   9873                                        binop(Iop_8HLto16,
   9874                                              mkexpr(t12), mkexpr(t11)),
   9875                                        binop(Iop_8HLto16,
   9876                                              mkexpr(t10), mkexpr(t9))));
   9877                      break;
   9878                   }
   9879                   case 0x8: {  /* ADDQH.PH */
   9880                      DIP("addqh.ph r%d, r%d, r%d", rd, rs, rt);
   9881                      vassert(!mode64);
   9882                      t0 = newTemp(Ity_I32);
   9883                      t1 = newTemp(Ity_I16);
   9884                      t2 = newTemp(Ity_I32);
   9885                      t3 = newTemp(Ity_I16);
   9886 
   9887                      /* Add lower halfs of rs and rt
   9888                         and right shift the result by 1. */
   9889                      assign(t0, binop(Iop_Add32,
   9890                                       unop(Iop_16Sto32,
   9891                                            unop(Iop_32to16, getIReg(rs))),
   9892                                       unop(Iop_16Sto32,
   9893                                            unop(Iop_32to16, getIReg(rt)))));
   9894                      assign(t1, unop(Iop_32to16,
   9895                                      binop(Iop_Shr32,
   9896                                            binop(Iop_And32,
   9897                                                  mkexpr(t0),
   9898                                                  mkU32(0x0001fffe)),
   9899                                            mkU8(0x1))));
   9900                      /* Add higher halfs of rs and rt
   9901                         and right shift the result by 1. */
   9902                      assign(t2, binop(Iop_Add32,
   9903                                       unop(Iop_16Sto32,
   9904                                            unop(Iop_32HIto16, getIReg(rs))),
   9905                                       unop(Iop_16Sto32,
   9906                                            unop(Iop_32HIto16, getIReg(rt)))));
   9907                      assign(t3, unop(Iop_32to16,
   9908                                      binop(Iop_Shr32,
   9909                                            binop(Iop_And32,
   9910                                                  mkexpr(t2),
   9911                                                  mkU32(0x0001fffe)),
   9912                                            mkU8(0x1))));
   9913                      putIReg(rd, binop(Iop_16HLto32, mkexpr(t3), mkexpr(t1)));
   9914                      break;
   9915                   }
   9916                   case 0x9: {  /* SUBQH.PH */
   9917                      DIP("subqh.ph r%d, r%d, r%d", rd, rs, rt);
   9918                      vassert(!mode64);
   9919 
   9920                      putIReg(rd, binop(Iop_HSub16Sx2,
   9921                                        getIReg(rs), getIReg(rt)));
   9922                      break;
   9923                   }
   9924                   case 0xA: {/* ADDQH_R.PH */
   9925                      DIP("addqh_r.ph r%d, r%d, r%d", rd, rs, rt);
   9926                      vassert(!mode64);
   9927                      t0 = newTemp(Ity_I32);
   9928                      t1 = newTemp(Ity_I16);
   9929                      t2 = newTemp(Ity_I32);
   9930                      t3 = newTemp(Ity_I16);
   9931 
   9932                      /* Add lower halfs of rs and rt, add 1
   9933                         and right shift the result by 1. */
   9934                      assign(t0, binop(Iop_Add32,
   9935                                       unop(Iop_16Sto32,
   9936                                            unop(Iop_32to16, getIReg(rs))),
   9937                                       unop(Iop_16Sto32,
   9938                                            unop(Iop_32to16, getIReg(rt)))));
   9939                      assign(t1, unop(Iop_32to16,
   9940                                      binop(Iop_Shr32,
   9941                                            binop(Iop_And32,
   9942                                                  binop(Iop_Add32,
   9943                                                        mkexpr(t0),
   9944                                                        mkU32(0x1)),
   9945                                                  mkU32(0x0001fffe)),
   9946                                            mkU8(0x1))));
   9947                      /* Add higher halfs of rs and rt, add 1
   9948                         and right shift the result by 1. */
   9949                      assign(t2, binop(Iop_Add32,
   9950                                       unop(Iop_16Sto32,
   9951                                            unop(Iop_32HIto16, getIReg(rs))),
   9952                                       unop(Iop_16Sto32,
   9953                                            unop(Iop_32HIto16, getIReg(rt)))));
   9954                      assign(t3, unop(Iop_32to16,
   9955                                      binop(Iop_Shr32,
   9956                                            binop(Iop_And32,
   9957                                                  binop(Iop_Add32,
   9958                                                        mkexpr(t2),
   9959                                                        mkU32(0x1)),
   9960                                                  mkU32(0x0001fffe)),
   9961                                            mkU8(0x1))));
   9962 
   9963                      putIReg(rd, binop(Iop_16HLto32, mkexpr(t3), mkexpr(t1)));
   9964                      break;
   9965                   }
   9966                   case 0xB: {  /* SUBQH_R.PH */
   9967                      DIP("subqh_r.ph r%d, r%d, r%d", rd, rs, rt);
   9968                      vassert(!mode64);
   9969                      t0 = newTemp(Ity_I32);
   9970                      t1 = newTemp(Ity_I16);
   9971                      t2 = newTemp(Ity_I32);
   9972                      t3 = newTemp(Ity_I16);
   9973 
   9974                      /* Sub lower halfs of rs and rt, add 1
   9975                         and right shift the result by 1. */
   9976                      assign(t0, binop(Iop_Sub32,
   9977                                       unop(Iop_16Sto32,
   9978                                            unop(Iop_32to16, getIReg(rs))),
   9979                                       unop(Iop_16Sto32,
   9980                                            unop(Iop_32to16, getIReg(rt)))));
   9981                      assign(t1, unop(Iop_32to16,
   9982                                      binop(Iop_Shr32,
   9983                                            binop(Iop_And32,
   9984                                                  binop(Iop_Add32,
   9985                                                        mkexpr(t0),
   9986                                                        mkU32(0x1)),
   9987                                                  mkU32(0x0001fffe)),
   9988                                            mkU8(0x1))));
   9989                      /* Sub higher halfs of rs and rt, add 1
   9990                         and right shift the result by 1. */
   9991                      assign(t2, binop(Iop_Sub32,
   9992                                       unop(Iop_16Sto32,
   9993                                            unop(Iop_32HIto16, getIReg(rs))),
   9994                                       unop(Iop_16Sto32,
   9995                                            unop(Iop_32HIto16, getIReg(rt)))));
   9996                      assign(t3, unop(Iop_32to16,
   9997                                      binop(Iop_Shr32,
   9998                                            binop(Iop_And32,
   9999                                                  binop(Iop_Add32,
   10000                                                        mkexpr(t2),
   10001                                                        mkU32(0x1)),
   10002                                                  mkU32(0x0001fffe)),
   10003                                            mkU8(0x1))));
   10004 
   10005                      putIReg(rd, binop(Iop_16HLto32, mkexpr(t3), mkexpr(t1)));
   10006                      break;
   10007                   }
   10008                   case 0xC: {  /* MUL.PH */
   10009                      DIP("mul.ph r%d, r%d, r%d", rd, rs, rt);
   10010                      vassert(!mode64);
   10011                      t0 = newTemp(Ity_I32);
   10012                      t1 = newTemp(Ity_I32);
   10013                      t2 = newTemp(Ity_I32);
   10014 
   10015                      assign(t0,
   10016                             binop(Iop_Mul32,
   10017                                   unop(Iop_16Sto32,
   10018                                        unop(Iop_32HIto16, getIReg(rs))),
   10019                                   unop(Iop_16Sto32,
   10020                                        unop(Iop_32HIto16, getIReg(rt)))));
   10021                      /* DSP Control flag. */
   10022                      putDSPControl(IRExpr_ITE(unop(Iop_Not1,
   10023                                                    binop(Iop_CmpLE32S,
   10024                                                          mkexpr(t0),
   10025                                                          mkU32(0x7FFF))),
   10026                                               binop(Iop_Or32,
   10027                                                     getDSPControl(),
   10028                                                     mkU32(0x00200000)),
   10029                                               IRExpr_ITE(binop(Iop_CmpLT32S,
   10030                                                                mkexpr(t0),
   10031                                                                mkU32(0xFFFF8000)
   10032                                                              ),
   10033                                                          binop(Iop_Or32,
   10034                                                                getDSPControl(),
   10035                                                                mkU32(0x00200000)
   10036                                                               ),
   10037                                                          getDSPControl())));
   10038 
   10039                      assign(t1,
   10040                             binop(Iop_Mul32,
   10041                                   unop(Iop_16Sto32,
   10042                                        unop(Iop_32to16, getIReg(rs))),
   10043                                   unop(Iop_16Sto32,
   10044                                        unop(Iop_32to16, getIReg(rt)))));
   10045                      /* DSP Control flag. */
   10046                      putDSPControl(IRExpr_ITE(unop(Iop_Not1,
   10047                                                    binop(Iop_CmpLE32S,
   10048                                                          mkexpr(t1),
   10049                                                          mkU32(0x7FFF))),
   10050                                               binop(Iop_Or32,
   10051                                                     getDSPControl(),
   10052                                                     mkU32(0x00200000)),
   10053                                               IRExpr_ITE(binop(Iop_CmpLT32S,
   10054                                                                mkexpr(t1),
   10055                                                                mkU32(0xFFFF8000)
   10056                                                               ),
   10057                                                          binop(Iop_Or32,
   10058                                                                getDSPControl(),
   10059                                                                mkU32(0x00200000)
   10060                                                               ),
   10061                                                          getDSPControl())));
   10062 
   10063                      assign(t2, binop(Iop_16HLto32,
   10064                                       unop(Iop_32to16, mkexpr(t0)),
   10065                                       unop(Iop_32to16, mkexpr(t1))));
   10066                      putIReg(rd, mkexpr(t2));
   10067                      break;
   10068                   }
   10069                   case 0xE: {  /* MUL_S.PH */
   10070                      DIP("mul_s.ph r%d r%d, r%d", rd, rs, rt);
   10071                      vassert(!mode64);
   10072 
   10073                      t0 = newTemp(Ity_I32);
   10074                      t1 = newTemp(Ity_I32);
   10075                      t2 = newTemp(Ity_I32);
   10076                      t3 = newTemp(Ity_I32);
   10077                      t4 = newTemp(Ity_I32);
   10078 
   10079                      /* t0 - signed intermediate result. */
   10080                      assign(t0,
   10081                            binop(Iop_Mul32,
   10082                                  unop(Iop_16Sto32,
   10083                                       unop(Iop_32HIto16, getIReg(rs))),
   10084                                  unop(Iop_16Sto32,
   10085                                       unop(Iop_32HIto16, getIReg(rt)))));
   10086 
   10087                      assign(t1,
   10088                             IRExpr_ITE(unop(Iop_Not1,
   10089                                             binop(Iop_CmpLE32S,
   10090                                                   mkexpr(t0),
   10091                                                   mkU32(0x7FFF))),
   10092                                        mkU32(0x00007FFF),
   10093                                        IRExpr_ITE(binop(Iop_CmpLT32S,
   10094                                                         mkexpr(t0),
   10095                                                         mkU32(0xFFFF8000)),
   10096                                                   mkU32(0xFFFF8000),
   10097                                                   mkexpr(t0))));
   10098 
   10099                      /* DSP Control flag. */
   10100                      putDSPControl(IRExpr_ITE(unop(Iop_Not1,
   10101                                                    binop(Iop_CmpLE32S,
   10102                                                          mkexpr(t0),
   10103                                                          mkU32(0x7FFF))),
   10104                                               binop(Iop_Or32,
   10105                                                     getDSPControl(),
   10106                                                     mkU32(0x00200000)),
   10107                                               IRExpr_ITE(binop(Iop_CmpLT32S,
   10108                                                                mkexpr(t0),
   10109                                                                mkU32(0xFFFF8000)
   10110                                                               ),
   10111                                                          binop(Iop_Or32,
   10112                                                                getDSPControl(),
   10113                                                                mkU32(0x00200000)
   10114                                                               ),
   10115                                                          getDSPControl())));
   10116 
   10117                      /* t2 - signed intermediate result. */
   10118                      assign(t2, binop(Iop_Mul32,
   10119                                       unop(Iop_16Sto32,
   10120                                            unop(Iop_32to16, getIReg(rs))),
   10121                                       unop(Iop_16Sto32,
   10122                                            unop(Iop_32to16, getIReg(rt)))));
   10123 
   10124                      assign(t3, IRExpr_ITE(unop(Iop_Not1,
   10125                                                 binop(Iop_CmpLE32S,
   10126                                                       mkexpr(t2),
   10127                                                       mkU32(0x7FFF))),
   10128                                            mkU32(0x00007FFF),
   10129                                            IRExpr_ITE(binop(Iop_CmpLT32S,
   10130                                                             mkexpr(t2),
   10131                                                             mkU32(0xFFFF8000)),
   10132                                                       mkU32(0xFFFF8000),
   10133                                                       mkexpr(t2))));
   10134 
   10135                      /* DSP Control flag. */
   10136                      putDSPControl(IRExpr_ITE(unop(Iop_Not1,
   10137                                                    binop(Iop_CmpLE32S,
   10138                                                          mkexpr(t2),
   10139                                                          mkU32(0x7FFF))),
   10140                                               binop(Iop_Or32,
   10141                                                     getDSPControl(),
   10142                                                     mkU32(0x00200000)),
   10143                                               IRExpr_ITE(binop(Iop_CmpLT32S,
   10144                                                                mkexpr(t2),
   10145                                                                mkU32(0xFFFF8000)
   10146                                                               ),
   10147                                                          binop(Iop_Or32,
   10148                                                                getDSPControl(),
   10149                                                                mkU32(0x00200000)
   10150                                                               ),
   10151                                                          getDSPControl())));
   10152 
   10153                      assign(t4, binop(Iop_16HLto32,
   10154                                       unop(Iop_32to16, mkexpr(t1)),
   10155                                       unop(Iop_32to16, mkexpr(t3))));
   10156                      putIReg(rd, mkexpr(t4));
   10157                      break;
   10158                   }
   10159                   case 0x10: {  /* ADDQH.W */
   10160                      DIP("addqh.w r%d, r%d, r%d", rd, rs, rt);
   10161                      vassert(!mode64);
   10162                      t0 = newTemp(Ity_I64);
   10163                      t1 = newTemp(Ity_I64);
   10164 
   10165                      assign(t0, binop(Iop_Add64,
   10166                                       unop(Iop_32Sto64, getIReg(rs)),
   10167                                       unop(Iop_32Sto64, getIReg(rt))));
   10168                      assign(t1, binop(Iop_And64,
   10169                                       mkexpr(t0),
   10170                                       mkU64(0x00000001fffffffeULL)));
   10171                      putIReg(rd, unop(Iop_64to32,
   10172                                       binop(Iop_Shr64, mkexpr(t1), mkU8(0x1))));
   10173                      break;
   10174                   }
   10175                   case 0x11: {  /* SUBQH.W */
   10176                      DIP("subqh.w r%d, r%d, r%d", rd, rs, rt);
   10177                      vassert(!mode64);
   10178                      t0 = newTemp(Ity_I64);
   10179                      t1 = newTemp(Ity_I64);
   10180 
   10181                      assign(t0, binop(Iop_Sub64,
   10182                                       unop(Iop_32Sto64, getIReg(rs)),
   10183                                       unop(Iop_32Sto64, getIReg(rt))));
   10184                      assign(t1, binop(Iop_And64,
   10185                                       mkexpr(t0),
   10186                                       mkU64(0x00000001fffffffeULL)));
   10187                      putIReg(rd, unop(Iop_64to32,
   10188                                       binop(Iop_Shr64, mkexpr(t1), mkU8(0x1))));
   10189                      break;
   10190                   }
   10191                   case 0x12: {  /* ADDQH_R.W */
   10192                      DIP("addqh_r.w r%d, r%d, r%d", rd, rs, rt);
   10193                      vassert(!mode64);
   10194                      t0 = newTemp(Ity_I64);
   10195                      t1 = newTemp(Ity_I64);
   10196                      t2 = newTemp(Ity_I64);
   10197 
   10198                      assign(t0, binop(Iop_Add64,
   10199                                       unop(Iop_32Sto64, getIReg(rs)),
   10200                                       unop(Iop_32Sto64, getIReg(rt))));
   10201                      assign(t1, binop(Iop_Add64,
   10202                                       mkexpr(t0),
   10203                                       mkU64(0x0000000000000001ULL)));
   10204                      assign(t2, binop(Iop_And64,
   10205                                       mkexpr(t1),
   10206                                       mkU64(0x00000001fffffffeULL)));
   10207                      putIReg(rd, unop(Iop_64to32,
   10208                                       binop(Iop_Shr64, mkexpr(t2), mkU8(0x1))));
   10209                      break;
   10210                   }
   10211                   case 0x13: {  /* SUBQH_R.W */
   10212                      DIP("subqh_r.w r%d, r%d, r%d", rd, rs, rt);
   10213                      vassert(!mode64);
   10214                      t0 = newTemp(Ity_I64);
   10215                      t1 = newTemp(Ity_I64);
   10216                      t2 = newTemp(Ity_I64);
   10217 
   10218                      assign(t0, binop(Iop_Sub64,
   10219                                       unop(Iop_32Sto64, getIReg(rs)),
   10220                                       unop(Iop_32Sto64, getIReg(rt))));
   10221                      assign(t1, binop(Iop_Add64,
   10222                                       mkexpr(t0),
   10223                                       mkU64(0x0000000000000001ULL)));
   10224                      assign(t2, binop(Iop_And64,
   10225                                       mkexpr(t1),
   10226                                       mkU64(0x00000001fffffffeULL)));
   10227                      putIReg(rd, unop(Iop_64to32,
   10228                                       binop(Iop_Shr64, mkexpr(t2), mkU8(0x1))));
   10229                      break;
   10230                   }
   10231                   case 0x16: {  /* MULQ_S.W */
   10232                      DIP("mulq_s.w r%d, r%d, r%d", rd, rs, rt);
   10233                      vassert(!mode64);
   10234                      t0 = newTemp(Ity_I64);
   10235                      t1 = newTemp(Ity_I1);
   10236                      t2 = newTemp(Ity_I1);
   10237 
   10238                      assign(t0, binop(Iop_Shl64,
   10239                                       binop(Iop_MullS32,
   10240                                             getIReg(rt), getIReg(rs)),
   10241                                       mkU8(0x1)));
   10242                      assign(t1, binop(Iop_CmpEQ32,
   10243                                       getIReg(rt), mkU32(0x80000000)));
   10244                      assign(t2, binop(Iop_CmpEQ32,
   10245                                       getIReg(rs), mkU32(0x80000000)));
   10246 
   10247                      putDSPControl(IRExpr_ITE(mkexpr(t1),
   10248                                               IRExpr_ITE(mkexpr(t2),
   10249                                                          binop(Iop_Or32,
   10250                                                                getDSPControl(),
   10251                                                                mkU32(0x00200000)
   10252                                                               ),
   10253                                                          getDSPControl()),
   10254                                               getDSPControl()));
   10255                      putIReg(rd, IRExpr_ITE(mkexpr(t1),
   10256                                             IRExpr_ITE(mkexpr(t2),
   10257                                                        mkU32(0x7fffffff),
   10258                                                        unop(Iop_64HIto32,
   10259                                                             mkexpr(t0))),
   10260                                             unop(Iop_64HIto32, mkexpr(t0))));
   10261                      break;
   10262                   }
   10263                   case 0x17: {  /* MULQ_RS.W */
   10264                      DIP("mulq_rs.w r%d, r%d, r%d", rd, rs, rt);
   10265                      vassert(!mode64);
   10266                      t0 = newTemp(Ity_I64);
   10267                      t1 = newTemp(Ity_I1);
   10268                      t2 = newTemp(Ity_I1);
   10269 
   10270                      assign(t0, binop(Iop_Add64,
   10271                                       binop(Iop_Shl64,
   10272                                             binop(Iop_MullS32,
   10273                                                   getIReg(rt),
   10274                                                   getIReg(rs)),
   10275                                             mkU8(0x1)),
   10276                                       mkU64(0x0000000080000000ULL)));
   10277                      assign(t1,
   10278                             binop(Iop_CmpEQ32, getIReg(rt), mkU32(0x80000000)));
   10279                      assign(t2,
   10280                             binop(Iop_CmpEQ32, getIReg(rs), mkU32(0x80000000)));
   10281                      putDSPControl(IRExpr_ITE(mkexpr(t1),
   10282                                               IRExpr_ITE(mkexpr(t2),
   10283                                                          binop(Iop_Or32,
   10284                                                                getDSPControl(),
   10285                                                                mkU32(0x00200000)
   10286                                                               ),
   10287                                                          getDSPControl()),
   10288                                               getDSPControl()));
   10289                      putIReg(rd, IRExpr_ITE(mkexpr(t1),
   10290                                             IRExpr_ITE(mkexpr(t2),
   10291                                                        mkU32(0x7fffffff),
   10292                                                        unop(Iop_64HIto32,
   10293                                                             mkexpr(t0))),
   10294                                             unop(Iop_64HIto32, mkexpr(t0))));
   10295                      break;
   10296                   }
   10297                   default:
   10298                      return -1;
   10299                }
   10300                break;  /* end of ADDUH.QB/MUL.PH */
   10301             }
   10302             case 0x30: {  /* DPAQ.W.PH */
   10303                switch(sa) {
   10304                   case 0x0: {  /* DPA.W.PH */
   10305                      DIP("dpa.w.ph ac%d, r%d, r%d", ac, rs, rt);
   10306                      vassert(!mode64);
   10307 
   10308                      t0 = newTemp(Ity_I64);
   10309                      t1 = newTemp(Ity_I64);
   10310                      t2 = newTemp(Ity_I64);
   10311 
   10312                      assign(t0,
   10313                             unop(Iop_32Sto64,
   10314                                  binop(Iop_Mul32,
   10315                                        unop(Iop_16Sto32,
   10316                                             unop(Iop_32HIto16, getIReg(rs))),
   10317                                        unop(Iop_16Sto32,
   10318                                             unop(Iop_32HIto16, getIReg(rt))))));
   10319                      assign(t1,
   10320                             unop(Iop_32Sto64,
   10321                                  binop(Iop_Mul32,
   10322                                        unop(Iop_16Sto32,
   10323                                             unop(Iop_32to16, getIReg(rs))),
   10324                                        unop(Iop_16Sto32,
   10325                                             unop(Iop_32to16, getIReg(rt))))));
   10326                      assign(t2,
   10327                             binop(Iop_Add64,
   10328                                   getAcc(ac),
   10329                                   binop(Iop_Add64, mkexpr(t0), mkexpr(t1))));
   10330                      putAcc(ac, mkexpr(t2));
   10331                      break;
   10332                   }
   10333                   case 0x1: {  /* DPS.W.PH */
   10334                      DIP("dps.w.ph ac%d, r%d, r%d", ac, rs, rt);
   10335                      vassert(!mode64);
   10336 
   10337                      t0 = newTemp(Ity_I64);
   10338                      t1 = newTemp(Ity_I64);
   10339                      t2 = newTemp(Ity_I64);
   10340 
   10341                      assign(t0,
   10342                             unop(Iop_32Sto64,
   10343                                  binop(Iop_Mul32,
   10344                                        unop(Iop_16Sto32,
   10345                                             unop(Iop_32HIto16, getIReg(rs))),
   10346                                        unop(Iop_16Sto32,
   10347                                             unop(Iop_32HIto16, getIReg(rt))))));
   10348                      assign(t1,
   10349                             unop(Iop_32Sto64,
   10350                                  binop(Iop_Mul32,
   10351                                        unop(Iop_16Sto32,
   10352                                             unop(Iop_32to16, getIReg(rs))),
   10353                                        unop(Iop_16Sto32,
   10354                                             unop(Iop_32to16, getIReg(rt))))));
   10355                      assign(t2,
   10356                             binop(Iop_Sub64,
   10357                                   getAcc(ac),
   10358                                   binop(Iop_Add64, mkexpr(t0), mkexpr(t1))));
   10359                      putAcc(ac, mkexpr(t2));
   10360                      break;
   10361                   }
   10362                   case 0x2: {  /* MULSA.W.PH */
   10363                      DIP("mulsa.w.ph ac%d, r%d, r%d", ac, rs, rt);
   10364                      vassert(!mode64);
   10365                      t0 = newTemp(Ity_I32);
   10366                      t1 = newTemp(Ity_I32);
   10367                      t2 = newTemp(Ity_I32);
   10368                      t3 = newTemp(Ity_I1);
   10369                      t4 = newTemp(Ity_I64);
   10370 
   10371                      assign(t4, getAcc(ac));
   10372                      assign(t0, binop(Iop_Mul32,
   10373                                       unop(Iop_16Sto32,
   10374                                            unop(Iop_32to16, getIReg(rt))),
   10375                                       unop(Iop_16Sto32,
   10376                                            unop(Iop_32to16, getIReg(rs)))));
   10377                      assign(t1, binop(Iop_Mul32,
   10378                                       unop(Iop_16Sto32,
   10379                                            unop(Iop_32HIto16, getIReg(rt))),
   10380                                       unop(Iop_16Sto32,
   10381                                            unop(Iop_32HIto16, getIReg(rs)))));
   10382                      assign(t2, binop(Iop_Sub32, mkexpr(t1), mkexpr(t0)));
   10383                      putAcc(ac, binop(Iop_Add64,
   10384                                       mkexpr(t4),
   10385                                       unop(Iop_32Sto64, mkexpr(t2))));
   10386                      break;
   10387                   }
   10388                   case 0x3: {  /* DPAU.H.QBL */
   10389                      DIP("dpau.h.qbl ac%d, r%d, r%d", ac, rs, rt);
   10390                      vassert(!mode64);
   10391                      t0 = newTemp(Ity_I32);
   10392                      t1 = newTemp(Ity_I32);
   10393                      t2 = newTemp(Ity_I64);
   10394                      t3 = newTemp(Ity_I64);
   10395 
   10396                      assign(t0,
   10397                             binop(Iop_Mul32,
   10398                                   unop(Iop_8Uto32,
   10399                                        unop(Iop_16HIto8,
   10400                                             unop(Iop_32HIto16, getIReg(rs)))),
   10401                                   unop(Iop_8Uto32,
   10402                                        unop(Iop_16HIto8,
   10403                                             unop(Iop_32HIto16, getIReg(rt))))));
   10404                      assign(t1,
   10405                             binop(Iop_Mul32,
   10406                                   unop(Iop_8Uto32,
   10407                                        unop(Iop_16to8,
   10408                                             unop(Iop_32HIto16, getIReg(rs)))),
   10409                                   unop(Iop_8Uto32,
   10410                                        unop(Iop_16to8,
   10411                                             unop(Iop_32HIto16, getIReg(rt))))));
   10412                      assign(t2,
   10413                             unop(Iop_32Uto64,
   10414                                  binop(Iop_Add32,
   10415                                        mkexpr(t0),
   10416                                        mkexpr(t1))));
   10417                      assign(t3,
   10418                             binop(Iop_Add64, getAcc(ac), mkexpr(t2)));
   10419                      putAcc(ac, mkexpr(t3));
   10420                      break;
   10421                   }
   10422                   case 0x4: {  /* DPAQ_S.W.PH */
   10423                      DIP("dpaq_s.w.ph ac%d, r%d, r%d", ac, rs, rt);
   10424                      vassert(!mode64);
   10425                      t0 = newTemp(Ity_I64);
   10426                      t1 = newTemp(Ity_I64);
   10427                      t2 = newTemp(Ity_I1);
   10428                      t3 = newTemp(Ity_I1);
   10429                      t4 = newTemp(Ity_I64);
   10430                      t5 = newTemp(Ity_I64);
   10431                      t6 = newTemp(Ity_I1);
   10432                      t7 = newTemp(Ity_I1);
   10433                      t8 = newTemp(Ity_I64);
   10434                      t9 = newTemp(Ity_I64);
   10435 
   10436                      assign(t0, getAcc(ac));
   10437 
   10438                      assign(t1, binop(Iop_Shl64,
   10439                                       binop(Iop_MullS32,
   10440                                             unop(Iop_16Sto32,
   10441                                                  unop(Iop_32HIto16,
   10442                                                       getIReg(rs))),
   10443                                             unop(Iop_16Sto32,
   10444                                                  unop(Iop_32HIto16,
   10445                                                       getIReg(rt)))),
   10446                                       mkU8(0x1)));
   10447                      assign(t2, binop(Iop_CmpEQ32,
   10448                                       unop(Iop_16Uto32,
   10449                                            unop(Iop_32HIto16, getIReg(rs))),
   10450                                       mkU32(0x00008000)));
   10451                      assign(t3, binop(Iop_CmpEQ32,
   10452                                       unop(Iop_16Uto32,
   10453                                            unop(Iop_32HIto16, getIReg(rt))),
   10454                                       mkU32(0x00008000)));
   10455                      assign(t4,
   10456                             IRExpr_ITE(mkexpr(t2),
   10457                                        IRExpr_ITE(mkexpr(t3),
   10458                                                   mkU64(0x000000007fffffffULL),
   10459                                                   mkexpr(t1)),
   10460                                        mkexpr(t1)));
   10461 
   10462                      putDSPControl(IRExpr_ITE(mkexpr(t2),
   10463                                               IRExpr_ITE(mkexpr(t3),
   10464                                                          binop(Iop_Or32,
   10465                                                                getDSPControl(),
   10466                                                                binop(Iop_Shl32,
   10467                                                                      mkU32(0x1),
   10468                                                                      mkU8(ac+16)
   10469                                                                     )
   10470                                                               ),
   10471                                                          getDSPControl()),
   10472                                               getDSPControl()));
   10473 
   10474                      assign(t5, binop(Iop_Shl64,
   10475                                       binop(Iop_MullS32,
   10476                                             unop(Iop_16Sto32,
   10477                                                  unop(Iop_32to16, getIReg(rs))),
   10478                                             unop(Iop_16Sto32,
   10479                                                  unop(Iop_32to16, getIReg(rt)))
   10480                                            ),
   10481                                       mkU8(0x1)));
   10482                      assign(t6, binop(Iop_CmpEQ32,
   10483                                       unop(Iop_16Uto32,
   10484                                            unop(Iop_32to16, getIReg(rs))),
   10485                                       mkU32(0x00008000)));
   10486                      assign(t7, binop(Iop_CmpEQ32,
   10487                                       unop(Iop_16Uto32,
   10488                                            unop(Iop_32to16, getIReg(rt))),
   10489                                       mkU32(0x00008000)));
   10490                      assign(t8,
   10491                             IRExpr_ITE(mkexpr(t6),
   10492                                        IRExpr_ITE(mkexpr(t7),
   10493                                                   mkU64(0x000000007fffffffULL),
   10494                                                   mkexpr(t5)),
   10495                                        mkexpr(t5)));
   10496 
   10497                      putDSPControl(IRExpr_ITE(mkexpr(t6),
   10498                                               IRExpr_ITE(mkexpr(t7),
   10499                                                          binop(Iop_Or32,
   10500                                                                getDSPControl(),
   10501                                                                binop(Iop_Shl32,
   10502                                                                      mkU32(0x1),
   10503                                                                      mkU8(ac+16)
   10504                                                                     )
   10505                                                               ),
   10506                                                          getDSPControl()),
   10507                                               getDSPControl()));
   10508 
   10509                      assign(t9, binop(Iop_Add64,
   10510                                       binop(Iop_Add64, mkexpr(t4), mkexpr(t8)),
   10511                                       mkexpr(t0)));
   10512                      putAcc(ac, mkexpr(t9));
   10513                      break;
   10514                   }
   10515                   case 0x5: {  /* DPSQ_S.W.PH */
   10516                      DIP("dpsq_s.w.ph ac%d r%d, r%d", ac, rs, rt);
   10517                      vassert(!mode64);
   10518                      t0 = newTemp(Ity_I64);
   10519                      t1 = newTemp(Ity_I64);
   10520                      t2 = newTemp(Ity_I1);
   10521                      t3 = newTemp(Ity_I1);
   10522                      t4 = newTemp(Ity_I64);
   10523                      t5 = newTemp(Ity_I64);
   10524                      t6 = newTemp(Ity_I1);
   10525                      t7 = newTemp(Ity_I1);
   10526                      t8 = newTemp(Ity_I64);
   10527                      t9 = newTemp(Ity_I64);
   10528 
   10529                      assign(t0, getAcc(ac));
   10530 
   10531                      assign(t1, binop(Iop_Shl64,
   10532                                       binop(Iop_MullS32,
   10533                                             unop(Iop_16Sto32,
   10534                                                  unop(Iop_32HIto16,
   10535                                                       getIReg(rs))),
   10536                                             unop(Iop_16Sto32,
   10537                                                  unop(Iop_32HIto16,
   10538                                                       getIReg(rt)))),
   10539                                       mkU8(0x1)));
   10540                      assign(t2, binop(Iop_CmpEQ32,
   10541                                       unop(Iop_16Uto32,
   10542                                            unop(Iop_32HIto16, getIReg(rs))),
   10543                                       mkU32(0x00008000)));
   10544                      assign(t3, binop(Iop_CmpEQ32,
   10545                                       unop(Iop_16Uto32,
   10546                                            unop(Iop_32HIto16, getIReg(rt))),
   10547                                       mkU32(0x00008000)));
   10548                      assign(t4,
   10549                             IRExpr_ITE(mkexpr(t2),
   10550                                        IRExpr_ITE(mkexpr(t3),
   10551                                                   mkU64(0x000000007fffffffULL),
   10552                                                   mkexpr(t1)),
   10553                                        mkexpr(t1)));
   10554 
   10555                      putDSPControl(IRExpr_ITE(mkexpr(t2),
   10556                                               IRExpr_ITE(mkexpr(t3),
   10557                                                          binop(Iop_Or32,
   10558                                                                getDSPControl(),
   10559                                                                binop(Iop_Shl32,
   10560                                                                      mkU32(0x1),
   10561                                                                      mkU8(ac+16)
   10562                                                                     )
   10563                                                               ),
   10564                                                          getDSPControl()),
   10565                                               getDSPControl()));
   10566 
   10567                      assign(t5,
   10568                             binop(Iop_Shl64,
   10569                                   binop(Iop_MullS32,
   10570                                         unop(Iop_16Sto32,
   10571                                              unop(Iop_32to16, getIReg(rs))),
   10572                                         unop(Iop_16Sto32,
   10573                                              unop(Iop_32to16, getIReg(rt)))),
   10574                                   mkU8(0x1)));
   10575                      assign(t6, binop(Iop_CmpEQ32,
   10576                                       unop(Iop_16Uto32,
   10577                                            unop(Iop_32to16, getIReg(rs))),
   10578                                       mkU32(0x00008000)));
   10579                      assign(t7, binop(Iop_CmpEQ32,
   10580                                       unop(Iop_16Uto32,
   10581                                            unop(Iop_32to16, getIReg(rt))),
   10582                                       mkU32(0x00008000)));
   10583                      assign(t8,
   10584                             IRExpr_ITE(mkexpr(t6),
   10585                                        IRExpr_ITE(mkexpr(t7),
   10586                                                   mkU64(0x000000007fffffffULL),
   10587                                                   mkexpr(t5)),
   10588                                        mkexpr(t5)));
   10589 
   10590                      putDSPControl(IRExpr_ITE(mkexpr(t6),
   10591                                               IRExpr_ITE(mkexpr(t7),
   10592                                                          binop(Iop_Or32,
   10593                                                                getDSPControl(),
   10594                                                                binop(Iop_Shl32,
   10595                                                                      mkU32(0x1),
   10596                                                                      mkU8(ac+16)
   10597                                                                     )
   10598                                                               ),
   10599                                                          getDSPControl()),
   10600                                               getDSPControl()));
   10601 
   10602                      assign(t9,
   10603                             binop(Iop_Sub64,
   10604                                   mkexpr(t0),
   10605                                   binop(Iop_Add64, mkexpr(t4), mkexpr(t8))));
   10606                      putAcc(ac, mkexpr(t9));
   10607                      break;
   10608                   }
   10609                   case 0x6: {  /* MULSAQ_S.W.PH */
   10610                      DIP("mulsaq_s.w.ph ac%d r%d, r%d", ac, rs, rt);
   10611                      vassert(!mode64);
   10612 
   10613                      t0 = newTemp(Ity_I32);
   10614                      t1 = newTemp(Ity_I32);
   10615                      t2 = newTemp(Ity_I32);
   10616                      t3 = newTemp(Ity_I32);
   10617                      t4 = newTemp(Ity_I32);
   10618                      t5 = newTemp(Ity_I32);
   10619                      t6 = newTemp(Ity_I64);
   10620                      t7 = newTemp(Ity_I64);
   10621                      t8 = newTemp(Ity_I32);
   10622                      t9 = newTemp(Ity_I32);
   10623 
   10624                      assign(t0, unop(Iop_16Sto32,
   10625                                      unop(Iop_32HIto16, getIReg(rs))));
   10626                      assign(t1, unop(Iop_16Sto32,
   10627                                      unop(Iop_32HIto16, getIReg(rt))));
   10628 
   10629                      assign(t8, binop(Iop_And32,
   10630                                       unop(Iop_1Sto32,
   10631                                            binop(Iop_CmpEQ32,
   10632                                                  unop(Iop_16Uto32,
   10633                                                       unop(Iop_32HIto16,
   10634                                                            getIReg(rs))),
   10635                                                  mkU32(0x8000))),
   10636                                     unop(Iop_1Sto32,
   10637                                          binop(Iop_CmpEQ32,
   10638                                                unop(Iop_16Uto32,
   10639                                                     unop(Iop_32HIto16,
   10640                                                          getIReg(rt))),
   10641                                                mkU32(0x8000)))));
   10642                      /* DSPControl_outflag:16+acc <- 1 */
   10643                      putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32,
   10644                                                     mkexpr(t8),
   10645                                                     mkU32(0x0)),
   10646                                               binop(Iop_Or32,
   10647                                                     getDSPControl(),
   10648                                                     binop(Iop_Shl32,
   10649                                                           mkU32(0x00010000),
   10650                                                           mkU8(ac))),
   10651                                               getDSPControl()));
   10652 
   10653                      /* tempB_31..0 */
   10654                      assign(t2,
   10655                             IRExpr_ITE(binop(Iop_CmpNE32,
   10656                                              mkexpr(t8), mkU32(0x0)),
   10657                                        mkU32(0x7FFFFFFF),
   10658                                        binop(Iop_Shl32,
   10659                                              binop(Iop_Mul32,
   10660                                                    mkexpr(t0), mkexpr(t1)),
   10661                                              mkU8(1))));
   10662 
   10663                      assign(t3, unop(Iop_16Sto32,
   10664                                      unop(Iop_32to16, getIReg(rs))));
   10665                      assign(t4, unop(Iop_16Sto32,
   10666                                      unop(Iop_32to16, getIReg(rt))));
   10667 
   10668                      assign(t9, binop(Iop_And32,
   10669                                       unop(Iop_1Sto32,
   10670                                            binop(Iop_CmpEQ32,
   10671                                                  unop(Iop_16Uto32,
   10672                                                       unop(Iop_32to16,
   10673                                                            getIReg(rs))),
   10674                                                  mkU32(0x8000))),
   10675                                       unop(Iop_1Sto32,
   10676                                            binop(Iop_CmpEQ32,
   10677                                                  unop(Iop_16Uto32,
   10678                                                       unop(Iop_32to16,
   10679                                                            getIReg(rt))),
   10680                                                  mkU32(0x8000)))));
   10681                      /* DSPControl_outflag:16+acc <- 1 */
   10682                      putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32,
   10683                                                     mkexpr(t9),
   10684                                                     mkU32(0x0)),
   10685                                               binop(Iop_Or32,
   10686                                                     getDSPControl(),
   10687                                                     binop(Iop_Shl32,
   10688                                                           mkU32(0x00010000),
   10689                                                           mkU8(ac))),
   10690                                               getDSPControl()));
   10691                      /* tempA_31..0 */
   10692                      assign(t5,
   10693                             IRExpr_ITE(binop(Iop_CmpNE32,
   10694                                              mkexpr(t9),
   10695                                              mkU32(0x0)),
   10696                                        mkU32(0x7FFFFFFF),
   10697                                        binop(Iop_Shl32,
   10698                                              binop(Iop_Mul32,
   10699                                                    mkexpr(t3),
   10700                                                    mkexpr(t4)),
   10701                                              mkU8(1))));
   10702                      /* dotp_63..0 */
   10703                      assign(t6,
   10704                             binop(Iop_Sub64,
   10705                                   unop(Iop_32Sto64, mkexpr(t2)),
   10706                                   unop(Iop_32Sto64, mkexpr(t5))));
   10707                      /* tempC_63..0 */
   10708                      assign(t7, binop(Iop_Add64, getAcc(ac), mkexpr(t6)));
   10709 
   10710                      putAcc(ac, mkexpr(t7));
   10711                      break;
   10712                   }
   10713                   case 0x7: {  /* DPAU.H.QBR */
   10714                      DIP("dpau.h.qbr ac%d, r%d, r%d", ac, rs, rt);
   10715                      vassert(!mode64);
   10716                      t0 = newTemp(Ity_I32);
   10717                      t1 = newTemp(Ity_I32);
   10718                      t2 = newTemp(Ity_I64);
   10719                      t3 = newTemp(Ity_I64);
   10720 
   10721                      assign(t0,
   10722                             binop(Iop_Mul32,
   10723                                   unop(Iop_8Uto32,
   10724                                        unop(Iop_16HIto8,
   10725                                             unop(Iop_32to16, getIReg(rs)))),
   10726                                   unop(Iop_8Uto32,
   10727                                        unop(Iop_16HIto8,
   10728                                             unop(Iop_32to16, getIReg(rt))))));
   10729                      assign(t1,
   10730                             binop(Iop_Mul32,
   10731                                   unop(Iop_8Uto32,
   10732                                        unop(Iop_16to8,
   10733                                             unop(Iop_32to16, getIReg(rs)))),
   10734                                   unop(Iop_8Uto32,
   10735                                        unop(Iop_16to8,
   10736                                             unop(Iop_32to16, getIReg(rt))))));
   10737                      assign(t2, unop(Iop_32Uto64,
   10738                                      binop(Iop_Add32, mkexpr(t0), mkexpr(t1))));
   10739                      assign(t3, binop(Iop_Add64, getAcc(ac), mkexpr(t2)));
   10740                      putAcc(ac, mkexpr(t3));
   10741                      break;
   10742                   }
   10743                   case 0x8: {  /* DPAX.W.PH */
   10744                      DIP("dpax.w.ph ac%d, r%d, r%d", ac, rs, rt);
   10745                      vassert(!mode64);
   10746                      t0 = newTemp(Ity_I64);
   10747                      t1 = newTemp(Ity_I64);
   10748                      t2 = newTemp(Ity_I64);
   10749 
   10750                      assign(t0,
   10751                             unop(Iop_32Sto64,
   10752                                  binop(Iop_Mul32,
   10753                                        unop(Iop_16Sto32,
   10754                                             unop(Iop_32HIto16, getIReg(rs))),
   10755                                        unop(Iop_16Sto32,
   10756                                             unop(Iop_32to16, getIReg(rt))))));
   10757                      assign(t1,
   10758                             unop(Iop_32Sto64,
   10759                                  binop(Iop_Mul32,
   10760                                        unop(Iop_16Sto32,
   10761                                             unop(Iop_32to16, getIReg(rs))),
   10762                                        unop(Iop_16Sto32,
   10763                                             unop(Iop_32HIto16, getIReg(rt))))));
   10764                      assign(t2,
   10765                             binop(Iop_Add64,
   10766                                   getAcc(ac),
   10767                                   binop(Iop_Add64, mkexpr(t0), mkexpr(t1))));
   10768                      putAcc(ac, mkexpr(t2));
   10769                      break;
   10770                   }
   10771                   case 0x9: {  /* DPSX.W.PH */
   10772                      DIP("dpsx.w.ph ac%d r%d, r%d", ac, rs, rt);
   10773                      vassert(!mode64);
   10774 
   10775                      t0 = newTemp(Ity_I64);
   10776                      t1 = newTemp(Ity_I64);
   10777                      t2 = newTemp(Ity_I64);
   10778 
   10779                      assign(t0,
   10780                             unop(Iop_32Sto64,
   10781                                  binop(Iop_Mul32,
   10782                                        unop(Iop_16Sto32,
   10783                                             unop(Iop_32HIto16, getIReg(rs))),
   10784                                        unop(Iop_16Sto32,
   10785                                             unop(Iop_32to16, getIReg(rt))))));
   10786                      assign(t1,
   10787                             unop(Iop_32Sto64,
   10788                                  binop(Iop_Mul32,
   10789                                        unop(Iop_16Sto32,
   10790                                             unop(Iop_32to16, getIReg(rs))),
   10791                                        unop(Iop_16Sto32,
   10792                                             unop(Iop_32HIto16, getIReg(rt))))));
   10793                      assign(t2,
   10794                             binop(Iop_Sub64,
   10795                                   getAcc(ac),
   10796                                   binop(Iop_Add64, mkexpr(t0), mkexpr(t1))));
   10797                      putAcc(ac, mkexpr(t2));
   10798                      break;
   10799                   }
   10800                   case 0xB: {  /* DPSU.H.QBL */
   10801                      DIP("dpsu.h.qbl ac%d, r%d, r%d", ac, rs, rt);
   10802                      vassert(!mode64);
   10803 
   10804                      t0 = newTemp(Ity_I32);
   10805                      t1 = newTemp(Ity_I32);
   10806                      t2 = newTemp(Ity_I64);
   10807                      t3 = newTemp(Ity_I64);
   10808 
   10809                      assign(t0,
   10810                             binop(Iop_Mul32,
   10811                                   unop(Iop_8Uto32,
   10812                                        unop(Iop_16HIto8,
   10813                                             unop(Iop_32HIto16, getIReg(rs)))),
   10814                                   unop(Iop_8Uto32,
   10815                                        unop(Iop_16HIto8,
   10816                                             unop(Iop_32HIto16, getIReg(rt))))));
   10817                      assign(t1,
   10818                             binop(Iop_Mul32,
   10819                                   unop(Iop_8Uto32,
   10820                                        unop(Iop_16to8,
   10821                                             unop(Iop_32HIto16, getIReg(rs)))),
   10822                                   unop(Iop_8Uto32,
   10823                                        unop(Iop_16to8,
   10824                                             unop(Iop_32HIto16, getIReg(rt))))));
   10825                      assign(t2,
   10826                             unop(Iop_32Uto64,
   10827                                  binop(Iop_Add32, mkexpr(t0), mkexpr(t1))));
   10828                      assign(t3,
   10829                             binop(Iop_Sub64, getAcc(ac), mkexpr(t2)));
   10830                      putAcc(ac, mkexpr(t3));
   10831                      break;
   10832                   }
   10833                   case 0xC: {  /* DPAQ_SA.L.W */
   10834                      DIP("dpaq_sa.l.w ac%d, r%d, r%d", ac, rs, rt);
   10835                      vassert(!mode64);
   10836                      t0 = newTemp(Ity_I64);
   10837                      t1 = newTemp(Ity_I64);
   10838                      t2 = newTemp(Ity_I1);
   10839                      t3 = newTemp(Ity_I1);
   10840                      t4 = newTemp(Ity_I64);
   10841                      t5 = newTemp(Ity_I64);
   10842                      t6 = newTemp(Ity_I64);
   10843                      t7 = newTemp(Ity_I64);
   10844                      t8 = newTemp(Ity_I1);
   10845                      t9 = newTemp(Ity_I1);
   10846 
   10847                      assign(t0, getAcc(ac));
   10848 
   10849                      assign(t1, binop(Iop_Shl64,
   10850                                       binop(Iop_MullS32,
   10851                                             getIReg(rs), getIReg(rt)),
   10852                                       mkU8(0x1)));
   10853 
   10854                      assign(t2, binop(Iop_CmpEQ32,
   10855                                       getIReg(rs),
   10856                                       mkU32(0x80000000)));
   10857                      assign(t3, binop(Iop_CmpEQ32,
   10858                                       getIReg(rt),
   10859                                       mkU32(0x80000000)));
   10860 
   10861                      assign(t4,
   10862                             IRExpr_ITE(mkexpr(t2),
   10863                                        IRExpr_ITE(mkexpr(t3),
   10864                                                   mkU64(0x7fffffffffffffffULL),
   10865                                                   mkexpr(t1)),
   10866                                        mkexpr(t1)));
   10867 
   10868                      putDSPControl(IRExpr_ITE(mkexpr(t2),
   10869                                               IRExpr_ITE(mkexpr(t3),
   10870                                                          binop(Iop_Or32,
   10871                                                                getDSPControl(),
   10872                                                                binop(Iop_Shl32,
   10873                                                                      mkU32(0x1),
   10874                                                                      mkU8(ac+16)
   10875                                                                     )
   10876                                                               ),
   10877                                                          getDSPControl()),
   10878                                               getDSPControl()));
   10879 
   10880                      assign(t5, binop(Iop_Add64,
   10881                                       unop(Iop_32Uto64,
   10882                                            unop(Iop_64to32, mkexpr(t0))),
   10883                                       unop(Iop_32Uto64,
   10884                                            unop(Iop_64to32, mkexpr(t4)))));
   10885                      assign(t6,
   10886                             binop(Iop_Add64,
   10887                                   binop(Iop_Add64,
   10888                                         unop(Iop_32Sto64,
   10889                                              unop(Iop_64HIto32, mkexpr(t0))),
   10890                                         unop(Iop_32Sto64,
   10891                                              unop(Iop_64HIto32, mkexpr(t4)))),
   10892                                   unop(Iop_32Uto64,
   10893                                        binop(Iop_And32,
   10894                                              unop(Iop_64HIto32, mkexpr(t5)),
   10895                                              mkU32(0x1)))));
   10896                      assign(t7, binop(Iop_32HLto64,
   10897                                       unop(Iop_64to32, mkexpr(t6)),
   10898                                       unop(Iop_64to32, mkexpr(t5))));
   10899                      assign(t8, binop(Iop_CmpEQ32,
   10900                                       binop(Iop_Shr32,
   10901                                             binop(Iop_And32,
   10902                                                   unop(Iop_64to32, mkexpr(t6)),
   10903                                                   mkU32(0x80000000)),
   10904                                             mkU8(31)),
   10905                                       binop(Iop_And32,
   10906                                             unop(Iop_64HIto32, mkexpr(t6)),
   10907                                             mkU32(0x00000001))));
   10908                      assign(t9, binop(Iop_CmpEQ32,
   10909                                       binop(Iop_And32,
   10910                                             unop(Iop_64HIto32,
   10911                                                  mkexpr(t6)),
   10912                                             mkU32(0x00000001)),
   10913                                       mkU32(0x1)));
   10914                      putDSPControl(IRExpr_ITE(mkexpr(t8),
   10915                                               getDSPControl(),
   10916                                               binop(Iop_Or32,
   10917                                                     getDSPControl(),
   10918                                                     binop(Iop_Shl32,
   10919                                                           mkU32(0x1),
   10920                                                           mkU8(ac+16)))));
   10921                      putAcc(ac,
   10922                             IRExpr_ITE(mkexpr(t8),
   10923                                        mkexpr(t7),
   10924                                        IRExpr_ITE(mkexpr(t9),
   10925                                                   mkU64(0x8000000000000000ULL),
   10926                                                   mkU64(0x7fffffffffffffffULL)))
   10927                            );
   10928                      break;
   10929                   }
   10930                   case 0xD: {  /* DPSQ_SA.L.W */
   10931                      DIP("dpsq_sa.l.w ac%d, r%d, r%d", ac, rs, rt);
   10932                      vassert(!mode64);
   10933                      t0 = newTemp(Ity_I64);
   10934                      t1 = newTemp(Ity_I64);
   10935                      t2 = newTemp(Ity_I1);
   10936                      t3 = newTemp(Ity_I1);
   10937                      t4 = newTemp(Ity_I64);
   10938                      t5 = newTemp(Ity_I64);
   10939                      t6 = newTemp(Ity_I64);
   10940                      t7 = newTemp(Ity_I64);
   10941                      t8 = newTemp(Ity_I1);
   10942                      t9 = newTemp(Ity_I1);
   10943 
   10944                      assign(t0, getAcc(ac));
   10945 
   10946                      assign(t1, binop(Iop_Shl64,
   10947                                       binop(Iop_MullS32,
   10948                                             getIReg(rs), getIReg(rt)),
   10949                                       mkU8(0x1)));
   10950 
   10951                      assign(t2, binop(Iop_CmpEQ32,
   10952                                       getIReg(rs),
   10953                                       mkU32(0x80000000)));
   10954                      assign(t3, binop(Iop_CmpEQ32,
   10955                                       getIReg(rt),
   10956                                       mkU32(0x80000000)));
   10957 
   10958                      assign(t4,
   10959                             IRExpr_ITE(mkexpr(t2),
   10960                                        IRExpr_ITE(mkexpr(t3),
   10961                                                   mkU64(0x7fffffffffffffffULL),
   10962                                                   mkexpr(t1)),
   10963                                        mkexpr(t1)));
   10964 
   10965                      putDSPControl(IRExpr_ITE(mkexpr(t2),
   10966                                               IRExpr_ITE(mkexpr(t3),
   10967                                                          binop(Iop_Or32,
   10968                                                                getDSPControl(),
   10969                                                                binop(Iop_Shl32,
   10970                                                                      mkU32(0x1),
   10971                                                                      mkU8(ac+16)
   10972                                                                     )
   10973                                                               ),
   10974                                                          getDSPControl()),
   10975                                               getDSPControl()));
   10976 
   10977                      assign(t5, binop(Iop_Sub64,
   10978                                       unop(Iop_32Uto64,
   10979                                            unop(Iop_64to32, mkexpr(t0))),
   10980                                       unop(Iop_32Uto64,
   10981                                            unop(Iop_64to32, mkexpr(t4)))));
   10982                      assign(t6, binop(Iop_Sub64,
   10983                                       binop(Iop_Add64,
   10984                                             unop(Iop_32Sto64,
   10985                                                  unop(Iop_64HIto32, mkexpr(t0))
   10986                                                 ),
   10987                                             unop(Iop_32Sto64,
   10988                                                  unop(Iop_1Sto32,
   10989                                                       binop(Iop_CmpLT32U,
   10990                                                             unop(Iop_64to32,
   10991                                                                  mkexpr(t0)),
   10992                                                             unop(Iop_64to32,
   10993                                                                 mkexpr(t4)))))),
   10994                                       unop(Iop_32Sto64,
   10995                                            unop(Iop_64HIto32, mkexpr(t4)))));
   10996                      assign(t7, binop(Iop_32HLto64,
   10997                                       unop(Iop_64to32, mkexpr(t6)),
   10998                                       unop(Iop_64to32, mkexpr(t5))));
   10999                      assign(t8, binop(Iop_CmpEQ32,
   11000                                       binop(Iop_Shr32,
   11001                                             binop(Iop_And32,
   11002                                                   unop(Iop_64to32, mkexpr(t6)),
   11003                                                   mkU32(0x80000000)),
   11004                                             mkU8(31)),
   11005                                       binop(Iop_And32,
   11006                                             unop(Iop_64HIto32, mkexpr(t6)),
   11007                                             mkU32(0x00000001))));
   11008                      assign(t9, binop(Iop_CmpEQ32,
   11009                                       binop(Iop_And32,
   11010                                             unop(Iop_64HIto32, mkexpr(t6)),
   11011                                             mkU32(0x00000001)),
   11012                                       mkU32(0x1)));
   11013                      putDSPControl(IRExpr_ITE(mkexpr(t8),
   11014                                               getDSPControl(),
   11015                                               binop(Iop_Or32,
   11016                                                     getDSPControl(),
   11017                                                     binop(Iop_Shl32,
   11018                                                           mkU32(0x1),
   11019                                                           mkU8(ac+16)))));
   11020                      putAcc(ac,
   11021                             IRExpr_ITE(mkexpr(t8),
   11022                                        mkexpr(t7),
   11023                                        IRExpr_ITE(mkexpr(t9),
   11024                                                   mkU64(0x8000000000000000ULL),
   11025                                                   mkU64(0x7fffffffffffffffULL)))
   11026                            );
   11027                      break;
   11028                   }
   11029                   case 0xF: {  /* DPSU.H.QBR */
   11030                      DIP("dpsu.h.qbr ac%d r%d, r%d", ac, rs, rt);
   11031                      vassert(!mode64);
   11032 
   11033                      t0 = newTemp(Ity_I32);
   11034                      t1 = newTemp(Ity_I32);
   11035                      t2 = newTemp(Ity_I64);
   11036                      t3 = newTemp(Ity_I64);
   11037 
   11038                      assign(t0,
   11039                             binop(Iop_Mul32,
   11040                                   unop(Iop_8Uto32,
   11041                                        unop(Iop_16HIto8,
   11042                                             unop(Iop_32to16, getIReg(rs)))),
   11043                                   unop(Iop_8Uto32,
   11044                                        unop(Iop_16HIto8,
   11045                                             unop(Iop_32to16, getIReg(rt))))));
   11046                      assign(t1,
   11047                             binop(Iop_Mul32,
   11048                                   unop(Iop_8Uto32,
   11049                                        unop(Iop_16to8,
   11050                                             unop(Iop_32to16, getIReg(rs)))),
   11051                                   unop(Iop_8Uto32,
   11052                                        unop(Iop_16to8,
   11053                                             unop(Iop_32to16, getIReg(rt))))));
   11054                      assign(t2, unop(Iop_32Uto64,
   11055                                      binop(Iop_Add32, mkexpr(t0), mkexpr(t1))));
   11056                      assign(t3, binop(Iop_Sub64, getAcc(ac), mkexpr(t2)));
   11057                      putAcc(ac, mkexpr(t3));
   11058 
   11059                      break;
   11060                   }
   11061                   case 0x10: {  /* MAQ_SA.W.PHL */
   11062                      DIP("maq_sa.w.phl ac%d, r%d, r%d", ac, rs, rt);
   11063                      vassert(!mode64);
   11064                      t0 = newTemp(Ity_I64);
   11065                      t1 = newTemp(Ity_I64);
   11066                      t2 = newTemp(Ity_I1);
   11067                      t3 = newTemp(Ity_I1);
   11068                      t4 = newTemp(Ity_I64);
   11069                      t5 = newTemp(Ity_I64);
   11070                      t6 = newTemp(Ity_I1);
   11071                      t7 = newTemp(Ity_I64);
   11072 
   11073                      assign(t0, getAcc(ac));
   11074                      assign(t1, unop(Iop_32Sto64,
   11075                                      binop(Iop_Shl32,
   11076                                            binop(Iop_Mul32,
   11077                                                  unop(Iop_16Sto32,
   11078                                                       unop(Iop_32HIto16,
   11079                                                            getIReg(rs))),
   11080                                                  unop(Iop_16Sto32,
   11081                                                       unop(Iop_32HIto16,
   11082                                                            getIReg(rt)))),
   11083                                            mkU8(0x1))));
   11084 
   11085                      /* If both input arguments are equal 0x8000, saturate
   11086                         intermediate product and write to DSPControl register.
   11087                      */
   11088                      assign(t2, binop(Iop_CmpEQ32,
   11089                                       unop(Iop_16Uto32,
   11090                                            unop(Iop_32HIto16, getIReg(rs))),
   11091                                       mkU32(0x00008000)));
   11092                      assign(t3, binop(Iop_CmpEQ32,
   11093                                       unop(Iop_16Uto32,
   11094                                            unop(Iop_32HIto16, getIReg(rt))),
   11095                                       mkU32(0x00008000)));
   11096 
   11097                      assign(t4,
   11098                             IRExpr_ITE(mkexpr(t2),
   11099                                        IRExpr_ITE(mkexpr(t3),
   11100                                                   mkU64(0x000000007fffffffULL),
   11101                                                   mkexpr(t1)),
   11102                                        mkexpr(t1)));
   11103 
   11104                      putDSPControl(IRExpr_ITE(mkexpr(t2),
   11105                                               IRExpr_ITE(mkexpr(t3),
   11106                                                          binop(Iop_Or32,
   11107                                                                getDSPControl(),
   11108                                                                binop(Iop_Shl32,
   11109                                                                      mkU32(0x1),
   11110                                                                      mkU8(ac+16)
   11111                                                                     )
   11112                                                               ),
   11113                                                          getDSPControl()),
   11114                                               getDSPControl()));
   11115                      /* Add intermediate product and value in the
   11116                         accumulator. */
   11117                      assign(t5, binop(Iop_Add64, mkexpr(t0), mkexpr(t4)));
   11118 
   11119                      /* Compare bits 31 and 32 of the value in t5. */
   11120                      assign(t6, binop(Iop_CmpEQ32,
   11121                                       binop(Iop_Shr32,
   11122                                             binop(Iop_And32,
   11123                                                   unop(Iop_64to32, mkexpr(t5)),
   11124                                                   mkU32(0x80000000)),
   11125                                             mkU8(31)),
   11126                                       binop(Iop_And32,
   11127                                             unop(Iop_64HIto32, mkexpr(t5)),
   11128                                             mkU32(1))));
   11129                      putDSPControl(IRExpr_ITE(mkexpr(t6),
   11130                                               getDSPControl(),
   11131                                               binop(Iop_Or32,
   11132                                                     getDSPControl(),
   11133                                                     binop(Iop_Shl32,
   11134                                                           mkU32(0x1),
   11135                                                           mkU8(ac+16)))));
   11136                      assign(t7,
   11137                             IRExpr_ITE(mkexpr(t6),
   11138                                        mkexpr(t5),
   11139                                        IRExpr_ITE(binop(Iop_CmpEQ32,
   11140                                                         binop(Iop_And32,
   11141                                                               unop(Iop_64HIto32,
   11142                                                                    mkexpr(t5)),
   11143                                                               mkU32(1)),
   11144                                                         mkU32(0x0)),
   11145                                                   mkU64(0x000000007fffffffULL),
   11146                                                   mkU64(0xffffffff80000000ULL)))
   11147                            );
   11148                      putAcc(ac, mkexpr(t7));
   11149                      break;
   11150                   }
   11151                   case 0x12: {  /* MAQ_SA.W.PHR */
   11152                      DIP("maq_sa.w.phr ac%d, r%d, r%d", ac, rs, rt);
   11153                      vassert(!mode64);
   11154                      t0 = newTemp(Ity_I64);
   11155                      t1 = newTemp(Ity_I64);
   11156                      t2 = newTemp(Ity_I1);
   11157                      t3 = newTemp(Ity_I1);
   11158                      t4 = newTemp(Ity_I64);
   11159                      t5 = newTemp(Ity_I64);
   11160                      t6 = newTemp(Ity_I1);
   11161                      t7 = newTemp(Ity_I64);
   11162 
   11163                      assign(t0, getAcc(ac));
   11164                      assign(t1, unop(Iop_32Sto64,
   11165                                      binop(Iop_Shl32,
   11166                                            binop(Iop_Mul32,
   11167                                                  unop(Iop_16Sto32,
   11168                                                       unop(Iop_32to16,
   11169                                                            getIReg(rs))),
   11170                                                  unop(Iop_16Sto32,
   11171                                                       unop(Iop_32to16,
   11172                                                            getIReg(rt)))),
   11173                                            mkU8(0x1))));
   11174 
   11175                      /* If both input arguments are equal 0x8000, saturate
   11176                         intermediate product and write to DSPControl
   11177                         register. */
   11178                      assign(t2, binop(Iop_CmpEQ32,
   11179                                       unop(Iop_16Uto32,
   11180                                            unop(Iop_32to16, getIReg(rs))),
   11181                                       mkU32(0x00008000)));
   11182                      assign(t3, binop(Iop_CmpEQ32,
   11183                                       unop(Iop_16Uto32,
   11184                                            unop(Iop_32to16, getIReg(rt))),
   11185                                       mkU32(0x00008000)));
   11186 
   11187                      assign(t4,
   11188                             IRExpr_ITE(mkexpr(t2),
   11189                                        IRExpr_ITE(mkexpr(t3),
   11190                                                   mkU64(0x000000007fffffffULL),
   11191                                                   mkexpr(t1)),
   11192                                        mkexpr(t1)));
   11193 
   11194                      putDSPControl(IRExpr_ITE(mkexpr(t2),
   11195                                               IRExpr_ITE(mkexpr(t3),
   11196                                                          binop(Iop_Or32,
   11197                                                                getDSPControl(),
   11198                                                                binop(Iop_Shl32,
   11199                                                                      mkU32(0x1),
   11200                                                                      mkU8(ac+16)
   11201                                                                     )
   11202                                                               ),
   11203                                                          getDSPControl()),
   11204                                               getDSPControl()));
   11205                      /* Add intermediate product and value in the
   11206                         accumulator. */
   11207                      assign(t5, binop(Iop_Add64, mkexpr(t0), mkexpr(t4)));
   11208 
   11209                      /* Compare bits 31 and 32 of the value in t5. */
   11210                      assign(t6, binop(Iop_CmpEQ32,
   11211                                       binop(Iop_Shr32,
   11212                                             binop(Iop_And32,
   11213                                                   unop(Iop_64to32, mkexpr(t5)),
   11214                                                   mkU32(0x80000000)),
   11215                                             mkU8(31)),
   11216                                       binop(Iop_And32,
   11217                                             unop(Iop_64HIto32, mkexpr(t5)),
   11218                                             mkU32(1))));
   11219                      putDSPControl(IRExpr_ITE(mkexpr(t6),
   11220                                               getDSPControl(),
   11221                                               binop(Iop_Or32,
   11222                                                     getDSPControl(),
   11223                                                     binop(Iop_Shl32,
   11224                                                           mkU32(0x1),
   11225                                                           mkU8(ac+16)))));
   11226                      assign(t7,
   11227                             IRExpr_ITE(mkexpr(t6),
   11228                                        mkexpr(t5),
   11229                                        IRExpr_ITE(binop(Iop_CmpEQ32,
   11230                                                         binop(Iop_And32,
   11231                                                               unop(Iop_64HIto32,
   11232                                                                    mkexpr(t5)),
   11233                                                               mkU32(1)),
   11234                                                         mkU32(0x0)),
   11235                                                   mkU64(0x000000007fffffffULL),
   11236                                                   mkU64(0xffffffff80000000ULL)))
   11237                            );
   11238                      putAcc(ac, mkexpr(t7));
   11239                      break;
   11240                   }
   11241                   case 0x14: {  /* MAQ_S.W.PHL */
   11242                      DIP("maq_s.w.phl ac%d, r%d, r%d", ac, rs, rt);
   11243                      vassert(!mode64);
   11244                      t0 = newTemp(Ity_I32);
   11245                      t1 = newTemp(Ity_I32);
   11246                      t2 = newTemp(Ity_I32);
   11247                      t3 = newTemp(Ity_I1);
   11248                      t4 = newTemp(Ity_I32);
   11249                      t5 = newTemp(Ity_I64);
   11250 
   11251                      assign(t5, getAcc(ac));
   11252 
   11253                      assign(t0, unop(Iop_16Sto32,
   11254                                      unop(Iop_32HIto16, getIReg(rs))));
   11255                      assign(t1, unop(Iop_16Sto32,
   11256                                      unop(Iop_32HIto16, getIReg(rt))));
   11257 
   11258                      assign(t2, binop(Iop_And32,
   11259                                       unop(Iop_1Sto32,
   11260                                            binop(Iop_CmpEQ32,
   11261                                                  binop(Iop_And32,
   11262                                                        mkexpr(t0),
   11263                                                        mkU32(0xffff)),
   11264                                                  mkU32(0x8000))),
   11265                                       unop(Iop_1Sto32,
   11266                                            binop(Iop_CmpEQ32,
   11267                                                  binop(Iop_And32,
   11268                                                        mkexpr(t1),
   11269                                                        mkU32(0xffff)),
   11270                                                  mkU32(0x8000)))));
   11271 
   11272                      assign(t3, binop(Iop_CmpEQ32, mkexpr(t2), mkU32(0x0)));
   11273 
   11274                      putDSPControl(IRExpr_ITE(mkexpr(t3),
   11275                                               getDSPControl(),
   11276                                               binop(Iop_Or32,
   11277                                                     getDSPControl(),
   11278                                                     binop(Iop_Shl32,
   11279                                                           mkU32(0x1),
   11280                                                           mkU8(ac+16)))));
   11281 
   11282                      assign(t4, unop(Iop_64to32,
   11283                                      binop(Iop_MullS32,
   11284                                            mkexpr(t0), mkexpr(t1))));
   11285                      putAcc(ac, IRExpr_ITE(mkexpr(t3),
   11286                                            binop(Iop_Add64,
   11287                                                  unop(Iop_32Sto64,
   11288                                                       binop(Iop_Shl32,
   11289                                                             mkexpr(t4),
   11290                                                             mkU8(0x1))),
   11291                                                  mkexpr(t5)),
   11292                                            binop(Iop_Add64,
   11293                                                  mkexpr(t5),
   11294                                                  unop(Iop_32Sto64,
   11295                                                       mkU32(0x7fffffff)))));
   11296                      break;
   11297                   }
   11298                   case 0x16: {  /* MAQ_S.W.PHR */
   11299                      DIP("maq_s.w.phr ac%d, r%d, r%d", ac, rs, rt);
   11300                      vassert(!mode64);
   11301                      t0 = newTemp(Ity_I32);
   11302                      t1 = newTemp(Ity_I32);
   11303                      t2 = newTemp(Ity_I32);
   11304                      t3 = newTemp(Ity_I1);
   11305                      t4 = newTemp(Ity_I32);
   11306                      t5 = newTemp(Ity_I64);
   11307 
   11308                      assign(t5, getAcc(ac));
   11309 
   11310                      assign(t0, unop(Iop_16Sto32,
   11311                                      unop(Iop_32to16, getIReg(rs))));
   11312                      assign(t1, unop(Iop_16Sto32,
   11313                                      unop(Iop_32to16, getIReg(rt))));
   11314 
   11315                      assign(t2, binop(Iop_And32,
   11316                                       unop(Iop_1Sto32,
   11317                                            binop(Iop_CmpEQ32,
   11318                                                  binop(Iop_And32,
   11319                                                        mkexpr(t0),
   11320                                                        mkU32(0xffff)),
   11321                                                  mkU32(0x8000))),
   11322                                       unop(Iop_1Sto32,
   11323                                            binop(Iop_CmpEQ32,
   11324                                                  binop(Iop_And32,
   11325                                                        mkexpr(t1),
   11326                                                        mkU32(0xffff)),
   11327                                                  mkU32(0x8000)))));
   11328 
   11329                      assign(t3, binop(Iop_CmpEQ32, mkexpr(t2), mkU32(0x0)));
   11330 
   11331                      putDSPControl(IRExpr_ITE(mkexpr(t3),
   11332                                               getDSPControl(),
   11333                                               binop(Iop_Or32,
   11334                                                     getDSPControl(),
   11335                                                     binop(Iop_Shl32,
   11336                                                           mkU32(0x1),
   11337                                                           mkU8(ac+16)))));
   11338 
   11339                      assign(t4, unop(Iop_64to32,
   11340                                      binop(Iop_MullS32,
   11341                                            mkexpr(t0), mkexpr(t1))));
   11342                      putAcc(ac, IRExpr_ITE(mkexpr(t3),
   11343                                            binop(Iop_Add64,
   11344                                                  unop(Iop_32Sto64,
   11345                                                       binop(Iop_Shl32,
   11346                                                             mkexpr(t4),
   11347                                                             mkU8(0x1))),
   11348                                                  mkexpr(t5)),
   11349                                            binop(Iop_Add64,
   11350                                                  mkexpr(t5),
   11351                                                  unop(Iop_32Sto64,
   11352                                                       mkU32(0x7fffffff)))));
   11353                      break;
   11354                   }
   11355                   case 0x18: {  /* DPAQX_S.W.PH */
   11356                      DIP("dpaqx_s.w.ph ac%d, r%d, r%d", ac, rs, rt);
   11357                      vassert(!mode64);
   11358                      t0 = newTemp(Ity_I64);
   11359                      t1 = newTemp(Ity_I64);
   11360                      t2 = newTemp(Ity_I1);
   11361                      t3 = newTemp(Ity_I1);
   11362                      t4 = newTemp(Ity_I64);
   11363                      t5 = newTemp(Ity_I64);
   11364                      t6 = newTemp(Ity_I1);
   11365                      t7 = newTemp(Ity_I1);
   11366                      t8 = newTemp(Ity_I64);
   11367                      t9 = newTemp(Ity_I64);
   11368 
   11369                      assign(t0, getAcc(ac));
   11370 
   11371                      assign(t1, binop(Iop_Shl64,
   11372                                       binop(Iop_MullS32,
   11373                                             unop(Iop_16Sto32,
   11374                                                  unop(Iop_32HIto16,
   11375                                                       getIReg(rs))),
   11376                                             unop(Iop_16Sto32,
   11377                                                  unop(Iop_32to16,
   11378                                                       getIReg(rt)))),
   11379                                       mkU8(0x1)));
   11380                      assign(t2, binop(Iop_CmpEQ32,
   11381                                       unop(Iop_16Uto32,
   11382                                            unop(Iop_32HIto16, getIReg(rs))),
   11383                                       mkU32(0x00008000)));
   11384                      assign(t3, binop(Iop_CmpEQ32,
   11385                                       unop(Iop_16Uto32,
   11386                                            unop(Iop_32to16, getIReg(rt))),
   11387                                       mkU32(0x00008000)));
   11388                      assign(t4,
   11389                             IRExpr_ITE(mkexpr(t2),
   11390                                        IRExpr_ITE(mkexpr(t3),
   11391                                                   mkU64(0x000000007fffffffULL),
   11392                                                   mkexpr(t1)),
   11393                                        mkexpr(t1)));
   11394 
   11395                      putDSPControl(IRExpr_ITE(mkexpr(t2),
   11396                                               IRExpr_ITE(mkexpr(t3),
   11397                                                          binop(Iop_Or32,
   11398                                                                getDSPControl(),
   11399                                                                binop(Iop_Shl32,
   11400                                                                   mkU32(0x1),
   11401                                                                   mkU8(ac+16))),
   11402                                                          getDSPControl()),
   11403                                               getDSPControl()));
   11404 
   11405                      assign(t5, binop(Iop_Shl64,
   11406                                       binop(Iop_MullS32,
   11407                                             unop(Iop_16Sto32,
   11408                                                  unop(Iop_32to16,
   11409                                                       getIReg(rs))),
   11410                                             unop(Iop_16Sto32,
   11411                                                  unop(Iop_32HIto16,
   11412                                                       getIReg(rt)))),
   11413                                       mkU8(0x1)));
   11414                      assign(t6, binop(Iop_CmpEQ32,
   11415                                       unop(Iop_16Uto32,
   11416                                            unop(Iop_32to16, getIReg(rs))),
   11417                                       mkU32(0x00008000)));
   11418                      assign(t7, binop(Iop_CmpEQ32,
   11419                                       unop(Iop_16Uto32,
   11420                                            unop(Iop_32HIto16, getIReg(rt))),
   11421                                       mkU32(0x00008000)));
   11422                      assign(t8,
   11423                             IRExpr_ITE(mkexpr(t6),
   11424                                        IRExpr_ITE(mkexpr(t7),
   11425                                                   mkU64(0x000000007fffffffULL),
   11426                                                   mkexpr(t5)),
   11427                                        mkexpr(t5)));
   11428 
   11429                      putDSPControl(IRExpr_ITE(mkexpr(t6),
   11430                                               IRExpr_ITE(mkexpr(t7),
   11431                                                          binop(Iop_Or32,
   11432                                                                getDSPControl(),
   11433                                                                binop(Iop_Shl32,
   11434                                                                      mkU32(0x1),
   11435                                                                      mkU8(ac+16)
   11436                                                                     )
   11437                                                               ),
   11438                                                          getDSPControl()),
   11439                                               getDSPControl()));
   11440 
   11441                      assign(t9, binop(Iop_Add64,
   11442                                       binop(Iop_Add64, mkexpr(t4), mkexpr(t8)),
   11443                                       mkexpr(t0)));
   11444                      putAcc(ac, mkexpr(t9));
   11445                      break;
   11446                   }
   11447                   case 0x19: {  /* DPSQX_S.W.PH */
   11448                      DIP("dpsqx_s.w.ph ac%d, r%d, r%d", ac, rs, rt);
   11449                      vassert(!mode64);
   11450                      t0 = newTemp(Ity_I64);
   11451                      t1 = newTemp(Ity_I64);
   11452                      t2 = newTemp(Ity_I1);
   11453                      t3 = newTemp(Ity_I1);
   11454                      t4 = newTemp(Ity_I64);
   11455                      t5 = newTemp(Ity_I64);
   11456                      t6 = newTemp(Ity_I1);
   11457                      t7 = newTemp(Ity_I1);
   11458                      t8 = newTemp(Ity_I64);
   11459                      t9 = newTemp(Ity_I64);
   11460 
   11461                      assign(t0, getAcc(ac));
   11462 
   11463                      assign(t1, binop(Iop_Shl64,
   11464                                       binop(Iop_MullS32,
   11465                                             unop(Iop_16Sto32,
   11466                                                  unop(Iop_32HIto16,
   11467                                                       getIReg(rs))),
   11468                                             unop(Iop_16Sto32,
   11469                                                  unop(Iop_32to16,
   11470                                                       getIReg(rt)))),
   11471                                       mkU8(0x1)));
   11472                      assign(t2, binop(Iop_CmpEQ32,
   11473                                       unop(Iop_16Uto32,
   11474                                            unop(Iop_32HIto16, getIReg(rs))),
   11475                                       mkU32(0x00008000)));
   11476                      assign(t3, binop(Iop_CmpEQ32,
   11477                                       unop(Iop_16Uto32,
   11478                                            unop(Iop_32to16, getIReg(rt))),
   11479                                       mkU32(0x00008000)));
   11480                      assign(t4,
   11481                             IRExpr_ITE(mkexpr(t2),
   11482                                        IRExpr_ITE(mkexpr(t3),
   11483                                                   mkU64(0x000000007fffffffULL),
   11484                                                   mkexpr(t1)),
   11485                                        mkexpr(t1)));
   11486 
   11487                      putDSPControl(IRExpr_ITE(mkexpr(t2),
   11488                                               IRExpr_ITE(mkexpr(t3),
   11489                                                          binop(Iop_Or32,
   11490                                                                getDSPControl(),
   11491                                                                binop(Iop_Shl32,
   11492                                                                      mkU32(0x1),
   11493                                                                      mkU8(ac+16)
   11494                                                                     )
   11495                                                               ),
   11496                                                          getDSPControl()),
   11497                                               getDSPControl()));
   11498 
   11499                      assign(t5, binop(Iop_Shl64,
   11500                                       binop(Iop_MullS32,
   11501                                             unop(Iop_16Sto32,
   11502                                                  unop(Iop_32to16,
   11503                                                       getIReg(rs))),
   11504                                             unop(Iop_16Sto32,
   11505                                                  unop(Iop_32HIto16,
   11506                                                       getIReg(rt)))),
   11507                                       mkU8(0x1)));
   11508                      assign(t6, binop(Iop_CmpEQ32,
   11509                                       unop(Iop_16Uto32,
   11510                                            unop(Iop_32to16, getIReg(rs))),
   11511                                       mkU32(0x00008000)));
   11512                      assign(t7, binop(Iop_CmpEQ32,
   11513                                       unop(Iop_16Uto32,
   11514                                            unop(Iop_32HIto16, getIReg(rt))),
   11515                                       mkU32(0x00008000)));
   11516                      assign(t8,
   11517                             IRExpr_ITE(mkexpr(t6),
   11518                                        IRExpr_ITE(mkexpr(t7),
   11519                                                   mkU64(0x000000007fffffffULL),
   11520                                                   mkexpr(t5)),
   11521                                        mkexpr(t5)));
   11522 
   11523                      putDSPControl(IRExpr_ITE(mkexpr(t6),
   11524                                               IRExpr_ITE(mkexpr(t7),
   11525                                                          binop(Iop_Or32,
   11526                                                                getDSPControl(),
   11527                                                                binop(Iop_Shl32,
   11528                                                                      mkU32(0x1),
   11529                                                                      mkU8(ac+16)
   11530                                                                     )
   11531                                                               ),
   11532                                                          getDSPControl()),
   11533                                               getDSPControl()));
   11534 
   11535                      assign(t9, binop(Iop_Sub64,
   11536                                      mkexpr(t0),
   11537                                      binop(Iop_Add64, mkexpr(t4), mkexpr(t8))));
   11538                      putAcc(ac, mkexpr(t9));
   11539                      break;
   11540                   }
   11541                   case 0x1A: {  /* DPAQX_SA.W.PH */
   11542                      DIP("dpaqx_sa.w.ph ac%d, r%d, r%d", ac, rs, rt);
   11543                      vassert(!mode64);
   11544                      t0 = newTemp(Ity_I64);
   11545                      t1 = newTemp(Ity_I64);
   11546                      t2 = newTemp(Ity_I1);
   11547                      t3 = newTemp(Ity_I1);
   11548                      t4 = newTemp(Ity_I64);
   11549                      t5 = newTemp(Ity_I64);
   11550                      t6 = newTemp(Ity_I1);
   11551                      t7 = newTemp(Ity_I1);
   11552                      t8 = newTemp(Ity_I64);
   11553                      t9 = newTemp(Ity_I64);
   11554                      t10 = newTemp(Ity_I32);
   11555 
   11556                      assign(t0, getAcc(ac));
   11557                      /* Calculate the first cross dot product and saturate if
   11558                         needed. */
   11559                      assign(t1, unop(Iop_32Sto64,
   11560                                      binop(Iop_Shl32,
   11561                                            binop(Iop_Mul32,
   11562                                                  unop(Iop_16Sto32,
   11563                                                       unop(Iop_32HIto16,
   11564                                                            getIReg(rs))),
   11565                                                  unop(Iop_16Sto32,
   11566                                                       unop(Iop_32to16,
   11567                                                            getIReg(rt)))),
   11568                                            mkU8(0x1))));
   11569 
   11570                      /* If both input arguments are equal 0x8000, saturate
   11571                         intermediate product and write to DSPControl
   11572                         register. */
   11573                      assign(t2, binop(Iop_CmpEQ32,
   11574                                       unop(Iop_16Uto32,
   11575                                            unop(Iop_32HIto16, getIReg(rs))),
   11576                                       mkU32(0x00008000)));
   11577                      assign(t3, binop(Iop_CmpEQ32,
   11578                                       unop(Iop_16Uto32,
   11579                                            unop(Iop_32to16, getIReg(rt))),
   11580                                       mkU32(0x00008000)));
   11581 
   11582                      assign(t4, IRExpr_ITE(binop(Iop_CmpNE32,
   11583                                                  binop(Iop_And32,
   11584                                                        unop(Iop_1Sto32,
   11585                                                             mkexpr(t2)),
   11586                                                        unop(Iop_1Sto32,
   11587                                                             mkexpr(t3))),
   11588                                                  mkU32(0)),
   11589                                            mkU64(0x000000007fffffffULL),
   11590                                            mkexpr(t1)));
   11591 
   11592                      putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32,
   11593                                                     binop(Iop_And32,
   11594                                                           unop(Iop_1Sto32,
   11595                                                                mkexpr(t2)),
   11596                                                           unop(Iop_1Sto32,
   11597                                                                mkexpr(t3))),
   11598                                                     mkU32(0)),
   11599                                               binop(Iop_Or32,
   11600                                                     getDSPControl(),
   11601                                                     binop(Iop_Shl32,
   11602                                                           mkU32(0x1),
   11603                                                           mkU8(ac+16))),
   11604                                               getDSPControl()));
   11605                      /* Calculate second cross dot product and saturate if
   11606                         needed. */
   11607                      assign(t5, unop(Iop_32Sto64,
   11608                                      binop(Iop_Shl32,
   11609                                            binop(Iop_Mul32,
   11610                                                  unop(Iop_16Sto32,
   11611                                                       unop(Iop_32to16,
   11612                                                            getIReg(rs))),
   11613                                                  unop(Iop_16Sto32,
   11614                                                       unop(Iop_32HIto16,
   11615                                                            getIReg(rt)))),
   11616                                            mkU8(0x1))));
   11617 
   11618                      /* If both input arguments are equal 0x8000, saturate
   11619                         intermediate product and write to DSPControl
   11620                         register. */
   11621                      assign(t6, binop(Iop_CmpEQ32,
   11622                                       unop(Iop_16Uto32,
   11623                                            unop(Iop_32to16, getIReg(rs))),
   11624                                       mkU32(0x00008000)));
   11625                      assign(t7, binop(Iop_CmpEQ32,
   11626                                       unop(Iop_16Uto32,
   11627                                            unop(Iop_32HIto16, getIReg(rt))),
   11628                                       mkU32(0x00008000)));
   11629 
   11630                      assign(t8, IRExpr_ITE(binop(Iop_CmpNE32,
   11631                                                  binop(Iop_And32,
   11632                                                        unop(Iop_1Sto32,
   11633                                                             mkexpr(t6)),
   11634                                                        unop(Iop_1Sto32,
   11635                                                             mkexpr(t7))),
   11636                                                  mkU32(0)),
   11637                                            mkU64(0x000000007fffffffULL),
   11638                                            mkexpr(t5)));
   11639 
   11640                      putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32,
   11641                                                     binop(Iop_And32,
   11642                                                           unop(Iop_1Sto32,
   11643                                                                mkexpr(t6)),
   11644                                                           unop(Iop_1Sto32,
   11645                                                                mkexpr(t7))),
   11646                                                     mkU32(0)),
   11647                                               binop(Iop_Or32,
   11648                                                     getDSPControl(),
   11649                                                     binop(Iop_Shl32,
   11650                                                           mkU32(0x1),
   11651                                                           mkU8(ac+16))),
   11652                                               getDSPControl()));
   11653                      /* Subtract intermediate products from value in the
   11654                         accumulator. */
   11655                      assign(t9,
   11656                             binop(Iop_Add64,
   11657                                   mkexpr(t0),
   11658                                   binop(Iop_Add64, mkexpr(t8), mkexpr(t4))));
   11659 
   11660                      putAcc(ac,
   11661                             IRExpr_ITE(binop(Iop_CmpEQ32,
   11662                                              binop(Iop_And32,
   11663                                                    unop(Iop_64HIto32,
   11664                                                         mkexpr(t9)),
   11665                                                    mkU32(0x80000000)),
   11666                                              mkU32(0x0)),
   11667                                        IRExpr_ITE(binop(Iop_CmpNE32,
   11668                                                         unop(Iop_64HIto32,
   11669                                                              binop(Iop_Shl64,
   11670                                                                    mkexpr(t9),
   11671                                                                    mkU8(1))),
   11672                                                         mkU32(0x0)),
   11673                                                   mkU64(0x000000007fffffffULL),
   11674                                                   mkexpr(t9)),
   11675                                        IRExpr_ITE(binop(Iop_CmpNE32,
   11676                                                         unop(Iop_64HIto32,
   11677                                                              binop(Iop_Shl64,
   11678                                                                    mkexpr(t9),
   11679                                                                    mkU8(1))),
   11680                                                         mkU32(0xffffffff)),
   11681                                                   mkU64(0xffffffff80000000ULL),
   11682                                                   mkexpr(t9))));
   11683                      assign(t10, IRExpr_ITE(binop(Iop_CmpEQ32,
   11684                                                   unop(Iop_64to32,
   11685                                                        mkexpr(t9)),
   11686                                                   unop(Iop_64to32,
   11687                                                        getAcc(ac))),
   11688                                            getDSPControl(),
   11689                                            binop(Iop_Or32,
   11690                                                  getDSPControl(),
   11691                                                  binop(Iop_Shl32,
   11692                                                        mkU32(0x1),
   11693                                                        mkU8(ac+16)))));
   11694                      putDSPControl(IRExpr_ITE(binop(Iop_CmpEQ32,
   11695                                                     unop(Iop_64HIto32,
   11696                                                          mkexpr(t9)),
   11697                                                     unop(Iop_64HIto32,
   11698                                                          getAcc(ac))),
   11699                                               mkexpr(t10),
   11700                                               binop(Iop_Or32,
   11701                                                     getDSPControl(),
   11702                                                     binop(Iop_Shl32,
   11703                                                           mkU32(0x1),
   11704                                                           mkU8(ac+16)))));
   11705                      break;
   11706                   }
   11707                   case 0x1B: {  /* DPSQX_SA.W.PH */
   11708                      DIP("dpsqx_sa.w.ph ac%d, r%d, r%d", ac, rs, rt);
   11709                      vassert(!mode64);
   11710                      t0 = newTemp(Ity_I64);
   11711                      t1 = newTemp(Ity_I64);
   11712                      t2 = newTemp(Ity_I1);
   11713                      t3 = newTemp(Ity_I1);
   11714                      t4 = newTemp(Ity_I64);
   11715                      t5 = newTemp(Ity_I64);
   11716                      t6 = newTemp(Ity_I1);
   11717                      t7 = newTemp(Ity_I1);
   11718                      t8 = newTemp(Ity_I64);
   11719                      t9 = newTemp(Ity_I64);
   11720                      t10 = newTemp(Ity_I32);
   11721 
   11722                      assign(t0, getAcc(ac));
   11723                      /* Calculate the first cross dot product and saturate if
   11724                         needed. */
   11725                      assign(t1, unop(Iop_32Sto64,
   11726                                      binop(Iop_Shl32,
   11727                                            binop(Iop_Mul32,
   11728                                                  unop(Iop_16Sto32,
   11729                                                       unop(Iop_32HIto16,
   11730                                                            getIReg(rs))),
   11731                                                  unop(Iop_16Sto32,
   11732                                                       unop(Iop_32to16,
   11733                                                            getIReg(rt)))),
   11734                                            mkU8(0x1))));
   11735 
   11736                      /* If both input arguments are equal 0x8000, saturate
   11737                         intermediate product and write to DSPControl
   11738                         register. */
   11739                      assign(t2, binop(Iop_CmpEQ32,
   11740                                       unop(Iop_16Uto32,
   11741                                            unop(Iop_32HIto16, getIReg(rs))),
   11742                                       mkU32(0x00008000)));
   11743                      assign(t3, binop(Iop_CmpEQ32,
   11744                                       unop(Iop_16Uto32,
   11745                                            unop(Iop_32to16, getIReg(rt))),
   11746                                       mkU32(0x00008000)));
   11747 
   11748                      assign(t4, IRExpr_ITE(binop(Iop_CmpNE32,
   11749                                                  binop(Iop_And32,
   11750                                                        unop(Iop_1Sto32,
   11751                                                             mkexpr(t2)),
   11752                                                        unop(Iop_1Sto32,
   11753                                                             mkexpr(t3))),
   11754                                                  mkU32(0)),
   11755                                            mkU64(0x000000007fffffffULL),
   11756                                            mkexpr(t1)));
   11757 
   11758                      putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32,
   11759                                                     binop(Iop_And32,
   11760                                                           unop(Iop_1Sto32,
   11761                                                                mkexpr(t2)),
   11762                                                           unop(Iop_1Sto32,
   11763                                                                mkexpr(t3))),
   11764                                                     mkU32(0)),
   11765                                               binop(Iop_Or32,
   11766                                                     getDSPControl(),
   11767                                                     binop(Iop_Shl32,
   11768                                                           mkU32(0x1),
   11769                                                           mkU8(ac+16))),
   11770                                               getDSPControl()));
   11771                      /* Calculate second cross dot product and saturate if
   11772                         needed. */
   11773                      assign(t5, unop(Iop_32Sto64,
   11774                                      binop(Iop_Shl32,
   11775                                            binop(Iop_Mul32,
   11776                                                  unop(Iop_16Sto32,
   11777                                                       unop(Iop_32to16,
   11778                                                            getIReg(rs))),
   11779                                                  unop(Iop_16Sto32,
   11780                                                       unop(Iop_32HIto16,
   11781                                                            getIReg(rt)))),
   11782                                            mkU8(0x1))));
   11783 
   11784                      /* If both input arguments are equal 0x8000, saturate
   11785                         intermediate product and write to DSPControl
   11786                         register. */
   11787                      assign(t6, binop(Iop_CmpEQ32,
   11788                                       unop(Iop_16Uto32,
   11789                                            unop(Iop_32to16, getIReg(rs))),
   11790                                       mkU32(0x00008000)));
   11791                      assign(t7, binop(Iop_CmpEQ32,
   11792                                       unop(Iop_16Uto32,
   11793                                            unop(Iop_32HIto16, getIReg(rt))),
   11794                                       mkU32(0x00008000)));
   11795 
   11796                      assign(t8, IRExpr_ITE(binop(Iop_CmpNE32,
   11797                                                  binop(Iop_And32,
   11798                                                        unop(Iop_1Sto32,
   11799                                                             mkexpr(t6)),
   11800                                                        unop(Iop_1Sto32,
   11801                                                             mkexpr(t7))),
   11802                                                  mkU32(0)),
   11803                                            mkU64(0x000000007fffffffULL),
   11804                                            mkexpr(t5)));
   11805 
   11806                      putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32,
   11807                                                     binop(Iop_And32,
   11808                                                           unop(Iop_1Sto32,
   11809                                                                mkexpr(t6)),
   11810                                                           unop(Iop_1Sto32,
   11811                                                                mkexpr(t7))),
   11812                                                     mkU32(0)),
   11813                                               binop(Iop_Or32,
   11814                                                     getDSPControl(),
   11815                                                     binop(Iop_Shl32,
   11816                                                           mkU32(0x1),
   11817                                                           mkU8(ac+16))),
   11818                                               getDSPControl()));
   11819                      /* Subtract intermediate products from value in the
   11820                         accumulator. */
   11821                      assign(t9,
   11822                             binop(Iop_Sub64,
   11823                                   mkexpr(t0),
   11824                                   binop(Iop_Add64, mkexpr(t8), mkexpr(t4))));
   11825 
   11826                      putAcc(ac,
   11827                             IRExpr_ITE(binop(Iop_CmpEQ32,
   11828                                              binop(Iop_And32,
   11829                                                    unop(Iop_64HIto32,
   11830                                                         mkexpr(t9)),
   11831                                                    mkU32(0x80000000)),
   11832                                              mkU32(0x0)),
   11833                                        IRExpr_ITE(binop(Iop_CmpNE32,
   11834                                                         unop(Iop_64HIto32,
   11835                                                              binop(Iop_Shl64,
   11836                                                                    mkexpr(t9),
   11837                                                                    mkU8(1))),
   11838                                                         mkU32(0x0)),
   11839                                                   mkU64(0x000000007fffffffULL),
   11840                                                   mkexpr(t9)),
   11841                                        IRExpr_ITE(binop(Iop_CmpNE32,
   11842                                                         unop(Iop_64HIto32,
   11843                                                              binop(Iop_Shl64,
   11844                                                                    mkexpr(t9),
   11845                                                                    mkU8(1))),
   11846                                                         mkU32(0xffffffff)),
   11847                                                   mkU64(0xffffffff80000000ULL),
   11848                                                   mkexpr(t9))));
   11849                      assign(t10, IRExpr_ITE(binop(Iop_CmpEQ32,
   11850                                                   unop(Iop_64to32,
   11851                                                        mkexpr(t9)),
   11852                                                   unop(Iop_64to32,
   11853                                                        getAcc(ac))),
   11854                                            getDSPControl(),
   11855                                            binop(Iop_Or32,
   11856                                                  getDSPControl(),
   11857                                                  binop(Iop_Shl32,
   11858                                                        mkU32(0x1),
   11859                                                        mkU8(ac+16)))));
   11860                      putDSPControl(IRExpr_ITE(binop(Iop_CmpEQ32,
   11861                                                     unop(Iop_64HIto32,
   11862                                                          mkexpr(t9)),
   11863                                                     unop(Iop_64HIto32,
   11864                                                          getAcc(ac))),
   11865                                               mkexpr(t10),
   11866                                               binop(Iop_Or32,
   11867                                                     getDSPControl(),
   11868                                                     binop(Iop_Shl32,
   11869                                                           mkU32(0x1),
   11870                                                           mkU8(ac+16)))));
   11871                      break;
   11872                   }
   11873                   default:
   11874                      return -1;
   11875                }
   11876                break;  /* end of DPAQ.W.PH */
   11877             }
   11878             case 0x31: {  /* APPEND */
   11879                switch(sa) {
   11880                   case 0x0: {  /* APPEND */
   11881                      DIP("append r%d, r%d, %d", rt, rs, rd);
   11882                      vassert(!mode64);
   11883                      t1 = newTemp(Ity_I32);
   11884                      t2 = newTemp(Ity_I32);
   11885                      t3 = newTemp(Ity_I32);
   11886 
   11887                      assign(t1, binop(Iop_Shl32, getIReg(rt), mkU8(rd)));
   11888 
   11889                      if (31 == rd) {
   11890                         putIReg(rt, binop(Iop_Or32,
   11891                                           mkexpr(t1),
   11892                                           binop(Iop_And32,
   11893                                                 getIReg(rs),
   11894                                                 mkU32(0x7fffffff))));
   11895                      } else if (1 == rd) {
   11896                         putIReg(rt,
   11897                                 binop(Iop_Or32,
   11898                                       mkexpr(t1),
   11899                                       binop(Iop_And32,
   11900                                             getIReg(rs), mkU32(0x1))));
   11901                      } else {
   11902                         assign(t2,
   11903                                unop(Iop_Not32,
   11904                                     binop(Iop_Shl32,
   11905                                           mkU32(0xffffffff), mkU8(rd))));
   11906 
   11907                         putIReg(rt, binop(Iop_Or32,
   11908                                           mkexpr(t1),
   11909                                           binop(Iop_And32,
   11910                                                 getIReg(rs), mkexpr(t2))));
   11911                      }
   11912                      break;
   11913                   }
   11914                   case 0x1: {  /* PREPEND */
   11915                      DIP("prepend r%d, r%d, %d", rt, rs, rd);
   11916                      vassert(!mode64);
   11917                      t1 = newTemp(Ity_I32);
   11918                      t2 = newTemp(Ity_I32);
   11919                      t3 = newTemp(Ity_I32);
   11920 
   11921                      if (0 != rd) {
   11922                         assign(t1, binop(Iop_Shr32, getIReg(rt), mkU8(rd)));
   11923 
   11924                         if (31 == rd) {
   11925                            putIReg(rt, binop(Iop_Or32,
   11926                                              mkexpr(t1),
   11927                                              binop(Iop_Shl32,
   11928                                                    binop(Iop_And32,
   11929                                                          getIReg(rs),
   11930                                                          mkU32(0x7fffffff)),
   11931                                                    mkU8(1))));
   11932                         } else if (1 == rd) {
   11933                            putIReg(rt, binop(Iop_Or32,
   11934                                              mkexpr(t1),
   11935                                              binop(Iop_Shl32,
   11936                                                    binop(Iop_And32,
   11937                                                          getIReg(rs),
   11938                                                          mkU32(0x1)),
   11939                                                    mkU8(31))));
   11940                         } else {
   11941                            assign(t2, binop(Iop_Add32, mkU32(rd), mkU32(0x1)));
   11942 
   11943                            assign(t3, unop(Iop_Not32,
   11944                                            binop(Iop_Shl32,
   11945                                                  mkU32(0xffffffff),
   11946                                                  unop(Iop_32to8, mkexpr(t2)))));
   11947 
   11948                            putIReg(rt, binop(Iop_Or32,
   11949                                              mkexpr(t1),
   11950                                              binop(Iop_Shl32,
   11951                                                    binop(Iop_And32,
   11952                                                          getIReg(rs),
   11953                                                          mkexpr(t3)),
   11954                                                    mkU8(32-rd))));
   11955                         }
   11956                      }
   11957                      break;
   11958                   }
   11959                   case 0x10: {  /* BALIGN */
   11960                      DIP("balign r%d, r%d, %d", rt, rs, rd);
   11961                      vassert(!mode64);
   11962                      t1 = newTemp(Ity_I32);
   11963                      t2 = newTemp(Ity_I32);
   11964                      t3 = newTemp(Ity_I32);
   11965 
   11966                      if ((2 != rd) && (0 != rd)) {
   11967                         assign(t1, binop(Iop_Shl32,
   11968                                          binop(Iop_And32,
   11969                                                mkU32(rd), mkU32(0x3)),
   11970                                          mkU8(0x3)));
   11971                         assign(t2, binop(Iop_Shl32,
   11972                                          getIReg(rt),
   11973                                          unop(Iop_32to8, mkexpr(t1))));
   11974                         assign(t3, binop(Iop_Shr32,
   11975                                          getIReg(rs),
   11976                                          unop(Iop_32to8,
   11977                                               binop(Iop_Shl32,
   11978                                                     binop(Iop_Sub32,
   11979                                                           mkU32(0x4),
   11980                                                           binop(Iop_And32,
   11981                                                                 mkU32(rd),
   11982                                                                 mkU32(0x3))),
   11983                                                     mkU8(0x3)))));
   11984                         putIReg(rt, binop(Iop_Or32, mkexpr(t2), mkexpr(t3)));
   11985                      }
   11986                      break;
   11987                   }
   11988                   default:
   11989                      return -1;
   11990                }
   11991                break;  /* end of APPEND */
   11992             }
   11993             default:
   11994                return -1;
   11995          }
   11996          break;
   11997       }
   11998       default:
   11999             return -1;
   12000    }
   12001    return 0;
   12002 }
   12003 
   12004 /*------------------------------------------------------------*/
   12005 /*---          Disassemble a single instruction            ---*/
   12006 /*------------------------------------------------------------*/
   12007 
   12008 /* Disassemble a single instruction into IR. The instruction is
   12009    located in host memory at guest_instr, and has guest IP of
   12010    guest_PC_curr_instr, which will have been set before the call
   12011    here. */
   12012 
   12013 static DisResult disInstr_MIPS_WRK ( Bool(*resteerOkFn) (/*opaque */void *,
   12014                                                                     Addr),
   12015                                      Bool         resteerCisOk,
   12016                                      void*        callback_opaque,
   12017                                      Long         delta64,
   12018                                      const VexArchInfo* archinfo,
   12019                                      const VexAbiInfo*  abiinfo,
   12020                                      Bool         sigill_diag )
   12021 {
   12022    IRTemp t0, t1 = 0, t2, t3, t4, t5, t6, t7;
   12023 
   12024    UInt opcode, cins, rs, rt, rd, sa, ft, fs, fd, fmt, tf, nd, function,
   12025         trap_code, imm, instr_index, p, msb, lsb, size, rot, sel;
   12026    /* Additional variables for instruction fields in DSP ASE insructions */
   12027    UInt ac;
   12028 
   12029    DisResult dres;
   12030 
   12031    static IRExpr *lastn = NULL;  /* last jump addr */
   12032    static IRStmt *bstmt = NULL;  /* branch (Exit) stmt */
   12033 
   12034    /* The running delta */
   12035    Int delta = (Int) delta64;
   12036 
   12037    /* Holds eip at the start of the insn, so that we can print
   12038       consistent error messages for unimplemented insns. */
   12039    Int delta_start = delta;
   12040 
   12041    /* Are we in a delay slot ? */
   12042    Bool delay_slot_branch, likely_delay_slot, delay_slot_jump;
   12043 
   12044    /* Set result defaults. */
   12045    dres.whatNext = Dis_Continue;
   12046    dres.len = 0;
   12047    dres.continueAt = 0;
   12048    dres.jk_StopHere = Ijk_INVALID;
   12049 
   12050    delay_slot_branch = likely_delay_slot = delay_slot_jump = False;
   12051 
   12052    const UChar *code = guest_code + delta;
   12053    cins = getUInt(code);
   12054    DIP("\t0x%lx:\t0x%08x\t", (long)guest_PC_curr_instr, cins);
   12055 
   12056    if (delta != 0) {
   12057       if (branch_or_jump(guest_code + delta - 4)) {
   12058          if (lastn == NULL && bstmt == NULL) {
   12059             vassert(0);
   12060          } else {
   12061             dres.whatNext = Dis_StopHere;
   12062             if (lastn != NULL) {
   12063                delay_slot_jump = True;
   12064             } else if (bstmt != NULL) {
   12065                delay_slot_branch = True;
   12066             }
   12067          }
   12068       }
   12069 
   12070       if (branch_or_link_likely(guest_code + delta - 4)) {
   12071          likely_delay_slot = True;
   12072       }
   12073    }
   12074 
   12075    /* Spot "Special" instructions (see comment at top of file). */
   12076    {
   12077       /* Spot the 16-byte preamble:
   12078        ****mips32****
   12079        "srl $0, $0, 13
   12080        "srl $0, $0, 29
   12081        "srl $0, $0, 3
   12082        "srl $0, $0, 19
   12083 
   12084        ****mips64****
   12085        dsll $0, $0, 3
   12086        dsll $0, $0, 13
   12087        dsll $0, $0, 29
   12088        dsll $0, $0, 19 */
   12089 
   12090       UInt word1 = mode64 ? 0xF8  : 0x342;
   12091       UInt word2 = mode64 ? 0x378 : 0x742;
   12092       UInt word3 = mode64 ? 0x778 : 0xC2;
   12093       UInt word4 = mode64 ? 0x4F8 : 0x4C2;
   12094       if (getUInt(code + 0) == word1 && getUInt(code + 4) == word2 &&
   12095           getUInt(code + 8) == word3 && getUInt(code + 12) == word4) {
   12096          /* Got a "Special" instruction preamble. Which one is it? */
   12097          if (getUInt(code + 16) == 0x01ad6825 /* or $13, $13, $13 */ ) {
   12098             /* $11 = client_request ( $12 ) */
   12099             DIP("$11 = client_request ( $12 )");
   12100             if (mode64)
   12101                putPC(mkU64(guest_PC_curr_instr + 20));
   12102             else
   12103                putPC(mkU32(guest_PC_curr_instr + 20));
   12104             dres.jk_StopHere = Ijk_ClientReq;
   12105             dres.whatNext    = Dis_StopHere;
   12106 
   12107             goto decode_success;
   12108          } else if (getUInt(code + 16) == 0x01ce7025 /* or $14, $14, $14 */ ) {
   12109             /* $11 = guest_NRADDR */
   12110             DIP("$11 = guest_NRADDR");
   12111             dres.len = 20;
   12112             delta += 20;
   12113             if (mode64)
   12114                putIReg(11, IRExpr_Get(offsetof(VexGuestMIPS64State,
   12115                                                guest_NRADDR), Ity_I64));
   12116             else
   12117                putIReg(11, IRExpr_Get(offsetof(VexGuestMIPS32State,
   12118                                                guest_NRADDR), Ity_I32));
   12119             goto decode_success;
   12120          } else if (getUInt(code + 16) == 0x01ef7825 /* or $15, $15, $15 */ ) {
   12121             /*  branch-and-link-to-noredir $25 */
   12122             DIP("branch-and-link-to-noredir $25");
   12123             if (mode64)
   12124                putIReg(31, mkU64(guest_PC_curr_instr + 20));
   12125             else
   12126                putIReg(31, mkU32(guest_PC_curr_instr + 20));
   12127             putPC(getIReg(25));
   12128             dres.jk_StopHere = Ijk_NoRedir;
   12129             dres.whatNext    = Dis_StopHere;
   12130             goto decode_success;
   12131          } else if (getUInt(code + 16) == 0x016b5825 /* or $11,$11,$11 */ ) {
   12132            /* IR injection */
   12133             DIP("IR injection");
   12134 #if defined (_MIPSEL)
   12135             vex_inject_ir(irsb, Iend_LE);
   12136 #elif defined (_MIPSEB)
   12137             vex_inject_ir(irsb, Iend_BE);
   12138 #endif
   12139             if (mode64) {
   12140                stmt(IRStmt_Put(offsetof(VexGuestMIPS64State, guest_CMSTART),
   12141                                mkU64(guest_PC_curr_instr)));
   12142                stmt(IRStmt_Put(offsetof(VexGuestMIPS64State, guest_CMLEN),
   12143                                mkU64(20)));
   12144 
   12145                putPC(mkU64(guest_PC_curr_instr + 20));
   12146             } else {
   12147                stmt(IRStmt_Put(offsetof(VexGuestMIPS32State, guest_CMSTART),
   12148                                mkU32(guest_PC_curr_instr)));
   12149                stmt(IRStmt_Put(offsetof(VexGuestMIPS32State, guest_CMLEN),
   12150                                mkU32(20)));
   12151 
   12152                putPC(mkU32(guest_PC_curr_instr + 20));
   12153             }
   12154             dres.whatNext    = Dis_StopHere;
   12155             dres.jk_StopHere = Ijk_InvalICache;
   12156             dres.len = 20;
   12157             delta += 20;
   12158             goto decode_success;
   12159          }
   12160 
   12161          /* We don't know what it is.  Set opc1/opc2 so decode_failure
   12162             can print the insn following the Special-insn preamble. */
   12163          delta += 16;
   12164          goto decode_failure;
   12165        /*NOTREACHED*/}
   12166    }
   12167 
   12168    opcode = get_opcode(cins);
   12169    imm = get_imm(cins);
   12170    rs = get_rs(cins);
   12171    rt = get_rt(cins);
   12172    rd = get_rd(cins);
   12173    sa = get_sa(cins);
   12174    fs = get_fs(cins);
   12175    fd = get_fd(cins);
   12176    ft = get_ft(cins);
   12177    tf = get_tf(cins);
   12178    nd = get_nd(cins);
   12179    sel = get_sel(cins);
   12180    fmt = get_fmt(cins);
   12181    instr_index = get_instr_index(cins);
   12182    trap_code = get_code(cins);
   12183    function = get_function(cins);
   12184    IRType ty = mode64 ? Ity_I64 : Ity_I32;
   12185    IRType tyF = fp_mode64 ? Ity_F64 : Ity_F32;
   12186 
   12187    ac = get_acNo(cins);
   12188 
   12189    switch (opcode) {
   12190 
   12191    case 0x03:     /* JAL */
   12192       DIP("jal 0x%x", instr_index);
   12193       if (mode64) {
   12194          putIReg(31, mkU64(guest_PC_curr_instr + 8));
   12195          t0 = newTemp(ty);
   12196          assign(t0, mkU64((guest_PC_curr_instr & 0xFFFFFFFFF0000000ULL) |
   12197                           (instr_index << 2)));
   12198       } else {
   12199          putIReg(31, mkU32(guest_PC_curr_instr + 8));
   12200          t0 = newTemp(ty);
   12201          assign(t0, mkU32((guest_PC_curr_instr & 0xF0000000) |
   12202                           (instr_index << 2)));
   12203       }
   12204       lastn = mkexpr(t0);
   12205       break;
   12206    case 0x02:     /* J */
   12207       DIP("j 0x%x", instr_index);
   12208       t0 = newTemp(ty);
   12209       if (mode64)
   12210          assign(t0, mkU64((guest_PC_curr_instr & 0xFFFFFFFFF0000000ULL) |
   12211                           (instr_index << 2)));
   12212       else
   12213          assign(t0, mkU32((guest_PC_curr_instr & 0xF0000000) |
   12214                           (instr_index << 2)));
   12215       lastn = mkexpr(t0);
   12216       break;
   12217 
   12218    case 0x11: {  /* COP1 */
   12219       if (fmt == 0x3 && fd == 0 && function == 0) {  /* MFHC1 */
   12220          DIP("mfhc1 r%d, f%d", rt, fs);
   12221          if (fp_mode64) {
   12222             t0 = newTemp(Ity_I64);
   12223             t1 = newTemp(Ity_I32);
   12224             assign(t0, unop(Iop_ReinterpF64asI64, getDReg(fs)));
   12225             assign(t1, unop(Iop_64HIto32, mkexpr(t0)));
   12226             putIReg(rt, mkWidenFrom32(ty, mkexpr(t1), True));
   12227          } else {
   12228             ILLEGAL_INSTRUCTON;
   12229          }
   12230          break;
   12231       } else if (fmt == 0x7 && fd == 0 && function == 0) {  /* MTHC1 */
   12232          DIP("mthc1 r%d, f%d", rt, fs);
   12233          if (fp_mode64) {
   12234             t0 = newTemp(Ity_I64);
   12235             assign(t0, binop(Iop_32HLto64, getIReg(rt),
   12236                              unop(Iop_ReinterpF32asI32,
   12237                                   getLoFromF64(Ity_F64 /* 32FPR mode. */,
   12238                                                getDReg(fs)))));
   12239             putDReg(fs, unop(Iop_ReinterpI64asF64, mkexpr(t0)));
   12240          } else {
   12241             ILLEGAL_INSTRUCTON;
   12242          }
   12243          break;
   12244       } else if (fmt == 0x8) {  /* BC */
   12245          /* FcConditionalCode(bc1_cc) */
   12246          UInt bc1_cc = get_bc1_cc(cins);
   12247          t1 = newTemp(Ity_I1);
   12248          t2 = newTemp(Ity_I32);
   12249          t3 = newTemp(Ity_I1);
   12250 
   12251          assign(t1, binop(Iop_CmpEQ32, mkU32(0), mkU32(bc1_cc)));
   12252          assign(t2, IRExpr_ITE(mkexpr(t1),
   12253                                binop(Iop_And32,
   12254                                      binop(Iop_Shr32, getFCSR(), mkU8(23)),
   12255                                      mkU32(0x1)),
   12256                                binop(Iop_And32,
   12257                                      binop(Iop_Shr32, getFCSR(),
   12258                                            mkU8(24 + bc1_cc)),
   12259                                      mkU32(0x1))));
   12260 
   12261          if (tf == 1 && nd == 0) {
   12262             /* branch on true */
   12263             DIP("bc1t %d, %d", bc1_cc, imm);
   12264             assign(t3, binop(Iop_CmpEQ32, mkU32(1), mkexpr(t2)));
   12265             dis_branch(False, mkexpr(t3), imm, &bstmt);
   12266             break;
   12267          } else if (tf == 0 && nd == 0) {
   12268             /* branch on false */
   12269             DIP("bc1f %d, %d", bc1_cc, imm);
   12270             assign(t3, binop(Iop_CmpEQ32, mkU32(0), mkexpr(t2)));
   12271             dis_branch(False, mkexpr(t3), imm, &bstmt);
   12272             break;
   12273          } else if (nd == 1 && tf == 0) {
   12274             DIP("bc1fl %d, %d", bc1_cc, imm);
   12275             lastn = dis_branch_likely(binop(Iop_CmpNE32, mkexpr(t2),
   12276                                             mkU32(0x0)), imm);
   12277             break;
   12278          } else if (nd == 1 && tf == 1) {
   12279             DIP("bc1tl %d, %d", bc1_cc, imm);
   12280             lastn = dis_branch_likely(binop(Iop_CmpEQ32, mkexpr(t2),
   12281                                             mkU32(0x0)), imm);
   12282             break;
   12283          } else
   12284             goto decode_failure;
   12285       } else {
   12286          switch (function) {
   12287             case 0x4: {  /* SQRT.fmt */
   12288                switch (fmt) {
   12289                   case 0x10: {  /* S */
   12290                      IRExpr *rm = get_IR_roundingmode();
   12291                      putFReg(fd, mkWidenFromF32(tyF, binop(Iop_SqrtF32, rm,
   12292                                  getLoFromF64(tyF, getFReg(fs)))));
   12293                      break;
   12294                   }
   12295                   case 0x11: {  /* D */
   12296                      IRExpr *rm = get_IR_roundingmode();
   12297                      putDReg(fd, binop(Iop_SqrtF64, rm, getDReg(fs)));
   12298                      break;
   12299                   }
   12300                   default:
   12301                      goto decode_failure;
   12302                   }
   12303                }
   12304                break;
   12305             case 0x5:  /* abs.fmt */
   12306                switch (fmt) {
   12307                   case 0x10:  /* S */
   12308                      DIP("abs.s f%d, f%d", fd, fs);
   12309                      putFReg(fd, mkWidenFromF32(tyF, unop(Iop_AbsF32,
   12310                                  getLoFromF64(tyF, getFReg(fs)))));
   12311                      break;
   12312                   case 0x11:  /* D  */
   12313                      DIP("abs.d f%d, f%d", fd, fs);
   12314                      putDReg(fd, unop(Iop_AbsF64, getDReg(fs)));
   12315                      break;
   12316                   default:
   12317                      goto decode_failure;
   12318                }
   12319                break;  /* case 0x5 */
   12320 
   12321             case 0x02:  /* MUL.fmt */
   12322                switch (fmt) {
   12323                   case 0x11: {  /* D */
   12324                      DIP("mul.d f%d, f%d, f%d", fd, fs, ft);
   12325                      IRExpr *rm = get_IR_roundingmode();
   12326                      putDReg(fd, triop(Iop_MulF64, rm, getDReg(fs),
   12327                                        getDReg(ft)));
   12328                      break;
   12329                   }
   12330                   case 0x10: {  /* S */
   12331                      DIP("mul.s f%d, f%d, f%d", fd, fs, ft);
   12332                      IRExpr *rm = get_IR_roundingmode();
   12333                      putFReg(fd, mkWidenFromF32(tyF, triop(Iop_MulF32, rm,
   12334                                  getLoFromF64(tyF, getFReg(fs)),
   12335                                  getLoFromF64(tyF, getFReg(ft)))));
   12336                      break;
   12337                   }
   12338                   default:
   12339                      goto decode_failure;
   12340                }
   12341                break;  /* MUL.fmt */
   12342 
   12343             case 0x03:  /* DIV.fmt */
   12344                switch (fmt) {
   12345                   case 0x11: {  /* D */
   12346                      DIP("div.d f%d, f%d, f%d", fd, fs, ft);
   12347                      IRExpr *rm = get_IR_roundingmode();
   12348                      putDReg(fd, triop(Iop_DivF64, rm, getDReg(fs),
   12349                                  getDReg(ft)));
   12350                      break;
   12351                   }
   12352                   case 0x10: {  /* S */
   12353                      DIP("div.s f%d, f%d, f%d", fd, fs, ft);
   12354                      calculateFCSR(fs, ft, DIVS, False, 2);
   12355                      IRExpr *rm = get_IR_roundingmode();
   12356                      putFReg(fd, mkWidenFromF32(tyF, triop(Iop_DivF32, rm,
   12357                                  getLoFromF64(tyF, getFReg(fs)),
   12358                                  getLoFromF64(tyF, getFReg(ft)))));
   12359                      break;
   12360                   }
   12361                   default:
   12362                      goto decode_failure;
   12363                }
   12364                break;  /* DIV.fmt */
   12365 
   12366             case 0x01:  /* SUB.fmt */
   12367                switch (fmt) {
   12368                   case 0x11: {  /* D */
   12369                      DIP("sub.d f%d, f%d, f%d", fd, fs, ft);
   12370                      calculateFCSR(fs, ft, SUBD, False, 2);
   12371                      IRExpr *rm = get_IR_roundingmode();
   12372                      putDReg(fd, triop(Iop_SubF64, rm, getDReg(fs),
   12373                                        getDReg(ft)));
   12374                      break;
   12375                   }
   12376                   case 0x10: {  /* S */
   12377                      DIP("sub.s f%d, f%d, f%d", fd, fs, ft);
   12378                      calculateFCSR(fs, ft, SUBS, True, 2);
   12379                      IRExpr *rm = get_IR_roundingmode();
   12380                      putFReg(fd, mkWidenFromF32(tyF, triop(Iop_SubF32, rm,
   12381                                  getLoFromF64(tyF, getFReg(fs)),
   12382                                  getLoFromF64(tyF, getFReg(ft)))));
   12383                      break;
   12384                   }
   12385                   default:
   12386                      goto decode_failure;
   12387                }
   12388                break;  /* SUB.fmt */
   12389 
   12390             case 0x06:  /* MOV.fmt */
   12391                switch (fmt) {
   12392                   case 0x11:  /* D */
   12393                      DIP("mov.d f%d, f%d", fd, fs);
   12394                      if (fp_mode64) {
   12395                         putDReg(fd, getDReg(fs));
   12396                      } else {
   12397                         putFReg(fd, getFReg(fs));
   12398                         putFReg(fd + 1, getFReg(fs + 1));
   12399                      }
   12400                      break;
   12401                   case 0x10:  /* S */
   12402                      DIP("mov.s f%d, f%d", fd, fs);
   12403                      putFReg(fd, getFReg(fs));
   12404                      break;
   12405                   default:
   12406                      goto decode_failure;
   12407                }
   12408                break;  /* MOV.fmt */
   12409 
   12410             case 0x7:  /* neg.fmt */
   12411                switch (fmt) {
   12412                   case 0x10:  /* S */
   12413                      DIP("neg.s f%d, f%d", fd, fs);
   12414                      putFReg(fd, mkWidenFromF32(tyF, unop(Iop_NegF32,
   12415                                  getLoFromF64(tyF, getFReg(fs)))));
   12416                      break;
   12417                   case 0x11:  /* D */
   12418                      DIP("neg.d f%d, f%d", fd, fs);
   12419                      putDReg(fd, unop(Iop_NegF64, getDReg(fs)));
   12420                      break;
   12421                   default:
   12422                      goto decode_failure;
   12423                }
   12424                break;  /* case 0x7 */
   12425 
   12426             case 0x08:  /* ROUND.L.fmt */
   12427                switch (fmt) {
   12428                   case 0x10:  /* S */
   12429                      DIP("round.l.s f%d, f%d", fd, fs);
   12430                      if (fp_mode64) {
   12431                         calculateFCSR(fs, 0, ROUNDLS, True, 1);
   12432                         t0 = newTemp(Ity_I64);
   12433 
   12434                         assign(t0, binop(Iop_F32toI64S, mkU32(0x0),
   12435                                          getLoFromF64(Ity_F64, getFReg(fs))));
   12436 
   12437                         putDReg(fd, unop(Iop_ReinterpI64asF64, mkexpr(t0)));
   12438                      } else {
   12439                         ILLEGAL_INSTRUCTON;
   12440                      }
   12441                      break;
   12442                   case 0x11:  /* D */
   12443                      DIP("round.l.d f%d, f%d", fd, fs);
   12444                      if (fp_mode64) {
   12445                         calculateFCSR(fs, 0, ROUNDLD, False, 1);
   12446                         putDReg(fd, binop(Iop_RoundF64toInt, mkU32(0x0),
   12447                                           getDReg(fs)));
   12448                      } else {
   12449                         ILLEGAL_INSTRUCTON;
   12450                      }
   12451                      break;
   12452                   default:
   12453                     goto decode_failure;
   12454 
   12455                }
   12456                break;  /* ROUND.L.fmt */
   12457 
   12458             case 0x09:  /* TRUNC.L.fmt */
   12459                switch (fmt) {
   12460                   case 0x10:  /* S */
   12461                      DIP("trunc.l.s f%d, f%d", fd, fs);
   12462                      if (fp_mode64) {
   12463                         calculateFCSR(fs, 0, TRUNCLS, True, 1);
   12464                         t0 = newTemp(Ity_I64);
   12465                         assign(t0, binop(Iop_F32toI64S, mkU32(0x3),
   12466                                          getLoFromF64(Ity_F64, getFReg(fs))));
   12467 
   12468                         putDReg(fd, unop(Iop_ReinterpI64asF64, mkexpr(t0)));
   12469                      } else {
   12470                         ILLEGAL_INSTRUCTON;
   12471                      }
   12472                      break;
   12473                   case 0x11:  /* D */
   12474                      DIP("trunc.l.d f%d, f%d", fd, fs);
   12475                      if (fp_mode64) {
   12476                         calculateFCSR(fs, 0, TRUNCLD, False, 1);
   12477                         putDReg(fd, binop(Iop_RoundF64toInt, mkU32(0x3),
   12478                                           getDReg(fs)));
   12479                      } else {
   12480                         ILLEGAL_INSTRUCTON;
   12481                      }
   12482                      break;
   12483                   default:
   12484                      goto decode_failure;
   12485                  }
   12486               break;  /* TRUNC.L.fmt */
   12487 
   12488             case 0x15:  /* RECIP.fmt */
   12489                switch (fmt) {
   12490                   case 0x10: {  /* S */
   12491                      DIP("recip.s f%d, f%d", fd, fs);
   12492                      IRExpr *rm = get_IR_roundingmode();
   12493                      putFReg(fd, mkWidenFromF32(tyF, triop(Iop_DivF32,
   12494                                  rm, unop(Iop_ReinterpI32asF32,
   12495                                  mkU32(ONE_SINGLE)), getLoFromF64(tyF,
   12496                                  getFReg(fs)))));
   12497                      break;
   12498                   }
   12499                   case 0x11: {  /* D */
   12500                      DIP("recip.d f%d, f%d", fd, fs);
   12501                      IRExpr *rm = get_IR_roundingmode();
   12502                      /* putDReg(fd, 1.0/getDreg(fs)); */
   12503                      putDReg(fd, triop(Iop_DivF64, rm,
   12504                                  unop(Iop_ReinterpI64asF64,
   12505                                  mkU64(ONE_DOUBLE)), getDReg(fs)));
   12506                      break;
   12507                   }
   12508                default:
   12509                   goto decode_failure;
   12510 
   12511                }
   12512                break;  /* case 0x15 */
   12513 
   12514             case 0x13:  /* MOVN.fmt */
   12515                switch (fmt) {
   12516                case 0x10:  /* S */
   12517                   DIP("movn.s f%d, f%d, r%d", fd, fs, rt);
   12518                   t1 = newTemp(Ity_F64);
   12519                   t2 = newTemp(Ity_F64);
   12520                   t3 = newTemp(Ity_I1);
   12521                   t4 = newTemp(Ity_F64);
   12522                   if (mode64) {
   12523                      assign(t1, getFReg(fs));
   12524                      assign(t2, getFReg(fd));
   12525                      assign(t3, binop(Iop_CmpNE64, mkU64(0), getIReg(rt)));
   12526                   } else {
   12527                      if (fp_mode64) {
   12528                         assign(t1, getFReg(fs));
   12529                         assign(t2, getFReg(fd));
   12530                         assign(t3, binop(Iop_CmpNE32, mkU32(0), getIReg(rt)));
   12531                      } else {
   12532                         assign(t1, unop(Iop_F32toF64, getFReg(fs)));
   12533                         assign(t2, unop(Iop_F32toF64, getFReg(fd)));
   12534                         assign(t3, binop(Iop_CmpNE32, mkU32(0), getIReg(rt)));
   12535                      }
   12536                   }
   12537 
   12538                   assign(t4, IRExpr_ITE(mkexpr(t3), mkexpr(t1), mkexpr(t2)));
   12539                   if (fp_mode64) {
   12540                      IRTemp f = newTemp(Ity_F64);
   12541                      IRTemp fd_hi = newTemp(Ity_I32);
   12542                      t5 = newTemp(Ity_I64);
   12543                      assign(f, getFReg(fd));
   12544                      assign(fd_hi, unop(Iop_64HIto32, unop(Iop_ReinterpF64asI64,
   12545                                         mkexpr(f))));
   12546 
   12547                      assign(t5, mkWidenFrom32(Ity_I64, unop(Iop_64to32,
   12548                                 unop(Iop_ReinterpF64asI64, mkexpr(t4))), True));
   12549 
   12550                      putFReg(fd, unop (Iop_ReinterpI64asF64, mkexpr(t5)));
   12551                   } else
   12552                      putFReg(fd, binop(Iop_F64toF32, get_IR_roundingmode(),
   12553                                        mkexpr(t4)));
   12554                   break;
   12555                case 0x11:  /* D */
   12556                   DIP("movn.d f%d, f%d, r%d", fd, fs, rt);
   12557 
   12558                   t3 = newTemp(Ity_I1);
   12559                   t4 = newTemp(Ity_F64);
   12560 
   12561                   if (mode64)
   12562                      assign(t3, binop(Iop_CmpNE64, mkU64(0), getIReg(rt)));
   12563                   else
   12564                      assign(t3, binop(Iop_CmpNE32, mkU32(0), getIReg(rt)));
   12565 
   12566                   putDReg(fd, IRExpr_ITE(mkexpr(t3), getDReg(fs), getDReg(fd)));
   12567                   break;
   12568                default:
   12569                   goto decode_failure;
   12570                }
   12571                break;  /* MOVN.fmt */
   12572 
   12573             case 0x12:  /* MOVZ.fmt */
   12574                switch (fmt) {
   12575                case 0x10:  /* S */
   12576                   DIP("movz.s f%d, f%d, r%d", fd, fs, rt);
   12577 
   12578                   t1 = newTemp(Ity_F64);
   12579                   t2 = newTemp(Ity_F64);
   12580                   t3 = newTemp(Ity_I1);
   12581                   t4 = newTemp(Ity_F64);
   12582                   if (fp_mode64) {
   12583                      assign(t1, getFReg(fs));
   12584                      assign(t2, getFReg(fd));
   12585                      if (mode64)
   12586                         assign(t3, binop(Iop_CmpEQ64, mkU64(0), getIReg(rt)));
   12587                      else
   12588                         assign(t3, binop(Iop_CmpEQ32, mkU32(0), getIReg(rt)));
   12589                   } else {
   12590                      assign(t1, unop(Iop_F32toF64, getFReg(fs)));
   12591                      assign(t2, unop(Iop_F32toF64, getFReg(fd)));
   12592                      assign(t3, binop(Iop_CmpEQ32, mkU32(0), getIReg(rt)));
   12593                   }
   12594                   assign(t4, IRExpr_ITE(mkexpr(t3), mkexpr(t1), mkexpr(t2)));
   12595 
   12596                  if (fp_mode64) {
   12597                      IRTemp f = newTemp(Ity_F64);
   12598                      IRTemp fd_hi = newTemp(Ity_I32);
   12599                      t7 = newTemp(Ity_I64);
   12600                      assign(f, getFReg(fd));
   12601                      assign(fd_hi, unop(Iop_64HIto32,
   12602                                    unop(Iop_ReinterpF64asI64, mkexpr(f))));
   12603                      assign(t7, mkWidenFrom32(Ity_I64, unop(Iop_64to32,
   12604                                 unop(Iop_ReinterpF64asI64, mkexpr(t4))), True));
   12605 
   12606                      putFReg(fd, unop(Iop_ReinterpI64asF64, mkexpr(t7)));
   12607                   } else
   12608                      putFReg(fd, binop(Iop_F64toF32, get_IR_roundingmode(),
   12609                                        mkexpr(t4)));
   12610 
   12611                   break;
   12612                case 0x11:  /* D */
   12613                   DIP("movz.d f%d, f%d, r%d", fd, fs, rt);
   12614                   t3 = newTemp(Ity_I1);
   12615                   t4 = newTemp(Ity_F64);
   12616                   if (mode64)
   12617                      assign(t3, binop(Iop_CmpEQ64, mkU64(0), getIReg(rt)));
   12618                   else
   12619                      assign(t3, binop(Iop_CmpEQ32, mkU32(0), getIReg(rt)));
   12620 
   12621                   putDReg(fd, IRExpr_ITE(mkexpr(t3), getDReg(fs), getDReg(fd)));
   12622                   break;
   12623                default:
   12624                   goto decode_failure;
   12625                }
   12626                break;  /* MOVZ.fmt */
   12627 
   12628             case 0x11:  /* MOVT.fmt */
   12629                if (tf == 1) {
   12630                   UInt mov_cc = get_mov_cc(cins);
   12631                   switch (fmt) {  /* MOVCF = 010001 */
   12632                   case 0x11:  /* D */
   12633                      DIP("movt.d f%d, f%d, %d", fd, fs, mov_cc);
   12634                      t1 = newTemp(Ity_I1);
   12635                      t2 = newTemp(Ity_I32);
   12636                      t3 = newTemp(Ity_I1);
   12637                      t4 = newTemp(Ity_F64);
   12638 
   12639                      assign(t1, binop(Iop_CmpEQ32, mkU32(0), mkU32(mov_cc)));
   12640                      assign(t2, IRExpr_ITE(mkexpr(t1),
   12641                                            binop(Iop_And32,
   12642                                                  binop(Iop_Shr32, getFCSR(),
   12643                                                        mkU8(23)),
   12644                                                  mkU32(0x1)),
   12645                                            binop(Iop_And32,
   12646                                                  binop(Iop_Shr32, getFCSR(),
   12647                                                        mkU8(24 + mov_cc)),
   12648                                                  mkU32(0x1))
   12649                                            ));
   12650 
   12651                      assign(t3, binop(Iop_CmpEQ32, mkU32(1), mkexpr(t2)));
   12652                      assign(t4, IRExpr_ITE(mkexpr(t3),
   12653                                            getDReg(fs), getDReg(fd)));
   12654                      putDReg(fd, mkexpr(t4));
   12655                      break;
   12656                   case 0x10:  /* S */
   12657                      DIP("movt.s f%d, f%d, %d", fd, fs, mov_cc);
   12658                      t1 = newTemp(Ity_I1);
   12659                      t2 = newTemp(Ity_I32);
   12660                      t3 = newTemp(Ity_I1);
   12661                      t4 = newTemp(Ity_F64);
   12662                      t5 = newTemp(Ity_F64);
   12663                      t6 = newTemp(Ity_F64);
   12664                      t7 = newTemp(Ity_I64);
   12665 
   12666                      if (fp_mode64) {
   12667                         assign(t5, getFReg(fs));
   12668                         assign(t6, getFReg(fd));
   12669                      } else {
   12670                         assign(t5, unop(Iop_F32toF64, getFReg(fs)));
   12671                         assign(t6, unop(Iop_F32toF64, getFReg(fd)));
   12672                      }
   12673 
   12674                      assign(t1, binop(Iop_CmpEQ32, mkU32(0), mkU32(mov_cc)));
   12675                      assign(t2, IRExpr_ITE(mkexpr(t1),
   12676                                            binop(Iop_And32,
   12677                                                  binop(Iop_Shr32, getFCSR(),
   12678                                                        mkU8(23)),
   12679                                                  mkU32(0x1)),
   12680                                            binop(Iop_And32,
   12681                                                  binop(Iop_Shr32, getFCSR(),
   12682                                                        mkU8(24 + mov_cc)),
   12683                                                  mkU32(0x1))
   12684                                            ));
   12685 
   12686                      assign(t3, binop(Iop_CmpEQ32, mkU32(1), mkexpr(t2)));
   12687                      assign(t4, IRExpr_ITE(mkexpr(t3),
   12688                                            mkexpr(t5), mkexpr(t6)));
   12689 
   12690                      if (fp_mode64) {
   12691                         IRTemp f = newTemp(Ity_F64);
   12692                         IRTemp fd_hi = newTemp(Ity_I32);
   12693                         assign(f, getFReg(fd));
   12694                         assign(fd_hi, unop(Iop_64HIto32,
   12695                                       unop(Iop_ReinterpF64asI64, mkexpr(f))));
   12696                         assign(t7, mkWidenFrom32(Ity_I64, unop(Iop_64to32,
   12697                                       unop(Iop_ReinterpF64asI64, mkexpr(t4))),
   12698                                       True));
   12699 
   12700                         putFReg(fd, unop(Iop_ReinterpI64asF64, mkexpr(t7)));
   12701                      } else
   12702                         putFReg(fd, binop(Iop_F64toF32, get_IR_roundingmode(),
   12703                                           mkexpr(t4)));
   12704                      break;
   12705                   default:
   12706                      goto decode_failure;
   12707                   }
   12708                } else if (tf == 0)  /* movf.fmt */
   12709                {
   12710                   UInt mov_cc = get_mov_cc(cins);
   12711                   switch (fmt)  /* MOVCF = 010001 */
   12712                   {
   12713                   case 0x11:  /* D */
   12714                      DIP("movf.d f%d, f%d, %d", fd, fs, mov_cc);
   12715                      t1 = newTemp(Ity_I1);
   12716                      t2 = newTemp(Ity_I32);
   12717                      t3 = newTemp(Ity_I1);
   12718                      t4 = newTemp(Ity_F64);
   12719 
   12720                      assign(t1, binop(Iop_CmpEQ32, mkU32(0), mkU32(mov_cc)));
   12721                      assign(t2, IRExpr_ITE(mkexpr(t1),
   12722                                            binop(Iop_And32,
   12723                                                  binop(Iop_Shr32, getFCSR(),
   12724                                                        mkU8(23)),
   12725                                                  mkU32(0x1)),
   12726                                            binop(Iop_And32,
   12727                                                  binop(Iop_Shr32, getFCSR(),
   12728                                                        mkU8(24 + mov_cc)),
   12729                                                  mkU32(0x1))
   12730                                            ));
   12731 
   12732                      assign(t3, binop(Iop_CmpEQ32, mkU32(0), mkexpr(t2)));
   12733                      assign(t4, IRExpr_ITE(mkexpr(t3),
   12734                                            getDReg(fs), getDReg(fd)));
   12735                      putDReg(fd, mkexpr(t4));
   12736                      break;
   12737                   case 0x10:  /* S */
   12738                      DIP("movf.s f%d, f%d, %d", fd, fs, mov_cc);
   12739                      t1 = newTemp(Ity_I1);
   12740                      t2 = newTemp(Ity_I32);
   12741                      t3 = newTemp(Ity_I1);
   12742                      t4 = newTemp(Ity_F64);
   12743                      t5 = newTemp(Ity_F64);
   12744                      t6 = newTemp(Ity_F64);
   12745 
   12746                      if (fp_mode64) {
   12747                         assign(t5, getFReg(fs));
   12748                         assign(t6, getFReg(fd));
   12749                      } else {
   12750                         assign(t5, unop(Iop_F32toF64, getFReg(fs)));
   12751                         assign(t6, unop(Iop_F32toF64, getFReg(fd)));
   12752                      }
   12753 
   12754                      assign(t1, binop(Iop_CmpEQ32, mkU32(0), mkU32(mov_cc)));
   12755                      assign(t2, IRExpr_ITE(mkexpr(t1),
   12756                                            binop(Iop_And32,
   12757                                                  binop(Iop_Shr32, getFCSR(),
   12758                                                        mkU8(23)),
   12759                                                  mkU32(0x1)),
   12760                                            binop(Iop_And32,
   12761                                                  binop(Iop_Shr32, getFCSR(),
   12762                                                        mkU8(24 + mov_cc)),
   12763                                                  mkU32(0x1))
   12764                                            ));
   12765 
   12766                      assign(t3, binop(Iop_CmpEQ32, mkU32(0), mkexpr(t2)));
   12767                      assign(t4, IRExpr_ITE(mkexpr(t3),
   12768                                            mkexpr(t5), mkexpr(t6)));
   12769 
   12770                      if (fp_mode64) {
   12771                         IRTemp f = newTemp(Ity_F64);
   12772                         IRTemp fd_hi = newTemp(Ity_I32);
   12773                         t7 = newTemp(Ity_I64);
   12774                         assign(f, getFReg(fd));
   12775                         assign(fd_hi, unop(Iop_64HIto32,
   12776                                       unop(Iop_ReinterpF64asI64, mkexpr(f))));
   12777                         assign(t7, mkWidenFrom32(Ity_I64, unop(Iop_64to32,
   12778                                    unop(Iop_ReinterpF64asI64, mkexpr(t4))),
   12779                                    True));
   12780 
   12781                         putFReg(fd, unop(Iop_ReinterpI64asF64, mkexpr(t7)));
   12782                      } else
   12783                         putFReg(fd, binop(Iop_F64toF32, get_IR_roundingmode(),
   12784                                           mkexpr(t4)));
   12785                      break;
   12786                   default:
   12787                      goto decode_failure;
   12788                   }
   12789                }
   12790 
   12791                break;  /* MOVT.fmt */
   12792 
   12793             case 0x0:  /* add.fmt */
   12794                switch (fmt) {
   12795                case 0x10: {  /* S */
   12796                   DIP("add.s f%d, f%d, f%d", fd, fs, ft);
   12797                   calculateFCSR(fs, ft, ADDS, True, 2);
   12798                   IRExpr *rm = get_IR_roundingmode();
   12799                   putFReg(fd, mkWidenFromF32(tyF, triop(Iop_AddF32, rm,
   12800                               getLoFromF64(tyF, getFReg(fs)),
   12801                               getLoFromF64(tyF, getFReg(ft)))));
   12802                   break;
   12803                }
   12804                case 0x11: {  /* D */
   12805                   DIP("add.d f%d, f%d, f%d", fd, fs, ft);
   12806                   calculateFCSR(fs, ft, ADDD, False, 2);
   12807                   IRExpr *rm = get_IR_roundingmode();
   12808                   putDReg(fd, triop(Iop_AddF64, rm, getDReg(fs), getDReg(ft)));
   12809                   break;
   12810                }
   12811 
   12812                case 0x4:  /* MTC1 (Move Word to Floating Point) */
   12813                   DIP("mtc1 r%d, f%d", rt, fs);
   12814                   if (fp_mode64) {
   12815                      t0 = newTemp(Ity_I32);
   12816                      t1 = newTemp(Ity_F32);
   12817                      assign(t0, mkNarrowTo32(ty, getIReg(rt)));
   12818                      assign(t1, unop(Iop_ReinterpI32asF32, mkexpr(t0)));
   12819 
   12820                      putFReg(fs, mkWidenFromF32(tyF, mkexpr(t1)));
   12821                   } else
   12822                      putFReg(fs, unop(Iop_ReinterpI32asF32, getIReg(rt)));
   12823                   break;
   12824 
   12825                case 0x5:  /* Doubleword Move to Floating Point DMTC1; MIPS64 */
   12826                   DIP("dmtc1 r%d, f%d", rt, fs);
   12827                   vassert(mode64);
   12828                   putFReg(fs, unop(Iop_ReinterpI64asF64, getIReg(rt)));
   12829                   break;
   12830 
   12831                case 0x0:  /* MFC1 */
   12832                   DIP("mfc1 r%d, f%d", rt, fs);
   12833                   if (fp_mode64) {
   12834                      t0 = newTemp(Ity_I64);
   12835                      t1 = newTemp(Ity_I32);
   12836                      assign(t0, unop(Iop_ReinterpF64asI64, getFReg(fs)));
   12837                      assign(t1, unop(Iop_64to32, mkexpr(t0)));
   12838                      putIReg(rt, mkWidenFrom32(ty, mkexpr(t1), True));
   12839                   } else
   12840                      putIReg(rt, unop(Iop_ReinterpF32asI32, getFReg(fs)));
   12841                   break;
   12842 
   12843                case 0x1:  /* Doubleword Move from Floating Point DMFC1;
   12844                              MIPS64 */
   12845                   DIP("dmfc1 r%d, f%d", rt, fs);
   12846                   putIReg(rt, unop(Iop_ReinterpF64asI64, getFReg(fs)));
   12847                   break;
   12848 
   12849                case 0x6:  /* CTC1 */
   12850                   DIP("ctc1 r%d, f%d", rt, fs);
   12851                   t0 = newTemp(Ity_I32);
   12852                   t1 = newTemp(Ity_I32);
   12853                   t2 = newTemp(Ity_I32);
   12854                   t3 = newTemp(Ity_I32);
   12855                   t4 = newTemp(Ity_I32);
   12856                   t5 = newTemp(Ity_I32);
   12857                   t6 = newTemp(Ity_I32);
   12858                   assign(t0, mkNarrowTo32(ty, getIReg(rt)));
   12859                   if (fs == 25) {  /* FCCR */
   12860                      assign(t1, binop(Iop_Shl32, binop(Iop_And32, mkexpr(t0),
   12861                                       mkU32(0x000000FE)), mkU8(24)));
   12862                      assign(t2, binop(Iop_And32, mkexpr(t0),
   12863                                       mkU32(0x01000000)));
   12864                      assign(t3, binop(Iop_Shl32, binop(Iop_And32, mkexpr(t0),
   12865                                       mkU32(0x00000001)), mkU8(23)));
   12866                      assign(t4, binop(Iop_And32, mkexpr(t0),
   12867                                       mkU32(0x007FFFFF)));
   12868                      putFCSR(binop(Iop_Or32, binop(Iop_Or32, mkexpr(t1),
   12869                                    mkexpr(t2)), binop(Iop_Or32, mkexpr(t3),
   12870                                    mkexpr(t4))));
   12871                   } else if (fs == 26) {  /* FEXR */
   12872                      assign(t1, binop(Iop_And32, getFCSR(), mkU32(0xFFFC0000)));
   12873                      assign(t2, binop(Iop_And32, mkexpr(t0),
   12874                                       mkU32(0x0003F000)));
   12875                      assign(t3, binop(Iop_And32, getFCSR(), mkU32(0x00000F80)));
   12876                      assign(t4, binop(Iop_And32, mkexpr(t0),
   12877                                       mkU32(0x0000007C)));
   12878                      assign(t5, binop(Iop_And32, getFCSR(), mkU32(0x00000003)));
   12879                      putFCSR(binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Or32,
   12880                                    mkexpr(t1), mkexpr(t2)), binop(Iop_Or32,
   12881                                    mkexpr(t3), mkexpr(t4))), mkexpr(t5)));
   12882                   } else if (fs == 28) {
   12883                      assign(t1, binop(Iop_And32, getFCSR(), mkU32(0xFE000000)));
   12884                      assign(t2, binop(Iop_Shl32, binop(Iop_And32, mkexpr(t0),
   12885                                 mkU32(0x00000002)), mkU8(22)));
   12886                      assign(t3, binop(Iop_And32, getFCSR(), mkU32(0x00FFF000)));
   12887                      assign(t4, binop(Iop_And32, mkexpr(t0),
   12888                                 mkU32(0x00000F80)));
   12889                      assign(t5, binop(Iop_And32, getFCSR(), mkU32(0x0000007C)));
   12890                      assign(t6, binop(Iop_And32, mkexpr(t0),
   12891                                 mkU32(0x00000003)));
   12892                      putFCSR(binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Or32,
   12893                                    mkexpr(t1), mkexpr(t2)), binop(Iop_Or32,
   12894                                    mkexpr(t3), mkexpr(t4))), binop(Iop_Or32,
   12895                                    mkexpr(t5), mkexpr(t6))));
   12896                   } else if (fs == 31) {
   12897                      putFCSR(mkexpr(t0));
   12898                   }
   12899                   break;
   12900                case 0x2:  /* CFC1 */
   12901                   DIP("cfc1 r%d, f%d", rt, fs);
   12902                   t0 = newTemp(Ity_I32);
   12903                   t1 = newTemp(Ity_I32);
   12904                   t2 = newTemp(Ity_I32);
   12905                   t3 = newTemp(Ity_I32);
   12906                   t4 = newTemp(Ity_I32);
   12907                   t5 = newTemp(Ity_I32);
   12908                   t6 = newTemp(Ity_I32);
   12909                   assign(t0, getFCSR());
   12910                   if (fs == 0) {
   12911                      putIReg(rt, mkWidenFrom32(ty,
   12912                              IRExpr_Get(offsetof(VexGuestMIPS32State,
   12913                                                  guest_FIR),
   12914                                        Ity_I32),
   12915                              False));
   12916                   } else if (fs == 25) {
   12917                      assign(t1, mkU32(0x000000FF));
   12918                      assign(t2, binop(Iop_Shr32, binop(Iop_And32, mkexpr(t0),
   12919                                       mkU32(0xFE000000)), mkU8(25)));
   12920                      assign(t3, binop(Iop_Shr32, binop(Iop_And32, mkexpr(t0),
   12921                                       mkU32(0x00800000)), mkU8(23)));
   12922                      putIReg(rt, mkWidenFrom32(ty, binop(Iop_Or32,
   12923                                  binop(Iop_Or32, mkexpr(t1), mkexpr(t2)),
   12924                                  mkexpr(t3)), False));
   12925                   } else if (fs == 26) {
   12926                      assign(t1, mkU32(0xFFFFF07C));
   12927                      assign(t2, binop(Iop_And32, mkexpr(t0),
   12928                                 mkU32(0x0003F000)));
   12929                      assign(t3, binop(Iop_And32, mkexpr(t0),
   12930                                       mkU32(0x0000007C)));
   12931                      putIReg(rt, mkWidenFrom32(ty, binop(Iop_Or32,
   12932                                  binop(Iop_Or32, mkexpr(t1), mkexpr(t2)),
   12933                                  mkexpr(t3)), False));
   12934                   } else if (fs == 28) {
   12935                      assign(t1, mkU32(0x00000F87));
   12936                      assign(t2, binop(Iop_And32, mkexpr(t0),
   12937                                       mkU32(0x00000F83)));
   12938                      assign(t3, binop(Iop_Shr32, binop(Iop_And32, mkexpr(t0),
   12939                                       mkU32(0x01000000)), mkU8(22)));
   12940                      putIReg(rt, mkWidenFrom32(ty, binop(Iop_Or32,
   12941                                  binop(Iop_Or32, mkexpr(t1), mkexpr(t2)),
   12942                                  mkexpr(t3)), False));
   12943                   } else if (fs == 31) {
   12944                      putIReg(rt, mkWidenFrom32(ty, getFCSR(), False));
   12945                   }
   12946                   break;
   12947                default:
   12948                   goto decode_failure;
   12949                }
   12950                break;
   12951 
   12952             case 0x21:  /* CVT.D */
   12953                switch (fmt) {
   12954                   case 0x10:  /* S */
   12955                      DIP("cvt.d.s f%d, f%d", fd, fs);
   12956                      calculateFCSR(fs, 0, CVTDS, True, 1);
   12957                      if (fp_mode64) {
   12958                         t0 = newTemp(Ity_I64);
   12959                         t1 = newTemp(Ity_I32);
   12960                         t3 = newTemp(Ity_F32);
   12961                         t4 = newTemp(Ity_F32);
   12962                         /* get lo half of FPR */
   12963                         assign(t0, unop(Iop_ReinterpF64asI64, getFReg(fs)));
   12964 
   12965                         assign(t1, unop(Iop_64to32, mkexpr(t0)));
   12966 
   12967                         assign(t3, unop(Iop_ReinterpI32asF32, mkexpr(t1)));
   12968 
   12969                         putFReg(fd, unop(Iop_F32toF64, mkexpr(t3)));
   12970                      } else
   12971                         putDReg(fd, unop(Iop_F32toF64, getFReg(fs)));
   12972                      break;
   12973 
   12974                   case 0x14:
   12975                      DIP("cvt.d.w %d, %d", fd, fs);
   12976                      calculateFCSR(fs, 0, CVTDW, True, 1);
   12977                      if (fp_mode64) {
   12978                         t0 = newTemp(Ity_I64);
   12979                         t1 = newTemp(Ity_I32);
   12980                         t3 = newTemp(Ity_F32);
   12981                         t4 = newTemp(Ity_F32);
   12982                         /* get lo half of FPR */
   12983                         assign(t0, unop(Iop_ReinterpF64asI64, getFReg(fs)));
   12984 
   12985                         assign(t1, unop(Iop_64to32, mkexpr(t0)));
   12986                         putDReg(fd,unop(Iop_I32StoF64, mkexpr(t1)));
   12987                         break;
   12988                      } else {
   12989                         t0 = newTemp(Ity_I32);
   12990                         assign(t0, unop(Iop_ReinterpF32asI32, getFReg(fs)));
   12991                         putDReg(fd, unop(Iop_I32StoF64, mkexpr(t0)));
   12992                         break;
   12993                      }
   12994 
   12995                   case 0x15: {  /* L */
   12996                      if (fp_mode64) {
   12997                         DIP("cvt.d.l %d, %d", fd, fs);
   12998                         calculateFCSR(fs, 0, CVTDL, False, 1);
   12999                         t0 = newTemp(Ity_I64);
   13000                         assign(t0, unop(Iop_ReinterpF64asI64, getFReg(fs)));
   13001 
   13002                         putFReg(fd, binop(Iop_I64StoF64,
   13003                                           get_IR_roundingmode(), mkexpr(t0)));
   13004                         break;
   13005                      } else
   13006                         goto decode_failure;
   13007                   }
   13008                   default:
   13009                      goto decode_failure;
   13010                }
   13011                break;  /* CVT.D */
   13012 
   13013             case 0x20:  /* cvt.s */
   13014                switch (fmt) {
   13015                   case 0x14:  /* W */
   13016                      DIP("cvt.s.w %d, %d", fd, fs);
   13017                      calculateFCSR(fs, 0, CVTSW, True, 1);
   13018                      if (fp_mode64) {
   13019                         t0 = newTemp(Ity_I64);
   13020                         t1 = newTemp(Ity_I32);
   13021                         t3 = newTemp(Ity_F32);
   13022                         t4 = newTemp(Ity_F32);
   13023                         /* get lo half of FPR */
   13024                         assign(t0, unop(Iop_ReinterpF64asI64, getFReg(fs)));
   13025 
   13026                         assign(t1, unop(Iop_64to32, mkexpr(t0)));
   13027                         putFReg(fd, mkWidenFromF32(tyF, binop(Iop_I32StoF32,
   13028                                     get_IR_roundingmode(), mkexpr(t1))));
   13029                      } else {
   13030                         t0 = newTemp(Ity_I32);
   13031                         assign(t0, unop(Iop_ReinterpF32asI32, getFReg(fs)));
   13032                         putFReg(fd, binop(Iop_I32StoF32, get_IR_roundingmode(),
   13033                                     mkexpr(t0)));
   13034                      }
   13035                      break;
   13036 
   13037                   case 0x11:  /* D */
   13038                      DIP("cvt.s.d %d, %d", fd, fs);
   13039                      calculateFCSR(fs, 0, CVTSD, False, 1);
   13040                      t0 = newTemp(Ity_F32);
   13041                      assign(t0, binop(Iop_F64toF32, get_IR_roundingmode(),
   13042                                       getDReg(fs)));
   13043                      putFReg(fd, mkWidenFromF32(tyF, mkexpr(t0)));
   13044                      break;
   13045 
   13046                   case 0x15:  /* L */
   13047                      DIP("cvt.s.l %d, %d", fd, fs);
   13048                      calculateFCSR(fs, 0, CVTSL, False, 1);
   13049                      t0 = newTemp(Ity_I64);
   13050                      assign(t0, unop(Iop_ReinterpF64asI64, getFReg(fs)));
   13051 
   13052                      putFReg(fd, mkWidenFromF32(tyF, binop(Iop_I64StoF32,
   13053                                  get_IR_roundingmode(), mkexpr(t0))));
   13054                      break;
   13055 
   13056                   default:
   13057                      goto decode_failure;
   13058                }
   13059                break;  /* cvt.s */
   13060 
   13061             case 0x24:  /* cvt.w */
   13062                switch (fmt) {
   13063                case 0x10:  /* S */
   13064                   DIP("cvt.w.s %d, %d", fd, fs);
   13065                   calculateFCSR(fs, 0, CVTWS, True, 1);
   13066                   putFReg(fd,
   13067                           mkWidenFromF32(tyF,
   13068                                          binop(Iop_RoundF32toInt,
   13069                                                get_IR_roundingmode(),
   13070                                                getLoFromF64(tyF, getFReg(fs))))
   13071                          );
   13072                   break;
   13073 
   13074                case 0x11:
   13075                   DIP("cvt.w.d %d, %d", fd, fs);
   13076                   calculateFCSR(fs, 0, CVTWD, False, 1);
   13077                   t0 = newTemp(Ity_I32);
   13078                   t1 = newTemp(Ity_F32);
   13079                   assign(t0, binop(Iop_F64toI32S, get_IR_roundingmode(),
   13080                                    getDReg(fs)));
   13081                   assign(t1, unop(Iop_ReinterpI32asF32, mkexpr(t0)));
   13082                   putFReg(fd, mkWidenFromF32(tyF, mkexpr(t1)));
   13083                   break;
   13084 
   13085                default:
   13086                   goto decode_failure;
   13087 
   13088                }
   13089                break;
   13090 
   13091             case 0x25:  /* cvt.l */
   13092                switch (fmt) {
   13093                   case 0x10:  /* S */
   13094                      DIP("cvt.l.s %d, %d", fd, fs);
   13095                      if (fp_mode64) {
   13096                         calculateFCSR(fs, 0, CVTLS, True, 1);
   13097                         t0 = newTemp(Ity_I64);
   13098 
   13099                         assign(t0, binop(Iop_F32toI64S, get_IR_roundingmode(),
   13100                                          getLoFromF64(tyF, getFReg(fs))));
   13101 
   13102                         putDReg(fd, unop(Iop_ReinterpI64asF64, mkexpr(t0)));
   13103                      } else {
   13104                         ILLEGAL_INSTRUCTON;
   13105                      }
   13106                      break;
   13107 
   13108                   case 0x11: {  /* D */
   13109                      DIP("cvt.l.d %d, %d", fd, fs);
   13110                      if (fp_mode64) {
   13111                         calculateFCSR(fs, 0, CVTLD, False, 1);
   13112                         putDReg(fd, binop(Iop_RoundF64toInt,
   13113                                 get_IR_roundingmode(), getDReg(fs)));
   13114                      } else {
   13115                         ILLEGAL_INSTRUCTON;
   13116                      }
   13117                      break;
   13118                   }
   13119 
   13120                   default:
   13121                      goto decode_failure;
   13122                }
   13123                break;
   13124 
   13125             case 0x0B:  /* FLOOR.L.fmt */
   13126                switch (fmt) {
   13127                   case 0x10:  /* S */
   13128                      DIP("floor.l.s %d, %d", fd, fs);
   13129                      if (fp_mode64) {
   13130                         calculateFCSR(fs, 0, FLOORLS, True, 1);
   13131                         t0 = newTemp(Ity_I64);
   13132 
   13133                         assign(t0, binop(Iop_F32toI64S, mkU32(0x1),
   13134                                          getLoFromF64(tyF, getFReg(fs))));
   13135 
   13136                         putDReg(fd, unop(Iop_ReinterpI64asF64, mkexpr(t0)));
   13137                      } else {
   13138                         ILLEGAL_INSTRUCTON;
   13139                      }
   13140                      break;
   13141 
   13142                   case 0x11:  /* D */
   13143                      DIP("floor.l.d %d, %d", fd, fs);
   13144                      if (fp_mode64) {
   13145                         calculateFCSR(fs, 0, FLOORLD, False, 1);
   13146                         putDReg(fd, binop(Iop_RoundF64toInt, mkU32(0x1),
   13147                                           getDReg(fs)));
   13148                      } else {
   13149                         ILLEGAL_INSTRUCTON;
   13150                      }
   13151                      break;
   13152                   default:
   13153                      goto decode_failure;
   13154                }
   13155                break;
   13156 
   13157             case 0x0C:  /* ROUND.W.fmt */
   13158                switch (fmt) {
   13159                   case 0x10:  /* S */
   13160                      DIP("round.w.s f%d, f%d", fd, fs);
   13161                      calculateFCSR(fs, 0, ROUNDWS, True, 1);
   13162                      if (fp_mode64) {
   13163                         t0 = newTemp(Ity_I64);
   13164                         t1 = newTemp(Ity_I32);
   13165                         t3 = newTemp(Ity_F32);
   13166                         t4 = newTemp(Ity_F32);
   13167                         /* get lo half of FPR */
   13168                         assign(t0, unop(Iop_ReinterpF64asI64, getFReg(fs)));
   13169 
   13170                         assign(t1, unop(Iop_64to32, mkexpr(t0)));
   13171 
   13172                         assign(t3, unop(Iop_ReinterpI32asF32, mkexpr(t1)));
   13173 
   13174                         assign(t4, binop(Iop_RoundF32toInt, mkU32(0x0),
   13175                                          mkexpr(t3)));
   13176 
   13177                         putFReg(fd, mkWidenFromF32(tyF, mkexpr(t4)));
   13178                      } else
   13179                         putFReg(fd, binop(Iop_RoundF32toInt, mkU32(0x0),
   13180                                           getFReg(fs)));
   13181                      break;
   13182 
   13183                   case 0x11:  /* D */
   13184                      DIP("round.w.d f%d, f%d", fd, fs);
   13185                      calculateFCSR(fs, 0, ROUNDWD, False, 1);
   13186                      if (fp_mode64) {
   13187                         t0 = newTemp(Ity_I32);
   13188                         assign(t0, binop(Iop_F64toI32S, mkU32(0x0),
   13189                                          getDReg(fs)));
   13190                         putFReg(fd, mkWidenFromF32(tyF,
   13191                                     unop(Iop_ReinterpI32asF32, mkexpr(t0))));
   13192                      } else {
   13193                         t0 = newTemp(Ity_I32);
   13194 
   13195                         assign(t0, binop(Iop_F64toI32S, mkU32(0x0),
   13196                                          getDReg(fs)));
   13197 
   13198                         putFReg(fd, unop(Iop_ReinterpI32asF32, mkexpr(t0)));
   13199                      }
   13200                      break;
   13201                   default:
   13202                      goto decode_failure;
   13203 
   13204                   }
   13205                   break;  /* ROUND.W.fmt */
   13206 
   13207             case 0x0F:  /* FLOOR.W.fmt */
   13208                switch (fmt) {
   13209                   case 0x10:  /* S */
   13210                      DIP("floor.w.s f%d, f%d", fd, fs);
   13211                      calculateFCSR(fs, 0, FLOORWS, True, 1);
   13212                      if (fp_mode64) {
   13213                         t0 = newTemp(Ity_I64);
   13214                         t1 = newTemp(Ity_I32);
   13215                         t3 = newTemp(Ity_F32);
   13216                         t4 = newTemp(Ity_F32);
   13217                         /* get lo half of FPR */
   13218                         assign(t0, unop(Iop_ReinterpF64asI64, getFReg(fs)));
   13219 
   13220                         assign(t1, unop(Iop_64to32, mkexpr(t0)));
   13221 
   13222                         assign(t3, unop(Iop_ReinterpI32asF32, mkexpr(t1)));
   13223 
   13224                         assign(t4, binop(Iop_RoundF32toInt, mkU32(0x1),
   13225                                          mkexpr(t3)));
   13226 
   13227                         putFReg(fd, mkWidenFromF32(tyF, mkexpr(t4)));
   13228                      } else
   13229                         putFReg(fd, binop(Iop_RoundF32toInt, mkU32(0x1),
   13230                                          getFReg(fs)));
   13231                      break;
   13232 
   13233                   case 0x11:  /* D */
   13234                      DIP("floor.w.d f%d, f%d", fd, fs);
   13235                      calculateFCSR(fs, 0, FLOORWD, False, 1);
   13236                      if (fp_mode64) {
   13237                         t0 = newTemp(Ity_I32);
   13238                         assign(t0, binop(Iop_F64toI32S, mkU32(0x1),
   13239                                          getDReg(fs)));
   13240                         putFReg(fd, mkWidenFromF32(tyF,
   13241                                     unop(Iop_ReinterpI32asF32, mkexpr(t0))));
   13242                         break;
   13243                      } else {
   13244                         t0 = newTemp(Ity_I32);
   13245 
   13246                         assign(t0, binop(Iop_F64toI32S, mkU32(0x1),
   13247                                          getDReg(fs)));
   13248 
   13249                         putFReg(fd, unop(Iop_ReinterpI32asF32, mkexpr(t0)));
   13250                         break;
   13251                      }
   13252                   default:
   13253                      goto decode_failure;
   13254 
   13255                }
   13256                break;  /* FLOOR.W.fmt */
   13257 
   13258             case 0x0D:  /* TRUNC.W */
   13259                switch (fmt) {
   13260                   case 0x10:  /* S */
   13261                      DIP("trunc.w.s %d, %d", fd, fs);
   13262                      calculateFCSR(fs, 0, TRUNCWS, True, 1);
   13263                      if (fp_mode64) {
   13264                         t0 = newTemp(Ity_I64);
   13265                         t1 = newTemp(Ity_I32);
   13266                         t3 = newTemp(Ity_F32);
   13267                         t4 = newTemp(Ity_F32);
   13268                         /* get lo half of FPR */
   13269                         assign(t0, unop(Iop_ReinterpF64asI64, getFReg(fs)));
   13270 
   13271                         assign(t1, unop(Iop_64to32, mkexpr(t0)));
   13272 
   13273                         assign(t3, unop(Iop_ReinterpI32asF32, mkexpr(t1)));
   13274 
   13275                         assign(t4, binop(Iop_RoundF32toInt, mkU32(0x3),
   13276                                          mkexpr(t3)));
   13277 
   13278                         putFReg(fd, mkWidenFromF32(tyF, mkexpr(t4)));
   13279                      } else
   13280                         putFReg(fd, binop(Iop_RoundF32toInt, mkU32(0x3),
   13281                                        getFReg(fs)));
   13282                      break;
   13283                   case 0x11:  /* D */
   13284                      DIP("trunc.w.d %d, %d", fd, fs);
   13285                      calculateFCSR(fs, 0, TRUNCWD, False, 1);
   13286                      if (fp_mode64) {
   13287                         t0 = newTemp(Ity_I32);
   13288 
   13289                         assign(t0, binop(Iop_F64toI32S, mkU32(0x3),
   13290                                          getFReg(fs)));
   13291 
   13292                         putFReg(fd, mkWidenFromF32(tyF,
   13293                                     unop(Iop_ReinterpI32asF32, mkexpr(t0))));
   13294                      } else {
   13295                         t0 = newTemp(Ity_I32);
   13296 
   13297                         assign(t0, binop(Iop_F64toI32S, mkU32(0x3),
   13298                                          getDReg(fs)));
   13299 
   13300                         putFReg(fd, unop(Iop_ReinterpI32asF32, mkexpr(t0)));
   13301                      }
   13302                      break;
   13303                   default:
   13304                      goto decode_failure;
   13305 
   13306                }
   13307                break;
   13308 
   13309             case 0x0E:  /* CEIL.W.fmt */
   13310                switch (fmt) {
   13311                   case 0x10:  /* S */
   13312                      DIP("ceil.w.s %d, %d", fd, fs);
   13313                      calculateFCSR(fs, 0, CEILWS, True, 1);
   13314                      if (fp_mode64) {
   13315                         t0 = newTemp(Ity_I64);
   13316                         t1 = newTemp(Ity_I32);
   13317                         t3 = newTemp(Ity_F32);
   13318                         t4 = newTemp(Ity_F32);
   13319                         /* get lo half of FPR */
   13320                         assign(t0, unop(Iop_ReinterpF64asI64, getFReg(fs)));
   13321 
   13322                         assign(t1, unop(Iop_64to32, mkexpr(t0)));
   13323 
   13324                         assign(t3, unop(Iop_ReinterpI32asF32, mkexpr(t1)));
   13325 
   13326                         assign(t4, binop(Iop_RoundF32toInt, mkU32(0x2),
   13327                                          mkexpr(t3)));
   13328 
   13329                         putFReg(fd, mkWidenFromF32(tyF, mkexpr(t4)));
   13330                      } else
   13331                         putFReg(fd, binop(Iop_RoundF32toInt, mkU32(0x2),
   13332                                           getFReg(fs)));
   13333                      break;
   13334 
   13335                   case 0x11:  /* D */
   13336                      DIP("ceil.w.d %d, %d", fd, fs);
   13337                      calculateFCSR(fs, 0, CEILWD, False, 1);
   13338                      if (!fp_mode64) {
   13339                         t0 = newTemp(Ity_I32);
   13340                         assign(t0, binop(Iop_F64toI32S, mkU32(0x2),
   13341                                          getDReg(fs)));
   13342                         putFReg(fd, unop(Iop_ReinterpI32asF32, mkexpr(t0)));
   13343                      } else {
   13344                         t0 = newTemp(Ity_I32);
   13345                         assign(t0, binop(Iop_F64toI32S, mkU32(0x2),
   13346                                          getDReg(fs)));
   13347                         putFReg(fd, mkWidenFromF32(tyF,
   13348                                     unop(Iop_ReinterpI32asF32, mkexpr(t0))));
   13349                      }
   13350                      break;
   13351                   default:
   13352                      goto decode_failure;
   13353 
   13354                }
   13355                break;
   13356 
   13357             case 0x0A:  /* CEIL.L.fmt */
   13358                switch (fmt) {
   13359                   case 0x10:  /* S */
   13360                      DIP("ceil.l.s %d, %d", fd, fs);
   13361                      if (fp_mode64) {
   13362                         calculateFCSR(fs, 0, CEILLS, True, 1);
   13363                         t0 = newTemp(Ity_I64);
   13364 
   13365                         assign(t0, binop(Iop_F32toI64S, mkU32(0x2),
   13366                                    getLoFromF64(tyF, getFReg(fs))));
   13367 
   13368                         putFReg(fd, unop(Iop_ReinterpI64asF64, mkexpr(t0)));
   13369                      } else {
   13370                         ILLEGAL_INSTRUCTON;
   13371                      }
   13372                      break;
   13373 
   13374                   case 0x11:  /* D */
   13375                      DIP("ceil.l.d %d, %d", fd, fs);
   13376                      if (fp_mode64) {
   13377                         calculateFCSR(fs, 0, CEILLD, False, 1);
   13378                         putDReg(fd, binop(Iop_RoundF64toInt, mkU32(0x2),
   13379                                           getDReg(fs)));
   13380                      } else {
   13381                         ILLEGAL_INSTRUCTON;
   13382                      }
   13383                      break;
   13384 
   13385                   default:
   13386                      goto decode_failure;
   13387 
   13388                }
   13389                break;
   13390 
   13391             case 0x16:  /* RSQRT.fmt */
   13392                switch (fmt) {
   13393                   case 0x10: {  /* S */
   13394                      DIP("rsqrt.s %d, %d", fd, fs);
   13395                      IRExpr *rm = get_IR_roundingmode();
   13396                      putFReg(fd, mkWidenFromF32(tyF, triop(Iop_DivF32, rm,
   13397                                  unop(Iop_ReinterpI32asF32, mkU32(ONE_SINGLE)),
   13398                                  binop(Iop_SqrtF32, rm, getLoFromF64(tyF,
   13399                                  getFReg(fs))))));
   13400                      break;
   13401                   }
   13402                   case 0x11: {  /* D */
   13403                      DIP("rsqrt.d %d, %d", fd, fs);
   13404                      IRExpr *rm = get_IR_roundingmode();
   13405                      putDReg(fd, triop(Iop_DivF64, rm,
   13406                                  unop(Iop_ReinterpI64asF64,
   13407                                  mkU64(ONE_DOUBLE)),
   13408                                  binop(Iop_SqrtF64, rm, getDReg(fs))));
   13409                      break;
   13410                   }
   13411                   default:
   13412                      goto decode_failure;
   13413 
   13414                }
   13415                break;
   13416 
   13417             default:
   13418                if (dis_instr_CCondFmt(cins))
   13419                   break;
   13420                goto decode_failure;
   13421 
   13422             }
   13423 
   13424          }
   13425       }
   13426       break;  /* COP1 */
   13427    case 0x10:  /* COP0 */
   13428       if (rs == 0) {  /* MFC0 */
   13429          DIP("mfc0 r%d, r%d, %d", rt, rd, sel);
   13430          IRTemp   val  = newTemp(Ity_I32);
   13431          IRExpr** args = mkIRExprVec_3 (IRExpr_BBPTR(), mkU32(rd), mkU32(sel));
   13432          IRDirty *d = unsafeIRDirty_1_N(val,
   13433                                         0,
   13434                                         "mips32_dirtyhelper_mfc0",
   13435                                         &mips32_dirtyhelper_mfc0,
   13436                                         args);
   13437          stmt(IRStmt_Dirty(d));
   13438          putIReg(rt, mkexpr(val));
   13439       } else if (rs == 1) {
   13440          /* Doubleword Move from Coprocessor 0 - DMFC0; MIPS64 */
   13441          DIP("dmfc0 r%d, r%d, %d", rt, rd, sel);
   13442          IRTemp   val  = newTemp(Ity_I64);
   13443          IRExpr** args = mkIRExprVec_3 (IRExpr_BBPTR(), mkU64(rd), mkU64(sel));
   13444          IRDirty *d = unsafeIRDirty_1_N(val,
   13445                                         0,
   13446                                         "mips64_dirtyhelper_dmfc0",
   13447                                         &mips64_dirtyhelper_dmfc0,
   13448                                         args);
   13449          stmt(IRStmt_Dirty(d));
   13450          putDReg(rt, mkexpr(val));
   13451       } else
   13452          goto decode_failure;
   13453       break;
   13454 
   13455    case 0x31:  /* LWC1 */
   13456       /* Load Word to Floating Point - LWC1 (MIPS32) */
   13457       DIP("lwc1 f%d, %d(r%d)", ft, imm, rs);
   13458       if (fp_mode64) {
   13459          t1 = newTemp(Ity_F32);
   13460          t2 = newTemp(Ity_I64);
   13461          if (mode64) {
   13462             t0 = newTemp(Ity_I64);
   13463             /* new LO */
   13464             assign(t0, binop(Iop_Add64, getIReg(rs),
   13465                              mkU64(extend_s_16to64(imm))));
   13466          } else {
   13467             t0 = newTemp(Ity_I32);
   13468             /* new LO */
   13469             assign(t0, binop(Iop_Add32, getIReg(rs),
   13470                              mkU32(extend_s_16to32(imm))));
   13471          }
   13472          assign(t1, load(Ity_F32, mkexpr(t0)));
   13473          assign(t2, mkWidenFrom32(Ity_I64, unop(Iop_ReinterpF32asI32,
   13474                                                 mkexpr(t1)), True));
   13475          putDReg(ft, unop(Iop_ReinterpI64asF64, mkexpr(t2)));
   13476       } else {
   13477          t0 = newTemp(Ity_I32);
   13478          assign(t0, binop(Iop_Add32, getIReg(rs),
   13479                            mkU32(extend_s_16to32(imm))));
   13480          putFReg(ft, load(Ity_F32, mkexpr(t0)));
   13481       }
   13482       break;
   13483 
   13484    case 0x39:  /* SWC1 */
   13485       DIP("swc1 f%d, %d(r%d)", ft, imm, rs);
   13486       if (fp_mode64) {
   13487          t0 = newTemp(Ity_I64);
   13488          t2 = newTemp(Ity_I32);
   13489          LOAD_STORE_PATTERN;
   13490          assign(t0, unop(Iop_ReinterpF64asI64, getFReg(ft)));
   13491          assign(t2, unop(Iop_64to32, mkexpr(t0)));
   13492          store(mkexpr(t1), unop(Iop_ReinterpI32asF32, mkexpr(t2)));
   13493       } else {
   13494          LOAD_STORE_PATTERN;
   13495          store(mkexpr(t1), getFReg(ft));
   13496       }
   13497       break;
   13498 
   13499    case 0x33:  /* PREF */
   13500       DIP("pref");
   13501       break;
   13502 
   13503    case 0x35:
   13504       /* Load Doubleword to Floating Point - LDC1 (MIPS32) */
   13505       DIP("ldc1 f%d, %d(%d)", rt, imm, rs);
   13506       LOAD_STORE_PATTERN;
   13507       putDReg(ft, load(Ity_F64, mkexpr(t1)));
   13508       break;
   13509 
   13510    case 0x3D:
   13511       /* Store Doubleword from Floating Point - SDC1 */
   13512       DIP("sdc1 f%d, %d(%d)", ft, imm, rs);
   13513       LOAD_STORE_PATTERN;
   13514       store(mkexpr(t1), getDReg(ft));
   13515       break;
   13516 
   13517    case 0x23:  /* LW */
   13518       DIP("lw r%d, %d(r%d)", rt, imm, rs);
   13519       LOAD_STORE_PATTERN;
   13520       putIReg(rt, mkWidenFrom32(ty, load(Ity_I32, mkexpr(t1)), True));
   13521       break;
   13522 
   13523    case 0x20:  /* LB */
   13524       DIP("lb r%d, %d(r%d)", rt, imm, rs);
   13525       LOAD_STORE_PATTERN;
   13526       if (mode64)
   13527          putIReg(rt, unop(Iop_8Sto64, load(Ity_I8, mkexpr(t1))));
   13528       else
   13529          putIReg(rt, unop(Iop_8Sto32, load(Ity_I8, mkexpr(t1))));
   13530       break;
   13531 
   13532    case 0x24:  /* LBU */
   13533       DIP("lbu r%d, %d(r%d)", rt, imm, rs);
   13534       LOAD_STORE_PATTERN;
   13535       if (mode64)
   13536          putIReg(rt, unop(Iop_8Uto64, load(Ity_I8, mkexpr(t1))));
   13537       else
   13538          putIReg(rt, unop(Iop_8Uto32, load(Ity_I8, mkexpr(t1))));
   13539       break;
   13540 
   13541    case 0x21:  /* LH */
   13542       DIP("lh r%d, %d(r%d)", rt, imm, rs);
   13543       LOAD_STORE_PATTERN;
   13544       if (mode64)
   13545          putIReg(rt, unop(Iop_16Sto64, load(Ity_I16, mkexpr(t1))));
   13546       else
   13547          putIReg(rt, unop(Iop_16Sto32, load(Ity_I16, mkexpr(t1))));
   13548       break;
   13549 
   13550    case 0x25:  /* LHU */
   13551       DIP("lhu r%d, %d(r%d)", rt, imm, rs);
   13552       LOAD_STORE_PATTERN;
   13553       if (mode64)
   13554          putIReg(rt, unop(Iop_16Uto64, load(Ity_I16, mkexpr(t1))));
   13555       else
   13556          putIReg(rt, unop(Iop_16Uto32, load(Ity_I16, mkexpr(t1))));
   13557       break;
   13558 
   13559    case 0x0F:  /* LUI */
   13560       p = (imm << 16);
   13561       DIP("lui r%d, imm: 0x%x", rt, imm);
   13562       if (mode64)
   13563          putIReg(rt, mkU64(extend_s_32to64(p)));
   13564       else
   13565          putIReg(rt, mkU32(p));
   13566       break;
   13567 
   13568    case 0x13:  /* COP1X */
   13569       switch (function) {
   13570       case 0x0: {  /* LWXC1 */
   13571          /* Load Word  Indexed to Floating Point - LWXC1 (MIPS32r2) */
   13572          DIP("lwxc1 f%d, r%d(r%d)", fd, rt, rs);
   13573          if (fp_mode64) {
   13574             t0 = newTemp(Ity_I64);
   13575             t1 = newTemp(Ity_I32);
   13576             t3 = newTemp(Ity_F32);
   13577             t4 = newTemp(Ity_I64);
   13578 
   13579             t2 = newTemp(ty);
   13580             /* new LO */
   13581             assign(t2, binop(mode64 ? Iop_Add64 : Iop_Add32, getIReg(rs),
   13582                              getIReg(rt)));
   13583             assign(t3, load(Ity_F32, mkexpr(t2)));
   13584 
   13585             assign(t4, mkWidenFrom32(Ity_I64, unop(Iop_ReinterpF32asI32,
   13586                                                    mkexpr(t3)), True));
   13587 
   13588             putFReg(fd, unop(Iop_ReinterpI64asF64, mkexpr(t4)));
   13589          } else {
   13590             t0 = newTemp(Ity_I32);
   13591             assign(t0, binop(Iop_Add32, getIReg(rs), getIReg(rt)));
   13592             putFReg(fd, load(Ity_F32, mkexpr(t0)));
   13593          }
   13594          break;
   13595       }
   13596 
   13597       case 0x1: {  /* LDXC1 */
   13598          /* Load Doubleword  Indexed to Floating Point
   13599             LDXC1 (MIPS32r2 and MIPS64) */
   13600          if (fp_mode64) {
   13601             DIP("ldxc1 f%d, r%d(r%d)", fd, rt, rs);
   13602             t0 = newTemp(ty);
   13603             assign(t0, binop(mode64 ? Iop_Add64 : Iop_Add32, getIReg(rs),
   13604                              getIReg(rt)));
   13605             putFReg(fd, load(Ity_F64, mkexpr(t0)));
   13606             break;
   13607          } else {
   13608             t0 = newTemp(Ity_I32);
   13609             assign(t0, binop(Iop_Add32, getIReg(rs), getIReg(rt)));
   13610 
   13611             t1 = newTemp(Ity_I32);
   13612             assign(t1, binop(Iop_Add32, mkexpr(t0), mkU32(4)));
   13613 
   13614 #if defined (_MIPSEL)
   13615             putFReg(fd, load(Ity_F32, mkexpr(t0)));
   13616             putFReg(fd + 1, load(Ity_F32, mkexpr(t1)));
   13617 #elif defined (_MIPSEB)
   13618             putFReg(fd + 1, load(Ity_F32, mkexpr(t0)));
   13619             putFReg(fd, load(Ity_F32, mkexpr(t1)));
   13620 #endif
   13621             break;
   13622          }
   13623       }
   13624 
   13625       case 0x5:  /* Load Doubleword Indexed Unaligned to Floating Point - LUXC1;
   13626                     MIPS32r2 */
   13627          DIP("luxc1 f%d, r%d(r%d)", fd, rt, rs);
   13628          t0 = newTemp(Ity_I64);
   13629          t1 = newTemp(Ity_I64);
   13630          assign(t0, binop(Iop_Add64, getIReg(rs), getIReg(rt)));
   13631          assign(t1, binop(Iop_And64, mkexpr(t0),
   13632                                      mkU64(0xfffffffffffffff8ULL)));
   13633          putFReg(fd, load(Ity_F64, mkexpr(t1)));
   13634          break;
   13635 
   13636       case 0x8: {  /* Store Word Indexed from Floating Point - SWXC1 */
   13637          DIP("swxc1 f%d, r%d(r%d)", ft, rt, rs);
   13638          if (fp_mode64) {
   13639             t0 = newTemp(ty);
   13640             assign(t0, binop(mode64 ? Iop_Add64 : Iop_Add32, getIReg(rs),
   13641                              getIReg(rt)));
   13642             store(mkexpr(t0), getLoFromF64(tyF, getFReg(fs)));
   13643 
   13644          } else {
   13645             t0 = newTemp(Ity_I32);
   13646             assign(t0, binop(Iop_Add32, getIReg(rs), getIReg(rt)));
   13647 
   13648             store(mkexpr(t0), getFReg(fs));
   13649          }
   13650          break;
   13651       }
   13652       case 0x9: {  /* Store Doubleword Indexed from Floating Point - SDXC1 */
   13653          DIP("sdc1 f%d, %d(%d)", ft, imm, rs);
   13654          if (fp_mode64) {
   13655             t0 = newTemp(ty);
   13656             assign(t0, binop(mode64 ? Iop_Add64 : Iop_Add32, getIReg(rs),
   13657                              getIReg(rt)));
   13658             store(mkexpr(t0), getFReg(fs));
   13659          } else {
   13660             t0 = newTemp(Ity_I32);
   13661             assign(t0, binop(Iop_Add32, getIReg(rs), getIReg(rt)));
   13662 
   13663             t1 = newTemp(Ity_I32);
   13664             assign(t1, binop(Iop_Add32, mkexpr(t0), mkU32(4)));
   13665 
   13666 #if defined (_MIPSEL)
   13667             store(mkexpr(t0), getFReg(fs));
   13668             store(mkexpr(t1), getFReg(fs + 1));
   13669 #elif defined (_MIPSEB)
   13670             store(mkexpr(t0), getFReg(fs + 1));
   13671             store(mkexpr(t1), getFReg(fs));
   13672 #endif
   13673          }
   13674          break;
   13675       }
   13676       case 0xD:  /* Store Doubleword Indexed Unaligned from Floating Point -
   13677                     SUXC1; MIPS64 MIPS32r2 */
   13678          DIP("suxc1 f%d, r%d(r%d)", fd, rt, rs);
   13679          t0 = newTemp(Ity_I64);
   13680          t1 = newTemp(Ity_I64);
   13681          assign(t0, binop(Iop_Add64, getIReg(rs), getIReg(rt)));
   13682          assign(t1, binop(Iop_And64, mkexpr(t0), mkU64(0xfffffffffffffff8ULL)));
   13683          store(mkexpr(t1), getFReg(fs));
   13684          break;
   13685 
   13686       case 0x0F: {
   13687          DIP("prefx");
   13688          break;
   13689       }
   13690       case 0x20:  {  /* MADD.S */
   13691          DIP("madd.s f%d, f%d, f%d, f%d", fd, fmt, fs, ft);
   13692          IRExpr *rm = get_IR_roundingmode();
   13693          t1 = newTemp(Ity_F32);
   13694          assign(t1, qop(Iop_MAddF32, rm,
   13695                         getLoFromF64(tyF, getFReg(fmt)),
   13696                         getLoFromF64(tyF, getFReg(fs)),
   13697                         getLoFromF64(tyF, getFReg(ft))));
   13698          putFReg(fd, mkWidenFromF32(tyF, mkexpr(t1)));
   13699          break;  /* MADD.S */
   13700       }
   13701       case 0x21: {  /* MADD.D */
   13702          DIP("madd.d f%d, f%d, f%d, f%d", fd, fmt, fs, ft);
   13703          IRExpr *rm = get_IR_roundingmode();
   13704          putDReg(fd, qop(Iop_MAddF64, rm, getDReg(fmt), getDReg(fs),
   13705                          getDReg(ft)));
   13706          break;  /* MADD.D */
   13707       }
   13708       case 0x28: {  /* MSUB.S */
   13709          DIP("msub.s f%d, f%d, f%d, f%d", fd, fmt, fs, ft);
   13710          IRExpr *rm = get_IR_roundingmode();
   13711          t1 = newTemp(Ity_F32);
   13712          assign(t1, qop(Iop_MSubF32, rm,
   13713                         getLoFromF64(tyF, getFReg(fmt)),
   13714                         getLoFromF64(tyF, getFReg(fs)),
   13715                         getLoFromF64(tyF, getFReg(ft))));
   13716          putFReg(fd, mkWidenFromF32(tyF, mkexpr(t1)));
   13717          break;  /* MSUB.S */
   13718       }
   13719       case 0x29: {  /* MSUB.D */
   13720          DIP("msub.d f%d, f%d, f%d, f%d", fd, fmt, fs, ft);
   13721          IRExpr *rm = get_IR_roundingmode();
   13722          putDReg(fd, qop(Iop_MSubF64, rm, getDReg(fmt), getDReg(fs),
   13723                          getDReg(ft)));
   13724          break;  /* MSUB.D */
   13725       }
   13726       case 0x30: {  /* NMADD.S */
   13727          DIP("nmadd.s f%d, f%d, f%d, f%d", fd, fmt, fs, ft);
   13728          IRExpr *rm = get_IR_roundingmode();
   13729          t1 = newTemp(Ity_F32);
   13730          assign(t1, qop(Iop_MAddF32, rm,
   13731                         getLoFromF64(tyF, getFReg(fmt)),
   13732                         getLoFromF64(tyF, getFReg(fs)),
   13733                         getLoFromF64(tyF, getFReg(ft))));
   13734 
   13735          putFReg(fd, mkWidenFromF32(tyF, unop(Iop_NegF32, mkexpr(t1))));
   13736          break;  /* NMADD.S */
   13737       }
   13738       case 0x31: {  /* NMADD.D */
   13739          DIP("nmadd.d f%d, f%d, f%d, f%d", fd, fmt, fs, ft);
   13740          IRExpr *rm = get_IR_roundingmode();
   13741          t1 = newTemp(Ity_F64);
   13742          assign(t1, qop(Iop_MAddF64, rm, getDReg(fmt), getDReg(fs),
   13743                         getDReg(ft)));
   13744          putDReg(fd, unop(Iop_NegF64, mkexpr(t1)));
   13745          break;  /* NMADD.D */
   13746       }
   13747       case 0x38: {  /* NMSUBB.S */
   13748          DIP("nmsub.s f%d, f%d, f%d, f%d", fd, fmt, fs, ft);
   13749          IRExpr *rm = get_IR_roundingmode();
   13750          t1 = newTemp(Ity_F32);
   13751          assign(t1, qop(Iop_MSubF32, rm,
   13752                         getLoFromF64(tyF, getFReg(fmt)),
   13753                         getLoFromF64(tyF, getFReg(fs)),
   13754                         getLoFromF64(tyF, getFReg(ft))));
   13755 
   13756          putFReg(fd, mkWidenFromF32(tyF, unop(Iop_NegF32, mkexpr(t1))));
   13757          break;  /* NMSUBB.S */
   13758       }
   13759       case 0x39: {  /* NMSUBB.D */
   13760          DIP("nmsub.d f%d, f%d, f%d, f%d", fd, fmt, fs, ft);
   13761          IRExpr *rm = get_IR_roundingmode();
   13762          t1 = newTemp(Ity_F64);
   13763          assign(t1, qop(Iop_MSubF64, rm, getDReg(fmt), getDReg(fs),
   13764                         getDReg(ft)));
   13765          putDReg(fd, unop(Iop_NegF64, mkexpr(t1)));
   13766          break;  /* NMSUBB.D */
   13767       }
   13768 
   13769       default:
   13770          goto decode_failure;
   13771       }
   13772       break;
   13773 
   13774    case 0x22:  /* LWL */
   13775       DIP("lwl r%d, %d(r%d)", rt, imm, rs);
   13776       if (mode64) {
   13777          /* t1 = addr */
   13778          t1 = newTemp(Ity_I64);
   13779 #if defined (_MIPSEL)
   13780          assign(t1, binop(Iop_Add64, getIReg(rs), mkU64(extend_s_16to64(imm))));
   13781          /* t2 = word addr */
   13782          /* t4 = addr mod 4 */
   13783          LWX_SWX_PATTERN64;
   13784 
   13785          /* t3 = word content - shifted */
   13786          t3 = newTemp(Ity_I32);
   13787          assign(t3, binop(Iop_Shl32, mkNarrowTo32(ty, load(Ity_I64,
   13788                           mkexpr(t2))), narrowTo(Ity_I8, binop(Iop_Shl32,
   13789                     binop(Iop_Sub32, mkU32(0x03), mkexpr(t4)), mkU8(3)))));
   13790 
   13791          /* rt content - adjusted */
   13792          t5 = newTemp(Ity_I32);
   13793          assign(t5, binop(Iop_And32,
   13794                           mkNarrowTo32(ty, getIReg(rt)),
   13795                           binop(Iop_Shr32,
   13796                                 mkU32(0x00FFFFFF),
   13797                                       narrowTo(Ity_I8, binop(Iop_Mul32,
   13798                                                              mkU32(0x08),
   13799                                                              mkexpr(t4))))));
   13800 
   13801          putIReg(rt, mkWidenFrom32(ty, binop(Iop_Or32, mkexpr(t5),
   13802                                              mkexpr(t3)), True));
   13803 #elif defined (_MIPSEB)
   13804          assign(t1, binop(Iop_Xor64, mkU64(0x3),
   13805                 binop(Iop_Add64, getIReg(rs), mkU64(extend_s_16to64(imm)))));
   13806          /* t2 = word addr */
   13807          /* t4 = addr mod 4 */
   13808          LWX_SWX_PATTERN64;
   13809 
   13810          /* t3 = word content - shifted */
   13811          t3 = newTemp(Ity_I32);
   13812          assign(t3, binop(Iop_Shl32, unop(Iop_64HIto32, load(Ity_I64,
   13813                           mkexpr(t2))), narrowTo(Ity_I8, binop(Iop_Shl32,
   13814                     binop(Iop_Sub32, mkU32(0x03), mkexpr(t4)), mkU8(3)))));
   13815 
   13816          /* rt content - adjusted */
   13817          t5 = newTemp(Ity_I32);
   13818          assign(t5, binop(Iop_And32,
   13819                           mkNarrowTo32(ty, getIReg(rt)),
   13820                           binop(Iop_Shr32,
   13821                                 mkU32(0x00FFFFFF),
   13822                                       narrowTo(Ity_I8, binop(Iop_Mul32,
   13823                                                              mkU32(0x08),
   13824                                                              mkexpr(t4))))));
   13825 
   13826          putIReg(rt, mkWidenFrom32(ty, binop(Iop_Or32, mkexpr(t5),
   13827                                              mkexpr(t3)), True));
   13828 #endif
   13829       } else {
   13830          /* t1 = addr */
   13831          t1 = newTemp(Ity_I32);
   13832 #if defined (_MIPSEL)
   13833          assign(t1, binop(Iop_Add32, getIReg(rs), mkU32(extend_s_16to32(imm))));
   13834 #elif defined (_MIPSEB)
   13835          assign(t1, binop(Iop_Xor32, mkU32(0x3), binop(Iop_Add32, getIReg(rs),
   13836                                      mkU32(extend_s_16to32(imm)))));
   13837 #endif
   13838 
   13839          /* t2 = word addr */
   13840          /* t4 = addr mod 4 */
   13841          LWX_SWX_PATTERN;
   13842 
   13843          /* t3 = word content - shifted */
   13844          t3 = newTemp(Ity_I32);
   13845          assign(t3, binop(Iop_Shl32, load(Ity_I32, mkexpr(t2)), narrowTo(Ity_I8,
   13846                     binop(Iop_Shl32, binop(Iop_Sub32, mkU32(0x03), mkexpr(t4)),
   13847                     mkU8(3)))));
   13848 
   13849          /* rt content  - adjusted */
   13850          t5 = newTemp(Ity_I32);
   13851          assign(t5, binop(Iop_And32,
   13852                           getIReg(rt),
   13853                           binop(Iop_Shr32,
   13854                                 mkU32(0x00FFFFFF),
   13855                                       narrowTo(Ity_I8, binop(Iop_Mul32,
   13856                                                              mkU32(0x08),
   13857                                                              mkexpr(t4))))));
   13858 
   13859          putIReg(rt, binop(Iop_Or32, mkexpr(t5), mkexpr(t3)));
   13860       }
   13861       break;
   13862 
   13863    case 0x26:  /* LWR */
   13864       DIP("lwr r%d, %d(r%d)", rt, imm, rs);
   13865       if (mode64) {
   13866          /* t1 = addr */
   13867          t1 = newTemp(Ity_I64);
   13868 #if defined (_MIPSEL)
   13869          assign(t1, binop(Iop_Add64, getIReg(rs), mkU64(extend_s_16to64(imm))));
   13870          /* t2 = word addr */
   13871          /* t4 = addr mod 8 */
   13872          LWX_SWX_PATTERN64;
   13873 
   13874          /* t3 = word content - shifted */
   13875          t3 = newTemp(Ity_I32);
   13876          assign(t3, binop(Iop_Shr32, mkNarrowTo32(ty, load(Ity_I64,mkexpr(t2))),
   13877                     narrowTo(Ity_I8, binop(Iop_Shl32, mkexpr(t4), mkU8(3)))));
   13878 
   13879          /* rt content  - adjusted */
   13880          t5 = newTemp(Ity_I32);
   13881          assign(t5, binop(Iop_And32, mkNarrowTo32(ty, getIReg(rt)),
   13882                 unop(Iop_Not32, binop(Iop_Shr32, mkU32(0xFFFFFFFF),
   13883                 narrowTo(Ity_I8, binop(Iop_Shl32, mkexpr(t4), mkU8(0x3)))))));
   13884 
   13885          putIReg(rt, mkWidenFrom32(ty, binop(Iop_Or32, mkexpr(t5),
   13886                                        mkexpr(t3)), True));
   13887 #elif defined (_MIPSEB)
   13888          assign(t1, binop(Iop_Xor64, mkU64(0x3), binop(Iop_Add64, getIReg(rs),
   13889                           mkU64(extend_s_16to64(imm)))));
   13890          /* t2 = word addr */
   13891          /* t4 = addr mod 4 */
   13892          LWX_SWX_PATTERN64;
   13893 
   13894          /* t3 = word content - shifted */
   13895          t3 = newTemp(Ity_I32);
   13896          assign(t3, binop(Iop_Shr32, unop(Iop_64HIto32, load(Ity_I64,mkexpr(t2))),
   13897                     narrowTo(Ity_I8, binop(Iop_Shl32, mkexpr(t4), mkU8(3)))));
   13898 
   13899          /* rt content  - adjusted */
   13900          t5 = newTemp(Ity_I32);
   13901          assign(t5, binop(Iop_And32, mkNarrowTo32(ty, getIReg(rt)),
   13902                 unop(Iop_Not32, binop(Iop_Shr32, mkU32(0xFFFFFFFF),
   13903                 narrowTo(Ity_I8, binop(Iop_Shl32, mkexpr(t4), mkU8(0x3)))))));
   13904 
   13905          putIReg(rt, mkWidenFrom32(ty, binop(Iop_Or32, mkexpr(t5),
   13906                                        mkexpr(t3)), True));
   13907 #endif
   13908 
   13909       } else {
   13910          /* t1 = addr */
   13911          t1 = newTemp(Ity_I32);
   13912 #if defined (_MIPSEL)
   13913          assign(t1, binop(Iop_Add32, getIReg(rs), mkU32(extend_s_16to32(imm))));
   13914 #elif defined (_MIPSEB)
   13915          assign(t1, binop(Iop_Xor32, mkU32(0x3), binop(Iop_Add32, getIReg(rs),
   13916                                      mkU32(extend_s_16to32(imm)))));
   13917 #endif
   13918 
   13919          /* t2 = word addr */
   13920          /* t4 = addr mod 4 */
   13921          LWX_SWX_PATTERN;
   13922 
   13923          /* t3 = word content - shifted */
   13924          t3 = newTemp(Ity_I32);
   13925          assign(t3, binop(Iop_Shr32, load(Ity_I32, mkexpr(t2)),
   13926                     narrowTo(Ity_I8, binop(Iop_Shl32, mkexpr(t4),
   13927                     mkU8(3)))));
   13928 
   13929          /* rt content  - adjusted */
   13930          t5 = newTemp(Ity_I32);
   13931          assign(t5, binop(Iop_And32, getIReg(rt), unop(Iop_Not32,
   13932                     binop(Iop_Shr32, mkU32(0xFFFFFFFF), narrowTo(Ity_I8,
   13933                           binop(Iop_Shl32, mkexpr(t4), mkU8(0x3)))))));
   13934 
   13935          putIReg(rt, binop(Iop_Or32, mkexpr(t5), mkexpr(t3)));
   13936       }
   13937       break;
   13938 
   13939    case 0x2B:  /* SW */
   13940       DIP("sw r%d, %d(r%d)", rt, imm, rs);
   13941       LOAD_STORE_PATTERN;
   13942       store(mkexpr(t1), mkNarrowTo32(ty, getIReg(rt)));
   13943       break;
   13944 
   13945    case 0x2C: {  /* SDL rt, offset(base) MIPS64 */
   13946       DIP("sdl r%u, %d(r%u)", rt, (Int) imm, rs);
   13947       vassert(mode64);
   13948       IRTemp A_byte = newTemp(Ity_I8);
   13949       IRTemp B_byte = newTemp(Ity_I8);
   13950       IRTemp C_byte = newTemp(Ity_I8);
   13951       IRTemp D_byte = newTemp(Ity_I8);
   13952       IRTemp E_byte = newTemp(Ity_I8);
   13953       IRTemp F_byte = newTemp(Ity_I8);
   13954       IRTemp G_byte = newTemp(Ity_I8);
   13955       IRTemp H_byte = newTemp(Ity_I8);
   13956       IRTemp B_pos  = newTemp(Ity_I64);
   13957       IRTemp C_pos  = newTemp(Ity_I64);
   13958       IRTemp D_pos  = newTemp(Ity_I64);
   13959       IRTemp E_pos  = newTemp(Ity_I64);
   13960       IRTemp F_pos  = newTemp(Ity_I64);
   13961       IRTemp G_pos  = newTemp(Ity_I64);
   13962 
   13963       /* H byte */
   13964       assign(H_byte, getByteFromReg(rt, 0));
   13965       /* G byte */
   13966       assign(G_byte, getByteFromReg(rt, 1));
   13967       /* F byte */
   13968       assign(F_byte, getByteFromReg(rt, 2));
   13969       /* E byte */
   13970       assign(E_byte, getByteFromReg(rt, 3));
   13971       /* D byte */
   13972       assign(D_byte, getByteFromReg(rt, 4));
   13973       /* C byte */
   13974       assign(C_byte, getByteFromReg(rt, 5));
   13975       /* B byte */
   13976       assign(B_byte, getByteFromReg(rt, 6));
   13977       /* A byte */
   13978       assign(A_byte, getByteFromReg(rt, 7));
   13979 
   13980       /* t1 = addr */
   13981       t1 = newTemp(Ity_I64);
   13982       assign(t1, binop(Iop_Add64, getIReg(rs), mkU64(extend_s_16to64(imm))));
   13983 
   13984       /* t2 = word addr */
   13985       t2 = newTemp(Ity_I64);
   13986       assign(t2, binop(Iop_And64, mkexpr(t1), mkU64(0xFFFFFFFFFFFFFFF8ULL)));
   13987 
   13988       /* t3 = addr mod 7 */
   13989       t3 = newTemp(Ity_I64);
   13990       assign(t3, binop(Iop_And64, mkexpr(t1), mkU64(0x7)));
   13991 
   13992 #if defined (_MIPSEL)
   13993       /* Calculate X_byte position. */
   13994       assign(B_pos, IRExpr_ITE(binop(Iop_CmpLT64U, mkexpr(t3), mkU64(0x1)),
   13995                                mkU64(0x0),
   13996                                mkU64(0x1)));
   13997 
   13998       assign(C_pos, IRExpr_ITE(binop(Iop_CmpLT64U, mkexpr(t3), mkU64(0x2)),
   13999                                mkU64(0x0),
   14000                                mkU64(0x2)));
   14001 
   14002       assign(D_pos, IRExpr_ITE(binop(Iop_CmpLT64U, mkexpr(t3), mkU64(0x3)),
   14003                                mkU64(0x0),
   14004                                mkU64(0x3)));
   14005 
   14006       assign(E_pos, IRExpr_ITE(binop(Iop_CmpLT64U, mkexpr(t3), mkU64(0x4)),
   14007                                mkU64(0x0),
   14008                                mkU64(0x4)));
   14009 
   14010       assign(F_pos, IRExpr_ITE(binop(Iop_CmpLT64U, mkexpr(t3), mkU64(0x5)),
   14011                                mkU64(0x0),
   14012                                mkU64(0x5)));
   14013 
   14014       assign(G_pos, IRExpr_ITE(binop(Iop_CmpEQ64, mkexpr(t3), mkU64(0x7)),
   14015                                mkU64(0x1),
   14016                                mkU64(0x0)));
   14017 
   14018       /* Store X_byte on the right place. */
   14019       store(mkexpr(t2), mkexpr(H_byte));
   14020       store(binop(Iop_Add64, mkexpr(t2), mkexpr(G_pos)), mkexpr(G_byte));
   14021       store(binop(Iop_Sub64, mkexpr(t1), mkexpr(F_pos)), mkexpr(F_byte));
   14022       store(binop(Iop_Sub64, mkexpr(t1), mkexpr(E_pos)), mkexpr(E_byte));
   14023       store(binop(Iop_Sub64, mkexpr(t1), mkexpr(D_pos)), mkexpr(D_byte));
   14024       store(binop(Iop_Sub64, mkexpr(t1), mkexpr(C_pos)), mkexpr(C_byte));
   14025       store(binop(Iop_Sub64, mkexpr(t1), mkexpr(B_pos)), mkexpr(B_byte));
   14026       store(mkexpr(t1), mkexpr(A_byte));
   14027 
   14028 #else /* _MIPSEB */
   14029       /* Calculate X_byte position. */
   14030       assign(B_pos, IRExpr_ITE(binop(Iop_CmpEQ64, mkexpr(t3), mkU64(0x7)),
   14031                                mkU64(0x0),
   14032                                mkU64(0x1)));
   14033 
   14034       assign(C_pos, IRExpr_ITE(binop(Iop_CmpLT64U, mkexpr(t3), mkU64(0x6)),
   14035                                mkU64(0x2),
   14036                                mkU64(0x0)));
   14037 
   14038       assign(D_pos, IRExpr_ITE(binop(Iop_CmpLT64U, mkexpr(t3), mkU64(0x5)),
   14039                                mkU64(0x3),
   14040                                mkU64(0x0)));
   14041 
   14042       assign(E_pos, IRExpr_ITE(binop(Iop_CmpLT64U, mkexpr(t3), mkU64(0x4)),
   14043                                mkU64(0x4),
   14044                                mkU64(0x0)));
   14045 
   14046       assign(F_pos, IRExpr_ITE(binop(Iop_CmpLT64U, mkexpr(t3), mkU64(0x3)),
   14047                                mkU64(0x5),
   14048                                mkU64(0x0)));
   14049 
   14050       assign(G_pos, IRExpr_ITE(binop(Iop_CmpEQ64, mkexpr(t3), mkU64(0x0)),
   14051                                mkU64(0x6),
   14052                                mkU64(0x7)));
   14053 
   14054       /* Store X_byte on the right place. */
   14055       store(binop(Iop_Add64, mkexpr(t2), mkU64(0x7)), mkexpr(H_byte));
   14056       store(binop(Iop_Add64, mkexpr(t2), mkexpr(G_pos)), mkexpr(G_byte));
   14057       store(binop(Iop_Add64, mkexpr(t1), mkexpr(F_pos)), mkexpr(F_byte));
   14058       store(binop(Iop_Add64, mkexpr(t1), mkexpr(E_pos)), mkexpr(E_byte));
   14059       store(binop(Iop_Add64, mkexpr(t1), mkexpr(D_pos)), mkexpr(D_byte));
   14060       store(binop(Iop_Add64, mkexpr(t1), mkexpr(C_pos)), mkexpr(C_byte));
   14061       store(binop(Iop_Add64, mkexpr(t1), mkexpr(B_pos)), mkexpr(B_byte));
   14062       store(mkexpr(t1), mkexpr(A_byte));
   14063 #endif
   14064 
   14065       break;
   14066    }
   14067 
   14068    case 0x2D: {
   14069       /* SDR rt, offset(base) - MIPS64 */
   14070       vassert(mode64);
   14071       DIP("sdr r%u, %d(r%u)", rt, imm, rs);
   14072       IRTemp A_byte = newTemp(Ity_I8);
   14073       IRTemp B_byte = newTemp(Ity_I8);
   14074       IRTemp C_byte = newTemp(Ity_I8);
   14075       IRTemp D_byte = newTemp(Ity_I8);
   14076       IRTemp E_byte = newTemp(Ity_I8);
   14077       IRTemp F_byte = newTemp(Ity_I8);
   14078       IRTemp G_byte = newTemp(Ity_I8);
   14079       IRTemp H_byte = newTemp(Ity_I8);
   14080       IRTemp B_pos  = newTemp(Ity_I64);
   14081       IRTemp C_pos  = newTemp(Ity_I64);
   14082       IRTemp D_pos  = newTemp(Ity_I64);
   14083       IRTemp E_pos  = newTemp(Ity_I64);
   14084       IRTemp F_pos  = newTemp(Ity_I64);
   14085       IRTemp G_pos  = newTemp(Ity_I64);
   14086 
   14087       /* H byte */
   14088       assign(H_byte, getByteFromReg(rt, 0));
   14089       /* G byte */
   14090       assign(G_byte, getByteFromReg(rt, 1));
   14091       /* F byte */
   14092       assign(F_byte, getByteFromReg(rt, 2));
   14093       /* E byte */
   14094       assign(E_byte, getByteFromReg(rt, 3));
   14095       /* D byte */
   14096       assign(D_byte, getByteFromReg(rt, 4));
   14097       /* C byte */
   14098       assign(C_byte, getByteFromReg(rt, 5));
   14099       /* B byte */
   14100       assign(B_byte, getByteFromReg(rt, 6));
   14101       /* A byte */
   14102       assign(A_byte, getByteFromReg(rt, 7));
   14103 
   14104       /* t1 = addr */
   14105       t1 = newTemp(Ity_I64);
   14106       assign(t1, binop(Iop_Add64, getIReg(rs), mkU64(extend_s_16to64(imm))));
   14107 
   14108       /* t2 = word addr */
   14109       t2 = newTemp(Ity_I64);
   14110       assign(t2, binop(Iop_And64, mkexpr(t1), mkU64(0xFFFFFFFFFFFFFFF8ULL)));
   14111 
   14112       /* t3 = addr mod 7 */
   14113       t3 = newTemp(Ity_I64);
   14114       assign(t3, binop(Iop_And64, mkexpr(t1), mkU64(0x7)));
   14115 
   14116 #if defined (_MIPSEL)
   14117       /* Calculate X_byte position. */
   14118       assign(B_pos, IRExpr_ITE(binop(Iop_CmpLT64U, mkU64(0x1), mkexpr(t3)),
   14119                                mkU64(0x0),
   14120                                mkU64(0x6)));
   14121 
   14122       assign(C_pos, IRExpr_ITE(binop(Iop_CmpLT64U, mkU64(0x2), mkexpr(t3)),
   14123                                mkU64(0x0),
   14124                                mkU64(0x5)));
   14125 
   14126       assign(D_pos, IRExpr_ITE(binop(Iop_CmpLT64U, mkU64(0x3), mkexpr(t3)),
   14127                                mkU64(0x0),
   14128                                mkU64(0x4)));
   14129 
   14130       assign(E_pos, IRExpr_ITE(binop(Iop_CmpLT64U, mkU64(0x4), mkexpr(t3)),
   14131                                mkU64(0x0),
   14132                                mkU64(0x3)));
   14133 
   14134       assign(F_pos, IRExpr_ITE(binop(Iop_CmpLT64U, mkU64(0x5), mkexpr(t3)),
   14135                                mkU64(0x0),
   14136                                mkU64(0x2)));
   14137 
   14138       assign(G_pos, IRExpr_ITE(binop(Iop_CmpEQ64, mkexpr(t3), mkU64(0x7)),
   14139                                mkU64(0x0),
   14140                                mkU64(0x1)));
   14141 
   14142       /* Store X_byte on the right place. */
   14143       store(binop(Iop_Add64, mkexpr(t2), mkU64(0x7)), mkexpr(A_byte));
   14144       store(binop(Iop_Add64, mkexpr(t1), mkexpr(B_pos)), mkexpr(B_byte));
   14145       store(binop(Iop_Add64, mkexpr(t1), mkexpr(C_pos)), mkexpr(C_byte));
   14146       store(binop(Iop_Add64, mkexpr(t1), mkexpr(D_pos)), mkexpr(D_byte));
   14147       store(binop(Iop_Add64, mkexpr(t1), mkexpr(E_pos)), mkexpr(E_byte));
   14148       store(binop(Iop_Add64, mkexpr(t1), mkexpr(F_pos)), mkexpr(F_byte));
   14149       store(binop(Iop_Add64, mkexpr(t1), mkexpr(G_pos)), mkexpr(G_byte));
   14150       store(mkexpr(t1), mkexpr(H_byte));
   14151 
   14152 #else /* _MIPSEB */
   14153       /* Calculate X_byte position. */
   14154       assign(B_pos, IRExpr_ITE(binop(Iop_CmpLT64U, mkU64(0x5), mkexpr(t3)),
   14155                                mkU64(0x6),
   14156                                mkU64(0x0)));
   14157 
   14158       assign(C_pos, IRExpr_ITE(binop(Iop_CmpLT64U, mkU64(0x4), mkexpr(t3)),
   14159                                mkU64(0x5),
   14160                                mkU64(0x0)));
   14161 
   14162       assign(D_pos, IRExpr_ITE(binop(Iop_CmpLT64U, mkU64(0x3), mkexpr(t3)),
   14163                                mkU64(0x4),
   14164                                mkU64(0x0)));
   14165 
   14166       assign(E_pos, IRExpr_ITE(binop(Iop_CmpLT64U, mkU64(0x2), mkexpr(t3)),
   14167                                mkU64(0x3),
   14168                                mkU64(0x0)));
   14169 
   14170       assign(F_pos, IRExpr_ITE(binop(Iop_CmpLT64U, mkU64(0x1), mkexpr(t3)),
   14171                                mkU64(0x2),
   14172                                mkU64(0x0)));
   14173 
   14174       assign(G_pos, IRExpr_ITE(binop(Iop_CmpEQ64, mkexpr(t3), mkU64(0x0)),
   14175                                mkU64(0x0),
   14176                                mkU64(0x1)));
   14177 
   14178       /* Store X_byte on the right place. */
   14179       store(mkexpr(t2), mkexpr(A_byte));
   14180       store(binop(Iop_Sub64, mkexpr(t1), mkexpr(B_pos)), mkexpr(B_byte));
   14181       store(binop(Iop_Sub64, mkexpr(t1), mkexpr(C_pos)), mkexpr(C_byte));
   14182       store(binop(Iop_Sub64, mkexpr(t1), mkexpr(D_pos)), mkexpr(D_byte));
   14183       store(binop(Iop_Sub64, mkexpr(t1), mkexpr(E_pos)), mkexpr(E_byte));
   14184       store(binop(Iop_Sub64, mkexpr(t1), mkexpr(F_pos)), mkexpr(F_byte));
   14185       store(binop(Iop_Sub64, mkexpr(t1), mkexpr(G_pos)), mkexpr(G_byte));
   14186       store(mkexpr(t1), mkexpr(H_byte));
   14187 #endif
   14188       break;
   14189    }
   14190 
   14191    case 0x28:  /* SB */
   14192       DIP("sb r%d, %d(r%d)", rt, imm, rs);
   14193       LOAD_STORE_PATTERN;
   14194       store(mkexpr(t1), narrowTo(Ity_I8, getIReg(rt)));
   14195       break;
   14196 
   14197    case 0x29:  /* SH */
   14198       DIP("sh r%d, %d(r%d)", rt, imm, rs);
   14199       LOAD_STORE_PATTERN;
   14200       store(mkexpr(t1), narrowTo(Ity_I16, getIReg(rt)));
   14201       break;
   14202 
   14203    case 0x2A:  /* SWL */
   14204       DIP("swl r%d, %d(r%d)", rt, imm, rs);
   14205       if (mode64) {
   14206          IRTemp E_byte = newTemp(Ity_I8);
   14207          IRTemp F_byte = newTemp(Ity_I8);
   14208          IRTemp G_byte = newTemp(Ity_I8);
   14209          IRTemp H_byte = newTemp(Ity_I8);
   14210          IRTemp F_pos  = newTemp(Ity_I64);
   14211          IRTemp G_pos  = newTemp(Ity_I64);
   14212 
   14213          /* H byte */
   14214          assign(H_byte, getByteFromReg(rt, 0));
   14215          /* G byte */
   14216          assign(G_byte, getByteFromReg(rt, 1));
   14217          /* F byte */
   14218          assign(F_byte, getByteFromReg(rt, 2));
   14219          /* E byte */
   14220          assign(E_byte, getByteFromReg(rt, 3));
   14221 
   14222          /* t1 = addr */
   14223          t1 = newTemp(Ity_I64);
   14224          assign(t1, binop(Iop_Add64, getIReg(rs), mkU64(extend_s_16to64(imm))));
   14225 
   14226          /* t2 = word addr */
   14227          t2 = newTemp(Ity_I64);
   14228          assign(t2, binop(Iop_And64, mkexpr(t1), mkU64(0xFFFFFFFFFFFFFFFCULL)));
   14229 
   14230          /* t3 = addr mod 4 */
   14231          t3 = newTemp(Ity_I64);
   14232          assign(t3, binop(Iop_And64, mkexpr(t1), mkU64(0x3)));
   14233 
   14234 #if defined (_MIPSEL)
   14235          /* Calculate X_byte position. */
   14236          assign(F_pos, IRExpr_ITE(binop(Iop_CmpEQ64, mkexpr(t3), mkU64(0x0)),
   14237                                   mkU64(0x0),
   14238                                   mkU64(0x1)));
   14239 
   14240          assign(G_pos, IRExpr_ITE(binop(Iop_CmpEQ64, mkexpr(t3), mkU64(0x3)),
   14241                                   mkU64(0x1),
   14242                                   mkU64(0x0)));
   14243 
   14244          /* Store X_byte on the right place. */
   14245          store(mkexpr(t2), mkexpr(H_byte));
   14246          store(binop(Iop_Add64, mkexpr(t2), mkexpr(G_pos)), mkexpr(G_byte));
   14247          store(binop(Iop_Sub64, mkexpr(t1), mkexpr(F_pos)), mkexpr(F_byte));
   14248          store(mkexpr(t1), mkexpr(E_byte));
   14249 
   14250 #else    /* _MIPSEB */
   14251          /* Calculate X_byte position. */
   14252          assign(F_pos, IRExpr_ITE(binop(Iop_CmpEQ64, mkexpr(t3), mkU64(0x3)),
   14253                                   mkU64(0x0),
   14254                                   mkU64(0x1)));
   14255 
   14256          assign(G_pos, IRExpr_ITE(binop(Iop_CmpEQ64, mkexpr(t3), mkU64(0x0)),
   14257                                   mkU64(0x2),
   14258                                   mkU64(0x3)));
   14259 
   14260          store(binop(Iop_Add64, mkexpr(t2), mkU64(3)), mkexpr(H_byte));
   14261          store(binop(Iop_Add64, mkexpr(t2), mkexpr(G_pos)), mkexpr(G_byte));
   14262          store(binop(Iop_Add64, mkexpr(t1), mkexpr(F_pos)), mkexpr(F_byte));
   14263          store(mkexpr(t1), mkexpr(E_byte));
   14264 
   14265 #endif
   14266       } else {
   14267          IRTemp E_byte = newTemp(Ity_I8);
   14268          IRTemp F_byte = newTemp(Ity_I8);
   14269          IRTemp G_byte = newTemp(Ity_I8);
   14270          IRTemp H_byte = newTemp(Ity_I8);
   14271          IRTemp F_pos  = newTemp(Ity_I32);
   14272          IRTemp G_pos  = newTemp(Ity_I32);
   14273 
   14274          /* H byte */
   14275          assign(H_byte, getByteFromReg(rt, 0));
   14276          /* G byte */
   14277          assign(G_byte, getByteFromReg(rt, 1));
   14278          /* F byte */
   14279          assign(F_byte, getByteFromReg(rt, 2));
   14280          /* E byte */
   14281          assign(E_byte, getByteFromReg(rt, 3));
   14282 
   14283          /* t1 = addr */
   14284          t1 = newTemp(Ity_I32);
   14285          assign(t1, binop(Iop_Add32, getIReg(rs), mkU32(extend_s_16to32(imm))));
   14286 
   14287          /* t2 = word addr */
   14288          t2 = newTemp(Ity_I32);
   14289          assign(t2, binop(Iop_And32, mkexpr(t1), mkU32(0xFFFFFFFCULL)));
   14290 
   14291          /* t3 = addr mod 4 */
   14292          t3 = newTemp(Ity_I32);
   14293          assign(t3, binop(Iop_And32, mkexpr(t1), mkU32(0x3)));
   14294 
   14295 #if defined (_MIPSEL)
   14296          /* Calculate X_byte position. */
   14297          assign(F_pos, IRExpr_ITE(binop(Iop_CmpEQ32, mkexpr(t3), mkU32(0x0)),
   14298                                   mkU32(0x0),
   14299                                   mkU32(0x1)));
   14300 
   14301          assign(G_pos, IRExpr_ITE(binop(Iop_CmpEQ32, mkexpr(t3), mkU32(0x3)),
   14302                                   mkU32(0x1),
   14303                                   mkU32(0x0)));
   14304 
   14305          /* Store X_byte on the right place. */
   14306          store(mkexpr(t2), mkexpr(H_byte));
   14307          store(binop(Iop_Add32, mkexpr(t2), mkexpr(G_pos)), mkexpr(G_byte));
   14308          store(binop(Iop_Sub32, mkexpr(t1), mkexpr(F_pos)), mkexpr(F_byte));
   14309          store(mkexpr(t1), mkexpr(E_byte));
   14310 
   14311 #else    /* _MIPSEB */
   14312          /* Calculate X_byte position. */
   14313          assign(F_pos, IRExpr_ITE(binop(Iop_CmpEQ32, mkexpr(t3), mkU32(0x3)),
   14314                                   mkU32(0x0),
   14315                                   mkU32(0x1)));
   14316 
   14317          assign(G_pos, IRExpr_ITE(binop(Iop_CmpEQ32, mkexpr(t3), mkU32(0x0)),
   14318                                   mkU32(0x2),
   14319                                   mkU32(0x3)));
   14320 
   14321          store(binop(Iop_Add32, mkexpr(t2), mkU32(3)), mkexpr(H_byte));
   14322          store(binop(Iop_Add32, mkexpr(t2), mkexpr(G_pos)), mkexpr(G_byte));
   14323          store(binop(Iop_Add32, mkexpr(t1), mkexpr(F_pos)), mkexpr(F_byte));
   14324          store(mkexpr(t1), mkexpr(E_byte));
   14325 
   14326 #endif
   14327       }
   14328       break;
   14329 
   14330    case 0x2E:  /* SWR */
   14331       DIP("swr r%d, %d(r%d)", rt, imm, rs);
   14332       if (mode64) {
   14333          IRTemp E_byte = newTemp(Ity_I8);
   14334          IRTemp F_byte = newTemp(Ity_I8);
   14335          IRTemp G_byte = newTemp(Ity_I8);
   14336          IRTemp H_byte = newTemp(Ity_I8);
   14337          IRTemp F_pos  = newTemp(Ity_I64);
   14338          IRTemp G_pos  = newTemp(Ity_I64);
   14339 
   14340          /* H byte */
   14341          assign(H_byte, getByteFromReg(rt, 0));
   14342          /* G byte */
   14343          assign(G_byte, getByteFromReg(rt, 1));
   14344          /* F byte */
   14345          assign(F_byte, getByteFromReg(rt, 2));
   14346          /* E byte */
   14347          assign(E_byte, getByteFromReg(rt, 3));
   14348 
   14349          /* t1 = addr */
   14350          t1 = newTemp(Ity_I64);
   14351          assign(t1, binop(Iop_Add64, getIReg(rs), mkU64(extend_s_16to64(imm))));
   14352 
   14353          /* t2 = word addr */
   14354          t2 = newTemp(Ity_I64);
   14355          assign(t2, binop(Iop_And64, mkexpr(t1), mkU64(0xFFFFFFFFFFFFFFFCULL)));
   14356 
   14357          /* t3 = addr mod 4 */
   14358          t3 = newTemp(Ity_I64);
   14359          assign(t3, binop(Iop_And64, mkexpr(t1), mkU64(0x3)));
   14360 
   14361 #if defined (_MIPSEL)
   14362          /* Calculate X_byte position. */
   14363          assign(F_pos, IRExpr_ITE(binop(Iop_CmpEQ64, mkexpr(t3), mkU64(0x0)),
   14364                                   mkU64(0x2),
   14365                                   mkU64(0x3)));
   14366 
   14367          assign(G_pos, IRExpr_ITE(binop(Iop_CmpEQ64, mkexpr(t3), mkU64(0x3)),
   14368                                   mkU64(0x0),
   14369                                   mkU64(0x1)));
   14370 
   14371          /* Store X_byte on the right place. */
   14372          store(binop(Iop_Add64, mkexpr(t2), mkU64(0x3)), mkexpr(E_byte));
   14373          store(binop(Iop_Add64, mkexpr(t2), mkexpr(F_pos)), mkexpr(F_byte));
   14374          store(binop(Iop_Add64, mkexpr(t1), mkexpr(G_pos)), mkexpr(G_byte));
   14375          store(mkexpr(t1), mkexpr(H_byte));
   14376 
   14377 #else    /* _MIPSEB */
   14378          /* Calculate X_byte position. */
   14379          assign(F_pos, IRExpr_ITE(binop(Iop_CmpEQ64, mkexpr(t3), mkU64(0x3)),
   14380                                   mkU64(0x1),
   14381                                   mkU64(0x0)));
   14382 
   14383          assign(G_pos, IRExpr_ITE(binop(Iop_CmpEQ64, mkexpr(t3), mkU64(0x0)),
   14384                                   mkU64(0x0),
   14385                                   mkU64(0x1)));
   14386 
   14387          /* Store X_byte on the right place. */
   14388          store(mkexpr(t2), mkexpr(E_byte));
   14389          store(binop(Iop_Add64, mkexpr(t2), mkexpr(F_pos)), mkexpr(F_byte));
   14390          store(binop(Iop_Sub64, mkexpr(t1), mkexpr(G_pos)), mkexpr(G_byte));
   14391          store(mkexpr(t1), mkexpr(H_byte));
   14392 #endif
   14393       } else {
   14394          IRTemp E_byte = newTemp(Ity_I8);
   14395          IRTemp F_byte = newTemp(Ity_I8);
   14396          IRTemp G_byte = newTemp(Ity_I8);
   14397          IRTemp H_byte = newTemp(Ity_I8);
   14398          IRTemp F_pos  = newTemp(Ity_I32);
   14399          IRTemp G_pos  = newTemp(Ity_I32);
   14400 
   14401          /* H byte */
   14402          assign(H_byte, getByteFromReg(rt, 0));
   14403          /* G byte */
   14404          assign(G_byte, getByteFromReg(rt, 1));
   14405          /* F byte */
   14406          assign(F_byte, getByteFromReg(rt, 2));
   14407          /* E byte */
   14408          assign(E_byte, getByteFromReg(rt, 3));
   14409 
   14410          /* t1 = addr */
   14411          t1 = newTemp(Ity_I32);
   14412          assign(t1, binop(Iop_Add32, getIReg(rs), mkU32(extend_s_16to32(imm))));
   14413 
   14414          /* t2 = word addr */
   14415          t2 = newTemp(Ity_I32);
   14416          assign(t2, binop(Iop_And32, mkexpr(t1), mkU32(0xFFFFFFFCULL)));
   14417 
   14418          /* t3 = addr mod 4 */
   14419          t3 = newTemp(Ity_I32);
   14420          assign(t3, binop(Iop_And32, mkexpr(t1), mkU32(0x3)));
   14421 
   14422 #if defined (_MIPSEL)
   14423          /* Calculate X_byte position. */
   14424          assign(F_pos, IRExpr_ITE(binop(Iop_CmpEQ32, mkexpr(t3), mkU32(0x0)),
   14425                                   mkU32(0x2),
   14426                                   mkU32(0x3)));
   14427 
   14428          assign(G_pos, IRExpr_ITE(binop(Iop_CmpEQ32, mkexpr(t3), mkU32(0x3)),
   14429                                   mkU32(0x0),
   14430                                   mkU32(0x1)));
   14431 
   14432          /* Store X_byte on the right place. */
   14433          store(binop(Iop_Add32, mkexpr(t2), mkU32(0x3)), mkexpr(E_byte));
   14434          store(binop(Iop_Add32, mkexpr(t2), mkexpr(F_pos)), mkexpr(F_byte));
   14435          store(binop(Iop_Add32, mkexpr(t1), mkexpr(G_pos)), mkexpr(G_byte));
   14436          store(mkexpr(t1), mkexpr(H_byte));
   14437 
   14438 #else    /* _MIPSEB */
   14439          /* Calculate X_byte position. */
   14440          assign(F_pos, IRExpr_ITE(binop(Iop_CmpEQ32, mkexpr(t3), mkU32(0x3)),
   14441                                   mkU32(0x1),
   14442                                   mkU32(0x0)));
   14443 
   14444          assign(G_pos, IRExpr_ITE(binop(Iop_CmpEQ32, mkexpr(t3), mkU32(0x0)),
   14445                                   mkU32(0x0),
   14446                                   mkU32(0x1)));
   14447 
   14448          /* Store X_byte on the right place. */
   14449          store(mkexpr(t2), mkexpr(E_byte));
   14450          store(binop(Iop_Add32, mkexpr(t2), mkexpr(F_pos)), mkexpr(F_byte));
   14451          store(binop(Iop_Sub32, mkexpr(t1), mkexpr(G_pos)), mkexpr(G_byte));
   14452          store(mkexpr(t1), mkexpr(H_byte));
   14453 #endif
   14454       }
   14455       break;
   14456 
   14457    case 0x1C:  /* Special2 */
   14458       switch (function) {
   14459          /* Cavium Specific instructions */
   14460          case 0x03: case 0x32: case 0x33:  /* DMUL, CINS , CINS32 */
   14461          case 0x3A: case 0x3B: case 0x2B:  /* EXT,  EXT32, SNE    */
   14462          /* CVM Compare Instructions */
   14463          case 0x2A: case 0x2E: case 0x2F:  /* SEQ,  SEQI,  SNEI   */
   14464          /* CPU Load, Store, Memory, and Control Instructions */
   14465          case 0x18: case 0x19:             /* SAA, SAAD */
   14466          case 0x1F:                        /* LAA, LAAD, LAI, LAID */
   14467          case 0x28: case 0x2C: case 0x2D:  /* BADDU, POP, DPOP */
   14468             if (VEX_MIPS_COMP_ID(archinfo->hwcaps) == VEX_PRID_COMP_CAVIUM) {
   14469                if (dis_instr_CVM(cins))
   14470                   break;
   14471                goto decode_failure;
   14472             } else {
   14473                goto decode_failure;
   14474             }
   14475          break;
   14476 
   14477          case 0x02: {  /* MUL */
   14478             DIP("mul r%d, r%d, r%d", rd, rs, rt);
   14479             if (mode64) {
   14480                IRTemp tmpRs32 = newTemp(Ity_I32);
   14481                IRTemp tmpRt32 = newTemp(Ity_I32);
   14482                IRTemp tmpRes = newTemp(Ity_I32);
   14483 
   14484                assign(tmpRs32, mkNarrowTo32(ty, getIReg(rs)));
   14485                assign(tmpRt32, mkNarrowTo32(ty, getIReg(rt)));
   14486                assign(tmpRes, binop(Iop_Mul32,
   14487                                     mkexpr(tmpRs32), mkexpr(tmpRt32)));
   14488                putIReg(rd, mkWidenFrom32(ty, mkexpr(tmpRes), True));
   14489             } else
   14490                putIReg(rd, binop(Iop_Mul32, getIReg(rs), getIReg(rt)));
   14491             break;
   14492          }
   14493 
   14494          case 0x00: {  /* MADD */
   14495             if (mode64) {
   14496                DIP("madd r%d, r%d", rs, rt);
   14497                t1 = newTemp(Ity_I32);
   14498                t2 = newTemp(Ity_I32);
   14499                t3 = newTemp(Ity_I64);
   14500                t4 = newTemp(Ity_I64);
   14501                t5 = newTemp(Ity_I64);
   14502                t6 = newTemp(Ity_I32);
   14503 
   14504                assign(t1, mkNarrowTo32(ty, getHI()));
   14505                assign(t2, mkNarrowTo32(ty, getLO()));
   14506 
   14507                assign(t3, binop(Iop_MullS32, mkNarrowTo32(ty, getIReg(rs)),
   14508                                              mkNarrowTo32(ty, getIReg(rt))));
   14509 
   14510                assign(t4, binop(Iop_32HLto64, mkexpr(t1), mkexpr(t2)));
   14511                assign(t5, binop(Iop_Add64, mkexpr(t3), mkexpr(t4)));
   14512 
   14513                putHI(mkWidenFrom32(ty, unop(Iop_64HIto32, mkexpr(t5)), True));
   14514                putLO(mkWidenFrom32(ty, unop(Iop_64to32, mkexpr(t5)), True));
   14515             } else {
   14516                if ( (1 <= ac) && ( 3 >= ac) ) {
   14517                   if (VEX_MIPS_PROC_DSP(archinfo->hwcaps)) {
   14518                      /* If DSP is present -> DSP ASE MADD */
   14519                      UInt retVal = disDSPInstr_MIPS_WRK ( cins );
   14520                      if (0 != retVal ) {
   14521                         goto decode_failure_dsp;
   14522                      }
   14523                      break;
   14524                   } else {
   14525                      goto decode_failure_dsp;
   14526                   }
   14527                } else {
   14528                   DIP("madd r%d, r%d", rs, rt);
   14529                   t1 = newTemp(Ity_I32);
   14530                   t2 = newTemp(Ity_I32);
   14531                   t3 = newTemp(Ity_I64);
   14532                   t4 = newTemp(Ity_I32);
   14533                   t5 = newTemp(Ity_I32);
   14534                   t6 = newTemp(Ity_I32);
   14535 
   14536                   assign(t1, getHI());
   14537                   assign(t2, getLO());
   14538 
   14539                   assign(t3, binop(Iop_MullS32, getIReg(rs), getIReg(rt)));
   14540 
   14541                   assign(t4, binop(Iop_Add32, mkexpr(t2), unop(Iop_64to32,
   14542                                                                mkexpr(t3))));
   14543 
   14544                   assign(t5, unop(Iop_1Uto32, binop(Iop_CmpLT32U, mkexpr(t4),
   14545                                               unop(Iop_64to32, mkexpr(t3)))));
   14546                   assign(t6, binop(Iop_Add32, mkexpr(t5), mkexpr(t1)));
   14547 
   14548                   putHI(binop(Iop_Add32, mkexpr(t6), unop(Iop_64HIto32,
   14549                                                           mkexpr(t3))));
   14550                   putLO(mkexpr(t4));
   14551                   break;
   14552                }
   14553             }
   14554             break;
   14555          }
   14556 
   14557       case 0x01: {  /* MADDU */
   14558          if (mode64) {
   14559             DIP("maddu r%d, r%d", rs, rt);
   14560             t1 = newTemp(Ity_I32);
   14561             t2 = newTemp(Ity_I32);
   14562             t3 = newTemp(Ity_I64);
   14563             t4 = newTemp(Ity_I64);
   14564             t5 = newTemp(Ity_I64);
   14565             t6 = newTemp(Ity_I32);
   14566 
   14567             assign(t1, mkNarrowTo32(ty, getHI()));
   14568             assign(t2, mkNarrowTo32(ty, getLO()));
   14569 
   14570             assign(t3, binop(Iop_MullU32, mkNarrowTo32(ty, getIReg(rs)),
   14571                                           mkNarrowTo32(ty, getIReg(rt))));
   14572 
   14573             assign(t4, binop(Iop_32HLto64, mkexpr(t1), mkexpr(t2)));
   14574             assign(t5, binop(Iop_Add64, mkexpr(t3), mkexpr(t4)));
   14575 
   14576             putHI(mkWidenFrom32(ty, unop(Iop_64HIto32, mkexpr(t5)), True));
   14577             putLO(mkWidenFrom32(ty, unop(Iop_64to32, mkexpr(t5)), True));
   14578          } else {
   14579             if ( (1 <= ac) && ( 3 >= ac) ) {
   14580                if (VEX_MIPS_PROC_DSP(archinfo->hwcaps)) {
   14581                   /* If DSP is present -> DSP ASE MADDU */
   14582                   UInt retVal = disDSPInstr_MIPS_WRK ( cins );
   14583                   if (0 != retVal ) {
   14584                      goto decode_failure_dsp;
   14585                   }
   14586                   break;
   14587                } else {
   14588                   goto decode_failure_dsp;
   14589                }
   14590             } else {
   14591                DIP("maddu r%d, r%d", rs, rt);
   14592                t1 = newTemp(Ity_I32);
   14593                t2 = newTemp(Ity_I32);
   14594                t3 = newTemp(Ity_I64);
   14595                t4 = newTemp(Ity_I32);
   14596                t5 = newTemp(Ity_I32);
   14597                t6 = newTemp(Ity_I32);
   14598 
   14599                assign(t1, getHI());
   14600                assign(t2, getLO());
   14601 
   14602                assign(t3, binop(Iop_MullU32, getIReg(rs), getIReg(rt)));
   14603 
   14604                assign(t4, binop(Iop_Add32, mkexpr(t2), unop(Iop_64to32,
   14605                                                             mkexpr(t3))));
   14606                assign(t5, unop(Iop_1Uto32, binop(Iop_CmpLT32U, mkexpr(t4),
   14607                                            unop(Iop_64to32, mkexpr(t3)))));
   14608                assign(t6, binop(Iop_Add32, mkexpr(t5), mkexpr(t1)));
   14609 
   14610                putHI(binop(Iop_Add32, mkexpr(t6), unop(Iop_64HIto32,
   14611                                                       mkexpr(t3))));
   14612                putLO(mkexpr(t4));
   14613                break;
   14614             }
   14615          }
   14616          break;
   14617       }
   14618 
   14619       case 0x04: {  /* MSUB */
   14620          if (mode64) {
   14621             DIP("msub r%d, r%d", rs, rt);
   14622             t1 = newTemp(Ity_I32);
   14623             t2 = newTemp(Ity_I32);
   14624             t3 = newTemp(Ity_I64);
   14625             t4 = newTemp(Ity_I64);
   14626             t5 = newTemp(Ity_I64);
   14627             t6 = newTemp(Ity_I32);
   14628 
   14629             assign(t1, mkNarrowTo32(ty, getHI()));
   14630             assign(t2, mkNarrowTo32(ty, getLO()));
   14631 
   14632             assign(t3, binop(Iop_MullS32, mkNarrowTo32(ty, getIReg(rs)),
   14633                                           mkNarrowTo32(ty, getIReg(rt))));
   14634 
   14635             assign(t4, binop(Iop_32HLto64, mkexpr(t1), mkexpr(t2)));
   14636             assign(t5, binop(Iop_Sub64, mkexpr(t4), mkexpr(t3)));
   14637 
   14638             putHI(mkWidenFrom32(ty, unop(Iop_64HIto32, mkexpr(t5)), True));
   14639             putLO(mkWidenFrom32(ty, unop(Iop_64to32, mkexpr(t5)), True));
   14640          } else {
   14641             if ( (1 <= ac) && ( 3 >= ac) ) {
   14642                if (VEX_MIPS_PROC_DSP(archinfo->hwcaps)) {
   14643                   /* If DSP is present -> DSP ASE MSUB */
   14644                   UInt retVal = disDSPInstr_MIPS_WRK ( cins );
   14645                   if (0 != retVal ) {
   14646                      goto decode_failure_dsp;
   14647                   }
   14648                   break;
   14649                } else {
   14650                   goto decode_failure_dsp;
   14651                }
   14652             } else {
   14653                DIP("msub r%d, r%d", rs, rt);
   14654                t1 = newTemp(Ity_I32);
   14655                t2 = newTemp(Ity_I32);
   14656                t3 = newTemp(Ity_I64);
   14657                t4 = newTemp(Ity_I32);
   14658                t5 = newTemp(Ity_I1);
   14659                t6 = newTemp(Ity_I32);
   14660 
   14661                assign(t1, getHI());
   14662                assign(t2, getLO());
   14663 
   14664                assign(t3, binop(Iop_MullS32, getIReg(rs), getIReg(rt)));
   14665                assign(t4, unop(Iop_64to32, mkexpr(t3)));  /* new lo */
   14666 
   14667                /* if lo<lo(mul) hi = hi - 1 */
   14668                assign(t5, binop(Iop_CmpLT32U,
   14669                                  mkexpr(t2),
   14670                                  mkexpr(t4)));
   14671 
   14672                assign(t6, IRExpr_ITE(mkexpr(t5),
   14673                                        binop(Iop_Sub32, mkexpr(t1), mkU32(0x1)),
   14674                                        mkexpr(t1)));
   14675 
   14676                putHI(binop(Iop_Sub32, mkexpr(t6), unop(Iop_64HIto32,
   14677                                                       mkexpr(t3))));
   14678                putLO(binop(Iop_Sub32, mkexpr(t2), mkexpr(t4)));
   14679                break;
   14680             }
   14681          }
   14682          break;
   14683       }
   14684 
   14685       case 0x05: {  /* MSUBU */
   14686          if (mode64) {
   14687             DIP("msubu r%d, r%d", rs, rt);
   14688             t1 = newTemp(Ity_I32);
   14689             t2 = newTemp(Ity_I32);
   14690             t3 = newTemp(Ity_I64);
   14691             t4 = newTemp(Ity_I64);
   14692             t5 = newTemp(Ity_I64);
   14693             t6 = newTemp(Ity_I32);
   14694 
   14695             assign(t1, mkNarrowTo32(ty, getHI()));
   14696             assign(t2, mkNarrowTo32(ty, getLO()));
   14697 
   14698             assign(t3, binop(Iop_MullU32, mkNarrowTo32(ty, getIReg(rs)),
   14699                                           mkNarrowTo32(ty, getIReg(rt))));
   14700 
   14701             assign(t4, binop(Iop_32HLto64, mkexpr(t1), mkexpr(t2)));
   14702             assign(t5, binop(Iop_Sub64, mkexpr(t4), mkexpr(t3)));
   14703 
   14704             putHI(mkWidenFrom32(ty, unop(Iop_64HIto32, mkexpr(t5)), True));
   14705             putLO(mkWidenFrom32(ty, unop(Iop_64to32, mkexpr(t5)), True));
   14706          } else {
   14707             if ( (1 <= ac) && ( 3 >= ac) ) {
   14708                if (VEX_MIPS_PROC_DSP(archinfo->hwcaps)) {
   14709                   /* If DSP is present -> DSP ASE MSUBU */
   14710                   UInt retVal = disDSPInstr_MIPS_WRK ( cins );
   14711                   if (0 != retVal ) {
   14712                      goto decode_failure_dsp;
   14713                   }
   14714                   break;
   14715                } else {
   14716                   goto decode_failure_dsp;
   14717                }
   14718             } else {
   14719                DIP("msubu r%d, r%d", rs, rt);
   14720                t1 = newTemp(Ity_I32);
   14721                t2 = newTemp(Ity_I32);
   14722                t3 = newTemp(Ity_I64);
   14723                t4 = newTemp(Ity_I32);
   14724                t5 = newTemp(Ity_I1);
   14725                t6 = newTemp(Ity_I32);
   14726 
   14727                assign(t1, getHI());
   14728                assign(t2, getLO());
   14729 
   14730                assign(t3, binop(Iop_MullU32, getIReg(rs), getIReg(rt)));
   14731                assign(t4, unop(Iop_64to32, mkexpr(t3)));  /* new lo */
   14732 
   14733                /* if lo<lo(mul) hi = hi - 1 */
   14734                assign(t5, binop(Iop_CmpLT32U,
   14735                                  mkexpr(t2),
   14736                                  mkexpr(t4)));
   14737 
   14738                assign(t6, IRExpr_ITE(mkexpr(t5),
   14739                                     binop(Iop_Sub32,
   14740                                           mkexpr(t1),
   14741                                           mkU32(0x1)),
   14742                                     mkexpr(t1)));
   14743 
   14744                putHI(binop(Iop_Sub32, mkexpr(t6), unop(Iop_64HIto32,
   14745                                                       mkexpr(t3))));
   14746                putLO(binop(Iop_Sub32, mkexpr(t2), mkexpr(t4)));
   14747                break;
   14748             }
   14749          }
   14750          break;
   14751       }
   14752 
   14753       case 0x6:  /* dmul MIPS64 - Netlogic */
   14754          DIP("dmul r%u, r%u, r%u", rd, rs, rt);
   14755          t0 = newTemp(Ity_I128);
   14756 
   14757          assign(t0, binop(Iop_MullU64, getIReg(rs), getIReg(rt)));
   14758 
   14759          putIReg(rd, unop(Iop_128to64, mkexpr(t0)));
   14760          break;
   14761 
   14762       case 0x10:  /* LDADDW - Swap Word - Netlogic */
   14763          DIP("ldaddw r%u, r%u", rt, rs);
   14764          t0 = newTemp(Ity_I32);
   14765          t1 = newTemp(Ity_I32);
   14766          t2 = newTemp(Ity_I32);
   14767          t3 = newTemp(Ity_I64);
   14768          t4 = newTemp(Ity_I32);
   14769          t5 = newTemp(Ity_I32);
   14770          t6 = newTemp(Ity_I32);
   14771 
   14772          /* v = GPR[rt] */
   14773          assign(t0, mkNarrowTo32(ty, getIReg(rt)));
   14774 
   14775          /* GPR[rt] = memory[base]; */
   14776          assign(t1, load(Ity_I32, getIReg(rs)));
   14777          putIReg(rt, mkWidenFrom32(ty, mkexpr(t1), True));
   14778 
   14779          /* memory[base] = memory[base] + v; */
   14780          store(getIReg(rs), binop(Iop_Add32, mkexpr(t0), mkexpr(t1)));
   14781          break;
   14782 
   14783       case 0x12:  /* LDADDD - Swap Word - Netlogic */
   14784          DIP("ldaddw r%u, r%u", rt, rs);
   14785          t0 = newTemp(Ity_I64);
   14786          t1 = newTemp(Ity_I64);
   14787 
   14788          /*  v = GPR[rt] */
   14789          assign(t0, getIReg(rt));
   14790 
   14791          /* GPR[rt] = memory[base]; */
   14792          assign(t1, load(Ity_I64, getIReg(rs)));
   14793          putIReg(rt, mkexpr(t1));
   14794 
   14795          /* memory[base] = memory[base] + v; */
   14796          store(getIReg(rs), binop(Iop_Add64, mkexpr(t0), mkexpr(t1)));
   14797          break;
   14798 
   14799       case 0x14:  /* SWAPW - Swap Word - Netlogic */
   14800          DIP("swapw r%u, r%u", rt, rs);
   14801          t0 = newTemp(Ity_I32);
   14802          t1 = newTemp(Ity_I32);
   14803          assign(t0, mkNarrowTo32(ty, getIReg(rt)));
   14804          assign(t1, load(Ity_I32, getIReg(rs)));
   14805          putIReg(rt, mkWidenFrom32(ty, mkexpr(t1), True));
   14806          store(getIReg(rs), mkexpr(t0));
   14807          break;
   14808 
   14809       case 0x16:  /* SWAPD - Swap Double - Netlogic */
   14810          DIP("swapw r%u, r%u", rt, rs);
   14811          t0 = newTemp(Ity_I64);
   14812          t1 = newTemp(Ity_I64);
   14813          assign(t0, getIReg(rt));
   14814          assign(t1, load(Ity_I64, getIReg(rs)));
   14815          putIReg(rt, mkexpr(t1));
   14816          store(getIReg(rs), mkexpr(t0));
   14817          break;
   14818 
   14819       case 0x20: {  /* CLZ */
   14820          DIP("clz r%d, r%d", rd, rs);
   14821          if (mode64) {
   14822             IRTemp tmpClz32 = newTemp(Ity_I32);
   14823             IRTemp tmpRs32 = newTemp(Ity_I32);
   14824 
   14825             assign(tmpRs32, mkNarrowTo32(ty, getIReg(rs)));
   14826             assign(tmpClz32, unop(Iop_Clz32, mkexpr(tmpRs32)));
   14827             putIReg(rd, mkWidenFrom32(ty, mkexpr(tmpClz32), True));
   14828          } else {
   14829             t1 = newTemp(Ity_I1);
   14830             assign(t1, binop(Iop_CmpEQ32, getIReg(rs), mkU32(0)));
   14831             putIReg(rd, IRExpr_ITE(mkexpr(t1),
   14832                                    mkU32(0x00000020),
   14833                                    unop(Iop_Clz32, getIReg(rs))));
   14834          }
   14835          break;
   14836       }
   14837 
   14838       case 0x21: {  /* CLO */
   14839          DIP("clo r%d, r%d", rd, rs);
   14840          if (mode64) {
   14841             IRTemp tmpClo32 = newTemp(Ity_I32);
   14842             IRTemp tmpRs32 = newTemp(Ity_I32);
   14843             assign(tmpRs32, mkNarrowTo32(ty, getIReg(rs)));
   14844 
   14845             t1 = newTemp(Ity_I1);
   14846             assign(t1, binop(Iop_CmpEQ32, mkexpr(tmpRs32), mkU32(0xffffffff)));
   14847             assign(tmpClo32, IRExpr_ITE(mkexpr(t1),
   14848                       mkU32(0x00000020),
   14849                       unop(Iop_Clz32, unop(Iop_Not32, mkexpr(tmpRs32)))));
   14850 
   14851             putIReg(rd, mkWidenFrom32(ty, mkexpr(tmpClo32), True));
   14852             break;
   14853          } else {
   14854             t1 = newTemp(Ity_I1);
   14855             assign(t1, binop(Iop_CmpEQ32, getIReg(rs), mkU32(0xffffffff)));
   14856             putIReg(rd, IRExpr_ITE(mkexpr(t1),
   14857                                    mkU32(0x00000020),
   14858                                    unop(Iop_Clz32,
   14859                                         unop(Iop_Not32, getIReg(rs)))));
   14860             break;
   14861          }
   14862       }
   14863 
   14864       case 0x24:  /* Count Leading Zeros in Doubleword - DCLZ; MIPS64 */
   14865          DIP("dclz r%d, r%d", rd, rs);
   14866          t1 = newTemp(Ity_I1);
   14867          assign(t1, binop(Iop_CmpEQ64, getIReg(rs), mkU64(0)));
   14868          putIReg(rd, IRExpr_ITE(mkexpr(t1),
   14869                      mkU64(0x00000040),
   14870                      unop(Iop_Clz64, getIReg(rs))));
   14871          break;
   14872 
   14873       case 0x25:  /* Count Leading Ones in Doubleword - DCLO; MIPS64 */
   14874          DIP("dclo r%d, r%d", rd, rs);
   14875          t1 = newTemp(Ity_I1);
   14876          assign(t1, binop(Iop_CmpEQ64, getIReg(rs),
   14877                                         mkU64(0xffffffffffffffffULL)));
   14878          putIReg(rd, IRExpr_ITE(mkexpr(t1),
   14879                                 mkU64(0x40),
   14880                                 unop(Iop_Clz64, unop(Iop_Not64,
   14881                                                      getIReg(rs)))));
   14882          break;
   14883 
   14884       default:
   14885          goto decode_failure;
   14886       }
   14887       break;
   14888 
   14889    case 0x1F:  /* Special3 */
   14890       switch (function) {
   14891          case 0x01: {
   14892             /* Doubleword Extract Bit Field - DEXTM; MIPS64r2 */
   14893             msb = get_msb(cins);
   14894             lsb = get_lsb(cins);
   14895             size = msb + 1;
   14896             UInt srcPos = lsb;
   14897             UInt dstSz = msb + 33;
   14898             t1 = newTemp(Ity_I64);
   14899             DIP("dextm r%u, r%u, %d, %d", rt, rs, lsb, msb + 1);
   14900 
   14901             UChar lsAmt = 64 - (srcPos + dstSz);  /* left shift amount; */
   14902             UChar rsAmt = 64 - dstSz;  /* right shift amount; */
   14903 
   14904             assign(t1, binop(Iop_Shl64, getIReg(rs), mkU8(lsAmt)));
   14905             putIReg(rt, binop(Iop_Shr64, mkexpr(t1), mkU8(rsAmt)));
   14906 
   14907             break;
   14908          }
   14909          case 0x02: {
   14910             /* Doubleword Extract Bit Field Upper - DEXTU; MIPS64r2 */
   14911             msb = get_msb(cins);
   14912             lsb = get_lsb(cins);
   14913             size = msb + 1;
   14914             UInt srcPos = lsb + 32;
   14915             UInt dstSz = msb + 1;
   14916             DIP("dextu r%u, r%u, %d, %d", rt, rs, srcPos, dstSz);
   14917             t1 = newTemp(Ity_I64);
   14918 
   14919             vassert(srcPos >= 32 && srcPos < 64);
   14920             vassert(dstSz > 0 && dstSz <= 32);
   14921             vassert((srcPos + dstSz) > 32 && (srcPos + dstSz) <= 64);
   14922 
   14923             UChar lsAmt = 64 - (srcPos + dstSz);  /* left shift amount; */
   14924             UChar rsAmt = 64 - dstSz;  /* right shift amount; */
   14925 
   14926             assign(t1, binop(Iop_Shl64, getIReg(rs), mkU8(lsAmt)));
   14927             putIReg(rt, binop(Iop_Shr64, mkexpr(t1), mkU8(rsAmt)));
   14928             break;
   14929          }
   14930          case 0x05: {
   14931             /* Doubleword Insert Bit Field Middle - DINSM; MIPS64r2 */
   14932             msb = get_msb(cins);
   14933             lsb = get_lsb(cins);
   14934             size = msb + 1;
   14935             UInt dstPos = lsb;
   14936             UInt srcSz = msb - lsb + 33;
   14937             t1 = newTemp(ty);
   14938             t2 = newTemp(ty);
   14939             t3 = newTemp(ty);
   14940             t4 = newTemp(ty);
   14941             IRTemp tmpT1 = newTemp(ty);
   14942             IRTemp tmpT2 = newTemp(ty);
   14943             IRTemp tmpT3 = newTemp(ty);
   14944             IRTemp tmpT4 = newTemp(ty);
   14945             IRTemp tmpT5 = newTemp(ty);
   14946             IRTemp tmpT6 = newTemp(ty);
   14947             IRTemp tmpT7 = newTemp(ty);
   14948             IRTemp tmpRs = newTemp(ty);
   14949             IRTemp tmpRt = newTemp(ty);
   14950             IRTemp tmpRd = newTemp(ty);
   14951 
   14952             assign(tmpRs, getIReg(rs));
   14953             assign(tmpRt, getIReg(rt));
   14954             DIP("dinsm r%u, r%u, %d, %d", rt, rs, lsb, msb);
   14955 
   14956             UChar lsAmt = dstPos + srcSz - 1;   /* left shift amount; */
   14957             UChar rsAmt = dstPos + srcSz - 1;   /* right shift amount; */
   14958 
   14959             assign(t1, binop(Iop_Shr64, mkexpr(tmpRt), mkU8(rsAmt)));
   14960             assign(tmpT1, binop(Iop_Shr64, mkexpr(t1), mkU8(1)));
   14961             assign(t2, binop(Iop_Shl64, mkexpr(tmpT1), mkU8(lsAmt)));
   14962             assign(tmpT2, binop(Iop_Shl64, mkexpr(t2), mkU8(1)));
   14963 
   14964             lsAmt = 63 - dstPos; /* left shift amount; */
   14965             rsAmt = 63 - dstPos; /* right shift amount; */
   14966 
   14967             assign(t3, binop(Iop_Shl64, mkexpr(tmpRt), mkU8(lsAmt)));
   14968             assign(tmpT3, binop(Iop_Shl64, mkexpr(t3), mkU8(1)));
   14969             assign(t4, binop(Iop_Shr64, mkexpr(tmpT3), mkU8(rsAmt)));
   14970             assign(tmpT4, binop(Iop_Shr64, mkexpr(t4), mkU8(1)));
   14971 
   14972             /* extract size from src register */
   14973             lsAmt = 64 - srcSz;  /* left shift amount; */
   14974             rsAmt = 64 - (lsb + srcSz);   /* right shift amount; */
   14975 
   14976             assign(tmpT5, binop(Iop_Shl64, mkexpr(tmpRs), mkU8(lsAmt)));
   14977             assign(tmpT6, binop(Iop_Shr64, mkexpr(tmpT5), mkU8(rsAmt)));
   14978 
   14979             assign(tmpT7, binop(Iop_Or64, mkexpr(tmpT2), mkexpr(tmpT4)));
   14980             assign(tmpRd, binop(Iop_Or64, mkexpr(tmpT6), mkexpr(tmpT7)));
   14981             putIReg(rt, mkexpr(tmpRd));
   14982             break;
   14983          }
   14984          case 0x06: {
   14985             /* Doubleword Insert Bit Field Upper - DINSU; MIPS64r2 */
   14986             msb = get_msb(cins);
   14987             lsb = get_lsb(cins);
   14988             size = msb + 1;
   14989             UInt dstPos = lsb + 32;
   14990             UInt srcSz = msb - lsb + 1;
   14991             IRTemp tmpT1 = newTemp(ty);
   14992             IRTemp tmpT2 = newTemp(ty);
   14993             IRTemp tmpT3 = newTemp(ty);
   14994             IRTemp tmpT4 = newTemp(ty);
   14995             IRTemp tmpT5 = newTemp(ty);
   14996             IRTemp tmpT6 = newTemp(ty);
   14997             IRTemp tmpT7 = newTemp(ty);
   14998             IRTemp tmpT8 = newTemp(ty);
   14999             IRTemp tmpT9 = newTemp(ty);
   15000             IRTemp tmpRs = newTemp(ty);
   15001             IRTemp tmpRt = newTemp(ty);
   15002             IRTemp tmpRd = newTemp(ty);
   15003 
   15004             assign(tmpRs, getIReg(rs));
   15005             assign(tmpRt, getIReg(rt));
   15006             DIP("dinsu r%u, r%u, %d, %d", rt, rs, lsb, msb);
   15007 
   15008             UChar lsAmt = 64 - srcSz;  /* left shift amount; */
   15009             UChar rsAmt = 64 - (dstPos + srcSz);  /* right shift amount; */
   15010             assign(tmpT1, binop(Iop_Shl64, mkexpr(tmpRs), mkU8(lsAmt)));
   15011             assign(tmpT2, binop(Iop_Shr64, mkexpr(tmpT1), mkU8(rsAmt)));
   15012 
   15013             lsAmt = 64 - dstPos;  /* left shift amount; */
   15014             rsAmt = 64 - dstPos;  /* right shift amount; */
   15015             assign(tmpT3, binop(Iop_Shl64, mkexpr(tmpRt), mkU8(lsAmt)));
   15016             assign(tmpT4, binop(Iop_Shr64, mkexpr(tmpT3), mkU8(rsAmt)));
   15017 
   15018             lsAmt = dstPos;  /* left shift amount; */
   15019             rsAmt = srcSz;  /* right shift amount; */
   15020             assign(tmpT5, binop(Iop_Shr64, mkexpr(tmpRt), mkU8(rsAmt)));
   15021             assign(tmpT6, binop(Iop_Shr64, mkexpr(tmpT5), mkU8(lsAmt)));
   15022 
   15023             assign(tmpT7, binop(Iop_Shl64, mkexpr(tmpT6), mkU8(rsAmt)));
   15024             assign(tmpT8, binop(Iop_Shl64, mkexpr(tmpT7), mkU8(lsAmt)));
   15025 
   15026             assign(tmpT9, binop(Iop_Or64, mkexpr(tmpT8), mkexpr(tmpT4)));
   15027             assign(tmpRd, binop(Iop_Or64, mkexpr(tmpT2), mkexpr(tmpT9)));
   15028             putIReg(rt, mkexpr(tmpRd));
   15029             break;
   15030          }
   15031          case 0x07: {
   15032             /* Doubleword Insert Bit Field - DINS; MIPS64r2 */
   15033             IRTemp tmp1 = newTemp(ty);
   15034             IRTemp tmpT1 = newTemp(ty);
   15035             IRTemp tmpT2 = newTemp(ty);
   15036             IRTemp tmpT3 = newTemp(ty);
   15037             IRTemp tmpT4 = newTemp(ty);
   15038             IRTemp tmpT5 = newTemp(ty);
   15039             IRTemp tmpT6 = newTemp(ty);
   15040             IRTemp tmpT7 = newTemp(ty);
   15041             IRTemp tmpT8 = newTemp(ty);
   15042             IRTemp tmpT9 = newTemp(ty);
   15043             IRTemp tmp = newTemp(ty);
   15044             IRTemp tmpRs = newTemp(ty);
   15045             IRTemp tmpRt = newTemp(ty);
   15046             IRTemp tmpRd = newTemp(ty);
   15047 
   15048             assign(tmpRs, getIReg(rs));
   15049             assign(tmpRt, getIReg(rt));
   15050 
   15051             msb = get_msb(cins);
   15052             lsb = get_lsb(cins);
   15053             size = msb + 1;
   15054             DIP("dins r%u, r%u, %d, %d", rt, rs, lsb,
   15055                 msb - lsb + 1);
   15056             UChar lsAmt = 63 - lsb;  /* left shift amount; */
   15057             UChar rsAmt = 63 - lsb;  /* right shift amount; */
   15058             assign(tmp, binop(Iop_Shl64, mkexpr(tmpRt), mkU8(lsAmt)));
   15059             assign(tmpT1, binop(Iop_Shl64, mkexpr(tmp), mkU8(1)));
   15060             assign(tmp1, binop(Iop_Shr64, mkexpr(tmpT1), mkU8(rsAmt)));
   15061             assign(tmpT2, binop(Iop_Shr64, mkexpr(tmp1), mkU8(1)));
   15062 
   15063             lsAmt = msb;  /* left shift amount; */
   15064             rsAmt = 1;  /*right shift amount; */
   15065             assign(tmpT3, binop(Iop_Shr64, mkexpr(tmpRt), mkU8(rsAmt)));
   15066             assign(tmpT4, binop(Iop_Shr64, mkexpr(tmpT3), mkU8(lsAmt)));
   15067             assign(tmpT5, binop(Iop_Shl64, mkexpr(tmpT4), mkU8(rsAmt)));
   15068             assign(tmpT6, binop(Iop_Shl64, mkexpr(tmpT5), mkU8(lsAmt)));
   15069 
   15070             lsAmt = 64 - (msb - lsb + 1);  /* left shift amount; */
   15071             rsAmt = 64 - (msb + 1);  /* right shift amount; */
   15072             assign(tmpT7, binop(Iop_Shl64, mkexpr(tmpRs), mkU8(lsAmt)));
   15073             assign(tmpT8, binop(Iop_Shr64, mkexpr(tmpT7), mkU8(rsAmt)));
   15074 
   15075             assign(tmpT9, binop(Iop_Or64, mkexpr(tmpT2), mkexpr(tmpT8)));
   15076             assign(tmpRd, binop(Iop_Or64, mkexpr(tmpT6), mkexpr(tmpT9)));
   15077             putIReg(rt, mkexpr(tmpRd));
   15078             break;
   15079          }
   15080       case 0x24:  /* DBSHFL */
   15081          lsb = get_lsb(cins);
   15082          IRTemp tmpRs = newTemp(ty);
   15083          IRTemp tmpRt = newTemp(ty);
   15084          IRTemp tmpRd = newTemp(ty);
   15085          assign(tmpRs, getIReg(rs));
   15086          assign(tmpRt, getIReg(rt));
   15087          switch (lsb) {
   15088             case 0x02: {  /* DSBH */
   15089                DIP("dsbh r%u, r%u", rd, rt);
   15090                IRTemp tmpT1 = newTemp(ty);
   15091                IRTemp tmpT2 = newTemp(ty);
   15092                IRTemp tmpT3 = newTemp(ty);
   15093                IRTemp tmpT4 = newTemp(ty);
   15094                IRTemp tmpT5 = newTemp(Ity_I64);
   15095                IRTemp tmpT6 = newTemp(ty);
   15096                assign(tmpT5, mkU64(0xFF00FF00FF00FF00ULL));
   15097                assign(tmpT6, mkU64(0x00FF00FF00FF00FFULL));
   15098                assign(tmpT1, binop(Iop_And64, mkexpr(tmpRt), mkexpr(tmpT5)));
   15099                assign(tmpT2, binop(Iop_Shr64, mkexpr(tmpT1), mkU8(8)));
   15100                assign(tmpT3, binop(Iop_And64, mkexpr(tmpRt), mkexpr(tmpT6)));
   15101                assign(tmpT4, binop(Iop_Shl64, mkexpr(tmpT3), mkU8(8)));
   15102                assign(tmpRd, binop(Iop_Or64, mkexpr(tmpT4), mkexpr(tmpT2)));
   15103                putIReg(rd, mkexpr(tmpRd));
   15104                break;
   15105             }
   15106             case 0x05: {  /* DSHD */
   15107                DIP("dshd r%u, r%u\n", rd, rt);
   15108                IRTemp tmpT1 = newTemp(ty);
   15109                IRTemp tmpT2 = newTemp(ty);
   15110                IRTemp tmpT3 = newTemp(ty);
   15111                IRTemp tmpT4 = newTemp(ty);
   15112                IRTemp tmpT5 = newTemp(Ity_I64);
   15113                IRTemp tmpT6 = newTemp(ty);
   15114                IRTemp tmpT7 = newTemp(ty);
   15115                IRTemp tmpT8 = newTemp(ty);
   15116                IRTemp tmpT9 = newTemp(ty);
   15117                assign(tmpT5, mkU64(0xFFFF0000FFFF0000ULL));
   15118                assign(tmpT6, mkU64(0x0000FFFF0000FFFFULL));
   15119                assign(tmpT1, binop(Iop_And64, mkexpr(tmpRt), mkexpr(tmpT5)));
   15120                assign(tmpT2, binop(Iop_Shr64, mkexpr(tmpT1), mkU8(16)));
   15121                assign(tmpT3, binop(Iop_And64, mkexpr(tmpRt), mkexpr(tmpT6)));
   15122                assign(tmpT4, binop(Iop_Shl64, mkexpr(tmpT3), mkU8(16)));
   15123                assign(tmpT7, binop(Iop_Or64, mkexpr(tmpT4), mkexpr(tmpT2)));
   15124                assign(tmpT8, binop(Iop_Shl64, mkexpr(tmpT7), mkU8(32)));
   15125                assign(tmpT9, binop(Iop_Shr64, mkexpr(tmpT7), mkU8(32)));
   15126                assign(tmpRd, binop(Iop_Or64, mkexpr(tmpT8), mkexpr(tmpT9)));
   15127                putIReg(rd, mkexpr(tmpRd));
   15128                break;
   15129             }
   15130          default:
   15131             vex_printf("\nop6o10 = %d", lsb);
   15132             goto decode_failure;;
   15133          }
   15134          break;
   15135       case 0x3B: {  /* RDHWR */
   15136          DIP("rdhwr r%d, r%d", rt, rd);
   15137             if (rd == 29) {
   15138                putIReg(rt, getULR());
   15139 #if defined(__mips__) && ((defined(__mips_isa_rev) && __mips_isa_rev >= 2))
   15140             } else if (rd == 1) {
   15141                if (mode64) {
   15142                   IRTemp   val  = newTemp(Ity_I64);
   15143                   IRExpr** args = mkIRExprVec_2 (mkU64(rt), mkU64(rd));
   15144                   IRDirty *d = unsafeIRDirty_1_N(val,
   15145                                                  0,
   15146                                                  "mips64_dirtyhelper_rdhwr",
   15147                                                  &mips64_dirtyhelper_rdhwr,
   15148                                                  args);
   15149                   stmt(IRStmt_Dirty(d));
   15150                   putIReg(rt, mkexpr(val));
   15151                } else {
   15152                   IRTemp   val  = newTemp(Ity_I32);
   15153                   IRExpr** args = mkIRExprVec_2 (mkU32(rt), mkU32(rd));
   15154                   IRDirty *d = unsafeIRDirty_1_N(val,
   15155                                                  0,
   15156                                                  "mips32_dirtyhelper_rdhwr",
   15157                                                  &mips32_dirtyhelper_rdhwr,
   15158                                                  args);
   15159                   stmt(IRStmt_Dirty(d));
   15160                   putIReg(rt, mkexpr(val));
   15161                }
   15162 #endif
   15163             } else
   15164                goto decode_failure;
   15165             break;
   15166          }
   15167       case 0x04:  /* INS */
   15168          msb = get_msb(cins);
   15169          lsb = get_lsb(cins);
   15170          size = msb - lsb + 1;
   15171          DIP("ins size:%d msb:%d lsb:%d", size, msb, lsb);
   15172 
   15173          vassert(lsb + size <= 32);
   15174          vassert(lsb + size > 0);
   15175 
   15176          /* put size bits from rs at the pos in temporary */
   15177          t0 = newTemp(Ity_I32);
   15178          t3 = newTemp(Ity_I32);
   15179          /* shift left for 32 - size to clear leading bits and get zeros
   15180             at the end */
   15181          assign(t0, binop(Iop_Shl32, mkNarrowTo32(ty, getIReg(rs)),
   15182                           mkU8(32 - size)));
   15183          /* now set it at pos */
   15184          t1 = newTemp(Ity_I32);
   15185          assign(t1, binop(Iop_Shr32, mkexpr(t0), mkU8(32 - size - lsb)));
   15186 
   15187          if (lsb > 0) {
   15188             t2 = newTemp(Ity_I32);
   15189             /* clear everything but lower pos bits from rt */
   15190             assign(t2, binop(Iop_Shl32, mkNarrowTo32(ty, getIReg(rt)),
   15191                              mkU8(32 - lsb)));
   15192             assign(t3, binop(Iop_Shr32, mkexpr(t2), mkU8(32 - lsb)));
   15193          } else
   15194             assign(t3, mkU32(0));
   15195 
   15196          if (msb < 31) {
   15197             t4 = newTemp(Ity_I32);
   15198             /* clear everything but upper msb + 1 bits from rt */
   15199             assign(t4, binop(Iop_Shr32, mkNarrowTo32(ty, getIReg(rt)),
   15200                              mkU8(msb + 1)));
   15201             t5 = newTemp(Ity_I32);
   15202             assign(t5, binop(Iop_Shl32, mkexpr(t4), mkU8(msb + 1)));
   15203 
   15204             /* now combine these registers */
   15205             if (lsb > 0) {
   15206                t6 = newTemp(Ity_I32);
   15207                assign(t6, binop(Iop_Or32, mkexpr(t5), mkexpr(t1)));
   15208                putIReg(rt, mkWidenFrom32(ty, binop(Iop_Or32, mkexpr(t6),
   15209                                                    mkexpr(t3)), True));
   15210             } else {
   15211                putIReg(rt, mkWidenFrom32(ty, binop(Iop_Or32, mkexpr(t1),
   15212                                                    mkexpr(t5)), True));
   15213             }
   15214          } else {
   15215             putIReg(rt, mkWidenFrom32(ty, binop(Iop_Or32, mkexpr(t1),
   15216                                                 mkexpr(t3)), True));
   15217          }
   15218          break;
   15219 
   15220       case 0x00:  /* EXT */
   15221          msb = get_msb(cins);
   15222          lsb = get_lsb(cins);
   15223          size = msb + 1;
   15224          DIP("ext size:%d msb:%d lsb:%d", size, msb, lsb);
   15225          vassert(lsb + size <= 32);
   15226          vassert(lsb + size > 0);
   15227          /* put size bits from rs at the top of in temporary */
   15228          if (lsb + size < 32) {
   15229             t0 = newTemp(Ity_I32);
   15230             assign(t0, binop(Iop_Shl32, mkNarrowTo32(ty, getIReg(rs)),
   15231                              mkU8(32 - lsb - size)));
   15232 
   15233             putIReg(rt, mkWidenFrom32(ty, binop(Iop_Shr32, mkexpr(t0),
   15234                                                 mkU8(32 - size)), True));
   15235          } else {
   15236             putIReg(rt, mkWidenFrom32(ty, binop(Iop_Shr32,
   15237                                                 mkNarrowTo32(ty, getIReg(rs)),
   15238                                                 mkU8(32 - size)), True));
   15239          }
   15240          break;
   15241 
   15242       case 0x03:  /* Doubleword Extract Bit Field - DEXT; MIPS64r2 */
   15243          msb = get_msb(cins);
   15244          lsb = get_lsb(cins);
   15245          size = msb + 1;
   15246          DIP("dext r%u, r%u, %d, %d", rt, rs, lsb, msb + 1);
   15247          t1 = newTemp(Ity_I64);
   15248          vassert(lsb >= 0 && lsb < 32);
   15249          vassert(size > 0 && size <= 32);
   15250          vassert((lsb + size) > 0 && (lsb + size) <= 63);
   15251 
   15252          UChar lsAmt = 63 - (lsb + msb);  /* left shift amount; */
   15253          UChar rsAmt = 63 - msb;  /* right shift amount; */
   15254 
   15255          assign(t1, binop(Iop_Shl64, getIReg(rs), mkU8(lsAmt)));
   15256          putIReg(rt, binop(Iop_Shr64, mkexpr(t1), mkU8(rsAmt)));
   15257 
   15258          break;
   15259 
   15260       case 0x20:  /* BSHFL */
   15261          switch (sa) {
   15262             case 0x02:  /* WSBH */
   15263                DIP("wsbh r%d, r%d", rd, rt);
   15264                t0 = newTemp(Ity_I32);
   15265                t1 = newTemp(Ity_I32);
   15266                t2 = newTemp(Ity_I32);
   15267                t3 = newTemp(Ity_I32);
   15268                assign(t0, binop(Iop_Shl32, binop(Iop_And32, mkNarrowTo32(ty,
   15269                                            getIReg(rt)), mkU32(0x00FF0000)),
   15270                                            mkU8(0x8)));
   15271                assign(t1, binop(Iop_Shr32, binop(Iop_And32, mkNarrowTo32(ty,
   15272                                 getIReg(rt)), mkU32(0xFF000000)), mkU8(0x8)));
   15273                assign(t2, binop(Iop_Shl32, binop(Iop_And32, mkNarrowTo32(ty,
   15274                                 getIReg(rt)), mkU32(0x000000FF)), mkU8(0x8)));
   15275                assign(t3, binop(Iop_Shr32, binop(Iop_And32, mkNarrowTo32(ty,
   15276                                 getIReg(rt)), mkU32(0x0000FF00)), mkU8(0x8)));
   15277                putIReg(rd, mkWidenFrom32(ty, binop(Iop_Or32, binop(Iop_Or32,
   15278                                          mkexpr(t0), mkexpr(t1)),
   15279                                          binop(Iop_Or32, mkexpr(t2),
   15280                                          mkexpr(t3))), True));
   15281                break;
   15282 
   15283             case 0x10:  /* SEB */
   15284                DIP("seb r%d, r%d", rd, rt);
   15285                if (mode64)
   15286                   putIReg(rd, unop(Iop_8Sto64, unop(Iop_64to8, getIReg(rt))));
   15287                else
   15288                   putIReg(rd, unop(Iop_8Sto32, unop(Iop_32to8, getIReg(rt))));
   15289                break;
   15290 
   15291             case 0x18:  /* SEH */
   15292                DIP("seh r%d, r%d", rd, rt);
   15293                if (mode64)
   15294                   putIReg(rd, unop(Iop_16Sto64, unop(Iop_64to16, getIReg(rt))));
   15295                else
   15296                   putIReg(rd, unop(Iop_16Sto32, unop(Iop_32to16, getIReg(rt))));
   15297                break;
   15298 
   15299             default:
   15300                goto decode_failure;
   15301 
   15302          }
   15303          break;  /* BSHFL */
   15304 
   15305       /* --- MIPS32(r2) DSP ASE(r2) / Cavium Specfic (LX) instructions --- */
   15306       case 0xA:  /* LX */
   15307          if (VEX_MIPS_COMP_ID(archinfo->hwcaps) == VEX_PRID_COMP_CAVIUM) {
   15308             if (dis_instr_CVM(cins))
   15309                break;
   15310             goto decode_failure;
   15311          }
   15312       case 0xC:  /* INSV */
   15313       case 0x38: {  /* EXTR.W */
   15314          if (VEX_MIPS_PROC_DSP(archinfo->hwcaps)) {
   15315             UInt retVal = disDSPInstr_MIPS_WRK ( cins );
   15316             if (0 != retVal ) {
   15317                goto decode_failure_dsp;
   15318             }
   15319             break;
   15320          } else {
   15321             goto decode_failure_dsp;
   15322          }
   15323          break;
   15324       }
   15325       case 0x10: {  /* ADDU.QB */
   15326          switch(sa) {
   15327             case  0xC:  /* SUBU_S.PH */
   15328             case  0xD:  /* ADDU_S.PH */
   15329             case 0x1E: {  /* MULQ_S.PH */
   15330                if (VEX_MIPS_PROC_DSP2(archinfo->hwcaps)) {
   15331                   UInt retVal = disDSPInstr_MIPS_WRK ( cins );
   15332                   if (0 != retVal ) {
   15333                      goto decode_failure_dsp;
   15334                   }
   15335                   break;
   15336                } else {
   15337                   goto decode_failure_dsp;
   15338                }
   15339                break;
   15340             }
   15341             default: {
   15342                if (VEX_MIPS_PROC_DSP(archinfo->hwcaps)) {
   15343                   UInt retVal = disDSPInstr_MIPS_WRK ( cins );
   15344                   if (0 != retVal ) {
   15345                      goto decode_failure_dsp;
   15346                   }
   15347                   break;
   15348                } else {
   15349                   goto decode_failure_dsp;
   15350                }
   15351                break;
   15352             }
   15353          }
   15354          break;
   15355       }
   15356       case 0x11: {  /* CMPU.EQ.QB */
   15357          switch(sa) {
   15358             case 0x18:  /* CMPGDU.EQ.QB */
   15359             case 0x19:  /* CMPGDU.LT.QB */
   15360             case 0x1A:  /* CMPGDU.LE.QB */
   15361             case 0x0D:  /* PRECR.QB.PH */
   15362             case 0x1E:  /* PRECR_SRA.PH.W */
   15363             case 0x1F: {  /* PRECR_SRA_R.PH.W */
   15364                if (VEX_MIPS_PROC_DSP2(archinfo->hwcaps)) {
   15365                   UInt retVal = disDSPInstr_MIPS_WRK ( cins );
   15366                   if (0 != retVal ) {
   15367                      goto decode_failure_dsp;
   15368                   }
   15369                   break;
   15370                } else {
   15371                   goto decode_failure_dsp;
   15372                }
   15373                break;
   15374             }
   15375             default: {
   15376                if (VEX_MIPS_PROC_DSP(archinfo->hwcaps)) {
   15377                   UInt retVal = disDSPInstr_MIPS_WRK ( cins );
   15378                   if (0 != retVal ) {
   15379                      goto decode_failure_dsp;
   15380                   }
   15381                   break;
   15382                } else {
   15383                   goto decode_failure_dsp;
   15384                }
   15385                break;
   15386             }
   15387          }
   15388          break;
   15389       }
   15390       case 0x12: {  /* ABSQ_S.PH */
   15391          switch(sa){
   15392             case 0x1: {  /* ABSQ_S.QB */
   15393                if (VEX_MIPS_PROC_DSP2(archinfo->hwcaps)) {
   15394                   UInt retVal = disDSPInstr_MIPS_WRK ( cins );
   15395                   if (0 != retVal ) {
   15396                      goto decode_failure_dsp;
   15397                   }
   15398                   break;
   15399                } else {
   15400                   goto decode_failure_dsp;
   15401                }
   15402                break;
   15403             }
   15404             default: {
   15405                if (VEX_MIPS_PROC_DSP(archinfo->hwcaps)) {
   15406                   UInt retVal = disDSPInstr_MIPS_WRK ( cins );
   15407                   if (0 != retVal ) {
   15408                      goto decode_failure_dsp;
   15409                   }
   15410                   break;
   15411                } else {
   15412                   goto decode_failure_dsp;
   15413                }
   15414                break;
   15415             }
   15416          }
   15417          break;
   15418       }
   15419       case 0x13: {  /* SHLL.QB */
   15420          switch(sa) {
   15421             case 0x04:  /* SHRA.QB */
   15422             case 0x05:  /* SHRA_R.QB */
   15423             case 0x06:  /* SHRAV.QB */
   15424             case 0x07:  /* SHRAV_R.QB */
   15425             case 0x19:  /* SHLR.PH */
   15426             case 0x1B: {  /* SHLRV.PH */
   15427                if (VEX_MIPS_PROC_DSP2(archinfo->hwcaps)) {
   15428                   UInt retVal = disDSPInstr_MIPS_WRK ( cins );
   15429                   if (0 != retVal ) {
   15430                      goto decode_failure_dsp;
   15431                   }
   15432                   break;
   15433                } else {
   15434                   goto decode_failure_dsp;
   15435                }
   15436                break;
   15437             }
   15438             default: {
   15439                if (VEX_MIPS_PROC_DSP(archinfo->hwcaps)) {
   15440                   UInt retVal = disDSPInstr_MIPS_WRK ( cins );
   15441                   if (0 != retVal ) {
   15442                      goto decode_failure_dsp;
   15443                   }
   15444                   break;
   15445                } else {
   15446                   goto decode_failure_dsp;
   15447                }
   15448                break;
   15449             }
   15450          }
   15451          break;
   15452       }
   15453       case 0x30: {  /* DPAQ.W.PH */
   15454          switch(sa) {
   15455             case  0x0:  /* DPA.W.PH */
   15456             case 0x18:  /* DPAQX_S.W.PH */
   15457             case 0x1A:  /* DPAQX_SA.W.PH */
   15458             case  0x8:  /* DPAX.W.PH */
   15459             case  0x1:  /* DPS.W.PH */
   15460             case 0x19:  /* DPSQX_S.W.PH */
   15461             case 0x1B:  /* DPSQX_SA.W.PH */
   15462             case  0x9:  /* DPSX.W.PH */
   15463             case  0x2: {  /* MULSA.W.PH */
   15464                if (VEX_MIPS_PROC_DSP2(archinfo->hwcaps)) {
   15465                   UInt retVal = disDSPInstr_MIPS_WRK ( cins );
   15466                   if (0 != retVal ) {
   15467                      goto decode_failure_dsp;
   15468                   }
   15469                   break;
   15470                } else {
   15471                   goto decode_failure_dsp;
   15472                }
   15473                break;
   15474             }
   15475             default: {
   15476                if (VEX_MIPS_PROC_DSP(archinfo->hwcaps)) {
   15477                   UInt retVal = disDSPInstr_MIPS_WRK ( cins );
   15478                   if (0 != retVal ) {
   15479                      goto decode_failure_dsp;
   15480                   }
   15481                   break;
   15482                } else {
   15483                   goto decode_failure_dsp;
   15484                }
   15485                break;
   15486             }
   15487          }
   15488          break;
   15489       }
   15490       case 0x18:  /* ADDUH.QB/MUL.PH */
   15491       case 0x31: {  /* APPEND */
   15492          if (VEX_MIPS_PROC_DSP2(archinfo->hwcaps)) {
   15493             UInt retVal = disDSPInstr_MIPS_WRK ( cins );
   15494             if (0 != retVal ) {
   15495                goto decode_failure_dsp;
   15496             }
   15497             break;
   15498          } else {
   15499             goto decode_failure_dsp;
   15500          }
   15501       }
   15502       default:
   15503          goto decode_failure;
   15504 
   15505    }
   15506       break;  /* Special3 */
   15507 
   15508    case 0x3B:
   15509       if (0x3B == function &&
   15510           (VEX_MIPS_COMP_ID(archinfo->hwcaps) == VEX_PRID_COMP_BROADCOM)) {
   15511          /*RDHWR*/
   15512          DIP("rdhwr r%d, r%d", rt, rd);
   15513          if (rd == 29) {
   15514             putIReg(rt, getULR());
   15515          } else
   15516             goto decode_failure;
   15517          break;
   15518       } else {
   15519          goto decode_failure;
   15520       }
   15521 
   15522    case 0x00:  /* Special */
   15523 
   15524       switch (function) {
   15525       case 0x1: {
   15526          UInt mov_cc = get_mov_cc(cins);
   15527          if (tf == 0) {  /* MOVF */
   15528             DIP("movf r%d, r%d, %d", rd, rs, mov_cc);
   15529             t1 = newTemp(Ity_I1);
   15530             t2 = newTemp(Ity_I32);
   15531             t3 = newTemp(Ity_I1);
   15532 
   15533             assign(t1, binop(Iop_CmpEQ32, mkU32(0), mkU32(mov_cc)));
   15534             assign(t2, IRExpr_ITE(mkexpr(t1),
   15535                                   binop(Iop_And32,
   15536                                         binop(Iop_Shr32, getFCSR(),
   15537                                               mkU8(23)),
   15538                                         mkU32(0x1)),
   15539                                   binop(Iop_And32,
   15540                                         binop(Iop_Shr32, getFCSR(),
   15541                                               mkU8(24 + mov_cc)),
   15542                                         mkU32(0x1))
   15543                                   ));
   15544             assign(t3, binop(Iop_CmpEQ32, mkU32(0), mkexpr(t2)));
   15545             putIReg(rd, IRExpr_ITE(mkexpr(t3), getIReg(rs), getIReg(rd)));
   15546          } else if (tf == 1) {  /* MOVT */
   15547             DIP("movt r%d, r%d, %d", rd, rs, mov_cc);
   15548             t1 = newTemp(Ity_I1);
   15549             t2 = newTemp(Ity_I32);
   15550             t3 = newTemp(Ity_I1);
   15551 
   15552             assign(t1, binop(Iop_CmpEQ32, mkU32(0), mkU32(mov_cc)));
   15553             assign(t2, IRExpr_ITE(mkexpr(t1),
   15554                                   binop(Iop_And32,
   15555                                         binop(Iop_Shr32, getFCSR(),
   15556                                               mkU8(23)),
   15557                                         mkU32(0x1)),
   15558                                   binop(Iop_And32,
   15559                                         binop(Iop_Shr32, getFCSR(),
   15560                                               mkU8(24 + mov_cc)),
   15561                                         mkU32(0x1))
   15562                                   ));
   15563             assign(t3, binop(Iop_CmpEQ32, mkU32(1), mkexpr(t2)));
   15564             putIReg(rd, IRExpr_ITE(mkexpr(t3), getIReg(rs), getIReg(rd)));
   15565          }
   15566          break;
   15567       }
   15568       case 0x0A: {  /* MOVZ */
   15569          DIP("movz r%d, r%d, r%d", rd, rs, rt);
   15570          t1 = newTemp(ty);
   15571          t2 = newTemp(ty);
   15572          if (mode64) {
   15573             assign(t1, unop(Iop_32Sto64, unop(Iop_1Sto32, binop(Iop_CmpEQ64,
   15574                             getIReg(rt), mkU64(0x0)))));
   15575             assign(t2, unop(Iop_32Sto64, unop(Iop_1Sto32, binop(Iop_CmpNE64,
   15576                             getIReg(rt), mkU64(0x0)))));
   15577             putIReg(rd, binop(Iop_Add64, binop(Iop_And64, getIReg(rs),
   15578                         mkexpr(t1)), binop(Iop_And64, getIReg(rd),mkexpr(t2))));
   15579          } else {
   15580             assign(t1, unop(Iop_1Sto32, binop(Iop_CmpEQ32, getIReg(rt),
   15581                                               mkU32(0x0))));
   15582             assign(t2, unop(Iop_1Sto32, binop(Iop_CmpNE32, getIReg(rt),
   15583                                               mkU32(0x0))));
   15584             putIReg(rd, binop(Iop_Add32, binop(Iop_And32, getIReg(rs),
   15585                         mkexpr(t1)), binop(Iop_And32, getIReg(rd),
   15586                         mkexpr(t2))));
   15587          }
   15588          break;
   15589       }
   15590 
   15591       case 0x0B: {  /* MOVN */
   15592          DIP("movn r%d, r%d, r%d", rd, rs, rt);
   15593          t1 = newTemp(ty);
   15594          t2 = newTemp(ty);
   15595          if (mode64) {
   15596             assign(t1, unop(Iop_32Sto64, unop(Iop_1Sto32, binop(Iop_CmpEQ64,
   15597                             getIReg(rt), mkU64(0x0)))));
   15598             assign(t2, unop(Iop_32Sto64, unop(Iop_1Sto32, binop(Iop_CmpNE64,
   15599                             getIReg(rt), mkU64(0x0)))));
   15600             putIReg(rd, binop(Iop_Add64, binop(Iop_And64, getIReg(rs),
   15601                         mkexpr(t2)), binop(Iop_And64, getIReg(rd),
   15602                                            mkexpr(t1))));
   15603          } else {
   15604             assign(t1, unop(Iop_1Sto32, binop(Iop_CmpEQ32, getIReg(rt),
   15605                                               mkU32(0x0))));
   15606             assign(t2, unop(Iop_1Sto32, binop(Iop_CmpNE32, getIReg(rt),
   15607                                               mkU32(0x0))));
   15608             putIReg(rd, binop(Iop_Add32, binop(Iop_And32, getIReg(rs),
   15609                         mkexpr(t2)), binop(Iop_And32, getIReg(rd),
   15610                         mkexpr(t1))));
   15611          }
   15612          break;
   15613       }
   15614 
   15615       case 0x18:  {  /* MULT */
   15616          if ( (1 <= ac) && ( 3 >= ac) ) {
   15617             if (VEX_MIPS_PROC_DSP(archinfo->hwcaps)) {
   15618                /* If DSP is present -> DSP ASE MULT */
   15619                UInt retVal = disDSPInstr_MIPS_WRK ( cins );
   15620                if (0 != retVal ) {
   15621                   goto decode_failure_dsp;
   15622                }
   15623                break;
   15624             } else {
   15625                goto decode_failure_dsp;
   15626             }
   15627          } else {
   15628             DIP("mult r%d, r%d", rs, rt);
   15629             t2 = newTemp(Ity_I64);
   15630 
   15631             assign(t2, binop(Iop_MullS32, mkNarrowTo32(ty, getIReg(rs)),
   15632                                           mkNarrowTo32(ty, getIReg(rt))));
   15633 
   15634             putHI(mkWidenFrom32(ty, unop(Iop_64HIto32, mkexpr(t2)), True));
   15635             putLO(mkWidenFrom32(ty, unop(Iop_64to32, mkexpr(t2)), True));
   15636             break;
   15637          }
   15638       }
   15639       case 0x19:  {  /* MULTU */
   15640          if ( (1 <= ac) && ( 3 >= ac) ) {
   15641             if (VEX_MIPS_PROC_DSP(archinfo->hwcaps)) {
   15642                /* If DSP is present -> DSP ASE MULTU */
   15643                UInt retVal = disDSPInstr_MIPS_WRK ( cins );
   15644                if (0 != retVal ) {
   15645                   goto decode_failure_dsp;
   15646                }
   15647                break;
   15648             } else {
   15649                goto decode_failure_dsp;
   15650             }
   15651          } else {
   15652             DIP("multu r%d, r%d", rs, rt);
   15653             t2 = newTemp(Ity_I64);
   15654 
   15655             assign(t2, binop(Iop_MullU32, mkNarrowTo32(ty, getIReg(rs)),
   15656                                           mkNarrowTo32(ty, getIReg(rt))));
   15657 
   15658             putHI(mkWidenFrom32(ty, unop(Iop_64HIto32, mkexpr(t2)), True));
   15659             putLO(mkWidenFrom32(ty, unop(Iop_64to32, mkexpr(t2)), True));
   15660             break;
   15661          }
   15662       }
   15663       case 0x20: {  /* ADD */
   15664          DIP("add r%d, r%d, r%d", rd, rs, rt);
   15665          IRTemp tmpRs32 = newTemp(Ity_I32);
   15666          IRTemp tmpRt32 = newTemp(Ity_I32);
   15667 
   15668          assign(tmpRs32, mkNarrowTo32(ty, getIReg(rs)));
   15669          assign(tmpRt32, mkNarrowTo32(ty, getIReg(rt)));
   15670 
   15671          t0 = newTemp(Ity_I32);
   15672          t1 = newTemp(Ity_I32);
   15673          t2 = newTemp(Ity_I32);
   15674          t3 = newTemp(Ity_I32);
   15675          t4 = newTemp(Ity_I32);
   15676          /* dst = src0 + src1
   15677             if (sign(src0 ) != sign(src1 ))
   15678             goto no overflow;
   15679             if (sign(dst) == sign(src0 ))
   15680             goto no overflow;
   15681             we have overflow! */
   15682 
   15683          assign(t0, binop(Iop_Add32, mkexpr(tmpRs32), mkexpr(tmpRt32)));
   15684          assign(t1, binop(Iop_Xor32, mkexpr(tmpRs32), mkexpr(tmpRt32)));
   15685          assign(t2, unop(Iop_1Uto32,
   15686                          binop(Iop_CmpEQ32,
   15687                                binop(Iop_And32, mkexpr(t1), mkU32(0x80000000)),
   15688                                mkU32(0x80000000))));
   15689 
   15690          assign(t3, binop(Iop_Xor32, mkexpr(t0), mkexpr(tmpRs32)));
   15691          assign(t4, unop(Iop_1Uto32,
   15692                          binop(Iop_CmpNE32,
   15693                                binop(Iop_And32, mkexpr(t3), mkU32(0x80000000)),
   15694                                mkU32(0x80000000))));
   15695 
   15696          stmt(IRStmt_Exit(binop(Iop_CmpEQ32,
   15697                                 binop(Iop_Or32, mkexpr(t2), mkexpr(t4)),
   15698                                 mkU32(0)),
   15699                           Ijk_SigFPE_IntOvf,
   15700                           mode64 ? IRConst_U64(guest_PC_curr_instr + 4) :
   15701                                    IRConst_U32(guest_PC_curr_instr + 4),
   15702                           OFFB_PC));
   15703 
   15704          putIReg(rd,  mkWidenFrom32(ty, mkexpr(t0), True));
   15705          break;
   15706       }
   15707       case 0x1A:  /* DIV */
   15708          DIP("div r%d, r%d", rs, rt);
   15709          if (mode64) {
   15710             t2 = newTemp(Ity_I64);
   15711 
   15712             assign(t2, binop(Iop_DivModS64to32,
   15713                              getIReg(rs), mkNarrowTo32(ty, getIReg(rt))));
   15714 
   15715             putHI(mkWidenFrom32(ty, unop(Iop_64HIto32, mkexpr(t2)), True));
   15716             putLO(mkWidenFrom32(ty, unop(Iop_64to32, mkexpr(t2)), True));
   15717          } else {
   15718             t1 = newTemp(Ity_I64);
   15719             t2 = newTemp(Ity_I64);
   15720 
   15721             assign(t1, unop(Iop_32Sto64, getIReg(rs)));
   15722             assign(t2, binop(Iop_DivModS64to32, mkexpr(t1), getIReg(rt)));
   15723 
   15724             putHI(unop(Iop_64HIto32, mkexpr(t2)));
   15725             putLO(unop(Iop_64to32, mkexpr(t2)));
   15726          }
   15727          break;
   15728 
   15729       case 0x1B:  /* DIVU */
   15730          DIP("divu r%d, r%d", rs, rt);
   15731          if (mode64) {
   15732             t2 = newTemp(Ity_I64);
   15733 
   15734             assign(t2, binop(Iop_DivModU64to32,
   15735                              getIReg(rs), mkNarrowTo32(ty, getIReg(rt))));
   15736 
   15737             putHI(mkWidenFrom32(ty, unop(Iop_64HIto32, mkexpr(t2)), True));
   15738             putLO(mkWidenFrom32(ty, unop(Iop_64to32, mkexpr(t2)), True));
   15739          } else {
   15740             t1 = newTemp(Ity_I64);
   15741             t2 = newTemp(Ity_I64);
   15742             assign(t1, unop(Iop_32Uto64, getIReg(rs)));
   15743             assign(t2, binop(Iop_DivModU64to32, mkexpr(t1), getIReg(rt)));
   15744             putHI(unop(Iop_64HIto32, mkexpr(t2)));
   15745             putLO(unop(Iop_64to32, mkexpr(t2)));
   15746          }
   15747          break;
   15748 
   15749       case 0x1C:  /* Doubleword Multiply - DMULT; MIPS64 */
   15750          DIP("dmult r%u, r%u", rs, rt);
   15751          t0 = newTemp(Ity_I128);
   15752 
   15753          assign(t0, binop(Iop_MullS64, getIReg(rs), getIReg(rt)));
   15754 
   15755          putHI(unop(Iop_128HIto64, mkexpr(t0)));
   15756          putLO(unop(Iop_128to64, mkexpr(t0)));
   15757          break;
   15758 
   15759       case 0x1D:  /* Doubleword Multiply Unsigned - DMULTU; MIPS64 */
   15760          DIP("dmultu r%u, r%u", rs, rt);
   15761          t0 = newTemp(Ity_I128);
   15762 
   15763          assign(t0, binop(Iop_MullU64, getIReg(rs), getIReg(rt)));
   15764 
   15765          putHI(unop(Iop_128HIto64, mkexpr(t0)));
   15766          putLO(unop(Iop_128to64, mkexpr(t0)));
   15767          break;
   15768 
   15769       case 0x1E:  /* Doubleword Divide DDIV; MIPS64 */
   15770          DIP("ddiv r%u, r%u", rs, rt);
   15771          t1 = newTemp(Ity_I128);
   15772 
   15773          assign(t1, binop(Iop_DivModS64to64, getIReg(rs), getIReg(rt)));
   15774 
   15775          putHI(unop(Iop_128HIto64, mkexpr(t1)));
   15776          putLO(unop(Iop_128to64, mkexpr(t1)));
   15777          break;
   15778 
   15779       case 0x1F:  /* Doubleword Divide Unsigned DDIVU; MIPS64 check this */
   15780          DIP("ddivu r%u, r%u", rs, rt);
   15781          t1 = newTemp(Ity_I128);
   15782          t2 = newTemp(Ity_I128);
   15783 
   15784          assign(t1, binop(Iop_64HLto128, mkU64(0), getIReg(rs)));
   15785 
   15786          assign(t2, binop(Iop_DivModU128to64, mkexpr(t1), getIReg(rt)));
   15787 
   15788          putHI(unop(Iop_128HIto64, mkexpr(t2)));
   15789          putLO(unop(Iop_128to64, mkexpr(t2)));
   15790          break;
   15791 
   15792       case 0x10: {  /* MFHI */
   15793          if (VEX_MIPS_PROC_DSP(archinfo->hwcaps)) {
   15794             /* If DSP is present -> DSP ASE MFHI */
   15795             UInt retVal = disDSPInstr_MIPS_WRK ( cins );
   15796             if (0 != retVal ) {
   15797                goto decode_failure;
   15798             }
   15799             break;
   15800          } else {
   15801             DIP("mfhi r%d", rd);
   15802             putIReg(rd, getHI());
   15803             break;
   15804          }
   15805       }
   15806 
   15807       case 0x11:  {  /* MTHI */
   15808          if (VEX_MIPS_PROC_DSP(archinfo->hwcaps)) {
   15809             /* If DSP is present -> DSP ASE MTHI */
   15810             UInt retVal = disDSPInstr_MIPS_WRK ( cins );
   15811             if (0 != retVal ) {
   15812                goto decode_failure;
   15813             }
   15814             break;
   15815          } else {
   15816             DIP("mthi r%d", rs);
   15817             putHI(getIReg(rs));
   15818             break;
   15819          }
   15820       }
   15821 
   15822       case 0x12:  {  /* MFLO */
   15823          if (VEX_MIPS_PROC_DSP(archinfo->hwcaps)) {
   15824             /* If DSP is present -> DSP ASE MFLO */
   15825             UInt retVal = disDSPInstr_MIPS_WRK ( cins );
   15826             if (0 != retVal ) {
   15827                goto decode_failure;
   15828             }
   15829             break;
   15830          } else {
   15831             DIP("mflo r%d", rd);
   15832             putIReg(rd, getLO());
   15833             break;
   15834          }
   15835       }
   15836 
   15837       case 0x13:  {  /* MTLO */
   15838          if (VEX_MIPS_PROC_DSP(archinfo->hwcaps)) {
   15839             /* If DSP is present -> DSP ASE MTLO */
   15840             UInt retVal = disDSPInstr_MIPS_WRK ( cins );
   15841             if (0 != retVal ) {
   15842                goto decode_failure;
   15843             }
   15844             break;
   15845          } else {
   15846             DIP("mtlo r%d", rs);
   15847             putLO(getIReg(rs));
   15848             break;
   15849          }
   15850       }
   15851 
   15852       case 0x21:  /* ADDU */
   15853          DIP("addu r%d, r%d, r%d", rd, rs, rt);
   15854          if (mode64) {
   15855             ALU_PATTERN64(Iop_Add32);
   15856          } else {
   15857             ALU_PATTERN(Iop_Add32);
   15858          }
   15859          break;
   15860 
   15861       case 0x22: {  /* SUB */
   15862          DIP("sub r%d, r%d, r%d", rd, rs, rt);
   15863          IRTemp tmpRs32 = newTemp(Ity_I32);
   15864          IRTemp tmpRt32 = newTemp(Ity_I32);
   15865 
   15866          assign(tmpRs32, mkNarrowTo32(ty, getIReg(rs)));
   15867          assign(tmpRt32, mkNarrowTo32(ty, getIReg(rt)));
   15868          t0 = newTemp(Ity_I32);
   15869          t1 = newTemp(Ity_I32);
   15870          t2 = newTemp(Ity_I32);
   15871          t3 = newTemp(Ity_I32);
   15872          t4 = newTemp(Ity_I32);
   15873          t5 = newTemp(Ity_I32);
   15874          /* dst = src0 + (-1 * src1)
   15875             if(sign(src0 ) != sign((-1 * src1) ))
   15876             goto no overflow;
   15877             if(sign(dst) == sign(src0 ))
   15878             goto no overflow;
   15879             we have overflow! */
   15880 
   15881          assign(t5, binop(Iop_Mul32, mkexpr(tmpRt32), mkU32(-1)));
   15882          assign(t0, binop(Iop_Add32, mkexpr(tmpRs32), mkexpr(t5)));
   15883          assign(t1, binop(Iop_Xor32, mkexpr(tmpRs32), mkexpr(t5)));
   15884          assign(t2, unop(Iop_1Sto32, binop(Iop_CmpEQ32, binop(Iop_And32,
   15885                          mkexpr(t1), mkU32(0x80000000)), mkU32(0x80000000))));
   15886 
   15887          assign(t3, binop(Iop_Xor32, mkexpr(t0), mkexpr(tmpRs32)));
   15888          assign(t4, unop(Iop_1Sto32, binop(Iop_CmpNE32, binop(Iop_And32,
   15889                          mkexpr(t3), mkU32(0x80000000)), mkU32(0x80000000))));
   15890 
   15891          stmt(IRStmt_Exit(binop(Iop_CmpEQ32, binop(Iop_Or32, mkexpr(t2),
   15892                                 mkexpr(t4)), mkU32(0)), Ijk_SigFPE_IntOvf,
   15893                           mode64 ? IRConst_U64(guest_PC_curr_instr + 4) :
   15894                                    IRConst_U32(guest_PC_curr_instr + 4),
   15895                           OFFB_PC));
   15896 
   15897          putIReg(rd, mkWidenFrom32(ty, mkexpr(t0), True));
   15898          break;
   15899       }
   15900       case 0x23:  /* SUBU */
   15901          DIP("subu r%d, r%d, r%d", rd, rs, rt);
   15902          if (mode64) {
   15903             ALU_PATTERN64(Iop_Sub32);
   15904          } else {
   15905             ALU_PATTERN(Iop_Sub32);
   15906          }
   15907          break;
   15908 
   15909       case 0x24:  /* AND */
   15910          DIP("and r%d, r%d, r%d", rd, rs, rt);
   15911          if (mode64) {
   15912             ALU_PATTERN(Iop_And64);
   15913          } else {
   15914             ALU_PATTERN(Iop_And32);
   15915          }
   15916          break;
   15917 
   15918       case 0x25:  /* OR */
   15919          DIP("or r%d, r%d, r%d", rd, rs, rt);
   15920          if (mode64) {
   15921             ALU_PATTERN(Iop_Or64);
   15922          } else {
   15923             ALU_PATTERN(Iop_Or32);
   15924          }
   15925          break;
   15926 
   15927       case 0x26:  /* XOR */
   15928          DIP("xor r%d, r%d, r%d", rd, rs, rt);
   15929          if (mode64) {
   15930             ALU_PATTERN(Iop_Xor64);
   15931          } else {
   15932             ALU_PATTERN(Iop_Xor32);
   15933          }
   15934          break;
   15935 
   15936       case 0x27:  /* NOR */
   15937          DIP("nor r%d, r%d, r%d", rd, rs, rt);
   15938          if (mode64)
   15939             putIReg(rd, unop(Iop_Not64, binop(Iop_Or64, getIReg(rs),
   15940                                               getIReg(rt))));
   15941          else
   15942             putIReg(rd, unop(Iop_Not32, binop(Iop_Or32, getIReg(rs),
   15943                                               getIReg(rt))));
   15944          break;
   15945 
   15946       case 0x08:  /* JR */
   15947          DIP("jr r%d", rs);
   15948          t0 = newTemp(ty);
   15949          assign(t0, getIReg(rs));
   15950          lastn = mkexpr(t0);
   15951          break;
   15952 
   15953       case 0x09:  /* JALR */
   15954          DIP("jalr r%d r%d", rd, rs);
   15955          if (mode64) {
   15956             putIReg(rd, mkU64(guest_PC_curr_instr + 8));
   15957             t0 = newTemp(Ity_I64);
   15958             assign(t0, getIReg(rs));
   15959             lastn = mkexpr(t0);
   15960          } else {
   15961             putIReg(rd, mkU32(guest_PC_curr_instr + 8));
   15962             t0 = newTemp(Ity_I32);
   15963             assign(t0, getIReg(rs));
   15964             lastn = mkexpr(t0);
   15965          }
   15966          break;
   15967 
   15968       case 0x0C:  /* SYSCALL */
   15969          DIP("syscall");
   15970          if (mode64)
   15971             putPC(mkU64(guest_PC_curr_instr + 4));
   15972          else
   15973             putPC(mkU32(guest_PC_curr_instr + 4));
   15974          dres.jk_StopHere = Ijk_Sys_syscall;
   15975          dres.whatNext    = Dis_StopHere;
   15976          break;
   15977 
   15978       case 0x2A:  /* SLT */
   15979          DIP("slt r%d, r%d, r%d", rd, rs, rt);
   15980          if (mode64)
   15981             putIReg(rd, unop(Iop_1Uto64, binop(Iop_CmpLT64S, getIReg(rs),
   15982                                                getIReg(rt))));
   15983          else
   15984             putIReg(rd, unop(Iop_1Uto32, binop(Iop_CmpLT32S, getIReg(rs),
   15985                                                getIReg(rt))));
   15986          break;
   15987 
   15988       case 0x2B:  /* SLTU */
   15989          DIP("sltu r%d, r%d, r%d", rd, rs, rt);
   15990          if (mode64)
   15991             putIReg(rd, unop(Iop_1Uto64, binop(Iop_CmpLT64U, getIReg(rs),
   15992                                          getIReg(rt))));
   15993          else
   15994             putIReg(rd, unop(Iop_1Uto32, binop(Iop_CmpLT32U, getIReg(rs),
   15995                                          getIReg(rt))));
   15996          break;
   15997 
   15998       case 0x00: {  /* SLL */
   15999          DIP("sll r%d, r%d, %d", rd, rt, sa);
   16000          IRTemp tmpRt32 = newTemp(Ity_I32);
   16001          IRTemp tmpSh32 = newTemp(Ity_I32);
   16002          IRTemp tmpRd = newTemp(Ity_I64);
   16003          if (mode64) {
   16004             assign(tmpRt32, mkNarrowTo32(ty, getIReg(rt)));
   16005             assign(tmpSh32, binop(Iop_Shl32, mkexpr(tmpRt32), mkU8(sa)));
   16006             assign(tmpRd, mkWidenFrom32(ty, mkexpr(tmpSh32), True));
   16007             putIReg(rd, mkexpr(tmpRd));
   16008          } else
   16009             SXX_PATTERN(Iop_Shl32);
   16010          break;
   16011       }
   16012 
   16013       case 0x04: {  /* SLLV */
   16014          DIP("sllv r%d, r%d, r%d", rd, rt, rs);
   16015          if (mode64) {
   16016             IRTemp tmpRs8 = newTemp(Ity_I8);
   16017             IRTemp tmpRt32 = newTemp(Ity_I32);
   16018             IRTemp tmpSh32 = newTemp(Ity_I32);
   16019             IRTemp tmp = newTemp(ty);
   16020             assign(tmp, binop(mkSzOp(ty, Iop_And8), getIReg(rs),
   16021                               mkSzImm(ty, 31)));
   16022             assign(tmpRs8, mkNarrowTo8(ty, mkexpr(tmp)));
   16023             assign(tmpRt32, mkNarrowTo32(ty, getIReg(rt)));
   16024             assign(tmpSh32, binop(Iop_Shl32, mkexpr(tmpRt32), mkexpr(tmpRs8)));
   16025             putIReg(rd, mkWidenFrom32(ty, mkexpr(tmpSh32), True));
   16026          } else {
   16027             SXXV_PATTERN(Iop_Shl32);
   16028          }
   16029          break;
   16030       }
   16031 
   16032       case 0x03:  /* SRA */
   16033          DIP("sra r%d, r%d, %d", rd, rt, sa);
   16034          if (mode64) {
   16035             IRTemp tmpRt32 = newTemp(Ity_I32);
   16036             IRTemp tmpSh32 = newTemp(Ity_I32);
   16037 
   16038             t1 = newTemp(Ity_I64);
   16039             t2 = newTemp(Ity_I64);
   16040             t3 = newTemp(Ity_I64);
   16041 
   16042             assign(t1, binop(Iop_And64, getIReg(rt),  /* hi */
   16043                              mkU64(0xFFFFFFFF00000000ULL)));
   16044 
   16045             assign(t2, binop(Iop_Sar64, mkexpr(t1), mkU8(sa)));
   16046 
   16047             assign(tmpRt32, mkNarrowTo32(ty, getIReg(rt)));
   16048             assign(tmpSh32, binop(Iop_Sar32, mkexpr(tmpRt32), mkU8(sa)));
   16049 
   16050             putIReg(rd, mkWidenFrom32(ty, mkexpr(tmpSh32), True));
   16051          } else {
   16052             SXX_PATTERN(Iop_Sar32);
   16053          }
   16054          break;
   16055 
   16056       case 0x07:  /* SRAV */
   16057          DIP("srav r%d, r%d, r%d", rd, rt, rs);
   16058          if (mode64) {
   16059             IRTemp tmpRt32 = newTemp(Ity_I32);
   16060             IRTemp tmpSh32 = newTemp(Ity_I32);
   16061 
   16062             t1 = newTemp(Ity_I64);
   16063             t2 = newTemp(Ity_I64);
   16064             t3 = newTemp(Ity_I64);
   16065             t4 = newTemp(Ity_I8);
   16066 
   16067             assign(t4, unop(Iop_32to8, binop(Iop_And32,
   16068                        mkNarrowTo32(ty, getIReg(rs)), mkU32(0x0000001F))));
   16069 
   16070             assign(t1, binop(Iop_And64, getIReg(rt),  /* hi */
   16071                    mkU64(0xFFFFFFFF00000000ULL)));
   16072 
   16073             assign(t2, binop(Iop_Sar64, mkexpr(t1), mkexpr(t4)));
   16074 
   16075             assign(tmpRt32, mkNarrowTo32(ty, getIReg(rt)));
   16076             assign(tmpSh32, binop(Iop_Sar32, mkexpr(tmpRt32), mkexpr(t4)));
   16077 
   16078             putIReg(rd, mkWidenFrom32(ty, mkexpr(tmpSh32), True));
   16079          } else {
   16080             SXXV_PATTERN(Iop_Sar32);
   16081          }
   16082          break;
   16083 
   16084       case 0x02: {  /* SRL */
   16085          rot = get_rot(cins);
   16086          if (rot) {
   16087             DIP("rotr r%d, r%d, %d", rd, rt, sa);
   16088             putIReg(rd, mkWidenFrom32(ty, genROR32(mkNarrowTo32(ty,
   16089                         getIReg(rt)), sa), True));
   16090          } else {
   16091             DIP("srl r%d, r%d, %d", rd, rt, sa);
   16092             if (mode64) {
   16093                IRTemp tmpSh32 = newTemp(Ity_I32);
   16094                IRTemp tmpRt32 = newTemp(Ity_I32);
   16095 
   16096                assign(tmpRt32, mkNarrowTo32(ty, getIReg(rt)));
   16097                assign(tmpSh32, binop(Iop_Shr32, mkexpr(tmpRt32), mkU8(sa)));
   16098                putIReg(rd, mkWidenFrom32(ty, mkexpr(tmpSh32), True));
   16099             } else {
   16100                SXX_PATTERN(Iop_Shr32);
   16101             }
   16102          }
   16103       break;
   16104       }
   16105 
   16106       case 0x06: {
   16107          rot = get_rotv(cins);
   16108          if (rot) {
   16109             DIP("rotrv r%d, r%d, r%d", rd, rt, rs);
   16110             putIReg(rd, mkWidenFrom32(ty, genRORV32(mkNarrowTo32(ty,
   16111                         getIReg(rt)), mkNarrowTo32(ty, getIReg(rs))), True));
   16112             break;
   16113          } else {  /* SRLV */
   16114             DIP("srlv r%d, r%d, r%d", rd, rt, rs);
   16115             if (mode64) {
   16116                SXXV_PATTERN64(Iop_Shr32);
   16117             } else {
   16118                SXXV_PATTERN(Iop_Shr32);
   16119             }
   16120             break;
   16121          }
   16122       }
   16123 
   16124       case 0x0D:  /* BREAK */
   16125          DIP("break 0x%x", trap_code);
   16126          if (mode64)
   16127             jmp_lit64(&dres, Ijk_SigTRAP, (guest_PC_curr_instr + 4));
   16128          else
   16129             jmp_lit32(&dres, Ijk_SigTRAP, (guest_PC_curr_instr + 4));
   16130          vassert(dres.whatNext == Dis_StopHere);
   16131          break;
   16132 
   16133       case 0x30: {  /* TGE */
   16134          DIP("tge r%d, r%d %d", rs, rt, trap_code);
   16135          if (mode64) {
   16136             if (trap_code == 7)
   16137                stmt (IRStmt_Exit (unop (Iop_Not1,
   16138                                         binop (Iop_CmpLT64S,
   16139                                                getIReg (rs),
   16140                                                getIReg (rt))),
   16141                                 Ijk_SigFPE_IntDiv,
   16142                                 IRConst_U64(guest_PC_curr_instr + 4),
   16143                                 OFFB_PC));
   16144             else if (trap_code == 6)
   16145                stmt (IRStmt_Exit (unop (Iop_Not1,
   16146                                         binop (Iop_CmpLT64S,
   16147                                                getIReg (rs),
   16148                                                getIReg (rt))),
   16149                                 Ijk_SigFPE_IntOvf,
   16150                                 IRConst_U64(guest_PC_curr_instr + 4),
   16151                                 OFFB_PC));
   16152             else
   16153                stmt (IRStmt_Exit (unop (Iop_Not1,
   16154                                         binop (Iop_CmpLT64S,
   16155                                                getIReg (rs),
   16156                                                getIReg (rt))),
   16157                                 Ijk_SigTRAP,
   16158                                 IRConst_U64(guest_PC_curr_instr + 4),
   16159                                 OFFB_PC));
   16160          } else {
   16161             if (trap_code == 7)
   16162                stmt (IRStmt_Exit (unop (Iop_Not1,
   16163                                         binop (Iop_CmpLT32S,
   16164                                                getIReg (rs),
   16165                                                getIReg (rt))),
   16166                                   Ijk_SigFPE_IntDiv,
   16167                                   IRConst_U32(guest_PC_curr_instr + 4),
   16168                                   OFFB_PC));
   16169             else if (trap_code == 6)
   16170                stmt (IRStmt_Exit (unop (Iop_Not1,
   16171                                         binop (Iop_CmpLT32S,
   16172                                                getIReg (rs),
   16173                                                getIReg (rt))),
   16174                                   Ijk_SigFPE_IntOvf,
   16175                                   IRConst_U32(guest_PC_curr_instr + 4),
   16176                                   OFFB_PC));
   16177             else
   16178                stmt (IRStmt_Exit (unop (Iop_Not1,
   16179                                         binop (Iop_CmpLT32S,
   16180                                                getIReg (rs),
   16181                                                getIReg (rt))),
   16182                                   Ijk_SigTRAP,
   16183                                   IRConst_U32(guest_PC_curr_instr + 4),
   16184                                   OFFB_PC));
   16185          }
   16186          break;
   16187       }
   16188       case 0x31: {  /* TGEU */
   16189          DIP("tgeu r%d, r%d %d", rs, rt, trap_code);
   16190          if (mode64) {
   16191             if (trap_code == 7)
   16192                stmt (IRStmt_Exit (unop (Iop_Not1,
   16193                                         binop (Iop_CmpLT64U,
   16194                                                getIReg (rs),
   16195                                                getIReg (rt))),
   16196                                   Ijk_SigFPE_IntDiv,
   16197                                   IRConst_U64(guest_PC_curr_instr + 4),
   16198                                   OFFB_PC));
   16199             else if (trap_code == 6)
   16200                stmt (IRStmt_Exit (unop (Iop_Not1,
   16201                                         binop (Iop_CmpLT64U,
   16202                                                getIReg (rs),
   16203                                                getIReg (rt))),
   16204                                   Ijk_SigFPE_IntOvf,
   16205                                   IRConst_U64(guest_PC_curr_instr + 4),
   16206                                   OFFB_PC));
   16207             else
   16208                stmt (IRStmt_Exit (unop (Iop_Not1,
   16209                                         binop (Iop_CmpLT64U,
   16210                                                getIReg (rs),
   16211                                                getIReg (rt))),
   16212                                   Ijk_SigTRAP,
   16213                                   IRConst_U64(guest_PC_curr_instr + 4),
   16214                                   OFFB_PC));
   16215          } else {
   16216             if (trap_code == 7)
   16217                stmt (IRStmt_Exit (unop (Iop_Not1,
   16218                                         binop (Iop_CmpLT32U,
   16219                                                getIReg (rs),
   16220                                                getIReg (rt))),
   16221                                   Ijk_SigFPE_IntDiv,
   16222                                   IRConst_U32(guest_PC_curr_instr + 4),
   16223                                   OFFB_PC));
   16224             else if (trap_code == 6)
   16225                stmt (IRStmt_Exit (unop (Iop_Not1,
   16226                                         binop (Iop_CmpLT32U,
   16227                                                getIReg (rs),
   16228                                                getIReg (rt))),
   16229                                   Ijk_SigFPE_IntOvf,
   16230                                   IRConst_U32(guest_PC_curr_instr + 4),
   16231                                   OFFB_PC));
   16232             else
   16233                stmt (IRStmt_Exit (unop (Iop_Not1,
   16234                                         binop (Iop_CmpLT32U,
   16235                                                getIReg (rs),
   16236                                                getIReg (rt))),
   16237                                   Ijk_SigTRAP,
   16238                                   IRConst_U32(guest_PC_curr_instr + 4),
   16239                                   OFFB_PC));
   16240          }
   16241          break;
   16242       }
   16243       case 0x32: {  /* TLT */
   16244          DIP("tlt r%d, r%d %d", rs, rt, trap_code);
   16245          if (mode64) {
   16246             if (trap_code == 7)
   16247                stmt(IRStmt_Exit(binop(Iop_CmpLT64S, getIReg(rs),
   16248                                       getIReg(rt)), Ijk_SigFPE_IntDiv,
   16249                                 IRConst_U64(guest_PC_curr_instr + 4),
   16250                                 OFFB_PC));
   16251             else if (trap_code == 6)
   16252                stmt(IRStmt_Exit(binop(Iop_CmpLT64S, getIReg(rs),
   16253                                       getIReg(rt)), Ijk_SigFPE_IntOvf,
   16254                                 IRConst_U64(guest_PC_curr_instr + 4),
   16255                                 OFFB_PC));
   16256             else
   16257                stmt(IRStmt_Exit(binop(Iop_CmpLT64S, getIReg(rs),
   16258                                       getIReg(rt)), Ijk_SigTRAP,
   16259                                 IRConst_U64(guest_PC_curr_instr + 4),
   16260                                 OFFB_PC));
   16261          } else {
   16262             if (trap_code == 7)
   16263                stmt(IRStmt_Exit(binop(Iop_CmpLT32S, getIReg(rs),
   16264                                       getIReg(rt)), Ijk_SigFPE_IntDiv,
   16265                                 IRConst_U32(guest_PC_curr_instr + 4),
   16266                                 OFFB_PC));
   16267             else if (trap_code == 6)
   16268                stmt(IRStmt_Exit(binop(Iop_CmpLT32S, getIReg(rs),
   16269                                       getIReg(rt)), Ijk_SigFPE_IntOvf,
   16270                                 IRConst_U32(guest_PC_curr_instr + 4),
   16271                                 OFFB_PC));
   16272             else
   16273                stmt(IRStmt_Exit(binop(Iop_CmpLT32S, getIReg(rs),
   16274                                       getIReg(rt)), Ijk_SigTRAP,
   16275                                 IRConst_U32(guest_PC_curr_instr + 4),
   16276                                 OFFB_PC));
   16277          }
   16278          break;
   16279       }
   16280       case 0x33: {  /* TLTU */
   16281          DIP("tltu r%d, r%d %d", rs, rt, trap_code);
   16282          if (mode64) {
   16283             if (trap_code == 7)
   16284                stmt(IRStmt_Exit(binop(Iop_CmpLT64U, getIReg(rs),
   16285                                       getIReg(rt)), Ijk_SigFPE_IntDiv,
   16286                                 IRConst_U64(guest_PC_curr_instr + 4),
   16287                                 OFFB_PC));
   16288             else if (trap_code == 6)
   16289                stmt(IRStmt_Exit(binop(Iop_CmpLT64U, getIReg(rs),
   16290                                       getIReg(rt)), Ijk_SigFPE_IntOvf,
   16291                                 IRConst_U64(guest_PC_curr_instr + 4),
   16292                                 OFFB_PC));
   16293             else
   16294                stmt(IRStmt_Exit(binop(Iop_CmpLT64U, getIReg(rs),
   16295                                       getIReg(rt)), Ijk_SigTRAP,
   16296                                 IRConst_U64(guest_PC_curr_instr + 4),
   16297                                 OFFB_PC));
   16298          } else {
   16299             if (trap_code == 7)
   16300                stmt(IRStmt_Exit(binop(Iop_CmpLT32U, getIReg(rs),
   16301                                       getIReg(rt)), Ijk_SigFPE_IntDiv,
   16302                                 IRConst_U32(guest_PC_curr_instr + 4),
   16303                                 OFFB_PC));
   16304             else if (trap_code == 6)
   16305                stmt(IRStmt_Exit(binop(Iop_CmpLT32U, getIReg(rs),
   16306                                       getIReg(rt)), Ijk_SigFPE_IntOvf,
   16307                                 IRConst_U32(guest_PC_curr_instr + 4),
   16308                                 OFFB_PC));
   16309             else
   16310                stmt(IRStmt_Exit(binop(Iop_CmpLT32U, getIReg(rs),
   16311                                       getIReg (rt)), Ijk_SigTRAP,
   16312                                 IRConst_U32(guest_PC_curr_instr + 4),
   16313                                 OFFB_PC));
   16314          }
   16315          break;
   16316       }
   16317       case 0x34: {  /* TEQ */
   16318          DIP("teq r%d, r%d, %d", rs, rt, trap_code);
   16319          if (mode64) {
   16320             if (trap_code == 7)
   16321                stmt(IRStmt_Exit(binop(Iop_CmpEQ64, getIReg(rs),
   16322                                       getIReg(rt)), Ijk_SigFPE_IntDiv,
   16323                                 IRConst_U64(guest_PC_curr_instr + 4),
   16324                                 OFFB_PC));
   16325             else if (trap_code == 6)
   16326                stmt(IRStmt_Exit(binop(Iop_CmpEQ64, getIReg(rs),
   16327                                       getIReg(rt)), Ijk_SigFPE_IntOvf,
   16328                                 IRConst_U64(guest_PC_curr_instr + 4),
   16329                                 OFFB_PC));
   16330             else
   16331                stmt(IRStmt_Exit(binop(Iop_CmpEQ64, getIReg(rs),
   16332                                       getIReg(rt)), Ijk_SigTRAP,
   16333                                 IRConst_U64(guest_PC_curr_instr + 4),
   16334                                 OFFB_PC));
   16335          } else {
   16336             if (trap_code == 7)
   16337                stmt(IRStmt_Exit(binop(Iop_CmpEQ32, getIReg(rs),
   16338                                       getIReg(rt)), Ijk_SigFPE_IntDiv,
   16339                                 IRConst_U32(guest_PC_curr_instr + 4),
   16340                                 OFFB_PC));
   16341             else if (trap_code == 6)
   16342                stmt(IRStmt_Exit(binop(Iop_CmpEQ32, getIReg(rs),
   16343                                       getIReg(rt)), Ijk_SigFPE_IntOvf,
   16344                                 IRConst_U32(guest_PC_curr_instr + 4),
   16345                                 OFFB_PC));
   16346             else
   16347                stmt(IRStmt_Exit(binop(Iop_CmpEQ32, getIReg(rs),
   16348                                       getIReg(rt)), Ijk_SigTRAP,
   16349                                 IRConst_U32(guest_PC_curr_instr + 4),
   16350                                 OFFB_PC));
   16351          }
   16352          break;
   16353       }
   16354       case 0x36: {  /* TNE */
   16355          DIP("tne r%d, r%d %d", rs, rt, trap_code);
   16356          if (mode64) {
   16357             if (trap_code == 7)
   16358                stmt(IRStmt_Exit(binop(Iop_CmpNE64, getIReg(rs),
   16359                                       getIReg(rt)), Ijk_SigFPE_IntDiv,
   16360                                 IRConst_U64(guest_PC_curr_instr + 4),
   16361                                 OFFB_PC));
   16362             else if (trap_code == 6)
   16363                stmt(IRStmt_Exit(binop(Iop_CmpNE64, getIReg(rs),
   16364                                       getIReg(rt)), Ijk_SigFPE_IntOvf,
   16365                                 IRConst_U64(guest_PC_curr_instr + 4),
   16366                                 OFFB_PC));
   16367             else
   16368                stmt(IRStmt_Exit(binop(Iop_CmpNE64, getIReg(rs),
   16369                                       getIReg(rt)), Ijk_SigTRAP,
   16370                                 IRConst_U64(guest_PC_curr_instr + 4),
   16371                                 OFFB_PC));
   16372          } else {
   16373             if (trap_code == 7)
   16374                stmt(IRStmt_Exit(binop(Iop_CmpNE32, getIReg(rs),
   16375                                       getIReg(rt)), Ijk_SigFPE_IntDiv,
   16376                                 IRConst_U32(guest_PC_curr_instr + 4),
   16377                                 OFFB_PC));
   16378             else if (trap_code == 6)
   16379                stmt(IRStmt_Exit(binop(Iop_CmpNE32, getIReg(rs),
   16380                                       getIReg(rt)), Ijk_SigFPE_IntOvf,
   16381                                 IRConst_U32(guest_PC_curr_instr + 4),
   16382                                 OFFB_PC));
   16383             else
   16384                stmt(IRStmt_Exit(binop(Iop_CmpNE32, getIReg(rs),
   16385                                       getIReg(rt)), Ijk_SigTRAP,
   16386                                 IRConst_U32(guest_PC_curr_instr + 4),
   16387                                 OFFB_PC));
   16388          }
   16389          break;
   16390       }
   16391       case 0x14:
   16392       case 0x16:
   16393       case 0x17:  /* DSLLV, DROTRV:DSRLV, DSRAV */
   16394       case 0x38:
   16395       case 0x3A:
   16396       case 0x3B:  /* DSLL, DROTL:DSRL, DSRA  */
   16397       case 0x3C:
   16398       case 0x3E:
   16399       case 0x3F:  /* DSLL32, DROTR32:DSRL32, DSRA32 */
   16400          if (dis_instr_shrt(cins))
   16401             break;
   16402          goto decode_failure;
   16403 
   16404       case 0x0F:  /* SYNC */
   16405          DIP("sync 0x%x", sel);
   16406          /* Just ignore it. */
   16407          break;
   16408 
   16409       case 0x2C: {  /* Doubleword Add - DADD; MIPS64 */
   16410          DIP("dadd r%d, r%d, r%d", rd, rs, rt);
   16411          IRTemp tmpRs64 = newTemp(Ity_I64);
   16412          IRTemp tmpRt64 = newTemp(Ity_I64);
   16413 
   16414          assign(tmpRs64, getIReg(rs));
   16415          assign(tmpRt64, getIReg(rt));
   16416 
   16417          t0 = newTemp(Ity_I64);
   16418          t1 = newTemp(Ity_I64);
   16419          t2 = newTemp(Ity_I64);
   16420          t3 = newTemp(Ity_I64);
   16421          t4 = newTemp(Ity_I64);
   16422          /* dst = src0 + src1
   16423             if(sign(src0 ) != sign(src1 ))
   16424             goto no overflow;
   16425             if(sign(dst) == sign(src0 ))
   16426             goto no overflow;
   16427             we have overflow! */
   16428 
   16429          assign(t0, binop(Iop_Add64, mkexpr(tmpRs64), mkexpr(tmpRt64)));
   16430          assign(t1, binop(Iop_Xor64, mkexpr(tmpRs64), mkexpr(tmpRt64)));
   16431          assign(t2, unop(Iop_1Uto64,
   16432                          binop(Iop_CmpEQ64,
   16433                                binop(Iop_And64, mkexpr(t1),
   16434                                      mkU64(0x8000000000000000ULL)),
   16435                                mkU64(0x8000000000000000ULL))));
   16436 
   16437          assign(t3, binop(Iop_Xor64, mkexpr(t0), mkexpr(tmpRs64)));
   16438          assign(t4, unop(Iop_1Uto64,
   16439                          binop(Iop_CmpNE64,
   16440                                binop(Iop_And64, mkexpr(t3),
   16441                                      mkU64(0x8000000000000000ULL)),
   16442                                mkU64(0x8000000000000000ULL))));
   16443 
   16444          stmt(IRStmt_Exit(binop(Iop_CmpEQ64,
   16445                                 binop(Iop_Or64, mkexpr(t2), mkexpr(t4)),
   16446                                 mkU64(0)),
   16447                           Ijk_SigFPE_IntOvf,
   16448                           IRConst_U64(guest_PC_curr_instr + 4),
   16449                           OFFB_PC));
   16450 
   16451          putIReg(rd,  mkexpr(t0));
   16452          break;
   16453       }
   16454 
   16455       case 0x2D:  /* Doubleword Add Unsigned - DADDU; MIPS64 */
   16456          DIP("daddu r%d, r%d, r%d", rd, rs, rt);
   16457          ALU_PATTERN(Iop_Add64);
   16458          break;
   16459 
   16460       case 0x2E: {  /* Doubleword Subtract - DSUB; MIPS64 */
   16461          DIP("dsub r%u, r%u, r%u", rd, rs, rt);
   16462          IRTemp tmpRs64 = newTemp(Ity_I64);
   16463          IRTemp tmpRt64 = newTemp(Ity_I64);
   16464 
   16465          assign(tmpRs64, getIReg(rs));
   16466          assign(tmpRt64, getIReg(rt));
   16467          t0 = newTemp(Ity_I64);
   16468          t1 = newTemp(Ity_I64);
   16469          t2 = newTemp(Ity_I64);
   16470          t3 = newTemp(Ity_I64);
   16471          t4 = newTemp(Ity_I64);
   16472          t5 = newTemp(Ity_I64);
   16473          /* dst = src0 + (-1 * src1)
   16474             if(sign(src0 ) != sign((-1 * src1) ))
   16475             goto no overflow;
   16476             if(sign(dst) == sign(src0 ))
   16477             goto no overflow;
   16478             we have overflow! */
   16479 
   16480          assign(t5, binop(Iop_Mul64,
   16481                           mkexpr(tmpRt64),
   16482                           mkU64(0xffffffffffffffffULL)));
   16483          assign(t0, binop(Iop_Add64, mkexpr(tmpRs64), mkexpr(t5)));
   16484          assign(t1, binop(Iop_Xor64, mkexpr(tmpRs64), mkexpr(t5)));
   16485          assign(t2, unop(Iop_1Sto64,
   16486                          binop(Iop_CmpEQ64,
   16487                                binop(Iop_And64,
   16488                                      mkexpr(t1),
   16489                                      mkU64(0x8000000000000000ULL)),
   16490                                mkU64(0x8000000000000000ULL))));
   16491 
   16492          assign(t3, binop(Iop_Xor64, mkexpr(t0), mkexpr(tmpRs64)));
   16493          assign(t4, unop(Iop_1Sto64,
   16494                          binop(Iop_CmpNE64,
   16495                                binop(Iop_And64,
   16496                                      mkexpr(t3),
   16497                                      mkU64(0x8000000000000000ULL)),
   16498                                mkU64(0x8000000000000000ULL))));
   16499 
   16500          stmt(IRStmt_Exit(binop(Iop_CmpEQ64, binop(Iop_Or64, mkexpr(t2),
   16501                                 mkexpr(t4)), mkU64(0)), Ijk_SigFPE_IntOvf,
   16502                           IRConst_U64(guest_PC_curr_instr + 4),
   16503                           OFFB_PC));
   16504 
   16505          putIReg(rd, binop(Iop_Sub64, getIReg(rs), getIReg(rt)));
   16506          break;
   16507       }
   16508 
   16509       case 0x2F:  /* Doubleword Subtract Unsigned - DSUBU; MIPS64 */
   16510          DIP("dsub r%u, r%u,r%u", rd, rt, rt);
   16511          ALU_PATTERN(Iop_Sub64);
   16512          break;
   16513 
   16514       default:
   16515          goto decode_failure;
   16516       }
   16517       break;
   16518 
   16519    case 0x01:  /* Regimm */
   16520 
   16521       switch (rt) {
   16522       case 0x00:  /* BLTZ */
   16523          DIP("bltz r%d, %d", rs, imm);
   16524          if (mode64) {
   16525             if (!dis_instr_branch(cins, &dres, resteerOkFn,
   16526                         callback_opaque, &bstmt))
   16527                goto decode_failure;
   16528          } else
   16529             dis_branch(False, binop(Iop_CmpEQ32, binop(Iop_And32, getIReg(rs),
   16530                        mkU32(0x80000000)), mkU32(0x80000000)), imm, &bstmt);
   16531          break;
   16532 
   16533       case 0x01:  /* BGEZ */
   16534          DIP("bgez r%d, %d", rs, imm);
   16535          if (mode64) {
   16536             if (!dis_instr_branch(cins, &dres, resteerOkFn,
   16537                                   callback_opaque, &bstmt))
   16538                goto decode_failure;
   16539          } else
   16540             dis_branch(False, binop(Iop_CmpEQ32, binop(Iop_And32, getIReg(rs),
   16541                               mkU32(0x80000000)), mkU32(0x0)), imm, &bstmt);
   16542          break;
   16543 
   16544       case 0x02:  /* BLTZL */
   16545          DIP("bltzl r%d, %d", rs, imm);
   16546          lastn = dis_branch_likely(binop(mode64 ? Iop_CmpNE64 : Iop_CmpNE32,
   16547                      binop(mode64 ? Iop_And64 : Iop_And32, getIReg(rs),
   16548                      mode64 ? mkU64(0x8000000000000000ULL) : mkU32(0x80000000)),
   16549                      mode64 ? mkU64(0x8000000000000000ULL) : mkU32(0x80000000)),
   16550                      imm);
   16551          break;
   16552 
   16553       case 0x03:  /* BGEZL */
   16554          DIP("bgezl r%d, %d", rs, imm);
   16555          lastn = dis_branch_likely(binop(mode64 ? Iop_CmpNE64 : Iop_CmpNE32,
   16556                      binop(mode64 ? Iop_And64 : Iop_And32, getIReg(rs),
   16557                      mode64 ? mkU64(0x8000000000000000ULL) : mkU32(0x80000000)),
   16558                      mode64 ? mkU64(0x0) : mkU32(0x0)), imm);
   16559          break;
   16560 
   16561       case 0x10:  /* BLTZAL */
   16562          DIP("bltzal r%d, %d", rs, imm);
   16563          if (mode64) {
   16564             if (!dis_instr_branch(cins, &dres, resteerOkFn,
   16565                         callback_opaque, &bstmt))
   16566                goto decode_failure;
   16567          } else
   16568             dis_branch(True, binop(Iop_CmpEQ32, binop(Iop_And32, getIReg(rs),
   16569                        mkU32(0x80000000)), mkU32(0x80000000)), imm, &bstmt);
   16570          break;
   16571 
   16572       case 0x12:  /* BLTZALL */
   16573          DIP("bltzall r%d, %d", rs, imm);
   16574          putIReg(31, mode64 ? mkU64(guest_PC_curr_instr + 8) :
   16575                               mkU32(guest_PC_curr_instr + 8));
   16576          lastn = dis_branch_likely(binop(mode64 ? Iop_CmpNE64 : Iop_CmpNE32,
   16577                      binop(mode64 ? Iop_And64 : Iop_And32, getIReg(rs),
   16578                      mode64 ? mkU64(0x8000000000000000ULL) : mkU32(0x80000000)),
   16579                      mode64 ? mkU64(0x8000000000000000ULL) : mkU32(0x80000000)),
   16580                      imm);
   16581          break;
   16582 
   16583       case 0x11:  /* BGEZAL */
   16584          DIP("bgezal r%d, %d", rs, imm);
   16585          if (mode64) {
   16586             if (!dis_instr_branch(cins, &dres, resteerOkFn,
   16587                         callback_opaque, &bstmt))
   16588                goto decode_failure;
   16589          } else
   16590             dis_branch(True, binop(Iop_CmpEQ32, binop(Iop_And32, getIReg(rs),
   16591                        mkU32(0x80000000)), mkU32(0x0)), imm, &bstmt);
   16592          break;
   16593 
   16594       case 0x13:  /* BGEZALL */
   16595          DIP("bgezall r%d, %d", rs, imm);
   16596          if (mode64) {
   16597             putIReg(31, mkU64(guest_PC_curr_instr + 8));
   16598             lastn = dis_branch_likely(binop(Iop_CmpNE64,
   16599                                             binop(Iop_And64,
   16600                                                   getIReg(rs),
   16601                                                   mkU64(0x8000000000000000ULL)),
   16602                                             mkU64(0x0)),
   16603                                       imm);
   16604          } else {
   16605             putIReg(31, mkU32(guest_PC_curr_instr + 8));
   16606             lastn = dis_branch_likely(binop(Iop_CmpNE32, binop(Iop_And32,
   16607                                       getIReg(rs), mkU32(0x80000000)),
   16608                                       mkU32(0x0)), imm);
   16609          }
   16610          break;
   16611 
   16612       case 0x08:  /* TGEI */
   16613          DIP("tgei r%d, %d %d", rs, imm, trap_code);
   16614          if (mode64) {
   16615             stmt (IRStmt_Exit (unop (Iop_Not1,
   16616                                      binop (Iop_CmpLT64S,
   16617                                             getIReg (rs),
   16618                                             mkU64 (extend_s_16to64 (imm)))),
   16619                              Ijk_SigTRAP,
   16620                              IRConst_U64(guest_PC_curr_instr + 4),
   16621                              OFFB_PC));
   16622          } else {
   16623             stmt (IRStmt_Exit (unop (Iop_Not1,
   16624                                      binop (Iop_CmpLT32S,
   16625                                      getIReg (rs),
   16626                                      mkU32 (extend_s_16to32 (imm)))),
   16627                              Ijk_SigTRAP,
   16628                              IRConst_U32(guest_PC_curr_instr + 4),
   16629                              OFFB_PC));
   16630          }
   16631          break;
   16632 
   16633       case 0x09: {  /* TGEIU */
   16634          DIP("tgeiu r%d, %d %d", rs, imm, trap_code);
   16635          if (mode64) {
   16636             stmt (IRStmt_Exit (unop (Iop_Not1,
   16637                                      binop (Iop_CmpLT64U,
   16638                                             getIReg (rs),
   16639                                             mkU64 (extend_s_16to64 (imm)))),
   16640                              Ijk_SigTRAP,
   16641                              IRConst_U64(guest_PC_curr_instr + 4),
   16642                              OFFB_PC));
   16643          } else {
   16644             stmt (IRStmt_Exit (unop (Iop_Not1,
   16645                                      binop (Iop_CmpLT32U,
   16646                                             getIReg (rs),
   16647                                             mkU32 (extend_s_16to32 (imm)))),
   16648                                Ijk_SigTRAP,
   16649                                IRConst_U32(guest_PC_curr_instr + 4),
   16650                                OFFB_PC));
   16651          }
   16652          break;
   16653       }
   16654       case 0x0A: {  /* TLTI */
   16655          DIP("tlti r%d, %d %d", rs, imm, trap_code);
   16656          if (mode64) {
   16657             stmt (IRStmt_Exit (binop (Iop_CmpLT64S, getIReg (rs),
   16658                                       mkU64 (extend_s_16to64 (imm))),
   16659                              Ijk_SigTRAP,
   16660                              IRConst_U64(guest_PC_curr_instr + 4),
   16661                              OFFB_PC));
   16662          } else {
   16663             stmt (IRStmt_Exit (binop (Iop_CmpLT32S, getIReg (rs),
   16664                                       mkU32 (extend_s_16to32 (imm))),
   16665                                Ijk_SigTRAP,
   16666                                IRConst_U32(guest_PC_curr_instr + 4),
   16667                                OFFB_PC));
   16668          }
   16669          break;
   16670       }
   16671       case 0x0B: {  /* TLTIU */
   16672          DIP("tltiu r%d, %d %d", rs, imm, trap_code);
   16673          if (mode64) {
   16674             stmt (IRStmt_Exit (binop (Iop_CmpLT64U, getIReg (rs),
   16675                                       mkU64 (extend_s_16to64 (imm))),
   16676                              Ijk_SigTRAP,
   16677                              IRConst_U64(guest_PC_curr_instr + 4),
   16678                              OFFB_PC));
   16679          } else {
   16680             stmt (IRStmt_Exit (binop (Iop_CmpLT32U, getIReg (rs),
   16681                                       mkU32 (extend_s_16to32 (imm))),
   16682                                Ijk_SigTRAP,
   16683                                IRConst_U32(guest_PC_curr_instr + 4),
   16684                                OFFB_PC));
   16685          }
   16686          break;
   16687       }
   16688       case 0x0C: {  /* TEQI */
   16689           DIP("teqi r%d, %d %d", rs, imm, trap_code);
   16690          if (mode64) {
   16691             stmt (IRStmt_Exit (binop (Iop_CmpEQ64, getIReg (rs),
   16692                                       mkU64 (extend_s_16to64 (imm))),
   16693                                Ijk_SigTRAP,
   16694                                IRConst_U64(guest_PC_curr_instr + 4),
   16695                                OFFB_PC));
   16696          } else {
   16697             stmt (IRStmt_Exit (binop (Iop_CmpEQ32, getIReg (rs),
   16698                                       mkU32 (extend_s_16to32 (imm))),
   16699                                Ijk_SigTRAP,
   16700                                IRConst_U32(guest_PC_curr_instr + 4),
   16701                                OFFB_PC));
   16702          }
   16703          break;
   16704       }
   16705       case 0x0E: {  /* TNEI */
   16706          DIP("tnei r%d, %d %d", rs, imm, trap_code);
   16707          if (mode64) {
   16708             stmt (IRStmt_Exit (binop (Iop_CmpNE64, getIReg (rs),
   16709                                       mkU64 (extend_s_16to64 (imm))),
   16710                                Ijk_SigTRAP,
   16711                                IRConst_U64(guest_PC_curr_instr + 4),
   16712                                OFFB_PC));
   16713          } else {
   16714             stmt (IRStmt_Exit (binop (Iop_CmpNE32, getIReg (rs),
   16715                                       mkU32 (extend_s_16to32 (imm))),
   16716                                Ijk_SigTRAP,
   16717                                IRConst_U32(guest_PC_curr_instr + 4),
   16718                                OFFB_PC));
   16719          }
   16720          break;
   16721       }
   16722       case 0x1C: {  /* BPOSGE32 */
   16723          DIP("bposge32 %d", imm);
   16724          vassert(!mode64);
   16725          t0 = newTemp(Ity_I32);
   16726          /* Get pos field from DSPControl register. */
   16727          assign(t0, binop(Iop_And32, getDSPControl(), mkU32(0x3f)));
   16728          dis_branch(False, unop(Iop_Not1, binop(Iop_CmpLT32U, mkexpr(t0),
   16729                                 mkU32(32))), imm, &bstmt);
   16730       }
   16731       case 0x1F:
   16732          /* SYNCI */
   16733          /* Just ignore it */
   16734          break;
   16735 
   16736       default:
   16737          goto decode_failure;
   16738       }
   16739       break;
   16740 
   16741    case 0x04:
   16742       DIP("beq r%d, r%d, %d", rs, rt, imm);
   16743       if (mode64)
   16744          dis_branch(False, binop(Iop_CmpEQ64, getIReg(rs), getIReg(rt)),
   16745                                  imm, &bstmt);
   16746       else
   16747          dis_branch(False, binop(Iop_CmpEQ32, getIReg(rs), getIReg(rt)),
   16748                                  imm, &bstmt);
   16749       break;
   16750 
   16751    case 0x14:
   16752       DIP("beql r%d, r%d, %d", rs, rt, imm);
   16753       lastn = dis_branch_likely(binop(mode64 ? Iop_CmpNE64 : Iop_CmpNE32,
   16754                                 getIReg(rs), getIReg(rt)), imm);
   16755       break;
   16756 
   16757    case 0x05:
   16758       DIP("bne r%d, r%d, %d", rs, rt, imm);
   16759       if (mode64)
   16760          dis_branch(False, binop(Iop_CmpNE64, getIReg(rs), getIReg(rt)),
   16761                                  imm, &bstmt);
   16762       else
   16763          dis_branch(False, binop(Iop_CmpNE32, getIReg(rs), getIReg(rt)),
   16764                                  imm, &bstmt);
   16765       break;
   16766 
   16767    case 0x15:
   16768       DIP("bnel r%d, r%d, %d", rs, rt, imm);
   16769       lastn = dis_branch_likely(binop(mode64 ? Iop_CmpEQ64 : Iop_CmpEQ32,
   16770                                       getIReg(rs), getIReg(rt)), imm);
   16771       break;
   16772 
   16773    case 0x07:  /* BGTZ */
   16774       DIP("bgtz r%d, %d", rs, imm);
   16775       if (mode64)
   16776          dis_branch(False, unop(Iop_Not1, binop(Iop_CmpLE64S, getIReg(rs),
   16777                                 mkU64(0x00))), imm, &bstmt);
   16778       else
   16779          dis_branch(False, unop(Iop_Not1, binop(Iop_CmpLE32S, getIReg(rs),
   16780                                 mkU32(0x00))), imm, &bstmt);
   16781       break;
   16782 
   16783    case 0x17:  /* BGTZL */
   16784       DIP("bgtzl r%d, %d", rs, imm);
   16785       if (mode64)
   16786          lastn = dis_branch_likely(binop(Iop_CmpLE64S, getIReg(rs),
   16787                                          mkU64(0x00)), imm);
   16788       else
   16789          lastn = dis_branch_likely(binop(Iop_CmpLE32S, getIReg(rs),
   16790                                          mkU32(0x00)), imm);
   16791       break;
   16792 
   16793    case 0x06:  /* BLEZ */
   16794       DIP("blez r%d, %d", rs, imm);
   16795       if (mode64)
   16796          dis_branch(False, binop(Iop_CmpLE64S, getIReg(rs), mkU64(0x0)),
   16797                                 imm, &bstmt);
   16798       else
   16799          dis_branch(False,binop(Iop_CmpLE32S, getIReg(rs), mkU32(0x0)), imm,
   16800                                 &bstmt);
   16801       break;
   16802 
   16803    case 0x16:  /* BLEZL */
   16804       DIP("blezl r%d, %d", rs, imm);
   16805       lastn = dis_branch_likely(unop(Iop_Not1, (binop(mode64 ? Iop_CmpLE64S :
   16806                                      Iop_CmpLE32S, getIReg(rs), mode64 ?
   16807                                      mkU64(0x0) : mkU32(0x0)))), imm);
   16808       break;
   16809 
   16810    case 0x08: {  /* ADDI */
   16811       DIP("addi r%d, r%d, %d", rt, rs, imm);
   16812       IRTemp tmpRs32 = newTemp(Ity_I32);
   16813       assign(tmpRs32, mkNarrowTo32(ty, getIReg(rs)));
   16814 
   16815       t0 = newTemp(Ity_I32);
   16816       t1 = newTemp(Ity_I32);
   16817       t2 = newTemp(Ity_I32);
   16818       t3 = newTemp(Ity_I32);
   16819       t4 = newTemp(Ity_I32);
   16820       /* dst = src0 + sign(imm)
   16821          if(sign(src0 ) != sign(imm ))
   16822          goto no overflow;
   16823          if(sign(dst) == sign(src0 ))
   16824          goto no overflow;
   16825          we have overflow! */
   16826 
   16827       assign(t0, binop(Iop_Add32, mkexpr(tmpRs32),
   16828                        mkU32(extend_s_16to32(imm))));
   16829       assign(t1, binop(Iop_Xor32, mkexpr(tmpRs32),
   16830                        mkU32(extend_s_16to32(imm))));
   16831       assign(t2, unop(Iop_1Sto32, binop(Iop_CmpEQ32, binop(Iop_And32,
   16832                       mkexpr(t1), mkU32(0x80000000)), mkU32(0x80000000))));
   16833 
   16834       assign(t3, binop(Iop_Xor32, mkexpr(t0), mkexpr(tmpRs32)));
   16835       assign(t4, unop(Iop_1Sto32, binop(Iop_CmpNE32, binop(Iop_And32,
   16836                       mkexpr(t3), mkU32(0x80000000)), mkU32(0x80000000))));
   16837 
   16838       stmt(IRStmt_Exit(binop(Iop_CmpEQ32, binop(Iop_Or32, mkexpr(t2),
   16839                              mkexpr(t4)), mkU32(0)), Ijk_SigFPE_IntOvf,
   16840                        mode64 ? IRConst_U64(guest_PC_curr_instr + 4) :
   16841                                 IRConst_U32(guest_PC_curr_instr + 4),
   16842                        OFFB_PC));
   16843 
   16844       putIReg(rt,  mkWidenFrom32(ty, mkexpr(t0), True));
   16845       break;
   16846    }
   16847    case 0x09:  /* ADDIU */
   16848       DIP("addiu r%d, r%d, %d", rt, rs, imm);
   16849       if (mode64) {
   16850          putIReg(rt, mkWidenFrom32(ty, binop(Iop_Add32,
   16851                      mkNarrowTo32(ty, getIReg(rs)),mkU32(extend_s_16to32(imm))),
   16852                      True));
   16853       } else
   16854          putIReg(rt, binop(Iop_Add32, getIReg(rs),mkU32(extend_s_16to32(imm))));
   16855       break;
   16856 
   16857    case 0x0C:  /* ANDI */
   16858       DIP("andi r%d, r%d, %d", rt, rs, imm);
   16859       if (mode64) {
   16860          ALUI_PATTERN64(Iop_And64);
   16861       } else {
   16862          ALUI_PATTERN(Iop_And32);
   16863       }
   16864       break;
   16865 
   16866    case 0x0E:  /* XORI */
   16867       DIP("xori r%d, r%d, %d", rt, rs, imm);
   16868       if (mode64) {
   16869          ALUI_PATTERN64(Iop_Xor64);
   16870       } else {
   16871          ALUI_PATTERN(Iop_Xor32);
   16872       }
   16873       break;
   16874 
   16875    case 0x0D:  /* ORI */
   16876       DIP("ori r%d, r%d, %d", rt, rs, imm);
   16877       if (mode64) {
   16878          ALUI_PATTERN64(Iop_Or64);
   16879       } else {
   16880          ALUI_PATTERN(Iop_Or32);
   16881       }
   16882       break;
   16883 
   16884    case 0x0A:  /* SLTI */
   16885       DIP("slti r%d, r%d, %d", rt, rs, imm);
   16886       if (mode64)
   16887          putIReg(rt, unop(Iop_1Uto64, binop(Iop_CmpLT64S, getIReg(rs),
   16888                                             mkU64(extend_s_16to64(imm)))));
   16889       else
   16890          putIReg(rt, unop(Iop_1Uto32, binop(Iop_CmpLT32S, getIReg(rs),
   16891                                             mkU32(extend_s_16to32(imm)))));
   16892       break;
   16893 
   16894    case 0x0B:  /* SLTIU */
   16895       DIP("sltiu r%d, r%d, %d", rt, rs, imm);
   16896       if (mode64)
   16897          putIReg(rt, unop(Iop_1Uto64, binop(Iop_CmpLT64U, getIReg(rs),
   16898                                             mkU64(extend_s_16to64(imm)))));
   16899       else
   16900          putIReg(rt, unop(Iop_1Uto32, binop(Iop_CmpLT32U, getIReg(rs),
   16901                                             mkU32(extend_s_16to32(imm)))));
   16902       break;
   16903 
   16904    case 0x18: {  /* Doubleword Add Immidiate - DADD; MIPS64 */
   16905       DIP("daddi r%d, r%d, %d", rt, rs, imm);
   16906       IRTemp tmpRs64 = newTemp(Ity_I64);
   16907       assign(tmpRs64, getIReg(rs));
   16908 
   16909       t0 = newTemp(Ity_I64);
   16910       t1 = newTemp(Ity_I64);
   16911       t2 = newTemp(Ity_I64);
   16912       t3 = newTemp(Ity_I64);
   16913       t4 = newTemp(Ity_I64);
   16914       /* dst = src0 + sign(imm)
   16915          if(sign(src0 ) != sign(imm ))
   16916          goto no overflow;
   16917          if(sign(dst) == sign(src0 ))
   16918          goto no overflow;
   16919          we have overflow! */
   16920 
   16921       assign(t0, binop(Iop_Add64, mkexpr(tmpRs64),
   16922                        mkU64(extend_s_16to64(imm))));
   16923       assign(t1, binop(Iop_Xor64, mkexpr(tmpRs64),
   16924                        mkU64(extend_s_16to64(imm))));
   16925       assign(t2, unop(Iop_1Sto64, binop(Iop_CmpEQ64, binop(Iop_And64,
   16926                       mkexpr(t1), mkU64(0x8000000000000000ULL)),
   16927                                         mkU64(0x8000000000000000ULL))));
   16928 
   16929       assign(t3, binop(Iop_Xor64, mkexpr(t0), mkexpr(tmpRs64)));
   16930       assign(t4, unop(Iop_1Sto64, binop(Iop_CmpNE64, binop(Iop_And64,
   16931                       mkexpr(t3), mkU64(0x8000000000000000ULL)),
   16932                                         mkU64(0x8000000000000000ULL))));
   16933 
   16934       stmt(IRStmt_Exit(binop(Iop_CmpEQ64, binop(Iop_Or64, mkexpr(t2),
   16935                              mkexpr(t4)), mkU64(0)), Ijk_SigFPE_IntOvf,
   16936                        IRConst_U64(guest_PC_curr_instr + 4),
   16937                        OFFB_PC));
   16938 
   16939       putIReg(rt,  mkexpr(t0));
   16940       break;
   16941    }
   16942 
   16943    case 0x19:  /* Doubleword Add Immidiate Unsigned - DADDIU; MIPS64 */
   16944       DIP("daddiu r%d, r%d, %d", rt, rs, imm);
   16945       putIReg(rt, binop(Iop_Add64, getIReg(rs), mkU64(extend_s_16to64(imm))));
   16946       break;
   16947 
   16948    case 0x1A: {
   16949       /* Load Doubleword Left - LDL; MIPS64 */
   16950       vassert(mode64);
   16951       DIP("ldl r%u, %d(r%u)", rt, imm, rs);
   16952       /* t1 = addr */
   16953 #if defined (_MIPSEL)
   16954       t1 = newTemp(Ity_I64);
   16955       assign(t1, binop(Iop_Add64, getIReg(rs), mkU64(extend_s_16to64(imm))));
   16956 #elif defined (_MIPSEB)
   16957       t1 = newTemp(Ity_I64);
   16958       assign(t1, binop(Iop_Xor64, mkU64(0x7), binop(Iop_Add64, getIReg(rs),
   16959                                   mkU64(extend_s_16to64(imm)))));
   16960 #endif
   16961       /* t2 = word addr */
   16962       /* t4 = addr mod 8 */
   16963       LWX_SWX_PATTERN64_1;
   16964 
   16965       /* t3 = word content - shifted */
   16966       t3 = newTemp(Ity_I64);
   16967       assign(t3, binop(Iop_Shl64, load(Ity_I64, mkexpr(t2)),
   16968                  narrowTo(Ity_I8, binop(Iop_Shl64, binop(Iop_Sub64, mkU64(0x07),
   16969                  mkexpr(t4)), mkU8(3)))));
   16970 
   16971       /* rt content  - adjusted */
   16972       t5 = newTemp(Ity_I64);
   16973       t6 = newTemp(Ity_I64);
   16974       t7 = newTemp(Ity_I64);
   16975 
   16976       assign(t5, binop(Iop_Mul64, mkexpr(t4), mkU64(0x8)));
   16977 
   16978       assign(t6, binop(Iop_Shr64, mkU64(0x00FFFFFFFFFFFFFFULL),
   16979                        narrowTo(Ity_I8, mkexpr(t5))));
   16980 
   16981       assign(t7, binop(Iop_And64, getIReg(rt), mkexpr(t6)));
   16982 
   16983       putIReg(rt, binop(Iop_Or64, mkexpr(t7), mkexpr(t3)));
   16984       break;
   16985    }
   16986 
   16987    case 0x1B: {
   16988       /* Load Doubleword Right - LDR; MIPS64 */
   16989       vassert(mode64);
   16990       DIP("ldr r%u,%d(r%u)", rt, imm, rs);
   16991       /* t1 = addr */
   16992 #if defined (_MIPSEL)
   16993       t1 = newTemp(Ity_I64);
   16994       assign(t1, binop(Iop_Add64, getIReg(rs), mkU64(extend_s_16to64(imm))));
   16995 #elif defined (_MIPSEB)
   16996       t1 = newTemp(Ity_I64);
   16997       assign(t1, binop(Iop_Xor64, mkU64(0x7), binop(Iop_Add64, getIReg(rs),
   16998                                   mkU64(extend_s_16to64(imm)))));
   16999 #endif
   17000       /* t2 = word addr */
   17001       /* t4 = addr mod 8 */
   17002       LWX_SWX_PATTERN64_1;
   17003 
   17004       /* t3 = word content - shifted */
   17005       t3 = newTemp(Ity_I64);
   17006       assign(t3, binop(Iop_Shr64, load(Ity_I64, mkexpr(t2)),
   17007                  narrowTo(Ity_I8, binop(Iop_Shl64, mkexpr(t4), mkU8(3)))));
   17008 
   17009       /* rt content  - adjusted */
   17010       t5 = newTemp(Ity_I64);
   17011       assign(t5, binop(Iop_And64, getIReg(rt), unop(Iop_Not64,
   17012                  binop(Iop_Shr64, mkU64(0xFFFFFFFFFFFFFFFFULL),
   17013                  narrowTo(Ity_I8, binop(Iop_Shl64, mkexpr(t4), mkU8(0x3)))))));
   17014 
   17015       putIReg(rt, binop(Iop_Or64, mkexpr(t5), mkexpr(t3)));
   17016       break;
   17017    }
   17018 
   17019    case 0x27:  /* Load Word unsigned - LWU; MIPS64 */
   17020       DIP("lwu r%u,%d(r%u)", rt, imm, rs);
   17021       LOAD_STORE_PATTERN;
   17022 
   17023       putIReg(rt, mkWidenFrom32(ty, load(Ity_I32, mkexpr(t1)), False));
   17024       break;
   17025 
   17026    case 0x30:  /* LL / LWC0 */
   17027       DIP("ll r%d, %d(r%d)", rt, imm, rs);
   17028       LOAD_STORE_PATTERN;
   17029 
   17030       t2 = newTemp(Ity_I32);
   17031 #if defined (_MIPSEL)
   17032       stmt(IRStmt_LLSC(Iend_LE, t2, mkexpr(t1), NULL /* this is a load */ ));
   17033 #elif defined (_MIPSEB)
   17034       stmt(IRStmt_LLSC(Iend_BE, t2, mkexpr(t1), NULL /* this is a load */ ));
   17035 #endif
   17036       if (mode64)
   17037          putIReg(rt, unop(Iop_32Sto64, mkexpr(t2)));
   17038       else
   17039          putIReg(rt, mkexpr(t2));
   17040       break;
   17041 
   17042    case 0x34:  /* Load Linked Doubleword - LLD; MIPS64 */
   17043       DIP("lld r%d, %d(r%d)", rt, imm, rs);
   17044       LOAD_STORE_PATTERN;
   17045 
   17046       t2 = newTemp(Ity_I64);
   17047 #if defined (_MIPSEL)
   17048       stmt(IRStmt_LLSC
   17049            (Iend_LE, t2, mkexpr(t1), NULL /* this is a load */ ));
   17050 #elif defined (_MIPSEB)
   17051       stmt(IRStmt_LLSC
   17052            (Iend_BE, t2, mkexpr(t1), NULL /* this is a load */ ));
   17053 #endif
   17054 
   17055       putIReg(rt, mkexpr(t2));
   17056       break;
   17057 
   17058    case 0x38:  /* SC / SWC0 */
   17059       DIP("sc r%d, %d(r%d)", rt, imm, rs);
   17060       LOAD_STORE_PATTERN;
   17061 
   17062       t2 = newTemp(Ity_I1);
   17063 #if defined (_MIPSEL)
   17064       stmt(IRStmt_LLSC(Iend_LE, t2, mkexpr(t1), mkNarrowTo32(ty, getIReg(rt))));
   17065 #elif defined (_MIPSEB)
   17066       stmt(IRStmt_LLSC(Iend_BE, t2, mkexpr(t1), mkNarrowTo32(ty, getIReg(rt))));
   17067 #endif
   17068 
   17069       putIReg(rt, unop(mode64 ? Iop_1Uto64 : Iop_1Uto32, mkexpr(t2)));
   17070       break;
   17071 
   17072    case 0x3C:  /* Store Conditional Doubleword - SCD; MIPS64 */
   17073       DIP("sdc r%d, %d(r%d)", rt, imm, rs);
   17074       LOAD_STORE_PATTERN;
   17075 
   17076       t2 = newTemp(Ity_I1);
   17077 #if defined (_MIPSEL)
   17078       stmt(IRStmt_LLSC(Iend_LE, t2, mkexpr(t1), getIReg(rt)));
   17079 #elif defined (_MIPSEB)
   17080       stmt(IRStmt_LLSC(Iend_BE, t2, mkexpr(t1), getIReg(rt)));
   17081 #endif
   17082 
   17083       putIReg(rt, unop(Iop_1Uto64, mkexpr(t2)));
   17084       break;
   17085 
   17086    case 0x37:  /* Load Doubleword - LD; MIPS64 */
   17087       DIP("ld r%u, %d(r%u)", rt, imm, rs);
   17088       LOAD_STORE_PATTERN;
   17089       putIReg(rt, load(Ity_I64, mkexpr(t1)));
   17090       break;
   17091 
   17092    case 0x3F:  /* Store Doubleword - SD; MIPS64 */
   17093       DIP("sd r%u, %d(r%u)", rt, imm, rs);
   17094       LOAD_STORE_PATTERN;
   17095       store(mkexpr(t1), getIReg(rt));
   17096       break;
   17097 
   17098    case 0x32:  /* Branch on Bit Clear - BBIT0; Cavium OCTEON */
   17099       /* Cavium Specific instructions. */
   17100       if (VEX_MIPS_COMP_ID(archinfo->hwcaps) == VEX_PRID_COMP_CAVIUM) {
   17101          DIP("bbit0 r%d, 0x%x, %x", rs, rt, imm);
   17102          t0 = newTemp(Ity_I32);
   17103          t1 = newTemp(Ity_I32);
   17104          assign(t0, mkU32(0x1));
   17105          assign(t1, binop(Iop_Shl32, mkexpr(t0), mkU8(rt)));
   17106          dis_branch(False, binop(Iop_CmpEQ32,
   17107                                  binop(Iop_And32,
   17108                                        mkexpr(t1),
   17109                                        mkNarrowTo32(ty, getIReg(rs))),
   17110                                  mkU32(0x0)),
   17111                     imm, &bstmt);
   17112          break;
   17113       } else {
   17114          goto decode_failure;
   17115       }
   17116 
   17117    case 0x36:  /* Branch on Bit Clear Plus 32 - BBIT032; Cavium OCTEON */
   17118       /* Cavium Specific instructions. */
   17119       if (VEX_MIPS_COMP_ID(archinfo->hwcaps) == VEX_PRID_COMP_CAVIUM) {
   17120          DIP("bbit032 r%d, 0x%x, %x", rs, rt, imm);
   17121          t0 = newTemp(Ity_I64);
   17122          t1 = newTemp(Ity_I8);  /* Shift. */
   17123          t2 = newTemp(Ity_I64);
   17124          assign(t0, mkU64(0x1));
   17125          assign(t1, binop(Iop_Add8, mkU8(rt), mkU8(32)));
   17126          assign(t2, binop(Iop_Shl64, mkexpr(t0), mkexpr(t1)));
   17127          dis_branch(False, binop(Iop_CmpEQ64,
   17128                                  binop(Iop_And64,
   17129                                        mkexpr(t2),
   17130                                        getIReg(rs)),
   17131                                  mkU64(0x0)),
   17132                     imm, &bstmt);
   17133          break;
   17134       } else {
   17135          goto decode_failure;
   17136       }
   17137 
   17138    case 0x3A:  /* Branch on Bit Set - BBIT1; Cavium OCTEON */
   17139       /* Cavium Specific instructions. */
   17140       if (VEX_MIPS_COMP_ID(archinfo->hwcaps) == VEX_PRID_COMP_CAVIUM) {
   17141          DIP("bbit1 r%d, 0x%x, %x", rs, rt, imm);
   17142          t0 = newTemp(Ity_I32);
   17143          t1 = newTemp(Ity_I32);
   17144          assign(t0, mkU32(0x1));
   17145          assign(t1, binop(Iop_Shl32, mkexpr(t0), mkU8(rt)));
   17146          dis_branch(False, binop(Iop_CmpNE32,
   17147                                  binop(Iop_And32,
   17148                                        mkexpr(t1),
   17149                                        mkNarrowTo32(ty, getIReg(rs))),
   17150                                  mkU32(0x0)),
   17151                     imm, &bstmt);
   17152          break;
   17153       } else {
   17154          goto decode_failure;
   17155       }
   17156 
   17157    case 0x3E:  /* Branch on Bit Set Plus 32 - BBIT132; Cavium OCTEON */
   17158       /* Cavium Specific instructions. */
   17159       if (VEX_MIPS_COMP_ID(archinfo->hwcaps) == VEX_PRID_COMP_CAVIUM) {
   17160          DIP("bbit132 r%d, 0x%x, %x", rs, rt, imm);
   17161          t0 = newTemp(Ity_I64);
   17162          t1 = newTemp(Ity_I8);  /* Shift. */
   17163          t2 = newTemp(Ity_I64);
   17164          assign(t0, mkU64(0x1));
   17165          assign(t1, binop(Iop_Add8, mkU8(rt), mkU8(32)));
   17166          assign(t2, binop(Iop_Shl64, mkexpr(t0), mkexpr(t1)));
   17167          dis_branch(False, binop(Iop_CmpNE64,
   17168                                  binop(Iop_And64,
   17169                                        mkexpr(t2),
   17170                                        getIReg(rs)),
   17171                                  mkU64(0x0)),
   17172                     imm, &bstmt);
   17173          break;
   17174       } else {
   17175          goto decode_failure;
   17176       }
   17177 
   17178    default:
   17179       goto decode_failure;
   17180 
   17181    decode_failure_dsp:
   17182       vex_printf("Error occured while trying to decode MIPS32 DSP "
   17183                  "instruction.\nYour platform probably doesn't support "
   17184                  "MIPS32 DSP ASE.\n");
   17185    decode_failure:
   17186       /* All decode failures end up here. */
   17187       if (sigill_diag)
   17188          vex_printf("vex mips->IR: unhandled instruction bytes: "
   17189                     "0x%x 0x%x 0x%x 0x%x\n",
   17190                     (Int) getIByte(delta_start + 0),
   17191                     (Int) getIByte(delta_start + 1),
   17192                     (Int) getIByte(delta_start + 2),
   17193                     (Int) getIByte(delta_start + 3));
   17194 
   17195       /* Tell the dispatcher that this insn cannot be decoded, and so has
   17196          not been executed, and (is currently) the next to be executed.
   17197          EIP should be up-to-date since it made so at the start bnezof each
   17198          insn, but nevertheless be paranoid and update it again right
   17199          now. */
   17200       if (mode64) {
   17201          stmt(IRStmt_Put(offsetof(VexGuestMIPS64State, guest_PC),
   17202               mkU64(guest_PC_curr_instr)));
   17203          jmp_lit64(&dres, Ijk_NoDecode, guest_PC_curr_instr);
   17204       } else {
   17205          stmt(IRStmt_Put(offsetof(VexGuestMIPS32State, guest_PC),
   17206               mkU32(guest_PC_curr_instr)));
   17207          jmp_lit32(&dres, Ijk_NoDecode, guest_PC_curr_instr);
   17208       }
   17209       dres.whatNext = Dis_StopHere;
   17210       dres.len = 0;
   17211       return dres;
   17212    }  /* switch (opc) for the main (primary) opcode switch. */
   17213 
   17214    /* All MIPS insn have 4 bytes */
   17215 
   17216    if (delay_slot_branch) {
   17217       delay_slot_branch = False;
   17218       stmt(bstmt);
   17219       bstmt = NULL;
   17220       if (mode64)
   17221          putPC(mkU64(guest_PC_curr_instr + 4));
   17222       else
   17223          putPC(mkU32(guest_PC_curr_instr + 4));
   17224       dres.jk_StopHere = is_Branch_or_Jump_and_Link(guest_code + delta - 4) ?
   17225                          Ijk_Call : Ijk_Boring;
   17226    }
   17227 
   17228    if (likely_delay_slot) {
   17229       dres.jk_StopHere = Ijk_Boring;
   17230       dres.whatNext = Dis_StopHere;
   17231       putPC(lastn);
   17232       lastn = NULL;
   17233    }
   17234    if (delay_slot_jump) {
   17235       putPC(lastn);
   17236       lastn = NULL;
   17237       dres.jk_StopHere = is_Branch_or_Jump_and_Link(guest_code + delta - 4) ?
   17238                          Ijk_Call : Ijk_Boring;
   17239    }
   17240 
   17241  decode_success:
   17242    /* All decode successes end up here. */
   17243    switch (dres.whatNext) {
   17244       case Dis_Continue:
   17245          if (mode64)
   17246             putPC(mkU64(guest_PC_curr_instr + 4));
   17247          else
   17248             putPC(mkU32(guest_PC_curr_instr + 4));
   17249          break;
   17250       case Dis_ResteerU:
   17251       case Dis_ResteerC:
   17252          putPC(mkU32(dres.continueAt));
   17253          break;
   17254       case Dis_StopHere:
   17255          break;
   17256       default:
   17257          vassert(0);
   17258          break;
   17259    }
   17260 
   17261    /* On MIPS we need to check if the last instruction in block is branch or
   17262       jump. */
   17263    if (((vex_control.guest_max_insns - 1) == (delta + 4) / 4)
   17264        &&  (dres.whatNext != Dis_StopHere))
   17265       if (branch_or_jump(guest_code + delta + 4)) {
   17266          dres.whatNext = Dis_StopHere;
   17267          dres.jk_StopHere = Ijk_Boring;
   17268          if (mode64)
   17269             putPC(mkU64(guest_PC_curr_instr + 4));
   17270          else
   17271             putPC(mkU32(guest_PC_curr_instr + 4));
   17272       }
   17273    dres.len = 4;
   17274 
   17275    DIP("\n");
   17276 
   17277    return dres;
   17278 
   17279 }
   17280 
   17281 /*------------------------------------------------------------*/
   17282 /*--- Top-level fn                                         ---*/
   17283 /*------------------------------------------------------------*/
   17284 
   17285 /* Disassemble a single instruction into IR.  The instruction
   17286    is located in host memory at &guest_code[delta]. */
   17287 DisResult disInstr_MIPS( IRSB*        irsb_IN,
   17288                          Bool         (*resteerOkFn) ( void *, Addr ),
   17289                          Bool         resteerCisOk,
   17290                          void*        callback_opaque,
   17291                          const UChar* guest_code_IN,
   17292                          Long         delta,
   17293                          Addr         guest_IP,
   17294                          VexArch      guest_arch,
   17295                          const VexArchInfo* archinfo,
   17296                          const VexAbiInfo*  abiinfo,
   17297                          VexEndness   host_endness_IN,
   17298                          Bool         sigill_diag_IN )
   17299 {
   17300    DisResult dres;
   17301    /* Set globals (see top of this file) */
   17302    vassert(guest_arch == VexArchMIPS32 || guest_arch == VexArchMIPS64);
   17303 
   17304    mode64 = guest_arch != VexArchMIPS32;
   17305 #if (__mips_fpr==64)
   17306    fp_mode64 = ((VEX_MIPS_REV(archinfo->hwcaps) == VEX_PRID_CPU_32FPR)
   17307                 || guest_arch == VexArchMIPS64);
   17308 #endif
   17309 
   17310    guest_code = guest_code_IN;
   17311    irsb = irsb_IN;
   17312    host_endness = host_endness_IN;
   17313 #if defined(VGP_mips32_linux)
   17314    guest_PC_curr_instr = (Addr32)guest_IP;
   17315 #elif defined(VGP_mips64_linux)
   17316    guest_PC_curr_instr = (Addr64)guest_IP;
   17317 #endif
   17318 
   17319    dres = disInstr_MIPS_WRK(resteerOkFn, resteerCisOk, callback_opaque,
   17320                             delta, archinfo, abiinfo, sigill_diag_IN);
   17321 
   17322    return dres;
   17323 }
   17324 
   17325 /*--------------------------------------------------------------------*/
   17326 /*--- end                                        guest_mips_toIR.c ---*/
   17327 /*--------------------------------------------------------------------*/
   17328