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-2017 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 #define LLADDR_INVALID \
    553    (mode64 ? mkU64(0xFFFFFFFFFFFFFFFFULL) : mkU32(0xFFFFFFFF))
    554 
    555 /*------------------------------------------------------------*/
    556 /*---                  Field helpers                       ---*/
    557 /*------------------------------------------------------------*/
    558 
    559 static UInt get_opcode(UInt mipsins)
    560 {
    561    return (0xFC000000 & mipsins) >> 26;
    562 }
    563 
    564 static UInt get_rs(UInt mipsins)
    565 {
    566    return (0x03E00000 & mipsins) >> 21;
    567 }
    568 
    569 static UInt get_rt(UInt mipsins)
    570 {
    571    return (0x001F0000 & mipsins) >> 16;
    572 }
    573 
    574 static UInt get_imm(UInt mipsins)
    575 {
    576    return (0x0000FFFF & mipsins);
    577 }
    578 
    579 static UInt get_instr_index(UInt mipsins)
    580 {
    581    return (0x03FFFFFF & mipsins);
    582 }
    583 
    584 static UInt get_rd(UInt mipsins)
    585 {
    586    return (0x0000F800 & mipsins) >> 11;
    587 }
    588 
    589 static UInt get_sa(UInt mipsins)
    590 {
    591    return (0x000007C0 & mipsins) >> 6;
    592 }
    593 
    594 static UInt get_function(UInt mipsins)
    595 {
    596    return (0x0000003F & mipsins);
    597 }
    598 
    599 static UInt get_ft(UInt mipsins)
    600 {
    601    return (0x001F0000 & mipsins) >> 16;
    602 }
    603 
    604 static UInt get_fs(UInt mipsins)
    605 {
    606    return (0x0000F800 & mipsins) >> 11;
    607 }
    608 
    609 static UInt get_fd(UInt mipsins)
    610 {
    611    return (0x000007C0 & mipsins) >> 6;
    612 }
    613 
    614 static UInt get_mov_cc(UInt mipsins)
    615 {
    616    return (0x001C0000 & mipsins) >> 18;
    617 }
    618 
    619 static UInt get_bc1_cc(UInt mipsins)
    620 {
    621    return (0x001C0000 & mipsins) >> 18;
    622 }
    623 
    624 static UInt get_fpc_cc(UInt mipsins)
    625 {
    626    return (0x00000700 & mipsins) >> 8;
    627 }
    628 
    629 static UInt get_tf(UInt mipsins)
    630 {
    631    return (0x00010000 & mipsins) >> 16;
    632 }
    633 
    634 static UInt get_nd(UInt mipsins)
    635 {
    636    return (0x00020000 & mipsins) >> 17;
    637 }
    638 
    639 static UInt get_fmt(UInt mipsins)
    640 {
    641    return (0x03E00000 & mipsins) >> 21;
    642 }
    643 
    644 static UInt get_FC(UInt mipsins)
    645 {
    646    return (0x000000F0 & mipsins) >> 4;
    647 }
    648 
    649 static UInt get_cond(UInt mipsins)
    650 {
    651    return (0x0000000F & mipsins);
    652 }
    653 
    654 /* for break & syscall */
    655 static UInt get_code(UInt mipsins)
    656 {
    657    return (0xFFC0 & mipsins) >> 6;
    658 }
    659 
    660 static UInt get_lsb(UInt mipsins)
    661 {
    662    return (0x7C0 & mipsins) >> 6;
    663 }
    664 
    665 static UInt get_msb(UInt mipsins)
    666 {
    667    return (0x0000F800 & mipsins) >> 11;
    668 }
    669 
    670 static UInt get_rot(UInt mipsins)
    671 {
    672    return (0x00200000 & mipsins) >> 21;
    673 }
    674 
    675 static UInt get_rotv(UInt mipsins)
    676 {
    677    return (0x00000040 & mipsins) >> 6;
    678 }
    679 
    680 static UInt get_sel(UInt mipsins)
    681 {
    682    return (0x00000007 & mipsins);
    683 }
    684 
    685 /* Get acc number for all MIPS32 DSP ASE(r2) instructions that use them,
    686    except for MFHI and MFLO. */
    687 static UInt get_acNo(UInt mipsins)
    688 {
    689    return (0x00001800 & mipsins) >> 11;
    690 }
    691 
    692 /* Get accumulator number for MIPS32 DSP ASEr2 MFHI and MFLO instructions. */
    693 static UInt get_acNo_mfhilo(UInt mipsins)
    694 {
    695    return (0x00600000 & mipsins) >> 21;
    696 }
    697 
    698 /* Get mask field (helper function for wrdsp instruction). */
    699 static UInt get_wrdspMask(UInt mipsins)
    700 {
    701    return (0x001ff800 & mipsins) >> 11;
    702 }
    703 
    704 /* Get mask field (helper function for rddsp instruction). */
    705 static UInt get_rddspMask(UInt mipsins)
    706 {
    707    return (0x03ff0000 & mipsins) >> 16;
    708 }
    709 
    710 /* Get shift field (helper function for DSP ASE instructions). */
    711 static UInt get_shift(UInt mipsins)
    712 {
    713    return (0x03f00000 & mipsins) >> 20;
    714 }
    715 
    716 /* Get immediate field for DSP ASE instructions. */
    717 static UInt get_dspImm(UInt mipsins)
    718 {
    719    return (0x03ff0000 & mipsins) >> 16;
    720 }
    721 
    722 static Bool branch_or_jump(const UChar * addr)
    723 {
    724    UInt fmt;
    725    UInt cins = getUInt(addr);
    726 
    727    UInt opcode = get_opcode(cins);
    728    UInt rt = get_rt(cins);
    729    UInt function = get_function(cins);
    730 
    731    /* bgtz, blez, bne, beq, jal */
    732    if (opcode == 0x07 || opcode == 0x06 || opcode == 0x05 || opcode == 0x04
    733        || opcode == 0x03 || opcode == 0x02) {
    734       return True;
    735    }
    736 
    737    /* bgez */
    738    if (opcode == 0x01 && rt == 0x01) {
    739       return True;
    740    }
    741 
    742    /* bgezal */
    743    if (opcode == 0x01 && rt == 0x11) {
    744       return True;
    745    }
    746 
    747    /* bltzal */
    748    if (opcode == 0x01 && rt == 0x10) {
    749       return True;
    750    }
    751 
    752    /* bltz */
    753    if (opcode == 0x01 && rt == 0x00) {
    754       return True;
    755    }
    756 
    757    /* jalr */
    758    if (opcode == 0x00 && function == 0x09) {
    759       return True;
    760    }
    761 
    762    /* jr */
    763    if (opcode == 0x00 && function == 0x08) {
    764       return True;
    765    }
    766 
    767    if (opcode == 0x11) {
    768       /*bc1f & bc1t */
    769       fmt = get_fmt(cins);
    770       if (fmt == 0x08) {
    771          return True;
    772       }
    773    }
    774 
    775    /* bposge32 */
    776    if (opcode == 0x01 && rt == 0x1c) {
    777       return True;
    778    }
    779 
    780    /* Cavium Specific instructions. */
    781    if (opcode == 0x32 || opcode == 0x3A || opcode == 0x36 || opcode == 0x3E) {
    782        /* BBIT0, BBIT1, BBIT032, BBIT132 */
    783       return True;
    784    }
    785 
    786    return False;
    787 }
    788 
    789 static Bool is_Branch_or_Jump_and_Link(const UChar * addr)
    790 {
    791    UInt cins = getUInt(addr);
    792 
    793    UInt opcode = get_opcode(cins);
    794    UInt rt = get_rt(cins);
    795    UInt function = get_function(cins);
    796 
    797    /* jal */
    798    if (opcode == 0x02) {
    799       return True;
    800    }
    801 
    802    /* bgezal */
    803    if (opcode == 0x01 && rt == 0x11) {
    804       return True;
    805    }
    806 
    807    /* bltzal */
    808    if (opcode == 0x01 && rt == 0x10) {
    809       return True;
    810    }
    811 
    812    /* jalr */
    813    if (opcode == 0x00 && function == 0x09) {
    814       return True;
    815    }
    816 
    817    return False;
    818 }
    819 
    820 static Bool branch_or_link_likely(const UChar * addr)
    821 {
    822    UInt cins = getUInt(addr);
    823    UInt opcode = get_opcode(cins);
    824    UInt rt = get_rt(cins);
    825 
    826    /* bgtzl, blezl, bnel, beql */
    827    if (opcode == 0x17 || opcode == 0x16 || opcode == 0x15 || opcode == 0x14)
    828       return True;
    829 
    830    /* bgezl */
    831    if (opcode == 0x01 && rt == 0x03)
    832       return True;
    833 
    834    /* bgezall */
    835    if (opcode == 0x01 && rt == 0x13)
    836       return True;
    837 
    838    /* bltzall */
    839    if (opcode == 0x01 && rt == 0x12)
    840       return True;
    841 
    842    /* bltzl */
    843    if (opcode == 0x01 && rt == 0x02)
    844       return True;
    845 
    846    return False;
    847 }
    848 
    849 /*------------------------------------------------------------*/
    850 /*--- Helper bits and pieces for creating IR fragments.    ---*/
    851 /*------------------------------------------------------------*/
    852 
    853 static IRExpr *mkU8(UInt i)
    854 {
    855    vassert(i < 256);
    856    return IRExpr_Const(IRConst_U8((UChar) i));
    857 }
    858 
    859 /* Create an expression node for a 16-bit integer constant. */
    860 static IRExpr *mkU16(UInt i)
    861 {
    862    return IRExpr_Const(IRConst_U16(i));
    863 }
    864 
    865 /* Create an expression node for a 32-bit integer constant. */
    866 static IRExpr *mkU32(UInt i)
    867 {
    868    return IRExpr_Const(IRConst_U32(i));
    869 }
    870 
    871 /* Create an expression node for a 64-bit integer constant. */
    872 static IRExpr *mkU64(ULong i)
    873 {
    874    return IRExpr_Const(IRConst_U64(i));
    875 }
    876 
    877 static IRExpr *mkexpr(IRTemp tmp)
    878 {
    879    return IRExpr_RdTmp(tmp);
    880 }
    881 
    882 static IRExpr *unop(IROp op, IRExpr * a)
    883 {
    884    return IRExpr_Unop(op, a);
    885 }
    886 
    887 static IRExpr *binop(IROp op, IRExpr * a1, IRExpr * a2)
    888 {
    889    return IRExpr_Binop(op, a1, a2);
    890 }
    891 
    892 static IRExpr *triop(IROp op, IRExpr * a1, IRExpr * a2, IRExpr * a3)
    893 {
    894    return IRExpr_Triop(op, a1, a2, a3);
    895 }
    896 
    897 static IRExpr *qop ( IROp op, IRExpr * a1, IRExpr * a2, IRExpr * a3,
    898                      IRExpr * a4 )
    899 {
    900    return IRExpr_Qop(op, a1, a2, a3, a4);
    901 }
    902 
    903 static IRExpr *load(IRType ty, IRExpr * addr)
    904 {
    905    IRExpr *load1 = NULL;
    906 #if defined (_MIPSEL)
    907    load1 = IRExpr_Load(Iend_LE, ty, addr);
    908 #elif defined (_MIPSEB)
    909    load1 = IRExpr_Load(Iend_BE, ty, addr);
    910 #endif
    911    return load1;
    912 }
    913 
    914 /* Add a statement to the list held by "irsb". */
    915 static void stmt(IRStmt * st)
    916 {
    917    addStmtToIRSB(irsb, st);
    918 }
    919 
    920 static void assign(IRTemp dst, IRExpr * e)
    921 {
    922    stmt(IRStmt_WrTmp(dst, e));
    923 }
    924 
    925 static void store(IRExpr * addr, IRExpr * data)
    926 {
    927 #if defined (_MIPSEL)
    928    stmt(IRStmt_Store(Iend_LE, addr, data));
    929 #elif defined (_MIPSEB)
    930    stmt(IRStmt_Store(Iend_BE, addr, data));
    931 #endif
    932 }
    933 
    934 /* Generate a new temporary of the given type. */
    935 static IRTemp newTemp(IRType ty)
    936 {
    937    vassert(isPlausibleIRType(ty));
    938    return newIRTemp(irsb->tyenv, ty);
    939 }
    940 
    941 /* Generate an expression for SRC rotated right by ROT. */
    942 static IRExpr *genROR32(IRExpr * src, Int rot)
    943 {
    944    vassert(rot >= 0 && rot < 32);
    945    if (rot == 0)
    946       return src;
    947    return binop(Iop_Or32, binop(Iop_Shl32, src, mkU8(32 - rot)),
    948                           binop(Iop_Shr32, src, mkU8(rot)));
    949 }
    950 
    951 static IRExpr *genRORV32(IRExpr * src, IRExpr * rs)
    952 {
    953    IRTemp t0 = newTemp(Ity_I8);
    954    IRTemp t1 = newTemp(Ity_I8);
    955 
    956    assign(t0, unop(Iop_32to8, binop(Iop_And32, rs, mkU32(0x0000001F))));
    957    assign(t1, binop(Iop_Sub8, mkU8(32), mkexpr(t0)));
    958    return binop(Iop_Or32, binop(Iop_Shl32, src, mkexpr(t1)),
    959                           binop(Iop_Shr32, src, mkexpr(t0)));
    960 }
    961 
    962 static UShort extend_s_10to16(UInt x)
    963 {
    964    return (UShort) ((((Int) x) << 22) >> 22);
    965 }
    966 
    967 static ULong extend_s_10to32(UInt x)
    968 {
    969    return (ULong)((((Long) x) << 22) >> 22);
    970 }
    971 
    972 static ULong extend_s_10to64(UInt x)
    973 {
    974    return (ULong)((((Long) x) << 54) >> 54);
    975 }
    976 
    977 static UInt extend_s_16to32(UInt x)
    978 {
    979    return (UInt) ((((Int) x) << 16) >> 16);
    980 }
    981 
    982 static UInt extend_s_18to32(UInt x)
    983 {
    984    return (UInt) ((((Int) x) << 14) >> 14);
    985 }
    986 
    987 static ULong extend_s_16to64 ( UInt x )
    988 {
    989    return (ULong) ((((Long) x) << 48) >> 48);
    990 }
    991 
    992 static ULong extend_s_18to64 ( UInt x )
    993 {
    994    return (ULong) ((((Long) x) << 46) >> 46);
    995 }
    996 
    997 static ULong extend_s_32to64 ( UInt x )
    998 {
    999    return (ULong) ((((Long) x) << 32) >> 32);
   1000 }
   1001 
   1002 static void jmp_lit32 ( /*MOD*/ DisResult* dres, IRJumpKind kind, Addr32 d32 )
   1003 {
   1004    vassert(dres->whatNext    == Dis_Continue);
   1005    vassert(dres->len         == 0);
   1006    vassert(dres->continueAt  == 0);
   1007    vassert(dres->jk_StopHere == Ijk_INVALID);
   1008    dres->whatNext    = Dis_StopHere;
   1009    dres->jk_StopHere = kind;
   1010    stmt( IRStmt_Put( OFFB_PC, mkU32(d32) ) );
   1011 }
   1012 
   1013 static void jmp_lit64 ( /*MOD*/ DisResult* dres, IRJumpKind kind, Addr64 d64 )
   1014 {
   1015    vassert(dres->whatNext    == Dis_Continue);
   1016    vassert(dres->len         == 0);
   1017    vassert(dres->continueAt  == 0);
   1018    vassert(dres->jk_StopHere == Ijk_INVALID);
   1019    dres->whatNext    = Dis_StopHere;
   1020    dres->jk_StopHere = kind;
   1021    stmt(IRStmt_Put(OFFB_PC, mkU64(d64)));
   1022 }
   1023 
   1024 /* Get value from accumulator (helper function for MIPS32 DSP ASE instructions).
   1025    This function should be called before any other operation if widening
   1026    multiplications are used. */
   1027 static IRExpr *getAcc(UInt acNo)
   1028 {
   1029    vassert(!mode64);
   1030    vassert(acNo <= 3);
   1031    return IRExpr_Get(accumulatorGuestRegOffset(acNo), Ity_I64);
   1032 }
   1033 
   1034 /* Get value from DSPControl register (helper function for MIPS32 DSP ASE
   1035    instructions). */
   1036 static IRExpr *getDSPControl(void)
   1037 {
   1038    vassert(!mode64);
   1039    return IRExpr_Get(offsetof(VexGuestMIPS32State, guest_DSPControl), Ity_I32);
   1040 }
   1041 
   1042 /* Put value to DSPControl register. Expression e is written to DSPControl as
   1043    is. If only certain bits of DSPControl need to be changed, it should be done
   1044    before calling putDSPControl(). It could be done by reading DSPControl and
   1045    ORing it with appropriate mask. */
   1046 static void putDSPControl(IRExpr * e)
   1047 {
   1048    vassert(!mode64);
   1049    stmt(IRStmt_Put(offsetof(VexGuestMIPS32State, guest_DSPControl), e));
   1050 }
   1051 
   1052 /* Fetch a byte from the guest insn stream. */
   1053 static UChar getIByte(Int delta)
   1054 {
   1055    return guest_code[delta];
   1056 }
   1057 
   1058 static IRExpr *getIReg(UInt iregNo)
   1059 {
   1060    if (0 == iregNo) {
   1061       return mode64 ? mkU64(0x0) : mkU32(0x0);
   1062    } else {
   1063       IRType ty = mode64 ? Ity_I64 : Ity_I32;
   1064       vassert(iregNo < 32);
   1065       return IRExpr_Get(integerGuestRegOffset(iregNo), ty);
   1066    }
   1067 }
   1068 
   1069 static IRExpr *getHI(void)
   1070 {
   1071    if (mode64)
   1072       return IRExpr_Get(offsetof(VexGuestMIPS64State, guest_HI), Ity_I64);
   1073    else
   1074       return IRExpr_Get(offsetof(VexGuestMIPS32State, guest_HI), Ity_I32);
   1075 }
   1076 
   1077 static IRExpr *getLO(void)
   1078 {
   1079    if (mode64)
   1080       return IRExpr_Get(offsetof(VexGuestMIPS64State, guest_LO), Ity_I64);
   1081    else
   1082       return IRExpr_Get(offsetof(VexGuestMIPS32State, guest_LO), Ity_I32);
   1083 }
   1084 
   1085 static IRExpr *getFCSR(void)
   1086 {
   1087    if (mode64)
   1088       return IRExpr_Get(offsetof(VexGuestMIPS64State, guest_FCSR), Ity_I32);
   1089    else
   1090       return IRExpr_Get(offsetof(VexGuestMIPS32State, guest_FCSR), Ity_I32);
   1091 }
   1092 
   1093 static IRExpr *getLLaddr(void)
   1094 {
   1095    if (mode64)
   1096       return IRExpr_Get(offsetof(VexGuestMIPS64State, guest_LLaddr), Ity_I64);
   1097    else
   1098       return IRExpr_Get(offsetof(VexGuestMIPS32State, guest_LLaddr), Ity_I32);
   1099 }
   1100 
   1101 static IRExpr *getLLdata(void)
   1102 {
   1103    if (mode64)
   1104       return IRExpr_Get(offsetof(VexGuestMIPS64State, guest_LLdata), Ity_I64);
   1105    else
   1106       return IRExpr_Get(offsetof(VexGuestMIPS32State, guest_LLdata), Ity_I32);
   1107 }
   1108 
   1109 /* Get byte from register reg, byte pos from 0 to 3 (or 7 for MIPS64) . */
   1110 static IRExpr *getByteFromReg(UInt reg, UInt byte_pos)
   1111 {
   1112   UInt pos = byte_pos * 8;
   1113   if (mode64)
   1114       return unop(Iop_64to8, binop(Iop_And64,
   1115                                    binop(Iop_Shr64, getIReg(reg), mkU8(pos)),
   1116                                    mkU64(0xFF)));
   1117    else
   1118       return unop(Iop_32to8, binop(Iop_And32,
   1119                                    binop(Iop_Shr32, getIReg(reg), mkU8(pos)),
   1120                                    mkU32(0xFF)));
   1121 }
   1122 
   1123 static void putFCSR(IRExpr * e)
   1124 {
   1125    if (mode64)
   1126       stmt(IRStmt_Put(offsetof(VexGuestMIPS64State, guest_FCSR), e));
   1127    else
   1128       stmt(IRStmt_Put(offsetof(VexGuestMIPS32State, guest_FCSR), e));
   1129 }
   1130 
   1131 static void putLLaddr(IRExpr * e)
   1132 {
   1133    if (mode64)
   1134       stmt(IRStmt_Put(offsetof(VexGuestMIPS64State, guest_LLaddr), e));
   1135    else
   1136       stmt(IRStmt_Put(offsetof(VexGuestMIPS32State, guest_LLaddr), e));
   1137 }
   1138 
   1139 static void putLLdata(IRExpr * e)
   1140 {
   1141    if (mode64)
   1142       stmt(IRStmt_Put(offsetof(VexGuestMIPS64State, guest_LLdata), e));
   1143    else
   1144       stmt(IRStmt_Put(offsetof(VexGuestMIPS32State, guest_LLdata), e));
   1145 }
   1146 
   1147 /* fs   - fpu source register number.
   1148    inst - fpu instruction that needs to be executed.
   1149    sz32 - size of source register.
   1150    opN  - number of operads:
   1151           1 - unary operation.
   1152           2 - binary operation. */
   1153 static void calculateFCSR(UInt fs, UInt ft, UInt inst, Bool sz32, UInt opN)
   1154 {
   1155    IRDirty *d;
   1156    IRTemp fcsr = newTemp(Ity_I32);
   1157    /* IRExpr_GSPTR() => Need to pass pointer to guest state to helper. */
   1158    if (fp_mode64)
   1159       d = unsafeIRDirty_1_N(fcsr, 0,
   1160                             "mips_dirtyhelper_calculate_FCSR_fp64",
   1161                             &mips_dirtyhelper_calculate_FCSR_fp64,
   1162                             mkIRExprVec_4(IRExpr_GSPTR(),
   1163                                           mkU32(fs),
   1164                                           mkU32(ft),
   1165                                           mkU32(inst)));
   1166    else
   1167       d = unsafeIRDirty_1_N(fcsr, 0,
   1168                             "mips_dirtyhelper_calculate_FCSR_fp32",
   1169                             &mips_dirtyhelper_calculate_FCSR_fp32,
   1170                             mkIRExprVec_4(IRExpr_GSPTR(),
   1171                                           mkU32(fs),
   1172                                           mkU32(ft),
   1173                                           mkU32(inst)));
   1174 
   1175    if (opN == 1) {  /* Unary operation. */
   1176       /* Declare we're reading guest state. */
   1177       if (sz32 || fp_mode64)
   1178          d->nFxState = 2;
   1179       else
   1180          d->nFxState = 3;
   1181       vex_bzero(&d->fxState, sizeof(d->fxState));
   1182 
   1183       d->fxState[0].fx     = Ifx_Read;  /* read */
   1184       if (mode64)
   1185          d->fxState[0].offset = offsetof(VexGuestMIPS64State, guest_FCSR);
   1186       else
   1187          d->fxState[0].offset = offsetof(VexGuestMIPS32State, guest_FCSR);
   1188       d->fxState[0].size   = sizeof(UInt);
   1189       d->fxState[1].fx     = Ifx_Read;  /* read */
   1190       d->fxState[1].offset = floatGuestRegOffset(fs);
   1191       d->fxState[1].size   = sizeof(ULong);
   1192 
   1193       if (!(sz32 || fp_mode64)) {
   1194          d->fxState[2].fx     = Ifx_Read;  /* read */
   1195          d->fxState[2].offset = floatGuestRegOffset(fs+1);
   1196          d->fxState[2].size   = sizeof(ULong);
   1197       }
   1198    } else if (opN == 2) {  /* Binary operation. */
   1199       /* Declare we're reading guest state. */
   1200       if (sz32 || fp_mode64)
   1201          d->nFxState = 3;
   1202       else
   1203          d->nFxState = 5;
   1204       vex_bzero(&d->fxState, sizeof(d->fxState));
   1205 
   1206       d->fxState[0].fx     = Ifx_Read;  /* read */
   1207       if (mode64)
   1208          d->fxState[0].offset = offsetof(VexGuestMIPS64State, guest_FCSR);
   1209       else
   1210          d->fxState[0].offset = offsetof(VexGuestMIPS32State, guest_FCSR);
   1211       d->fxState[0].size   = sizeof(UInt);
   1212       d->fxState[1].fx     = Ifx_Read;  /* read */
   1213       d->fxState[1].offset = floatGuestRegOffset(fs);
   1214       d->fxState[1].size   = sizeof(ULong);
   1215       d->fxState[2].fx     = Ifx_Read;  /* read */
   1216       d->fxState[2].offset = floatGuestRegOffset(ft);
   1217       d->fxState[2].size   = sizeof(ULong);
   1218 
   1219       if (!(sz32 || fp_mode64)) {
   1220          d->fxState[3].fx     = Ifx_Read;  /* read */
   1221          d->fxState[3].offset = floatGuestRegOffset(fs+1);
   1222          d->fxState[3].size   = sizeof(ULong);
   1223          d->fxState[4].fx     = Ifx_Read;  /* read */
   1224          d->fxState[4].offset = floatGuestRegOffset(ft+1);
   1225          d->fxState[4].size   = sizeof(ULong);
   1226       }
   1227    }
   1228 
   1229    stmt(IRStmt_Dirty(d));
   1230 
   1231    putFCSR(mkexpr(fcsr));
   1232 }
   1233 
   1234 static IRExpr *getULR(void)
   1235 {
   1236    if (mode64)
   1237       return IRExpr_Get(offsetof(VexGuestMIPS64State, guest_ULR), Ity_I64);
   1238    else
   1239       return IRExpr_Get(offsetof(VexGuestMIPS32State, guest_ULR), Ity_I32);
   1240 }
   1241 
   1242 static void putIReg(UInt archreg, IRExpr * e)
   1243 {
   1244    IRType ty = mode64 ? Ity_I64 : Ity_I32;
   1245    vassert(archreg < 32);
   1246    vassert(typeOfIRExpr(irsb->tyenv, e) == ty);
   1247    if (archreg != 0)
   1248       stmt(IRStmt_Put(integerGuestRegOffset(archreg), e));
   1249 }
   1250 
   1251 static IRExpr *mkNarrowTo32(IRType ty, IRExpr * src)
   1252 {
   1253    vassert(ty == Ity_I32 || ty == Ity_I64);
   1254    return ty == Ity_I64 ? unop(Iop_64to32, src) : src;
   1255 }
   1256 
   1257 static void putLO(IRExpr * e)
   1258 {
   1259    if (mode64) {
   1260       stmt(IRStmt_Put(offsetof(VexGuestMIPS64State, guest_LO), e));
   1261    } else {
   1262       stmt(IRStmt_Put(offsetof(VexGuestMIPS32State, guest_LO), e));
   1263    /* Add value to lower 32 bits of ac0 to maintain compatibility between
   1264       regular MIPS32 instruction set and MIPS DSP ASE. Keep higher 32bits
   1265       unchanged. */
   1266       IRTemp t_lo = newTemp(Ity_I32);
   1267       IRTemp t_hi = newTemp(Ity_I32);
   1268       assign(t_lo, e);
   1269       assign(t_hi, unop(Iop_64HIto32, getAcc(0)));
   1270       stmt(IRStmt_Put(accumulatorGuestRegOffset(0),
   1271            binop(Iop_32HLto64, mkexpr(t_hi), mkexpr(t_lo))));
   1272    }
   1273 }
   1274 
   1275 static void putHI(IRExpr * e)
   1276 {
   1277    if (mode64) {
   1278       stmt(IRStmt_Put(offsetof(VexGuestMIPS64State, guest_HI), e));
   1279    } else {
   1280       stmt(IRStmt_Put(offsetof(VexGuestMIPS32State, guest_HI), e));
   1281    /* Add value to higher 32 bits of ac0 to maintain compatibility between
   1282       regular MIPS32 instruction set and MIPS DSP ASE. Keep lower 32bits
   1283       unchanged. */
   1284       IRTemp t_lo = newTemp(Ity_I32);
   1285       IRTemp t_hi = newTemp(Ity_I32);
   1286       assign(t_hi, e);
   1287       assign(t_lo, unop(Iop_64to32, getAcc(0)));
   1288       stmt(IRStmt_Put(accumulatorGuestRegOffset(0),
   1289            binop(Iop_32HLto64, mkexpr(t_hi), mkexpr(t_lo))));
   1290    }
   1291 }
   1292 
   1293 /* Put value to accumulator(helper function for MIPS32 DSP ASE instructions). */
   1294 static void putAcc(UInt acNo, IRExpr * e)
   1295 {
   1296    vassert(!mode64);
   1297    vassert(acNo <= 3);
   1298    vassert(typeOfIRExpr(irsb->tyenv, e) == Ity_I64);
   1299    stmt(IRStmt_Put(accumulatorGuestRegOffset(acNo), e));
   1300 /* If acNo = 0, split value to HI and LO regs in order to maintain compatibility
   1301    between MIPS32 and MIPS DSP ASE insn sets. */
   1302    if (0 == acNo) {
   1303      putLO(unop(Iop_64to32, e));
   1304      putHI(unop(Iop_64HIto32, e));
   1305    }
   1306 }
   1307 
   1308 static IRExpr *mkNarrowTo8 ( IRType ty, IRExpr * src )
   1309 {
   1310    vassert(ty == Ity_I32 || ty == Ity_I64);
   1311    return ty == Ity_I64 ? unop(Iop_64to8, src) : unop(Iop_32to8, src);
   1312 }
   1313 
   1314 static void putPC(IRExpr * e)
   1315 {
   1316    stmt(IRStmt_Put(OFFB_PC, e));
   1317 }
   1318 
   1319 static IRExpr *mkWidenFrom32(IRType ty, IRExpr * src, Bool sined)
   1320 {
   1321    vassert(ty == Ity_I32 || ty == Ity_I64);
   1322    if (ty == Ity_I32)
   1323       return src;
   1324    return (sined) ? unop(Iop_32Sto64, src) : unop(Iop_32Uto64, src);
   1325 }
   1326 
   1327 /* Narrow 8/16/32 bit int expr to 8/16/32.  Clearly only some
   1328    of these combinations make sense. */
   1329 static IRExpr *narrowTo(IRType dst_ty, IRExpr * e)
   1330 {
   1331    IRType src_ty = typeOfIRExpr(irsb->tyenv, e);
   1332    if (src_ty == dst_ty)
   1333       return e;
   1334    if (src_ty == Ity_I32 && dst_ty == Ity_I16)
   1335       return unop(Iop_32to16, e);
   1336    if (src_ty == Ity_I32 && dst_ty == Ity_I8)
   1337       return unop(Iop_32to8, e);
   1338    if (src_ty == Ity_I64 && dst_ty == Ity_I8) {
   1339       vassert(mode64);
   1340       return unop(Iop_64to8, e);
   1341    }
   1342    if (src_ty == Ity_I64 && dst_ty == Ity_I16) {
   1343       vassert(mode64);
   1344       return unop(Iop_64to16, e);
   1345    }
   1346    vpanic("narrowTo(mips)");
   1347    return 0;
   1348 }
   1349 
   1350 static IRExpr *getLoFromF64(IRType ty, IRExpr * src)
   1351 {
   1352    vassert(ty == Ity_F32 || ty == Ity_F64);
   1353    if (ty == Ity_F64) {
   1354       IRTemp t0, t1;
   1355       t0 = newTemp(Ity_I64);
   1356       t1 = newTemp(Ity_I32);
   1357       assign(t0, unop(Iop_ReinterpF64asI64, src));
   1358       assign(t1, unop(Iop_64to32, mkexpr(t0)));
   1359       return unop(Iop_ReinterpI32asF32, mkexpr(t1));
   1360    } else
   1361       return src;
   1362 }
   1363 
   1364 static IRExpr *mkWidenFromF32(IRType ty, IRExpr * src)
   1365 {
   1366    vassert(ty == Ity_F32 || ty == Ity_F64);
   1367    if (ty == Ity_F64) {
   1368       IRTemp t0 = newTemp(Ity_I32);
   1369       IRTemp t1 = newTemp(Ity_I64);
   1370       assign(t0, unop(Iop_ReinterpF32asI32, src));
   1371       assign(t1, binop(Iop_32HLto64, mkU32(0x0), mkexpr(t0)));
   1372       return unop(Iop_ReinterpI64asF64, mkexpr(t1));
   1373    } else
   1374       return src;
   1375 }
   1376 
   1377 /* Convenience function to move to next instruction on condition. */
   1378 static void mips_next_insn_if(IRExpr *condition) {
   1379    vassert(typeOfIRExpr(irsb->tyenv, condition) == Ity_I1);
   1380 
   1381    stmt(IRStmt_Exit(condition, Ijk_Boring,
   1382         mode64 ? IRConst_U64(guest_PC_curr_instr + 4) :
   1383                  IRConst_U32(guest_PC_curr_instr + 4),
   1384         OFFB_PC));
   1385 }
   1386 
   1387 static IRExpr *dis_branch_likely(IRExpr * guard, UInt imm)
   1388 {
   1389    ULong branch_offset;
   1390    IRTemp t0;
   1391 
   1392    /* PC = PC + (SignExtend(signed_immed_24) << 2)
   1393       An 18-bit signed offset (the 16-bit offset field shifted left 2 bits)
   1394       is added to the address of the instruction following
   1395       the branch (not the branch itself), in the branch delay slot, to form
   1396       a PC-relative effective target address. */
   1397    if (mode64)
   1398       branch_offset = extend_s_18to64(imm << 2);
   1399    else
   1400       branch_offset = extend_s_18to32(imm << 2);
   1401 
   1402    t0 = newTemp(Ity_I1);
   1403    assign(t0, guard);
   1404 
   1405    if (mode64)
   1406       stmt(IRStmt_Exit(mkexpr(t0), Ijk_Boring,
   1407                        IRConst_U64(guest_PC_curr_instr + 8), OFFB_PC));
   1408    else
   1409       stmt(IRStmt_Exit(mkexpr(t0), Ijk_Boring,
   1410                        IRConst_U32(guest_PC_curr_instr + 8), OFFB_PC));
   1411 
   1412    irsb->jumpkind = Ijk_Boring;
   1413 
   1414    if (mode64)
   1415       return mkU64(guest_PC_curr_instr + 4 + branch_offset);
   1416    else
   1417       return mkU32(guest_PC_curr_instr + 4 + branch_offset);
   1418 }
   1419 
   1420 static void dis_branch(Bool link, IRExpr * guard, UInt imm, IRStmt ** set)
   1421 {
   1422    ULong branch_offset;
   1423    IRTemp t0;
   1424 
   1425    if (link) {  /* LR (GPR31) = addr of the 2nd instr after branch instr */
   1426       if (mode64)
   1427          putIReg(31, mkU64(guest_PC_curr_instr + 8));
   1428       else
   1429          putIReg(31, mkU32(guest_PC_curr_instr + 8));
   1430    }
   1431 
   1432    /* PC = PC + (SignExtend(signed_immed_24) << 2)
   1433       An 18-bit signed offset (the 16-bit offset field shifted left 2 bits)
   1434       is added to the address of the instruction following
   1435       the branch (not the branch itself), in the branch delay slot, to form
   1436       a PC-relative effective target address. */
   1437 
   1438    if (mode64)
   1439       branch_offset = extend_s_18to64(imm << 2);
   1440    else
   1441       branch_offset = extend_s_18to32(imm << 2);
   1442 
   1443    t0 = newTemp(Ity_I1);
   1444    assign(t0, guard);
   1445    if (mode64)
   1446       *set = IRStmt_Exit(mkexpr(t0), link ? Ijk_Call : Ijk_Boring,
   1447                          IRConst_U64(guest_PC_curr_instr + 4 + branch_offset),
   1448                          OFFB_PC);
   1449    else
   1450       *set = IRStmt_Exit(mkexpr(t0), link ? Ijk_Call : Ijk_Boring,
   1451                          IRConst_U32(guest_PC_curr_instr + 4 +
   1452                                      (UInt) branch_offset), OFFB_PC);
   1453 }
   1454 
   1455 static IRExpr *getFReg(UInt fregNo)
   1456 {
   1457    vassert(fregNo < 32);
   1458    IRType ty = fp_mode64 ? Ity_F64 : Ity_F32;
   1459    return IRExpr_Get(floatGuestRegOffset(fregNo), ty);
   1460 }
   1461 
   1462 static IRExpr *getDReg(UInt dregNo)
   1463 {
   1464    vassert(dregNo < 32);
   1465    if (fp_mode64) {
   1466       return IRExpr_Get(floatGuestRegOffset(dregNo), Ity_F64);
   1467    } else {
   1468       /* Read a floating point register pair and combine their contents into a
   1469          64-bit value */
   1470       IRTemp t0 = newTemp(Ity_F32);
   1471       IRTemp t1 = newTemp(Ity_F32);
   1472       IRTemp t2 = newTemp(Ity_F64);
   1473       IRTemp t3 = newTemp(Ity_I32);
   1474       IRTemp t4 = newTemp(Ity_I32);
   1475       IRTemp t5 = newTemp(Ity_I64);
   1476 
   1477       assign(t0, getFReg(dregNo & (~1)));
   1478       assign(t1, getFReg(dregNo | 1));
   1479 
   1480       assign(t3, unop(Iop_ReinterpF32asI32, mkexpr(t0)));
   1481       assign(t4, unop(Iop_ReinterpF32asI32, mkexpr(t1)));
   1482       assign(t5, binop(Iop_32HLto64, mkexpr(t4), mkexpr(t3)));
   1483       assign(t2, unop(Iop_ReinterpI64asF64, mkexpr(t5)));
   1484 
   1485       return mkexpr(t2);
   1486    }
   1487 }
   1488 
   1489 static void putFReg(UInt dregNo, IRExpr * e)
   1490 {
   1491    vassert(dregNo < 32);
   1492    IRType ty = fp_mode64 ? Ity_F64 : Ity_F32;
   1493    vassert(typeOfIRExpr(irsb->tyenv, e) == ty);
   1494    stmt(IRStmt_Put(floatGuestRegOffset(dregNo), e));
   1495 }
   1496 
   1497 static void putDReg(UInt dregNo, IRExpr * e)
   1498 {
   1499    if (fp_mode64) {
   1500       vassert(dregNo < 32);
   1501       IRType ty = Ity_F64;
   1502       vassert(typeOfIRExpr(irsb->tyenv, e) == ty);
   1503       stmt(IRStmt_Put(floatGuestRegOffset(dregNo), e));
   1504    } else {
   1505       vassert(dregNo < 32);
   1506       vassert(typeOfIRExpr(irsb->tyenv, e) == Ity_F64);
   1507       IRTemp t1 = newTemp(Ity_F64);
   1508       IRTemp t4 = newTemp(Ity_I32);
   1509       IRTemp t5 = newTemp(Ity_I32);
   1510       IRTemp t6 = newTemp(Ity_I64);
   1511       assign(t1, e);
   1512       assign(t6, unop(Iop_ReinterpF64asI64, mkexpr(t1)));
   1513       assign(t4, unop(Iop_64HIto32, mkexpr(t6)));  /* hi */
   1514       assign(t5, unop(Iop_64to32, mkexpr(t6)));    /* lo */
   1515       putFReg(dregNo & (~1), unop(Iop_ReinterpI32asF32, mkexpr(t5)));
   1516       putFReg(dregNo | 1, unop(Iop_ReinterpI32asF32, mkexpr(t4)));
   1517    }
   1518 }
   1519 
   1520 static void setFPUCondCode(IRExpr * e, UInt cc)
   1521 {
   1522    if (cc == 0) {
   1523       putFCSR(binop(Iop_And32, getFCSR(), mkU32(0xFF7FFFFF)));
   1524       putFCSR(binop(Iop_Or32, getFCSR(), binop(Iop_Shl32, e, mkU8(23))));
   1525    } else {
   1526       putFCSR(binop(Iop_And32, getFCSR(), unop(Iop_Not32,
   1527                                binop(Iop_Shl32, mkU32(0x01000000), mkU8(cc)))));
   1528       putFCSR(binop(Iop_Or32, getFCSR(), binop(Iop_Shl32, e, mkU8(24 + cc))));
   1529    }
   1530 }
   1531 
   1532 static IRExpr* get_IR_roundingmode ( void )
   1533 {
   1534 /*
   1535    rounding mode | MIPS | IR
   1536    ------------------------
   1537    to nearest    | 00  | 00
   1538    to zero       | 01  | 11
   1539    to +infinity  | 10  | 10
   1540    to -infinity  | 11  | 01
   1541 */
   1542    IRTemp rm_MIPS = newTemp(Ity_I32);
   1543    /* Last two bits in FCSR are rounding mode. */
   1544 
   1545    if (mode64)
   1546       assign(rm_MIPS, binop(Iop_And32, IRExpr_Get(offsetof(VexGuestMIPS64State,
   1547                                        guest_FCSR), Ity_I32), mkU32(3)));
   1548    else
   1549       assign(rm_MIPS, binop(Iop_And32, IRExpr_Get(offsetof(VexGuestMIPS32State,
   1550                                        guest_FCSR), Ity_I32), mkU32(3)));
   1551 
   1552    /* rm_IR = XOR( rm_MIPS32, (rm_MIPS32 << 1) & 2) */
   1553 
   1554    return binop(Iop_Xor32, mkexpr(rm_MIPS), binop(Iop_And32,
   1555                 binop(Iop_Shl32, mkexpr(rm_MIPS), mkU8(1)), mkU32(2)));
   1556 }
   1557 
   1558 /* sz, ULong -> IRExpr */
   1559 static IRExpr *mkSzImm ( IRType ty, ULong imm64 )
   1560 {
   1561    vassert(ty == Ity_I32 || ty == Ity_I64);
   1562    return ty == Ity_I64 ? mkU64(imm64) : mkU32((UInt) imm64);
   1563 }
   1564 
   1565 static IRConst *mkSzConst ( IRType ty, ULong imm64 )
   1566 {
   1567    vassert(ty == Ity_I32 || ty == Ity_I64);
   1568    return (ty == Ity_I64 ? IRConst_U64(imm64) : IRConst_U32((UInt) imm64));
   1569 }
   1570 
   1571 /* Make sure we get valid 32 and 64bit addresses */
   1572 static Addr64 mkSzAddr ( IRType ty, Addr64 addr )
   1573 {
   1574    vassert(ty == Ity_I32 || ty == Ity_I64);
   1575    return (ty == Ity_I64 ? (Addr64) addr :
   1576                            (Addr64) extend_s_32to64(toUInt(addr)));
   1577 }
   1578 
   1579 /* Shift and Rotate instructions for MIPS64 */
   1580 static Bool dis_instr_shrt ( UInt theInstr )
   1581 {
   1582    UInt opc2 = get_function(theInstr);
   1583    UChar regRs = get_rs(theInstr);
   1584    UChar regRt = get_rt(theInstr);
   1585    UChar regRd = get_rd(theInstr);
   1586    UChar uImmsa = get_sa(theInstr);
   1587    Long sImmsa = extend_s_16to64(uImmsa);
   1588    IRType ty = mode64 ? Ity_I64 : Ity_I32;
   1589    IRTemp tmp = newTemp(ty);
   1590    IRTemp tmpOr = newTemp(ty);
   1591    IRTemp tmpRt = newTemp(ty);
   1592    IRTemp tmpRs = newTemp(ty);
   1593    IRTemp tmpRd = newTemp(ty);
   1594 
   1595    assign(tmpRs, getIReg(regRs));
   1596    assign(tmpRt, getIReg(regRt));
   1597 
   1598    switch (opc2) {
   1599       case 0x3A:
   1600          if ((regRs & 0x01) == 0) {
   1601             /* Doubleword Shift Right Logical - DSRL; MIPS64 */
   1602             DIP("dsrl r%u, r%u, %lld", regRd, regRt, sImmsa);
   1603             assign(tmpRd, binop(Iop_Shr64, mkexpr(tmpRt), mkU8(uImmsa)));
   1604             putIReg(regRd, mkexpr(tmpRd));
   1605          } else if ((regRs & 0x01) == 1) {
   1606             /* Doubleword Rotate Right - DROTR; MIPS64r2 */
   1607             vassert(mode64);
   1608             DIP("drotr r%u, r%u, %lld", regRd, regRt, sImmsa);
   1609             IRTemp tmpL = newTemp(ty);
   1610             IRTemp tmpR = newTemp(ty);
   1611             assign(tmpR, binop(Iop_Shr64, mkexpr(tmpRt), mkU8(uImmsa)));
   1612             assign(tmp, binop(Iop_Shl64, mkexpr(tmpRt), mkU8(63 - uImmsa)));
   1613             assign(tmpL, binop(Iop_Shl64, mkexpr(tmp), mkU8(1)));
   1614             assign(tmpRd, binop(Iop_Or64, mkexpr(tmpL), mkexpr(tmpR)));
   1615             putIReg(regRd, mkexpr(tmpRd));
   1616          } else
   1617             return False;
   1618          break;
   1619 
   1620       case 0x3E:
   1621          if ((regRs & 0x01) == 0) {
   1622             /* Doubleword Shift Right Logical Plus 32 - DSRL32; MIPS64 */
   1623             DIP("dsrl32 r%u, r%u, %lld", regRd, regRt, sImmsa + 32);
   1624             assign(tmpRd, binop(Iop_Shr64, mkexpr(tmpRt), mkU8(uImmsa + 32)));
   1625             putIReg(regRd, mkexpr(tmpRd));
   1626          } else if ((regRs & 0x01) == 1) {
   1627             /* Doubleword Rotate Right Plus 32 - DROTR32; MIPS64r2 */
   1628             DIP("drotr32 r%u, r%u, %lld", regRd, regRt, sImmsa);
   1629             vassert(mode64);
   1630             IRTemp tmpL = newTemp(ty);
   1631             IRTemp tmpR = newTemp(ty);
   1632             /* (tmpRt >> sa) | (tmpRt << (64 - sa)) */
   1633             assign(tmpR, binop(Iop_Shr64, mkexpr(tmpRt), mkU8(uImmsa + 32)));
   1634             assign(tmp, binop(Iop_Shl64, mkexpr(tmpRt),
   1635                               mkU8(63 - (uImmsa + 32))));
   1636             assign(tmpL, binop(Iop_Shl64, mkexpr(tmp), mkU8(1)));
   1637             assign(tmpRd, binop(Iop_Or64, mkexpr(tmpL), mkexpr(tmpR)));
   1638             putIReg(regRd, mkexpr(tmpRd));
   1639          } else
   1640             return False;
   1641          break;
   1642 
   1643       case 0x16:
   1644          if ((uImmsa & 0x01) == 0) {
   1645             /* Doubleword Shift Right Logical Variable - DSRLV; MIPS64 */
   1646             DIP("dsrlv r%u, r%u, r%u", regRd, regRt, regRs);
   1647             IRTemp tmpRs8 = newTemp(Ity_I8);
   1648             /* s = tmpRs[5..0] */
   1649             assign(tmp, binop(Iop_And64, mkexpr(tmpRs), mkU64(63)));
   1650             assign(tmpRs8, mkNarrowTo8(ty, mkexpr(tmp)));
   1651             assign(tmpRd, binop(Iop_Shr64, mkexpr(tmpRt), mkexpr(tmpRs8)));
   1652             putIReg(regRd, mkexpr(tmpRd));
   1653          } else if ((uImmsa & 0x01) == 1) {
   1654             /* Doubleword Rotate Right Variable - DROTRV; MIPS64r2 */
   1655             DIP("drotrv r%u, r%u, r%u", regRd, regRt, regRs);
   1656             IRTemp tmpL = newTemp(ty);
   1657             IRTemp tmpR = newTemp(ty);
   1658             IRTemp tmpRs8 = newTemp(Ity_I8);
   1659             IRTemp tmpLs8 = newTemp(Ity_I8);
   1660             IRTemp tmp64 = newTemp(ty);
   1661             /* s = tmpRs[5...0]
   1662                m = 64 - s
   1663                (tmpRt << s) | (tmpRt >> m) */
   1664 
   1665             assign(tmp64, binop(Iop_And64, mkexpr(tmpRs), mkSzImm(ty, 63)));
   1666             assign(tmp, binop(Iop_Sub64, mkU64(63), mkexpr(tmp64)));
   1667 
   1668             assign(tmpLs8, mkNarrowTo8(ty, mkexpr(tmp)));
   1669             assign(tmpRs8, mkNarrowTo8(ty, mkexpr(tmp64)));
   1670 
   1671             assign(tmpR, binop(Iop_Shr64, mkexpr(tmpRt), mkexpr(tmpRs8)));
   1672             assign(tmpL, binop(Iop_Shl64, mkexpr(tmpRt), mkexpr(tmpLs8)));
   1673             assign(tmpRd, binop(Iop_Shl64, mkexpr(tmpL), mkU8(1)));
   1674             assign(tmpOr, binop(Iop_Or64, mkexpr(tmpRd), mkexpr(tmpR)));
   1675 
   1676             putIReg(regRd, mkexpr(tmpOr));
   1677          } else
   1678             return False;
   1679          break;
   1680 
   1681       case 0x38:  /* Doubleword Shift Left Logical - DSLL; MIPS64 */
   1682          DIP("dsll r%u, r%u, %lld", regRd, regRt, sImmsa);
   1683          vassert(mode64);
   1684          assign(tmpRd, binop(Iop_Shl64, mkexpr(tmpRt), mkU8(uImmsa)));
   1685          putIReg(regRd, mkexpr(tmpRd));
   1686          break;
   1687 
   1688       case 0x3C:  /* Doubleword Shift Left Logical Plus 32 - DSLL32; MIPS64 */
   1689          DIP("dsll32 r%u, r%u, %lld", regRd, regRt, sImmsa);
   1690          assign(tmpRd, binop(Iop_Shl64, mkexpr(tmpRt), mkU8(uImmsa + 32)));
   1691          putIReg(regRd, mkexpr(tmpRd));
   1692          break;
   1693 
   1694       case 0x14: {  /* Doubleword Shift Left Logical Variable - DSLLV; MIPS64 */
   1695          DIP("dsllv r%u, r%u, r%u", regRd, regRt, regRs);
   1696          IRTemp tmpRs8 = newTemp(Ity_I8);
   1697 
   1698          assign(tmp, binop(Iop_And64, mkexpr(tmpRs), mkSzImm(ty, 63)));
   1699          assign(tmpRs8, mkNarrowTo8(ty, mkexpr(tmp)));
   1700          assign(tmpRd, binop(Iop_Shl64, mkexpr(tmpRt), mkexpr(tmpRs8)));
   1701          putIReg(regRd, mkexpr(tmpRd));
   1702          break;
   1703       }
   1704 
   1705       case 0x3B:  /* Doubleword Shift Right Arithmetic - DSRA; MIPS64 */
   1706          DIP("dsra r%u, r%u, %lld", regRd, regRt, sImmsa);
   1707          assign(tmpRd, binop(Iop_Sar64, mkexpr(tmpRt), mkU8(uImmsa)));
   1708          putIReg(regRd, mkexpr(tmpRd));
   1709          break;
   1710 
   1711       case 0x3F:  /* Doubleword Shift Right Arithmetic Plus 32 - DSRA32;
   1712                      MIPS64 */
   1713          DIP("dsra32 r%u, r%u, %lld", regRd, regRt, sImmsa);
   1714          assign(tmpRd, binop(Iop_Sar64, mkexpr(tmpRt), mkU8(uImmsa + 32)));
   1715          putIReg(regRd, mkexpr(tmpRd));
   1716          break;
   1717 
   1718       case 0x17: {  /* Doubleword Shift Right Arithmetic Variable - DSRAV;
   1719                        MIPS64 */
   1720          DIP("dsrav r%u, r%u, r%u", regRd, regRt, regRs);
   1721          IRTemp tmpRs8 = newTemp(Ity_I8);
   1722          assign(tmp, binop(Iop_And64, mkexpr(tmpRs), mkSzImm(ty, 63)));
   1723          assign(tmpRs8, mkNarrowTo8(ty, mkexpr(tmp)));
   1724          assign(tmpRd, binop(Iop_Sar64, mkexpr(tmpRt), mkexpr(tmpRs8)));
   1725          putIReg(regRd, mkexpr(tmpRd));
   1726          break;
   1727 
   1728       }
   1729 
   1730       default:
   1731          return False;
   1732 
   1733    }
   1734    return True;
   1735 }
   1736 
   1737 static IROp mkSzOp ( IRType ty, IROp op8 )
   1738 {
   1739    Int adj;
   1740    vassert(ty == Ity_I8 || ty == Ity_I16 || ty == Ity_I32 || ty == Ity_I64);
   1741    vassert(op8 == Iop_Add8 || op8 == Iop_Sub8 || op8 == Iop_Mul8
   1742            || op8 == Iop_Or8 || op8 == Iop_And8 || op8 == Iop_Xor8
   1743            || op8 == Iop_Shl8 || op8 == Iop_Shr8 || op8 == Iop_Sar8
   1744            || op8 == Iop_CmpEQ8 || op8 == Iop_CmpNE8 || op8 == Iop_Not8);
   1745    adj = ty == Ity_I8 ? 0 : (ty == Ity_I16 ? 1 : (ty == Ity_I32 ? 2 : 3));
   1746    return adj + op8;
   1747 }
   1748 
   1749 /*********************************************************/
   1750 /*---             Floating Point Compare              ---*/
   1751 /*********************************************************/
   1752 /* Function that returns a string that represent mips cond
   1753    mnemonic for the input code. */
   1754 static const HChar* showCondCode(UInt code) {
   1755    const HChar* ret;
   1756    switch (code) {
   1757       case 0: ret = "f"; break;
   1758       case 1: ret = "un"; break;
   1759       case 2: ret = "eq"; break;
   1760       case 3: ret = "ueq"; break;
   1761       case 4: ret = "olt"; break;
   1762       case 5: ret = "ult"; break;
   1763       case 6: ret = "ole"; break;
   1764       case 7: ret = "ule"; break;
   1765       case 8: ret = "sf"; break;
   1766       case 9: ret = "ngle"; break;
   1767       case 10: ret = "seq"; break;
   1768       case 11: ret = "ngl"; break;
   1769       case 12: ret = "lt"; break;
   1770       case 13: ret = "nge"; break;
   1771       case 14: ret = "le"; break;
   1772       case 15: ret = "ngt"; break;
   1773       default: vpanic("showCondCode"); break;
   1774    }
   1775    return ret;
   1776 }
   1777 
   1778 static Bool dis_instr_CCondFmt ( UInt cins )
   1779 {
   1780    IRTemp t0, t1, t2, t3, tmp5, tmp6;
   1781    IRTemp ccIR = newTemp(Ity_I32);
   1782    IRTemp ccMIPS = newTemp(Ity_I32);
   1783    UInt FC = get_FC(cins);
   1784    UInt fmt = get_fmt(cins);
   1785    UInt fs = get_fs(cins);
   1786    UInt ft = get_ft(cins);
   1787    UInt cond = get_cond(cins);
   1788 
   1789    if (FC == 0x3) {  /* C.cond.fmt */
   1790       UInt fpc_cc = get_fpc_cc(cins);
   1791       switch (fmt) {
   1792          case 0x10: {  /* C.cond.S */
   1793             DIP("c.%s.s %u, f%u, f%u", showCondCode(cond), fpc_cc, fs, ft);
   1794             if (fp_mode64) {
   1795                t0 = newTemp(Ity_I32);
   1796                t1 = newTemp(Ity_I32);
   1797                t2 = newTemp(Ity_I32);
   1798                t3 = newTemp(Ity_I32);
   1799 
   1800                tmp5 = newTemp(Ity_F64);
   1801                tmp6 = newTemp(Ity_F64);
   1802 
   1803                assign(tmp5, unop(Iop_F32toF64, getLoFromF64(Ity_F64,
   1804                                  getFReg(fs))));
   1805                assign(tmp6, unop(Iop_F32toF64, getLoFromF64(Ity_F64,
   1806                                  getFReg(ft))));
   1807 
   1808                assign(ccIR, binop(Iop_CmpF64, mkexpr(tmp5), mkexpr(tmp6)));
   1809                putHI(mkWidenFrom32(mode64 ? Ity_I64: Ity_I32,
   1810                                    mkexpr(ccIR), True));
   1811                /* Map compare result from IR to MIPS
   1812                   FP cmp result | MIPS | IR
   1813                   --------------------------
   1814                   UN            | 0x1 | 0x45
   1815                   EQ            | 0x2 | 0x40
   1816                   GT            | 0x4 | 0x00
   1817                   LT            | 0x8 | 0x01
   1818                 */
   1819 
   1820                /* ccMIPS = Shl(1, (~(ccIR>>5) & 2) | ((ccIR ^ (ccIR>>6)) & 1) */
   1821                assign(ccMIPS, binop(Iop_Shl32, mkU32(1), unop(Iop_32to8,
   1822                               binop(Iop_Or32, binop(Iop_And32, unop(Iop_Not32,
   1823                               binop(Iop_Shr32, mkexpr(ccIR),mkU8(5))),mkU32(2)),
   1824                               binop(Iop_And32, binop(Iop_Xor32, mkexpr(ccIR),
   1825                               binop(Iop_Shr32, mkexpr(ccIR), mkU8(6))),
   1826                               mkU32(1))))));
   1827                putLO(mkWidenFrom32(mode64 ? Ity_I64: Ity_I32,
   1828                                    mkexpr(ccMIPS), True));
   1829 
   1830                /* UN */
   1831                assign(t0, binop(Iop_And32, mkexpr(ccMIPS), mkU32(0x1)));
   1832                /* EQ */
   1833                assign(t1, binop(Iop_And32, binop(Iop_Shr32, mkexpr(ccMIPS),
   1834                                                  mkU8(0x1)), mkU32(0x1)));
   1835                /* NGT */
   1836                assign(t2, binop(Iop_And32, unop(Iop_Not32, binop(Iop_Shr32,
   1837                                  mkexpr(ccMIPS), mkU8(0x2))),mkU32(0x1)));
   1838                /* LT */
   1839                assign(t3, binop(Iop_And32, binop(Iop_Shr32, mkexpr(ccMIPS),
   1840                                                  mkU8(0x3)), mkU32(0x1)));
   1841                switch (cond) {
   1842                   case 0x0:
   1843                      setFPUCondCode(mkU32(0), fpc_cc);
   1844                      break;
   1845                   case 0x1:
   1846                      setFPUCondCode(mkexpr(t0), fpc_cc);
   1847                      break;
   1848                   case 0x2:
   1849                      setFPUCondCode(mkexpr(t1), fpc_cc);
   1850                      break;
   1851                   case 0x3:
   1852                      setFPUCondCode(binop(Iop_Or32, mkexpr(t0), mkexpr(t1)),
   1853                                           fpc_cc);
   1854                      break;
   1855                   case 0x4:
   1856                      setFPUCondCode(mkexpr(t3), fpc_cc);
   1857                      break;
   1858                   case 0x5:
   1859                      setFPUCondCode(binop(Iop_Or32, mkexpr(t0), mkexpr(t3)),
   1860                                           fpc_cc);
   1861                      break;
   1862                   case 0x6:
   1863                      setFPUCondCode(binop(Iop_Or32, mkexpr(t3), mkexpr(t1)),
   1864                                           fpc_cc);
   1865                      break;
   1866                   case 0x7:
   1867                      setFPUCondCode(mkexpr(t2), fpc_cc);
   1868                      break;
   1869                   case 0x8:
   1870                      setFPUCondCode(mkU32(0), fpc_cc);
   1871                      break;
   1872                   case 0x9:
   1873                      setFPUCondCode(mkexpr(t0), fpc_cc);
   1874                      break;
   1875                   case 0xA:
   1876                      setFPUCondCode(mkexpr(t1), fpc_cc);
   1877                      break;
   1878                   case 0xB:
   1879                      setFPUCondCode(binop(Iop_Or32, mkexpr(t0), mkexpr(t1)),
   1880                                           fpc_cc);
   1881                      break;
   1882                   case 0xC:
   1883                      setFPUCondCode(mkexpr(t3), fpc_cc);
   1884                      break;
   1885                   case 0xD:
   1886                      setFPUCondCode(binop(Iop_Or32, mkexpr(t0), mkexpr(t3)),
   1887                                           fpc_cc);
   1888                      break;
   1889                   case 0xE:
   1890                      setFPUCondCode(binop(Iop_Or32, mkexpr(t3), mkexpr(t1)),
   1891                                           fpc_cc);
   1892                      break;
   1893                   case 0xF:
   1894                      setFPUCondCode(mkexpr(t2), fpc_cc);
   1895                      break;
   1896 
   1897                   default:
   1898                      return False;
   1899                }
   1900 
   1901             } else {
   1902                t0 = newTemp(Ity_I32);
   1903                t1 = newTemp(Ity_I32);
   1904                t2 = newTemp(Ity_I32);
   1905                t3 = newTemp(Ity_I32);
   1906 
   1907                assign(ccIR, binop(Iop_CmpF64, unop(Iop_F32toF64, getFReg(fs)),
   1908                                   unop(Iop_F32toF64, getFReg(ft))));
   1909                /* Map compare result from IR to MIPS
   1910                   FP cmp result | MIPS | IR
   1911                   --------------------------
   1912                   UN            | 0x1 | 0x45
   1913                   EQ            | 0x2 | 0x40
   1914                   GT            | 0x4 | 0x00
   1915                   LT            | 0x8 | 0x01
   1916                 */
   1917 
   1918                /* ccMIPS = Shl(1, (~(ccIR>>5) & 2) | ((ccIR ^ (ccIR>>6)) & 1) */
   1919                assign(ccMIPS, binop(Iop_Shl32, mkU32(1), unop(Iop_32to8,
   1920                               binop(Iop_Or32, binop(Iop_And32, unop(Iop_Not32,
   1921                               binop(Iop_Shr32, mkexpr(ccIR), mkU8(5))),
   1922                                     mkU32(2)), binop(Iop_And32,
   1923                               binop(Iop_Xor32, mkexpr(ccIR),
   1924                               binop(Iop_Shr32, mkexpr(ccIR), mkU8(6))),
   1925                               mkU32(1))))));
   1926                /* UN */
   1927                assign(t0, binop(Iop_And32, mkexpr(ccMIPS), mkU32(0x1)));
   1928                /* EQ */
   1929                assign(t1, binop(Iop_And32, binop(Iop_Shr32, mkexpr(ccMIPS),
   1930                       mkU8(0x1)), mkU32(0x1)));
   1931                /* NGT */
   1932                assign(t2, binop(Iop_And32, unop(Iop_Not32, binop(Iop_Shr32,
   1933                       mkexpr(ccMIPS), mkU8(0x2))), mkU32(0x1)));
   1934                /* LT */
   1935                assign(t3, binop(Iop_And32, binop(Iop_Shr32, mkexpr(ccMIPS),
   1936                       mkU8(0x3)), mkU32(0x1)));
   1937 
   1938                switch (cond) {
   1939                   case 0x0:
   1940                      setFPUCondCode(mkU32(0), fpc_cc);
   1941                      break;
   1942                   case 0x1:
   1943                      setFPUCondCode(mkexpr(t0), fpc_cc);
   1944                      break;
   1945                   case 0x2:
   1946                      setFPUCondCode(mkexpr(t1), fpc_cc);
   1947                      break;
   1948                   case 0x3:
   1949                      setFPUCondCode(binop(Iop_Or32, mkexpr(t0), mkexpr(t1)),
   1950                                           fpc_cc);
   1951                      break;
   1952                   case 0x4:
   1953                      setFPUCondCode(mkexpr(t3), fpc_cc);
   1954                      break;
   1955                   case 0x5:
   1956                      setFPUCondCode(binop(Iop_Or32, mkexpr(t0), mkexpr(t3)),
   1957                                           fpc_cc);
   1958                      break;
   1959                   case 0x6:
   1960                      setFPUCondCode(binop(Iop_Or32, mkexpr(t3), mkexpr(t1)),
   1961                                           fpc_cc);
   1962                      break;
   1963                   case 0x7:
   1964                      setFPUCondCode(mkexpr(t2), fpc_cc);
   1965                      break;
   1966                   case 0x8:
   1967                      setFPUCondCode(mkU32(0), fpc_cc);
   1968                      break;
   1969                   case 0x9:
   1970                      setFPUCondCode(mkexpr(t0), fpc_cc);
   1971                      break;
   1972                   case 0xA:
   1973                      setFPUCondCode(mkexpr(t1), fpc_cc);
   1974                      break;
   1975                   case 0xB:
   1976                      setFPUCondCode(binop(Iop_Or32, mkexpr(t0), mkexpr(t1)),
   1977                                           fpc_cc);
   1978                      break;
   1979                   case 0xC:
   1980                      setFPUCondCode(mkexpr(t3), fpc_cc);
   1981                      break;
   1982                   case 0xD:
   1983                      setFPUCondCode(binop(Iop_Or32, mkexpr(t0), mkexpr(t3)),
   1984                                           fpc_cc);
   1985                      break;
   1986                   case 0xE:
   1987                      setFPUCondCode(binop(Iop_Or32, mkexpr(t3), mkexpr(t1)),
   1988                                           fpc_cc);
   1989                      break;
   1990                   case 0xF:
   1991                      setFPUCondCode(mkexpr(t2), fpc_cc);
   1992                      break;
   1993 
   1994                   default:
   1995                      return False;
   1996                }
   1997             }
   1998          }
   1999             break;
   2000 
   2001          case 0x11: {  /* C.cond.D */
   2002             DIP("c.%s.d %u, f%u, f%u", showCondCode(cond), fpc_cc, fs, ft);
   2003             t0 = newTemp(Ity_I32);
   2004             t1 = newTemp(Ity_I32);
   2005             t2 = newTemp(Ity_I32);
   2006             t3 = newTemp(Ity_I32);
   2007             assign(ccIR, binop(Iop_CmpF64, getDReg(fs), getDReg(ft)));
   2008             /* Map compare result from IR to MIPS
   2009                FP cmp result | MIPS | IR
   2010                --------------------------
   2011                UN            | 0x1 | 0x45
   2012                EQ            | 0x2 | 0x40
   2013                GT            | 0x4 | 0x00
   2014                LT            | 0x8 | 0x01
   2015              */
   2016 
   2017             /* ccMIPS = Shl(1, (~(ccIR>>5) & 2) | ((ccIR ^ (ccIR>>6)) & 1) */
   2018             assign(ccMIPS, binop(Iop_Shl32, mkU32(1), unop(Iop_32to8,
   2019                            binop(Iop_Or32, binop(Iop_And32, unop(Iop_Not32,
   2020                            binop(Iop_Shr32, mkexpr(ccIR), mkU8(5))), mkU32(2)),
   2021                            binop(Iop_And32, binop(Iop_Xor32, mkexpr(ccIR),
   2022                            binop(Iop_Shr32, mkexpr(ccIR), mkU8(6))),
   2023                            mkU32(1))))));
   2024 
   2025             /* UN */
   2026             assign(t0, binop(Iop_And32, mkexpr(ccMIPS), mkU32(0x1)));
   2027             /* EQ */
   2028             assign(t1, binop(Iop_And32, binop(Iop_Shr32, mkexpr(ccMIPS),
   2029                    mkU8(0x1)), mkU32(0x1)));
   2030             /* NGT */
   2031             assign(t2, binop(Iop_And32, unop(Iop_Not32, binop(Iop_Shr32,
   2032                    mkexpr(ccMIPS), mkU8(0x2))), mkU32(0x1)));
   2033             /* LT */
   2034             assign(t3, binop(Iop_And32, binop(Iop_Shr32, mkexpr(ccMIPS),
   2035                    mkU8(0x3)), mkU32(0x1)));
   2036 
   2037             switch (cond) {
   2038                case 0x0:
   2039                   setFPUCondCode(mkU32(0), fpc_cc);
   2040                   break;
   2041                case 0x1:
   2042                   setFPUCondCode(mkexpr(t0), fpc_cc);
   2043                   break;
   2044                case 0x2:
   2045                   setFPUCondCode(mkexpr(t1), fpc_cc);
   2046                   break;
   2047                case 0x3:
   2048                   setFPUCondCode(binop(Iop_Or32, mkexpr(t0), mkexpr(t1)),
   2049                                        fpc_cc);
   2050                   break;
   2051                case 0x4:
   2052                   setFPUCondCode(mkexpr(t3), fpc_cc);
   2053                   break;
   2054                case 0x5:
   2055                   setFPUCondCode(binop(Iop_Or32, mkexpr(t0), mkexpr(t3)),
   2056                                        fpc_cc);
   2057                   break;
   2058                case 0x6:
   2059                   setFPUCondCode(binop(Iop_Or32, mkexpr(t3), mkexpr(t1)),
   2060                                        fpc_cc);
   2061                   break;
   2062                case 0x7:
   2063                   setFPUCondCode(mkexpr(t2), fpc_cc);
   2064                   break;
   2065                case 0x8:
   2066                   setFPUCondCode(mkU32(0), fpc_cc);
   2067                   break;
   2068                case 0x9:
   2069                   setFPUCondCode(mkexpr(t0), fpc_cc);
   2070                   break;
   2071                case 0xA:
   2072                   setFPUCondCode(mkexpr(t1), fpc_cc);
   2073                   break;
   2074                case 0xB:
   2075                   setFPUCondCode(binop(Iop_Or32, mkexpr(t0), mkexpr(t1)),
   2076                                        fpc_cc);
   2077                   break;
   2078                case 0xC:
   2079                   setFPUCondCode(mkexpr(t3), fpc_cc);
   2080                   break;
   2081                case 0xD:
   2082                   setFPUCondCode(binop(Iop_Or32, mkexpr(t0), mkexpr(t3)),
   2083                                        fpc_cc);
   2084                   break;
   2085                case 0xE:
   2086                   setFPUCondCode(binop(Iop_Or32, mkexpr(t3), mkexpr(t1)),
   2087                                        fpc_cc);
   2088                   break;
   2089                case 0xF:
   2090                   setFPUCondCode(mkexpr(t2), fpc_cc);
   2091                   break;
   2092                default:
   2093                   return False;
   2094             }
   2095          }
   2096          break;
   2097 
   2098          default:
   2099             return False;
   2100       }
   2101    } else {
   2102       return False;
   2103    }
   2104 
   2105    return True;
   2106 }
   2107 
   2108 /*********************************************************/
   2109 /*---        Branch Instructions for mips64           ---*/
   2110 /*********************************************************/
   2111 static Bool dis_instr_branch ( UInt theInstr, DisResult * dres,
   2112                                Bool(*resteerOkFn) (void *, Addr),
   2113                                void *callback_opaque, IRStmt ** set )
   2114 {
   2115    UInt jmpKind = 0;
   2116    UChar opc1 = get_opcode(theInstr);
   2117    UChar regRs = get_rs(theInstr);
   2118    UChar regRt = get_rt(theInstr);
   2119    UInt offset = get_imm(theInstr);
   2120    Long sOffset = extend_s_16to64(offset);
   2121    IRType ty = mode64 ? Ity_I64 : Ity_I32;
   2122    IROp opSlt = mode64 ? Iop_CmpLT64S : Iop_CmpLT32S;
   2123 
   2124    IRTemp tmp = newTemp(ty);
   2125    IRTemp tmpRs = newTemp(ty);
   2126    IRTemp tmpRt = newTemp(ty);
   2127    IRTemp tmpLt = newTemp(ty);
   2128    IRTemp tmpReg0 = newTemp(ty);
   2129 
   2130    UChar regLnk = 31;   /* reg 31 is link reg in MIPS */
   2131    Addr64 addrTgt = 0;
   2132    Addr64 cia = guest_PC_curr_instr;
   2133 
   2134    IRExpr *eConst0 = mkSzImm(ty, (UInt) 0);
   2135    IRExpr *eNia = mkSzImm(ty, cia + 8);
   2136    IRExpr *eCond = NULL;
   2137 
   2138    assign(tmpRs, getIReg(regRs));
   2139    assign(tmpRt, getIReg(regRt));
   2140    assign(tmpReg0, getIReg(0));
   2141 
   2142    eCond = binop(mkSzOp(ty, Iop_CmpNE8), mkexpr(tmpReg0), mkexpr(tmpReg0));
   2143 
   2144    switch (opc1) {
   2145       case 0x01:
   2146          switch (regRt) {
   2147             case 0x00: {  /* BLTZ rs, offset */
   2148                addrTgt = mkSzAddr(ty, cia + 4 + (sOffset << 2));
   2149                IRTemp tmpLtRes = newTemp(Ity_I1);
   2150 
   2151                assign(tmp, eConst0);
   2152                assign(tmpLtRes, binop(opSlt, mkexpr(tmpRs), mkexpr(tmp)));
   2153                assign(tmpLt, mode64 ? unop(Iop_1Uto64, mkexpr(tmpLtRes)) :
   2154                       unop(Iop_1Uto32, mkexpr(tmpLtRes)));
   2155 
   2156                eCond = binop(mkSzOp(ty, Iop_CmpNE8), mkexpr(tmpLt),
   2157                              mkexpr(tmpReg0));
   2158 
   2159                jmpKind = Ijk_Boring;
   2160                break;
   2161             }
   2162 
   2163             case 0x01: {  /* BGEZ rs, offset */
   2164                IRTemp tmpLtRes = newTemp(Ity_I1);
   2165                addrTgt = mkSzAddr(ty, cia + 4 + (sOffset << 2));
   2166 
   2167                assign(tmp, eConst0);
   2168                assign(tmpLtRes, binop(opSlt, mkexpr(tmpRs), mkexpr(tmp)));
   2169                assign(tmpLt, mode64 ? unop(Iop_1Uto64, mkexpr(tmpLtRes)) :
   2170                                       unop(Iop_1Uto32, mkexpr(tmpLtRes)));
   2171                eCond = binop(mkSzOp(ty, Iop_CmpEQ8), mkexpr(tmpLt),
   2172                                     mkexpr(tmpReg0));
   2173 
   2174                jmpKind = Ijk_Boring;
   2175                break;
   2176             }
   2177 
   2178             case 0x11: {  /* BGEZAL rs, offset */
   2179                addrTgt = mkSzAddr(ty, cia + 4 + (sOffset << 2));
   2180                putIReg(regLnk, eNia);
   2181                IRTemp tmpLtRes = newTemp(Ity_I1);
   2182 
   2183                assign(tmpLtRes, binop(opSlt, mkexpr(tmpRs), eConst0));
   2184                assign(tmpLt, mode64 ? unop(Iop_1Uto64, mkexpr(tmpLtRes)) :
   2185                                       unop(Iop_1Uto32, mkexpr(tmpLtRes)));
   2186 
   2187                eCond = binop(mkSzOp(ty, Iop_CmpEQ8), mkexpr(tmpLt),
   2188                                     mkexpr(tmpReg0));
   2189 
   2190                jmpKind = Ijk_Call;
   2191                break;
   2192             }
   2193 
   2194             case 0x10: {  /* BLTZAL rs, offset */
   2195                IRTemp tmpLtRes = newTemp(Ity_I1);
   2196                IRTemp tmpRes = newTemp(ty);
   2197 
   2198                addrTgt = mkSzAddr(ty, cia + 4 + (sOffset << 2));
   2199                putIReg(regLnk, eNia);
   2200 
   2201                assign(tmp, eConst0);
   2202                assign(tmpLtRes, binop(opSlt, mkexpr(tmpRs), mkexpr(tmp)));
   2203                assign(tmpRes, mode64 ? unop(Iop_1Uto64,
   2204                       mkexpr(tmpLtRes)) : unop(Iop_1Uto32, mkexpr(tmpLtRes)));
   2205                eCond = binop(mkSzOp(ty, Iop_CmpNE8), mkexpr(tmpRes),
   2206                                                      mkexpr(tmpReg0));
   2207 
   2208                jmpKind = Ijk_Call;
   2209                break;
   2210             }
   2211 
   2212          }
   2213          break;
   2214       default:
   2215          return False;
   2216       }
   2217    *set = IRStmt_Exit(eCond, jmpKind, mkSzConst(ty, addrTgt), OFFB_PC);
   2218    return True;
   2219 }
   2220 
   2221 /*********************************************************/
   2222 /*---         Cavium Specific Instructions            ---*/
   2223 /*********************************************************/
   2224 
   2225 /* Convenience function to yield to thread scheduler */
   2226 static void jump_back(IRExpr *condition)
   2227 {
   2228    stmt( IRStmt_Exit(condition,
   2229                      Ijk_Yield,
   2230                      IRConst_U64( guest_PC_curr_instr ),
   2231                      OFFB_PC) );
   2232 }
   2233 
   2234 /* Based on s390_irgen_load_and_add32. */
   2235 static void mips_load_store32(IRTemp op1addr, IRTemp new_val,
   2236                               IRTemp expd, UChar rd, Bool putIntoRd)
   2237 {
   2238    IRCAS *cas;
   2239    IRTemp old_mem = newTemp(Ity_I32);
   2240    IRType ty      = mode64 ? Ity_I64 : Ity_I32;
   2241 
   2242    cas = mkIRCAS(IRTemp_INVALID, old_mem,
   2243 #if defined (_MIPSEL)
   2244                  Iend_LE, mkexpr(op1addr),
   2245 #else /* _MIPSEB */
   2246                  Iend_BE, mkexpr(op1addr),
   2247 #endif
   2248                  NULL, mkexpr(expd), /* expected value */
   2249                  NULL, mkexpr(new_val)  /* new value */);
   2250    stmt(IRStmt_CAS(cas));
   2251 
   2252    /* If old_mem contains the expected value, then the CAS succeeded.
   2253       Otherwise, it did not */
   2254    jump_back(binop(Iop_CmpNE32, mkexpr(old_mem), mkexpr(expd)));
   2255    if (putIntoRd)
   2256       putIReg(rd, mkWidenFrom32(ty, mkexpr(old_mem), True));
   2257 }
   2258 
   2259 /* Based on s390_irgen_load_and_add64. */
   2260 static void mips_load_store64(IRTemp op1addr, IRTemp new_val,
   2261                               IRTemp expd, UChar rd, Bool putIntoRd)
   2262 {
   2263    IRCAS *cas;
   2264    IRTemp old_mem = newTemp(Ity_I64);
   2265    vassert(mode64);
   2266    cas = mkIRCAS(IRTemp_INVALID, old_mem,
   2267 #if defined (_MIPSEL)
   2268                  Iend_LE, mkexpr(op1addr),
   2269 #else /* _MIPSEB */
   2270                  Iend_BE, mkexpr(op1addr),
   2271 #endif
   2272                  NULL, mkexpr(expd), /* expected value */
   2273                  NULL, mkexpr(new_val)  /* new value */);
   2274    stmt(IRStmt_CAS(cas));
   2275 
   2276    /* If old_mem contains the expected value, then the CAS succeeded.
   2277       Otherwise, it did not */
   2278    jump_back(binop(Iop_CmpNE64, mkexpr(old_mem), mkexpr(expd)));
   2279    if (putIntoRd)
   2280       putIReg(rd, mkexpr(old_mem));
   2281 }
   2282 
   2283 static Bool dis_instr_CVM ( UInt theInstr )
   2284 {
   2285    UChar  opc2     = get_function(theInstr);
   2286    UChar  opc1     = get_opcode(theInstr);
   2287    UChar  regRs    = get_rs(theInstr);
   2288    UChar  regRt    = get_rt(theInstr);
   2289    UChar  regRd    = get_rd(theInstr);
   2290    /* MIPS trap instructions extract code from theInstr[15:6].
   2291       Cavium OCTEON instructions SNEI, SEQI extract immediate operands
   2292       from the same bit field [15:6]. */
   2293    UInt   imm      = get_code(theInstr);
   2294    UChar  lenM1    = get_msb(theInstr);
   2295    UChar  p        = get_lsb(theInstr);
   2296    IRType ty       = mode64? Ity_I64 : Ity_I32;
   2297    IRTemp tmp      = newTemp(ty);
   2298    IRTemp tmpRs    = newTemp(ty);
   2299    IRTemp tmpRt    = newTemp(ty);
   2300    IRTemp t1       = newTemp(ty);
   2301    UInt size;
   2302    assign(tmpRs, getIReg(regRs));
   2303 
   2304    switch(opc1) {
   2305       case 0x1C: {
   2306          switch(opc2) {
   2307             case 0x03: {  /* DMUL rd, rs, rt */
   2308                DIP("dmul r%u, r%u, r%u", regRd, regRs, regRt);
   2309                IRTemp t0 = newTemp(Ity_I128);
   2310                assign(t0, binop(Iop_MullU64, getIReg(regRs), getIReg(regRt)));
   2311                putIReg(regRd, unop(Iop_128to64, mkexpr(t0)));
   2312                break;
   2313             }
   2314 
   2315             case 0x18: {  /* Store Atomic Add Word - SAA; Cavium OCTEON */
   2316                DIP("saa r%u, (r%u)", regRt, regRs);
   2317                IRTemp addr = newTemp(Ity_I64);
   2318                IRTemp new_val = newTemp(Ity_I32);
   2319                IRTemp old = newTemp(Ity_I32);
   2320                assign(addr, getIReg(regRs));
   2321                assign(old, load(Ity_I32, mkexpr(addr)));
   2322                assign(new_val, binop(Iop_Add32,
   2323                                      mkexpr(old),
   2324                                      mkNarrowTo32(ty, getIReg(regRt))));
   2325                mips_load_store32(addr, new_val, old, 0, False);
   2326                break;
   2327             }
   2328 
   2329             /* Store Atomic Add Doubleword - SAAD; Cavium OCTEON */
   2330             case 0x19: {
   2331                DIP( "saad r%u, (r%u)", regRt, regRs);
   2332                IRTemp addr = newTemp(Ity_I64);
   2333                IRTemp new_val = newTemp(Ity_I64);
   2334                IRTemp old = newTemp(Ity_I64);
   2335                assign(addr, getIReg(regRs));
   2336                assign(old, load(Ity_I64, mkexpr(addr)));
   2337                assign(new_val, binop(Iop_Add64,
   2338                                      mkexpr(old),
   2339                                      getIReg(regRt)));
   2340                mips_load_store64(addr, new_val, old, 0, False);
   2341                break;
   2342             }
   2343 
   2344             /* LAI, LAID, LAD, LADD, LAS, LASD,
   2345                LAC, LACD, LAA, LAAD, LAW, LAWD */
   2346             case 0x1f: {
   2347                UInt opc3 = get_sa(theInstr);
   2348                IRTemp addr = newTemp(Ity_I64);
   2349                switch (opc3) {
   2350                   /* Load Atomic Increment Word - LAI; Cavium OCTEON2 */
   2351                   case 0x02: {
   2352                      DIP("lai r%u,(r%u)\n", regRd, regRs);
   2353                      IRTemp new_val = newTemp(Ity_I32);
   2354                      IRTemp old = newTemp(Ity_I32);
   2355                      assign(addr, getIReg(regRs));
   2356                      assign(old, load(Ity_I32, mkexpr(addr)));
   2357                      assign(new_val, binop(Iop_Add32,
   2358                                            mkexpr(old),
   2359                                            mkU32(1)));
   2360                      mips_load_store32(addr, new_val, old, regRd, True);
   2361                      break;
   2362                   }
   2363                   /* Load Atomic Increment Doubleword - LAID; Cavium OCTEON2 */
   2364                   case 0x03: {
   2365                      DIP("laid r%u,(r%u)\n", regRd, regRs);
   2366                      IRTemp new_val = newTemp(Ity_I64);
   2367                      IRTemp old = newTemp(Ity_I64);
   2368                      assign(addr, getIReg(regRs));
   2369                      assign(old, load(Ity_I64, mkexpr(addr)));
   2370                      assign(new_val, binop(Iop_Add64,
   2371                                            mkexpr(old),
   2372                                            mkU64(1)));
   2373                      mips_load_store64(addr, new_val, old, regRd, True);
   2374                      break;
   2375                   }
   2376                   /* Load Atomic Decrement Word - LAD; Cavium OCTEON2 */
   2377                   case 0x06: {
   2378                      DIP("lad r%u,(r%u)\n", regRd, regRs);
   2379                      IRTemp new_val = newTemp(Ity_I32);
   2380                      IRTemp old = newTemp(Ity_I32);
   2381                      assign(addr, getIReg(regRs));
   2382                      assign(old, load(Ity_I32, mkexpr(addr)));
   2383                      assign(new_val, binop(Iop_Sub32,
   2384                                            mkexpr(old),
   2385                                            mkU32(1)));
   2386                      mips_load_store32(addr, new_val, old, regRd, True);
   2387                      break;
   2388                   }
   2389                   /* Load Atomic Decrement Doubleword - LADD; Cavium OCTEON2 */
   2390                   case 0x07: {
   2391                      DIP("ladd r%u,(r%u)\n", regRd, regRs);
   2392                      IRTemp new_val = newTemp(Ity_I64);
   2393                      IRTemp old = newTemp(Ity_I64);
   2394                      assign(addr, getIReg(regRs));
   2395                      assign(old, load(Ity_I64, mkexpr(addr)));
   2396                      assign(new_val, binop(Iop_Sub64,
   2397                                            mkexpr(old),
   2398                                            mkU64(1)));
   2399                      mips_load_store64(addr, new_val, old, regRd, True);
   2400                      break;
   2401                   }
   2402                   /* Load Atomic Set Word - LAS; Cavium OCTEON2 */
   2403                   case 0x0a: {
   2404                      DIP("las r%u,(r%u)\n", regRd, regRs);
   2405                      IRTemp new_val = newTemp(Ity_I32);
   2406                      IRTemp old = newTemp(Ity_I32);
   2407                      assign(addr, getIReg(regRs));
   2408                      assign(new_val, mkU32(0xffffffff));
   2409                      assign(old, load(Ity_I32, mkexpr(addr)));
   2410                      mips_load_store32(addr, new_val, old, regRd, True);
   2411                      break;
   2412                   }
   2413                   /* Load Atomic Set Doubleword - LASD; Cavium OCTEON2 */
   2414                   case 0x0b: {
   2415                      DIP("lasd r%u,(r%u)\n", regRd, regRs);
   2416                      IRTemp new_val = newTemp(Ity_I64);
   2417                      IRTemp old = newTemp(Ity_I64);
   2418                      assign(addr, getIReg(regRs));
   2419                      assign(new_val, mkU64(0xffffffffffffffffULL));
   2420                      assign(old, load(Ity_I64, mkexpr(addr)));
   2421                      mips_load_store64(addr, new_val, old, regRd, True);
   2422                      break;
   2423                   }
   2424                   /* Load Atomic Clear Word - LAC; Cavium OCTEON2 */
   2425                   case 0x0e: {
   2426                      DIP("lac r%u,(r%u)\n", regRd, regRs);
   2427                      IRTemp new_val = newTemp(Ity_I32);
   2428                      IRTemp old = newTemp(Ity_I32);
   2429                      assign(addr, getIReg(regRs));
   2430                      assign(new_val, mkU32(0));
   2431                      assign(old, load(Ity_I32, mkexpr(addr)));
   2432                      mips_load_store32(addr, new_val, old, regRd, True);
   2433                      break;
   2434                   }
   2435                   /* Load Atomic Clear Doubleword - LACD; Cavium OCTEON2 */
   2436                   case 0x0f: {
   2437                      DIP("lacd r%u,(r%u)\n", regRd, regRs);
   2438                      IRTemp new_val = newTemp(Ity_I64);
   2439                      IRTemp old = newTemp(Ity_I64);
   2440                      assign(addr, getIReg(regRs));
   2441                      assign(new_val, mkU64(0));
   2442                      assign(old, load(Ity_I64, mkexpr(addr)));
   2443                      mips_load_store64(addr, new_val, old, regRd, True);
   2444                      break;
   2445                   }
   2446                   /* Load Atomic Add Word - LAA; Cavium OCTEON2 */
   2447                   case 0x12: {
   2448                      DIP("laa r%u,(r%u),r%u\n", regRd, regRs, regRt);
   2449                      IRTemp new_val = newTemp(Ity_I32);
   2450                      IRTemp old = newTemp(Ity_I32);
   2451                      assign(addr, getIReg(regRs));
   2452                      assign(old, load(Ity_I32, mkexpr(addr)));
   2453                      assign(new_val, binop(Iop_Add32,
   2454                                            mkexpr(old),
   2455                                            mkNarrowTo32(ty, getIReg(regRt))));
   2456                      mips_load_store32(addr, new_val, old, regRd, True);
   2457                      break;
   2458                   }
   2459                   /* Load Atomic Add Doubleword - LAAD; Cavium OCTEON2 */
   2460                   case 0x13: {
   2461                      DIP("laad r%u,(r%u),r%u\n", regRd, regRs, regRt);
   2462                      IRTemp new_val = newTemp(Ity_I64);
   2463                      IRTemp old = newTemp(Ity_I64);
   2464                      assign(addr, getIReg(regRs));
   2465                      assign(old, load(Ity_I64, mkexpr(addr)));
   2466                      assign(new_val, binop(Iop_Add64,
   2467                                            load(Ity_I64, mkexpr(addr)),
   2468                                            getIReg(regRt)));
   2469                      mips_load_store64(addr, new_val, old, regRd, True);
   2470                      break;
   2471                   }
   2472                   /* Load Atomic Swap Word - LAW; Cavium OCTEON2 */
   2473                   case 0x16: {
   2474                      DIP("law r%u,(r%u)\n", regRd, regRs);
   2475                      IRTemp new_val = newTemp(Ity_I32);
   2476                      IRTemp old = newTemp(Ity_I32);
   2477                      assign(addr, getIReg(regRs));
   2478                      assign(new_val, mkNarrowTo32(ty, getIReg(regRt)));
   2479                      assign(old, load(Ity_I32, mkexpr(addr)));
   2480                      mips_load_store32(addr, new_val, old, regRd, True);
   2481                      break;
   2482                   }
   2483                   /* Load Atomic Swap Doubleword - LAWD; Cavium OCTEON2 */
   2484                   case 0x17: {
   2485                      DIP("lawd r%u,(r%u)\n", regRd, regRs);
   2486                      IRTemp new_val = newTemp(Ity_I64);
   2487                      IRTemp old = newTemp(Ity_I64);
   2488                      assign(addr, getIReg(regRs));
   2489                      assign(new_val, getIReg(regRt));
   2490                      assign(old, load(Ity_I64, mkexpr(addr)));
   2491                      mips_load_store64(addr, new_val, old, regRd, True);
   2492                      break;
   2493                   }
   2494                   default:
   2495                      vex_printf("Unknown laxx instruction, opc3=0x%x\n", opc3);
   2496                      vex_printf("Instruction=0x%08x\n", theInstr);
   2497                      return False;
   2498                }
   2499                break;
   2500             }
   2501 
   2502             /* Unsigned Byte Add - BADDU rd, rs, rt; Cavium OCTEON */
   2503             case 0x28: {
   2504                DIP("BADDU r%u, r%u, r%u", regRs, regRt, regRd);
   2505                IRTemp t0 = newTemp(Ity_I8);
   2506 
   2507                assign(t0, binop(Iop_Add8,
   2508                                 mkNarrowTo8(ty, getIReg(regRs)),
   2509                                 mkNarrowTo8(ty, getIReg(regRt))));
   2510 
   2511                if (mode64)
   2512                   putIReg(regRd, binop(mkSzOp(ty, Iop_And8),
   2513                                        unop(Iop_8Uto64, mkexpr(t0)),
   2514                                        mkSzImm(ty, 0xFF)));
   2515                else
   2516                   putIReg(regRd, binop(mkSzOp(ty, Iop_And8),
   2517                                        unop(Iop_8Uto32, mkexpr(t0)),
   2518                                        mkSzImm(ty, 0xFF)));
   2519                break;
   2520             }
   2521 
   2522             case 0x2c: {  /* Count Ones in a Word - POP; Cavium OCTEON */
   2523                int i, shift[5];
   2524                IRTemp mask[5];
   2525                IRTemp old = newTemp(ty);
   2526                IRTemp nyu = IRTemp_INVALID;
   2527                assign(old, getIReg(regRs));
   2528                DIP("pop r%u, r%u", regRd, regRs);
   2529 
   2530                for (i = 0; i < 5; i++) {
   2531                   mask[i] = newTemp(ty);
   2532                   shift[i] = 1 << i;
   2533                }
   2534                if(mode64) {
   2535                   assign(mask[0], mkU64(0x0000000055555555));
   2536                   assign(mask[1], mkU64(0x0000000033333333));
   2537                   assign(mask[2], mkU64(0x000000000F0F0F0F));
   2538                   assign(mask[3], mkU64(0x0000000000FF00FF));
   2539                   assign(mask[4], mkU64(0x000000000000FFFF));
   2540 
   2541                   for (i = 0; i < 5; i++) {
   2542                      nyu = newTemp(ty);
   2543                      assign(nyu,
   2544                             binop(Iop_Add64,
   2545                                   binop(Iop_And64,
   2546                                         mkexpr(old), mkexpr(mask[i])),
   2547                                   binop(Iop_And64,
   2548                                         binop(Iop_Shr64,
   2549                                               mkexpr(old), mkU8(shift[i])),
   2550                                         mkexpr(mask[i]))));
   2551                      old = nyu;
   2552                   }
   2553                } else {
   2554                   assign(mask[0], mkU32(0x55555555));
   2555                   assign(mask[1], mkU32(0x33333333));
   2556                   assign(mask[2], mkU32(0x0F0F0F0F));
   2557                   assign(mask[3], mkU32(0x00FF00FF));
   2558                   assign(mask[4], mkU32(0x0000FFFF));
   2559                   assign(old, getIReg(regRs));
   2560 
   2561                   for (i = 0; i < 5; i++) {
   2562                      nyu = newTemp(ty);
   2563                      assign(nyu,
   2564                             binop(Iop_Add32,
   2565                                   binop(Iop_And32,
   2566                                         mkexpr(old), mkexpr(mask[i])),
   2567                                   binop(Iop_And32,
   2568                                         binop(Iop_Shr32,
   2569                                               mkexpr(old), mkU8(shift[i])),
   2570                                         mkexpr(mask[i]))));
   2571                      old = nyu;
   2572                   }
   2573                }
   2574                putIReg(regRd, mkexpr(nyu));
   2575                break;
   2576             }
   2577 
   2578             /* Count Ones in a Doubleword - DPOP; Cavium OCTEON */
   2579             case 0x2d: {
   2580                int i, shift[6];
   2581                IRTemp mask[6];
   2582                IRTemp old = newTemp(ty);
   2583                IRTemp nyu = IRTemp_INVALID;
   2584                DIP("dpop r%u, r%u", regRd, regRs);
   2585 
   2586                for (i = 0; i < 6; i++) {
   2587                   mask[i] = newTemp(ty);
   2588                   shift[i] = 1 << i;
   2589                }
   2590                vassert(mode64); /*Caution! Only for Mode 64*/
   2591                assign(mask[0], mkU64(0x5555555555555555ULL));
   2592                assign(mask[1], mkU64(0x3333333333333333ULL));
   2593                assign(mask[2], mkU64(0x0F0F0F0F0F0F0F0FULL));
   2594                assign(mask[3], mkU64(0x00FF00FF00FF00FFULL));
   2595                assign(mask[4], mkU64(0x0000FFFF0000FFFFULL));
   2596                assign(mask[5], mkU64(0x00000000FFFFFFFFULL));
   2597                assign(old, getIReg(regRs));
   2598                for (i = 0; i < 6; i++) {
   2599                   nyu = newTemp(Ity_I64);
   2600                   assign(nyu,
   2601                          binop(Iop_Add64,
   2602                                binop(Iop_And64,
   2603                                      mkexpr(old), mkexpr(mask[i])),
   2604                                binop(Iop_And64,
   2605                                      binop(Iop_Shr64,
   2606                                            mkexpr(old), mkU8(shift[i])),
   2607                                      mkexpr(mask[i]))));
   2608                   old = nyu;
   2609                }
   2610                putIReg(regRd, mkexpr(nyu));
   2611                break;
   2612             }
   2613 
   2614             case 0x32:  /* 5. CINS rd, rs, p, lenm1 */
   2615                DIP("cins r%u, r%u, %u, %u\n", regRt, regRs, p, lenM1);
   2616                assign ( tmp  , binop(Iop_Shl64, mkexpr(tmpRs),
   2617                                      mkU8(64-( lenM1+1 ))));
   2618                assign ( tmpRt, binop(Iop_Shr64, mkexpr( tmp ),
   2619                                      mkU8(64-(p+lenM1+1))));
   2620                putIReg( regRt, mkexpr(tmpRt));
   2621                break;
   2622 
   2623             case 0x33:  /* 6. CINS32 rd, rs, p+32, lenm1 */
   2624                DIP("cins32 r%u, r%u, %d, %d\n", regRt, regRs, p+32, lenM1);
   2625                assign ( tmp  , binop(Iop_Shl64, mkexpr(tmpRs),
   2626                                      mkU8(64-( lenM1+1 ))));
   2627                assign ( tmpRt, binop(Iop_Shr64, mkexpr( tmp ),
   2628                                      mkU8(32-(p+lenM1+1))));
   2629                putIReg( regRt, mkexpr(tmpRt));
   2630                break;
   2631 
   2632             case 0x3A:  /* 3. EXTS rt, rs, p len */
   2633                DIP("exts r%u, r%u, %d, %d\n", regRt, regRs, p, lenM1);
   2634                size = lenM1 + 1;  /* lenm1+1 */
   2635                UChar lsAmt = 64 - (p + size);  /* p+lenm1+1 */
   2636                UChar rsAmt = 64 - size;  /* lenm1+1 */
   2637                tmp = newTemp(Ity_I64);
   2638                assign(tmp, binop(Iop_Shl64, mkexpr(tmpRs), mkU8(lsAmt)));
   2639                putIReg(regRt, binop(Iop_Sar64, mkexpr(tmp), mkU8(rsAmt)));
   2640                break;
   2641 
   2642             case 0x3B:  /* 4. EXTS32 rt, rs, p len */
   2643                DIP("exts32 r%u, r%u, %d, %d\n", regRt, regRs, p, lenM1);
   2644                assign ( tmp  , binop(Iop_Shl64, mkexpr(tmpRs),
   2645                                      mkU8(32-(p+lenM1+1))));
   2646                assign ( tmpRt, binop(Iop_Sar64, mkexpr(tmp),
   2647                                      mkU8(64-(lenM1+1))) );
   2648                putIReg( regRt, mkexpr(tmpRt));
   2649                break;
   2650 
   2651             case 0x2B:  /* 20. SNE rd, rs, rt */
   2652                DIP("sne r%u, r%u, r%u", regRd,regRs, regRt);
   2653                if (mode64)
   2654                   putIReg(regRd, unop(Iop_1Uto64, binop(Iop_CmpNE64,
   2655                                                         getIReg(regRs),
   2656                                                         getIReg(regRt))));
   2657                else
   2658                   putIReg(regRd,unop(Iop_1Uto32, binop(Iop_CmpNE32,
   2659                                                        getIReg(regRs),
   2660                                                        getIReg(regRt))));
   2661                break;
   2662 
   2663             case 0x2A:  /* Set Equals - SEQ; Cavium OCTEON */
   2664                DIP("seq r%u, r%u, %d", regRd, regRs, regRt);
   2665                if (mode64)
   2666                   putIReg(regRd, unop(Iop_1Uto64,
   2667                                       binop(Iop_CmpEQ64, getIReg(regRs),
   2668                                             getIReg(regRt))));
   2669                else
   2670                   putIReg(regRd, unop(Iop_1Uto32,
   2671                                       binop(Iop_CmpEQ32, getIReg(regRs),
   2672                                             getIReg(regRt))));
   2673                break;
   2674 
   2675             case 0x2E:  /* Set Equals Immediate - SEQI; Cavium OCTEON */
   2676                DIP("seqi r%u, r%u, %u", regRt, regRs, imm);
   2677                if (mode64)
   2678                   putIReg(regRt, unop(Iop_1Uto64,
   2679                                       binop(Iop_CmpEQ64, getIReg(regRs),
   2680                                             mkU64(extend_s_10to64(imm)))));
   2681                else
   2682                   putIReg(regRt, unop(Iop_1Uto32,
   2683                                       binop(Iop_CmpEQ32, getIReg(regRs),
   2684                                             mkU32(extend_s_10to32(imm)))));
   2685                break;
   2686 
   2687             case 0x2F:  /* Set Not Equals Immediate - SNEI; Cavium OCTEON */
   2688                DIP("snei r%u, r%u, %u", regRt, regRs, imm);
   2689                if (mode64)
   2690                   putIReg(regRt, unop(Iop_1Uto64,
   2691                                    binop(Iop_CmpNE64,
   2692                                          getIReg(regRs),
   2693                                          mkU64(extend_s_10to64(imm)))));
   2694                else
   2695                   putIReg(regRt, unop(Iop_1Uto32,
   2696                                    binop(Iop_CmpNE32,
   2697                                          getIReg(regRs),
   2698                                          mkU32(extend_s_10to32(imm)))));
   2699                break;
   2700 
   2701             default:
   2702                return False;
   2703          }
   2704          break;
   2705       } /* opc1 0x1C ends here*/
   2706       case 0x1F: {
   2707          switch(opc2) {
   2708             case 0x0A: {  // lx - Load indexed instructions
   2709                switch (get_sa(theInstr)) {
   2710                   case 0x00: {  // LWX rd, index(base)
   2711                      DIP("lwx r%u, r%u(r%u)", regRd, regRt, regRs);
   2712                      LOADX_STORE_PATTERN;
   2713                      putIReg(regRd, mkWidenFrom32(ty, load(Ity_I32, mkexpr(t1)),
   2714                                                   True));
   2715                      break;
   2716                   }
   2717                   case 0x04:  // LHX rd, index(base)
   2718                      DIP("lhx r%u, r%u(r%u)", regRd, regRt, regRs);
   2719                      LOADX_STORE_PATTERN;
   2720                      if (mode64)
   2721                         putIReg(regRd, unop(Iop_16Sto64, load(Ity_I16,
   2722                                                               mkexpr(t1))));
   2723                      else
   2724                         putIReg(regRd, unop(Iop_16Sto32, load(Ity_I16,
   2725                                                               mkexpr(t1))));
   2726                      break;
   2727                   case 0x08: {  // LDX rd, index(base)
   2728                      DIP("ldx r%u, r%u(r%u)", regRd, regRt, regRs);
   2729                      vassert(mode64); /* Currently Implemented only for n64 */
   2730                      LOADX_STORE_PATTERN;
   2731                      putIReg(regRd, load(Ity_I64, mkexpr(t1)));
   2732                      break;
   2733                   }
   2734                   case 0x06: {  // LBUX rd, index(base)
   2735                      DIP("lbux r%u, r%u(r%u)", regRd, regRt, regRs);
   2736                      LOADX_STORE_PATTERN;
   2737                      if (mode64)
   2738                         putIReg(regRd, unop(Iop_8Uto64, load(Ity_I8,
   2739                                                              mkexpr(t1))));
   2740                      else
   2741                         putIReg(regRd, unop(Iop_8Uto32, load(Ity_I8,
   2742                                                              mkexpr(t1))));
   2743                      break;
   2744                   }
   2745                   case 0x10: {  // LWUX rd, index(base) (Cavium OCTEON)
   2746                      DIP("lwux r%u, r%u(r%u)", regRd, regRt, regRs);
   2747                      LOADX_STORE_PATTERN; /* same for both 32 and 64 modes*/
   2748                      putIReg(regRd, mkWidenFrom32(ty, load(Ity_I32, mkexpr(t1)),
   2749                                                   False));
   2750                      break;
   2751                   }
   2752                   case 0x14: {  // LHUX rd, index(base) (Cavium OCTEON)
   2753                      DIP("lhux r%u, r%u(r%u)", regRd, regRt, regRs);
   2754                      LOADX_STORE_PATTERN;
   2755                      if (mode64)
   2756                         putIReg(regRd,
   2757                                 unop(Iop_16Uto64, load(Ity_I16, mkexpr(t1))));
   2758                      else
   2759                         putIReg(regRd,
   2760                                 unop(Iop_16Uto32, load(Ity_I16, mkexpr(t1))));
   2761                      break;
   2762                   }
   2763                   case 0x16: {  // LBX rd, index(base) (Cavium OCTEON)
   2764                      DIP("lbx r%u, r%u(r%u)", regRd, regRs, regRt);
   2765                      LOADX_STORE_PATTERN;
   2766                      if (mode64)
   2767                         putIReg(regRd,
   2768                                 unop(Iop_8Sto64, load(Ity_I8, mkexpr(t1))));
   2769                      else
   2770                         putIReg(regRd,
   2771                                 unop(Iop_8Sto32, load(Ity_I8, mkexpr(t1))));
   2772                      break;
   2773                   }
   2774                   default:
   2775                      vex_printf("\nUnhandled LX instruction opc3 = %x\n",
   2776                                 get_sa(theInstr));
   2777                      return False;
   2778                }
   2779                break;
   2780             }
   2781          } /* opc1 = 0x1F & opc2 = 0xA (LX) ends here*/
   2782          break;
   2783       } /* opc1 = 0x1F ends here*/
   2784       default:
   2785          return False;
   2786    } /* main opc1 switch ends here */
   2787    return True;
   2788 }
   2789 
   2790 /*------------------------------------------------------------*/
   2791 /*---       Disassemble a single DSP ASE instruction       ---*/
   2792 /*------------------------------------------------------------*/
   2793 
   2794 static UInt disDSPInstr_MIPS_WRK ( UInt cins )
   2795 {
   2796    IRTemp t0, t1 = 0, t2, t3, t4, t5, t6, t7, t8, t9, t10, t11, t12, t13, t14,
   2797           t15, t16, t17;
   2798    UInt opcode, rs, rt, rd, sa, function, ac, ac_mfhilo, rddsp_mask,
   2799         wrdsp_mask, dsp_imm, shift;
   2800 
   2801    opcode = get_opcode(cins);
   2802    rs = get_rs(cins);
   2803    rt = get_rt(cins);
   2804    rd = get_rd(cins);
   2805    sa = get_sa(cins);
   2806    function = get_function(cins);
   2807    ac = get_acNo(cins);
   2808    ac_mfhilo = get_acNo_mfhilo(cins);
   2809    rddsp_mask = get_rddspMask(cins);
   2810    wrdsp_mask = get_wrdspMask(cins);
   2811    dsp_imm = get_dspImm(cins);
   2812    shift = get_shift(cins);
   2813 
   2814    switch (opcode) {
   2815       case 0x00: {  /* Special */
   2816          switch (function) {
   2817             case 0x10: {  /* MFHI */
   2818                DIP("mfhi ac%u r%u", ac_mfhilo, rd);
   2819                putIReg(rd, unop(Iop_64HIto32, getAcc(ac_mfhilo)));
   2820                break;
   2821             }
   2822 
   2823             case 0x11: {  /* MTHI */
   2824                DIP("mthi ac%u r%u", ac, rs);
   2825                t1 = newTemp(Ity_I32);
   2826                assign(t1, unop(Iop_64to32, getAcc(ac)));
   2827                putAcc(ac, binop(Iop_32HLto64, getIReg(rs), mkexpr(t1)));
   2828                break;
   2829             }
   2830 
   2831             case 0x12: {  /* MFLO */
   2832                DIP("mflo ac%u r%u", ac_mfhilo, rd);
   2833                putIReg(rd, unop(Iop_64to32, getAcc(ac_mfhilo)));
   2834                break;
   2835             }
   2836 
   2837             case 0x13: {  /* MTLO */
   2838                DIP("mtlo ac%u r%u", ac, rs);
   2839                t1 = newTemp(Ity_I32);
   2840                assign(t1, unop(Iop_64HIto32, getAcc(ac)));
   2841                putAcc(ac, binop(Iop_32HLto64, mkexpr(t1), getIReg(rs)));
   2842                break;
   2843             }
   2844 
   2845             case 0x18: {  /* MULT */
   2846                DIP("mult ac%u r%u, r%u", ac, rs, rt);
   2847                t1 = newTemp(Ity_I64);
   2848                assign(t1, binop(Iop_MullS32, mkNarrowTo32(Ity_I32, getIReg(rs)),
   2849                                 mkNarrowTo32(Ity_I32, getIReg(rt))));
   2850                putAcc(ac, mkexpr(t1));
   2851                break;
   2852             }
   2853 
   2854             case 0x19: {  /* MULTU */
   2855                DIP("multu ac%u r%u, r%u", ac, rs, rt);
   2856                t1 = newTemp(Ity_I64);
   2857                assign(t1, binop(Iop_MullU32, mkNarrowTo32(Ity_I32, getIReg(rs)),
   2858                                              mkNarrowTo32(Ity_I32,
   2859                                                           getIReg(rt))));
   2860                putAcc(ac, mkexpr(t1));
   2861             break;
   2862             }
   2863          }
   2864          break;
   2865       }
   2866       case 0x1C: {  /* Special2 */
   2867          switch (function) {
   2868             case 0x00: {  /* MADD */
   2869                DIP("madd ac%u, r%u, r%u", ac, rs, rt);
   2870                t1 = newTemp(Ity_I64);
   2871                t2 = newTemp(Ity_I64);
   2872                t3 = newTemp(Ity_I64);
   2873 
   2874                assign(t1, getAcc(ac));
   2875                assign(t2, binop(Iop_MullS32, getIReg(rs), getIReg(rt)));
   2876                assign(t3, binop(Iop_Add64, mkexpr(t1), mkexpr(t2)));
   2877 
   2878                putAcc(ac, mkexpr(t3));
   2879                break;
   2880             }
   2881             case 0x01: {  /* MADDU */
   2882                DIP("maddu ac%u r%u, r%u", ac, rs, rt);
   2883                t1 = newTemp(Ity_I64);
   2884                t2 = newTemp(Ity_I64);
   2885                t3 = newTemp(Ity_I64);
   2886 
   2887                assign(t1, getAcc(ac));
   2888                assign(t2, binop(Iop_MullU32, getIReg(rs), getIReg(rt)));
   2889                assign(t3, binop(Iop_Add64, mkexpr(t2), mkexpr(t1)));
   2890 
   2891                putAcc(ac, mkexpr(t3));
   2892                break;
   2893             }
   2894             case 0x04: {  /* MSUB */
   2895                DIP("msub ac%u r%u, r%u", ac, rs, rt);
   2896                t1 = newTemp(Ity_I64);
   2897                t2 = newTemp(Ity_I64);
   2898                t3 = newTemp(Ity_I64);
   2899 
   2900                assign(t1, getAcc(ac));
   2901                assign(t2, binop(Iop_MullS32, getIReg(rs), getIReg(rt)));
   2902                assign(t3, binop(Iop_Sub64, mkexpr(t1), mkexpr(t2)));
   2903 
   2904                putAcc(ac, mkexpr(t3));
   2905                break;
   2906             }
   2907             case 0x05: {  /* MSUBU */
   2908                DIP("msubu ac%u r%u, r%u", ac, rs, rt);
   2909                t1 = newTemp(Ity_I64);
   2910                t2 = newTemp(Ity_I64);
   2911                t3 = newTemp(Ity_I64);
   2912 
   2913                assign(t1, getAcc(ac));
   2914                assign(t2, binop(Iop_MullU32, getIReg(rs), getIReg(rt)));
   2915                assign(t3, binop(Iop_Sub64, mkexpr(t1), mkexpr(t2)));
   2916 
   2917                putAcc(ac, mkexpr(t3));
   2918                break;
   2919             }
   2920          }
   2921          break;
   2922       }
   2923       case 0x1F: {  /* Special3 */
   2924          switch (function) {
   2925             case 0x12: {  /* ABSQ_S.PH */
   2926                switch (sa) {
   2927                   case 0x1: {  /* ABSQ_S.QB */
   2928                      DIP("absq_s.qb r%u, r%u", rd, rt);
   2929                      vassert(!mode64);
   2930                      t0 = newTemp(Ity_I8);
   2931                      t1 = newTemp(Ity_I1);
   2932                      t2 = newTemp(Ity_I1);
   2933                      t3 = newTemp(Ity_I8);
   2934                      t4 = newTemp(Ity_I8);
   2935                      t5 = newTemp(Ity_I1);
   2936                      t6 = newTemp(Ity_I1);
   2937                      t7 = newTemp(Ity_I8);
   2938                      t8 = newTemp(Ity_I8);
   2939                      t9 = newTemp(Ity_I1);
   2940                      t10 = newTemp(Ity_I1);
   2941                      t11 = newTemp(Ity_I8);
   2942                      t12 = newTemp(Ity_I8);
   2943                      t13 = newTemp(Ity_I1);
   2944                      t14 = newTemp(Ity_I1);
   2945                      t15 = newTemp(Ity_I8);
   2946                      t16 = newTemp(Ity_I32);
   2947                      t17 = newTemp(Ity_I32);
   2948 
   2949                      /* Absolute value of the rightmost byte (bits 7-0). */
   2950                      /* t0 - rightmost byte. */
   2951                      assign(t0, unop(Iop_16to8, unop(Iop_32to16, getIReg(rt))));
   2952                      /* t1 holds 1 if t0 is equal to 0x80, or 0 otherwise. */
   2953                      assign(t1, binop(Iop_CmpEQ32,
   2954                                       unop(Iop_8Uto32, mkexpr(t0)),
   2955                                       mkU32(0x00000080)));
   2956                      /* t2 holds 1 if value in t0 is negative, 0 otherwise. */
   2957                      assign(t2, unop(Iop_32to1,
   2958                                      binop(Iop_Shr32,
   2959                                            binop(Iop_And32,
   2960                                                  getIReg(rt),
   2961                                                  mkU32(0x00000080)),
   2962                                            mkU8(0x7))));
   2963                      /* t3 holds abs(t0). */
   2964                      assign(t3, IRExpr_ITE(mkexpr(t1),
   2965                                            mkU8(0x7F),
   2966                                            IRExpr_ITE(mkexpr(t2),
   2967                                                       binop(Iop_Add8,
   2968                                                             unop(Iop_Not8,
   2969                                                                  mkexpr(t0)),
   2970                                                             mkU8(0x1)),
   2971                                                       mkexpr(t0))));
   2972 
   2973                      /* Absolute value of bits 15-8. */
   2974                      /* t4 - input byte. */
   2975                      assign(t4,
   2976                             unop(Iop_16HIto8, unop(Iop_32to16, getIReg(rt))));
   2977                      /* t5 holds 1 if t4 is equal to 0x80, or 0 otherwise. */
   2978                      assign(t5, binop(Iop_CmpEQ32,
   2979                                       unop(Iop_8Uto32, mkexpr(t4)),
   2980                                       mkU32(0x00000080)));
   2981                      /* t6 holds 1 if value in t4 is negative, 0 otherwise. */
   2982                      assign(t6, unop(Iop_32to1,
   2983                                      binop(Iop_Shr32,
   2984                                            binop(Iop_And32,
   2985                                                  getIReg(rt),
   2986                                                  mkU32(0x00008000)),
   2987                                            mkU8(15))));
   2988                      /* t3 holds abs(t4). */
   2989                      assign(t7, IRExpr_ITE(mkexpr(t5),
   2990                                            mkU8(0x7F),
   2991                                            IRExpr_ITE(mkexpr(t6),
   2992                                                       binop(Iop_Add8,
   2993                                                             unop(Iop_Not8,
   2994                                                                  mkexpr(t4)),
   2995                                                             mkU8(0x1)),
   2996                                                       mkexpr(t4))));
   2997 
   2998                      /* Absolute value of bits 23-15. */
   2999                      /* t8 - input byte. */
   3000                      assign(t8,
   3001                             unop(Iop_16to8, unop(Iop_32HIto16, getIReg(rt))));
   3002                      /* t9 holds 1 if t8 is equal to 0x80, or 0 otherwise. */
   3003                      assign(t9, binop(Iop_CmpEQ32,
   3004                                       unop(Iop_8Uto32, mkexpr(t8)),
   3005                                       mkU32(0x00000080)));
   3006                      /* t6 holds 1 if value in t8 is negative, 0 otherwise. */
   3007                      assign(t10, unop(Iop_32to1,
   3008                                       binop(Iop_Shr32,
   3009                                             binop(Iop_And32,
   3010                                                   getIReg(rt),
   3011                                                   mkU32(0x00800000)),
   3012                                             mkU8(23))));
   3013                      /* t3 holds abs(t8). */
   3014                      assign(t11, IRExpr_ITE(mkexpr(t9),
   3015                                             mkU8(0x7F),
   3016                                             IRExpr_ITE(mkexpr(t10),
   3017                                                        binop(Iop_Add8,
   3018                                                              unop(Iop_Not8,
   3019                                                                   mkexpr(t8)),
   3020                                                              mkU8(0x1)),
   3021                                                        mkexpr(t8))));
   3022 
   3023                      /* Absolute value of bits 31-24. */
   3024                      /* t12 - input byte. */
   3025                      assign(t12,
   3026                             unop(Iop_16HIto8, unop(Iop_32HIto16, getIReg(rt))));
   3027                      /* t13 holds 1 if t12 is equal to 0x80, or 0 otherwise. */
   3028                      assign(t13, binop(Iop_CmpEQ32,
   3029                                        unop(Iop_8Uto32, mkexpr(t12)),
   3030                                        mkU32(0x00000080)));
   3031                      /* t14 holds 1 if value in t12 is negative, 0 otherwise. */
   3032                      assign(t14, unop(Iop_32to1,
   3033                                       binop(Iop_Shr32,
   3034                                             binop(Iop_And32,
   3035                                                   getIReg(rt),
   3036                                                   mkU32(0x80000000)),
   3037                                             mkU8(31))));
   3038                      /* t15 holds abs(t12). */
   3039                      assign(t15, IRExpr_ITE(mkexpr(t13),
   3040                                             mkU8(0x7F),
   3041                                             IRExpr_ITE(mkexpr(t14),
   3042                                                        binop(Iop_Add8,
   3043                                                              unop(Iop_Not8,
   3044                                                                   mkexpr(t12)),
   3045                                                              mkU8(0x1)),
   3046                                                        mkexpr(t12))));
   3047 
   3048                      /* t16 holds !0 if any of input bytes is 0x80 or 0
   3049                         otherwise. */
   3050                      assign(t16,
   3051                             binop(Iop_Or32,
   3052                                   binop(Iop_Or32,
   3053                                         binop(Iop_Or32,
   3054                                               unop(Iop_1Sto32, mkexpr(t13)),
   3055                                               unop(Iop_1Sto32, mkexpr(t9))),
   3056                                         unop(Iop_1Sto32, mkexpr(t5))),
   3057                                   unop(Iop_1Sto32, mkexpr(t1))));
   3058 
   3059                      putDSPControl(IRExpr_ITE(binop(Iop_CmpEQ32,
   3060                                                     mkexpr(t16),
   3061                                                     mkU32(0x0)),
   3062                                               getDSPControl(),
   3063                                               binop(Iop_Or32,
   3064                                                     getDSPControl(),
   3065                                                     mkU32(0x00100000))));
   3066 
   3067                      /* t17 = t15|t11|t7|t3 */
   3068                      assign(t17,
   3069                             binop(Iop_16HLto32,
   3070                                   binop(Iop_8HLto16, mkexpr(t15), mkexpr(t11)),
   3071                                   binop(Iop_8HLto16, mkexpr(t7), mkexpr(t3))));
   3072 
   3073                      putIReg(rd, mkexpr(t17));
   3074                      break;
   3075                   }
   3076                   case 0x2: {  /* REPL.QB */
   3077                      DIP("repl.qb r%u, %u", rd, dsp_imm);
   3078                      vassert(!mode64);
   3079 
   3080                      putIReg(rd, mkU32((dsp_imm << 24) | (dsp_imm << 16) |
   3081                                        (dsp_imm << 8) | (dsp_imm)));
   3082                      break;
   3083                   }
   3084                   case 0x3: {  /* REPLV.QB */
   3085                      DIP("replv.qb r%u, r%u", rd, rt);
   3086                      vassert(!mode64);
   3087                      t0 = newTemp(Ity_I8);
   3088 
   3089                      assign(t0, unop(Iop_32to8,
   3090                                 binop(Iop_And32, getIReg(rt), mkU32(0xff))));
   3091                      putIReg(rd,
   3092                              binop(Iop_16HLto32,
   3093                                    binop(Iop_8HLto16, mkexpr(t0), mkexpr(t0)),
   3094                                    binop(Iop_8HLto16, mkexpr(t0), mkexpr(t0))));
   3095                      break;
   3096                   }
   3097                   case 0x4: {  /* PRECEQU.PH.QBL */
   3098                      DIP("precequ.ph.qbl r%u, r%u", rd, rt);
   3099                      vassert(!mode64);
   3100 
   3101                      putIReg(rd, binop(Iop_Or32,
   3102                                        binop(Iop_Shr32,
   3103                                              binop(Iop_And32,
   3104                                                    getIReg(rt),
   3105                                                    mkU32(0xff000000)),
   3106                                              mkU8(1)),
   3107                                        binop(Iop_Shr32,
   3108                                              binop(Iop_And32,
   3109                                                    getIReg(rt),
   3110                                                    mkU32(0x00ff0000)),
   3111                                              mkU8(9))));
   3112                      break;
   3113                   }
   3114                   case 0x5: {  /* PRECEQU.PH.QBR */
   3115                      DIP("precequ.ph.qbr r%u, r%u", rd, rt);
   3116                      vassert(!mode64);
   3117 
   3118                      putIReg(rd, binop(Iop_Or32,
   3119                                        binop(Iop_Shl32,
   3120                                              binop(Iop_And32,
   3121                                                    getIReg(rt),
   3122                                                    mkU32(0x0000ff00)),
   3123                                              mkU8(15)),
   3124                                        binop(Iop_Shl32,
   3125                                              binop(Iop_And32,
   3126                                                    getIReg(rt),
   3127                                                    mkU32(0x000000ff)),
   3128                                              mkU8(7))));
   3129                      break;
   3130                   }
   3131                   case 0x6: {  /* PRECEQU.PH.QBLA */
   3132                      DIP("precequ.ph.qbla r%u, r%u", rd, rt);
   3133                      vassert(!mode64);
   3134 
   3135                      putIReg(rd, binop(Iop_Or32,
   3136                                        binop(Iop_Shr32,
   3137                                              binop(Iop_And32,
   3138                                                    getIReg(rt),
   3139                                                    mkU32(0xff000000)),
   3140                                              mkU8(1)),
   3141                                        binop(Iop_Shr32,
   3142                                              binop(Iop_And32,
   3143                                                    getIReg(rt),
   3144                                                    mkU32(0x0000ff00)),
   3145                                              mkU8(1))));
   3146                      break;
   3147                   }
   3148                   case 0x7: {  /* PRECEQU.PH.QBRA */
   3149                      DIP("precequ.ph.qbra r%u, r%u", rd, rt);
   3150                      vassert(!mode64);
   3151 
   3152                      putIReg(rd, binop(Iop_Or32,
   3153                                        binop(Iop_Shl32,
   3154                                              binop(Iop_And32,
   3155                                                    getIReg(rt),
   3156                                                    mkU32(0x00ff0000)),
   3157                                              mkU8(7)),
   3158                                        binop(Iop_Shl32,
   3159                                              binop(Iop_And32,
   3160                                                    getIReg(rt),
   3161                                                    mkU32(0x000000ff)),
   3162                                              mkU8(7))));
   3163                      break;
   3164                   }
   3165                   case 0x9: {  /* ABSQ_S.PH */
   3166                      DIP("absq_s.ph r%u, r%u", rd, rt);
   3167                      vassert(!mode64);
   3168                      t0 = newTemp(Ity_I16);
   3169                      t1 = newTemp(Ity_I1);
   3170                      t2 = newTemp(Ity_I1);
   3171                      t3 = newTemp(Ity_I16);
   3172                      t4 = newTemp(Ity_I16);
   3173                      t5 = newTemp(Ity_I1);
   3174                      t6 = newTemp(Ity_I1);
   3175                      t7 = newTemp(Ity_I16);
   3176                      t8 = newTemp(Ity_I32);
   3177                      t9 = newTemp(Ity_I32);
   3178 
   3179                      /* t0 holds lower 16 bits of value in rt. */
   3180                      assign(t0, unop(Iop_32to16, getIReg(rt)));
   3181                      /* t1 holds 1 if t0 is equal to 0x8000. */
   3182                      assign(t1, binop(Iop_CmpEQ32,
   3183                                       unop(Iop_16Uto32, mkexpr(t0)),
   3184                                       mkU32(0x00008000)));
   3185                      /* t2 holds 1 if value in t0 is negative, 0 otherwise. */
   3186                      assign(t2, unop(Iop_32to1,
   3187                                      binop(Iop_Shr32,
   3188                                            binop(Iop_And32,
   3189                                                  getIReg(rt),
   3190                                                  mkU32(0x00008000)),
   3191                                            mkU8(15))));
   3192                      /* t3 holds abs(t0). */
   3193                      assign(t3, IRExpr_ITE(mkexpr(t1),
   3194                                            mkU16(0x7FFF),
   3195                                            IRExpr_ITE(mkexpr(t2),
   3196                                                       binop(Iop_Add16,
   3197                                                             unop(Iop_Not16,
   3198                                                                  mkexpr(t0)),
   3199                                                             mkU16(0x1)),
   3200                                                       mkexpr(t0))));
   3201 
   3202                      /* t4 holds lower 16 bits of value in rt. */
   3203                      assign(t4, unop(Iop_32HIto16, getIReg(rt)));
   3204                      /* t5 holds 1 if t4 is equal to 0x8000. */
   3205                      assign(t5, binop(Iop_CmpEQ32,
   3206                                       unop(Iop_16Uto32, mkexpr(t4)),
   3207                                       mkU32(0x00008000)));
   3208                      /* t6 holds 1 if value in t4 is negative, 0 otherwise. */
   3209                      assign(t6, unop(Iop_32to1,
   3210                                      binop(Iop_Shr32,
   3211                                            binop(Iop_And32,
   3212                                                  getIReg(rt),
   3213                                                  mkU32(0x80000000)),
   3214                                            mkU8(31))));
   3215                      /* t7 holds abs(t4). */
   3216                      assign(t7, IRExpr_ITE(mkexpr(t5),
   3217                                            mkU16(0x7FFF),
   3218                                            IRExpr_ITE(mkexpr(t6),
   3219                                                       binop(Iop_Add16,
   3220                                                             unop(Iop_Not16,
   3221                                                                  mkexpr(t4)),
   3222                                                             mkU16(0x1)),
   3223                                                       mkexpr(t4))));
   3224                      /* If any of the two input halfwords is equal 0x8000,
   3225                         set bit 20 in DSPControl register. */
   3226                      assign(t8, binop(Iop_Or32,
   3227                                       unop(Iop_1Sto32, mkexpr(t5)),
   3228                                       unop(Iop_1Sto32, mkexpr(t1))));
   3229 
   3230                      putDSPControl(IRExpr_ITE(binop(Iop_CmpEQ32,
   3231                                                     mkexpr(t8),
   3232                                                     mkU32(0x0)),
   3233                                               getDSPControl(),
   3234                                               binop(Iop_Or32,
   3235                                                     getDSPControl(),
   3236                                                     mkU32(0x00100000))));
   3237 
   3238                      /* t9 = t7|t3 */
   3239                      assign(t9, binop(Iop_16HLto32, mkexpr(t7), mkexpr(t3)));
   3240 
   3241                      putIReg(rd, mkexpr(t9));
   3242                      break;
   3243                   }
   3244                   case 0xA: {  /* REPL.PH */
   3245                      DIP("repl.ph r%u, %u", rd, dsp_imm);
   3246                      vassert(!mode64);
   3247                      UShort immediate = extend_s_10to16(dsp_imm);
   3248 
   3249                      putIReg(rd, mkU32(immediate << 16 | immediate));
   3250                      break;
   3251                   }
   3252                   case 0xB: {  /* REPLV.PH */
   3253                      DIP("replv.ph r%u, r%u", rd, rt);
   3254                      vassert(!mode64);
   3255 
   3256                      putIReg(rd, binop(Iop_16HLto32,
   3257                                        unop(Iop_32to16, getIReg(rt)),
   3258                                        unop(Iop_32to16, getIReg(rt))));
   3259                      break;
   3260                   }
   3261                   case 0xC: {  /* PRECEQ.W.PHL */
   3262                      DIP("preceq.w.phl r%u, r%u", rd, rt);
   3263                      vassert(!mode64);
   3264                      putIReg(rd, binop(Iop_And32,
   3265                                        getIReg(rt),
   3266                                        mkU32(0xffff0000)));
   3267                      break;
   3268                   }
   3269                   case 0xD: {  /* PRECEQ.W.PHR */
   3270                      DIP("preceq.w.phr r%u, r%u", rd, rt);
   3271                      vassert(!mode64);
   3272                      putIReg(rd, binop(Iop_16HLto32,
   3273                                        unop(Iop_32to16, getIReg(rt)),
   3274                                        mkU16(0x0)));
   3275                      break;
   3276                   }
   3277                   case 0x11: {  /* ABSQ_S.W */
   3278                      DIP("absq_s.w r%u, r%u", rd, rt);
   3279                      vassert(!mode64);
   3280                      t0 = newTemp(Ity_I1);
   3281                      t1 = newTemp(Ity_I1);
   3282                      t2 = newTemp(Ity_I32);
   3283 
   3284                      assign(t0,
   3285                             binop(Iop_CmpEQ32, getIReg(rt), mkU32(0x80000000)));
   3286 
   3287                      putDSPControl(IRExpr_ITE(mkexpr(t0),
   3288                                               binop(Iop_Or32,
   3289                                                     getDSPControl(),
   3290                                                     mkU32(0x00100000)),
   3291                                               getDSPControl()));
   3292 
   3293                      assign(t1, binop(Iop_CmpLT32S, getIReg(rt), mkU32(0x0)));
   3294 
   3295                      assign(t2, IRExpr_ITE(mkexpr(t0),
   3296                                            mkU32(0x7FFFFFFF),
   3297                                            IRExpr_ITE(mkexpr(t1),
   3298                                                       binop(Iop_Add32,
   3299                                                             unop(Iop_Not32,
   3300                                                                  getIReg(rt)),
   3301                                                             mkU32(0x1)),
   3302                                                       getIReg(rt))));
   3303                      putIReg(rd, mkexpr(t2));
   3304                      break;
   3305                   }
   3306                   case 0x1B: {  /* BITREV */
   3307                      DIP("bitrev r%u, r%u", rd, rt);
   3308                      vassert(!mode64);
   3309                      /* 32bit reversal as seen on Bit Twiddling Hacks site
   3310                         http://graphics.stanford.edu/~seander/bithacks.html
   3311                         section ReverseParallel */
   3312                      t1 = newTemp(Ity_I32);
   3313                      t2 = newTemp(Ity_I32);
   3314                      t3 = newTemp(Ity_I32);
   3315                      t4 = newTemp(Ity_I32);
   3316                      t5 = newTemp(Ity_I32);
   3317 
   3318                      assign(t1, binop(Iop_Or32,
   3319                                       binop(Iop_Shr32,
   3320                                             binop(Iop_And32,
   3321                                                   getIReg(rt),
   3322                                                   mkU32(0xaaaaaaaa)),
   3323                                             mkU8(0x1)),
   3324                                       binop(Iop_Shl32,
   3325                                             binop(Iop_And32,
   3326                                                   getIReg(rt),
   3327                                                   mkU32(0x55555555)),
   3328                                             mkU8(0x1))));
   3329                      assign(t2, binop(Iop_Or32,
   3330                                       binop(Iop_Shr32,
   3331                                             binop(Iop_And32,
   3332                                                   mkexpr(t1),
   3333                                                   mkU32(0xcccccccc)),
   3334                                             mkU8(0x2)),
   3335                                       binop(Iop_Shl32,
   3336                                             binop(Iop_And32,
   3337                                                   mkexpr(t1),
   3338                                                   mkU32(0x33333333)),
   3339                                             mkU8(0x2))));
   3340                      assign(t3, binop(Iop_Or32,
   3341                                       binop(Iop_Shr32,
   3342                                             binop(Iop_And32,
   3343                                                   mkexpr(t2),
   3344                                                   mkU32(0xf0f0f0f0)),
   3345                                             mkU8(0x4)),
   3346                                       binop(Iop_Shl32,
   3347                                             binop(Iop_And32,
   3348                                                   mkexpr(t2),
   3349                                                   mkU32(0x0f0f0f0f)),
   3350                                             mkU8(0x4))));
   3351                      assign(t4, binop(Iop_Or32,
   3352                                       binop(Iop_Shr32,
   3353                                             binop(Iop_And32,
   3354                                                   mkexpr(t3),
   3355                                                   mkU32(0xff00ff00)),
   3356                                             mkU8(0x8)),
   3357                                       binop(Iop_Shl32,
   3358                                             binop(Iop_And32,
   3359                                                   mkexpr(t3),
   3360                                                   mkU32(0x00ff00ff)),
   3361                                             mkU8(0x8))));
   3362                      assign(t5, binop(Iop_Or32,
   3363                                       binop(Iop_Shr32,
   3364                                             mkexpr(t4),
   3365                                             mkU8(0x10)),
   3366                                       binop(Iop_Shl32,
   3367                                             mkexpr(t4),
   3368                                             mkU8(0x10))));
   3369                      putIReg(rd, binop(Iop_Shr32,
   3370                                        mkexpr(t5),
   3371                                        mkU8(16)));
   3372                      break;
   3373                   }
   3374                   case 0x1C: {  /* PRECEU.PH.QBL */
   3375                      DIP("preceu.ph.qbl r%u, r%u", rd, rt);
   3376                      vassert(!mode64);
   3377 
   3378                      putIReg(rd, binop(Iop_Or32,
   3379                                        binop(Iop_Shr32,
   3380                                              binop(Iop_And32,
   3381                                                    getIReg(rt),
   3382                                                    mkU32(0xff000000)),
   3383                                              mkU8(8)),
   3384                                        binop(Iop_Shr32,
   3385                                              binop(Iop_And32,
   3386                                                    getIReg(rt),
   3387                                                    mkU32(0x00ff0000)),
   3388                                              mkU8(16))));
   3389                      break;
   3390                   }
   3391                   case 0x1E: {  /* PRECEU.PH.QBLA */
   3392                      DIP("preceu.ph.qbla r%u, r%u", rd, rt);
   3393                      vassert(!mode64);
   3394 
   3395                      putIReg(rd, binop(Iop_Or32,
   3396                                        binop(Iop_Shr32,
   3397                                              binop(Iop_And32,
   3398                                                    getIReg(rt),
   3399                                                    mkU32(0xff000000)),
   3400                                              mkU8(8)),
   3401                                        binop(Iop_Shr32,
   3402                                              binop(Iop_And32,
   3403                                                    getIReg(rt),
   3404                                                    mkU32(0x0000ff00)),
   3405                                              mkU8(8))));
   3406                      break;
   3407                   }
   3408                   case 0x1D: {  /* PRECEU.PH.QBR */
   3409                      DIP("preceu.ph.qbr r%u, r%u", rd, rt);
   3410                      vassert(!mode64);
   3411 
   3412                      putIReg(rd, binop(Iop_Or32,
   3413                                        binop(Iop_Shl32,
   3414                                              binop(Iop_And32,
   3415                                                    getIReg(rt),
   3416                                                    mkU32(0x0000ff00)),
   3417                                              mkU8(8)),
   3418                                        binop(Iop_And32,
   3419                                              getIReg(rt),
   3420                                              mkU32(0x000000ff))));
   3421                      break;
   3422                   }
   3423                   case 0x1F: {  /* PRECEU.PH.QBRA */
   3424                      DIP("preceu.ph.qbra r%u, r%u", rd, rt);
   3425                      vassert(!mode64);
   3426 
   3427                      putIReg(rd, binop(Iop_Or32,
   3428                                        binop(Iop_And32,
   3429                                              getIReg(rt),
   3430                                              mkU32(0x00ff0000)),
   3431                                        binop(Iop_And32,
   3432                                              getIReg(rt),
   3433                                              mkU32(0x000000ff))));
   3434                      break;
   3435                   }
   3436                   default:
   3437                      return -1;
   3438                }
   3439                break;  /* end of ABSQ_S.PH */
   3440             }
   3441             case 0x38: {  /* EXTR.W */
   3442                switch(sa) {
   3443                   case 0x0: {  /* EXTR.W */
   3444                      DIP("extr.w r%u, ac%u, %u", rt, ac, rs);
   3445                      vassert(!mode64);
   3446                      t0 = newTemp(Ity_I64);
   3447                      t1 = newTemp(Ity_I64);
   3448                      t2 = newTemp(Ity_I32);
   3449                      t3 = newTemp(Ity_I1);
   3450                      t4 = newTemp(Ity_I1);
   3451                      t5 = newTemp(Ity_I1);
   3452                      t6 = newTemp(Ity_I1);
   3453                      t7 = newTemp(Ity_I32);
   3454                      t8 = newTemp(Ity_I64);
   3455                      t9 = newTemp(Ity_I64);
   3456                      t10 = newTemp(Ity_I1);
   3457                      t11 = newTemp(Ity_I1);
   3458                      t12 = newTemp(Ity_I1);
   3459                      t13 = newTemp(Ity_I1);
   3460                      t14 = newTemp(Ity_I32);
   3461 
   3462                      assign(t0, getAcc(ac));
   3463                      if (0 == rs) {
   3464                         assign(t1, mkexpr(t0));
   3465                      } else {
   3466                         assign(t1, binop(Iop_Sar64, mkexpr(t0), mkU8(rs)));
   3467                      }
   3468                      /* Check if bits 63..31 of the result in t1 aren't 0. */
   3469                      assign(t3, binop(Iop_CmpNE32,
   3470                                       unop(Iop_64HIto32,
   3471                                            mkexpr(t1)),
   3472                                       mkU32(0)));
   3473                      assign(t4, binop(Iop_CmpNE32,
   3474                                       binop(Iop_And32,
   3475                                             unop(Iop_64to32,
   3476                                                  mkexpr(t1)),
   3477                                             mkU32(0x80000000)),
   3478                                       mkU32(0)));
   3479                      /* Check if bits 63..31 of the result in t1 aren't
   3480                         0x1ffffffff. */
   3481                      assign(t5, binop(Iop_CmpNE32,
   3482                                       unop(Iop_64HIto32,
   3483                                            mkexpr(t1)),
   3484                                       mkU32(0xffffffff)));
   3485                      assign(t6, binop(Iop_CmpNE32,
   3486                                       binop(Iop_And32,
   3487                                             unop(Iop_64to32,
   3488                                                  mkexpr(t1)),
   3489                                             mkU32(0x80000000)),
   3490                                       mkU32(0x80000000)));
   3491                      /* If bits 63..31 aren't 0 nor 0x1ffffffff, set DSP
   3492                         control register. */
   3493                      assign(t7, binop(Iop_And32,
   3494                                       binop(Iop_Or32,
   3495                                             unop(Iop_1Sto32, mkexpr(t3)),
   3496                                             unop(Iop_1Sto32, mkexpr(t4))),
   3497                                       binop(Iop_Or32,
   3498                                             unop(Iop_1Sto32, mkexpr(t5)),
   3499                                             unop(Iop_1Sto32, mkexpr(t6)))));
   3500                      putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32,
   3501                                                     mkexpr(t7),
   3502                                                     mkU32(0)),
   3503                                               binop(Iop_Or32,
   3504                                                     getDSPControl(),
   3505                                                     mkU32(0x00800000)),
   3506                                               getDSPControl()));
   3507 
   3508                      /* If the last discarded bit is 1, there would be carry
   3509                         when rounding, otherwise there wouldn't. We use that
   3510                         fact and just add the value of the last discarded bit
   3511                         to the least sifgnificant bit of the shifted value
   3512                         from acc. */
   3513                      if (0 == rs) {
   3514                         assign(t8, mkU64(0x0ULL));
   3515                      } else {
   3516                         assign(t8, binop(Iop_And64,
   3517                                          binop(Iop_Shr64,
   3518                                                mkexpr(t0),
   3519                                                mkU8(rs-1)),
   3520                                          mkU64(0x1ULL)));
   3521                      }
   3522                      assign(t9, binop(Iop_Add64, mkexpr(t1), mkexpr(t8)));
   3523 
   3524                      /* Repeat previous steps for the rounded value. */
   3525                      assign(t10, binop(Iop_CmpNE32,
   3526                                       unop(Iop_64HIto32,
   3527                                            mkexpr(t9)),
   3528                                       mkU32(0)));
   3529                      assign(t11, binop(Iop_CmpNE32,
   3530                                       binop(Iop_And32,
   3531                                             unop(Iop_64to32,
   3532                                                  mkexpr(t9)),
   3533                                             mkU32(0x80000000)),
   3534                                       mkU32(0)));
   3535 
   3536                      assign(t12, binop(Iop_CmpNE32,
   3537                                       unop(Iop_64HIto32,
   3538                                            mkexpr(t9)),
   3539                                       mkU32(0xffffffff)));
   3540                      assign(t13, binop(Iop_CmpNE32,
   3541                                       binop(Iop_And32,
   3542                                             unop(Iop_64to32,
   3543                                                  mkexpr(t9)),
   3544                                             mkU32(0x80000000)),
   3545                                       mkU32(0x80000000)));
   3546 
   3547                      assign(t14, binop(Iop_And32,
   3548                                       binop(Iop_Or32,
   3549                                             unop(Iop_1Sto32, mkexpr(t10)),
   3550                                             unop(Iop_1Sto32, mkexpr(t11))),
   3551                                       binop(Iop_Or32,
   3552                                             unop(Iop_1Sto32, mkexpr(t12)),
   3553                                             unop(Iop_1Sto32, mkexpr(t13)))));
   3554                      putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32,
   3555                                                     mkexpr(t14),
   3556                                                     mkU32(0)),
   3557                                               binop(Iop_Or32,
   3558                                                     getDSPControl(),
   3559                                                     mkU32(0x00800000)),
   3560                                               getDSPControl()));
   3561                      if (0 == rs) {
   3562                         putIReg(rt, unop(Iop_64to32, mkexpr(t0)));
   3563                      } else {
   3564                         putIReg(rt, unop(Iop_64to32, mkexpr(t1)));
   3565                      }
   3566                      break;
   3567                   }
   3568                   case 0x1: {  /* EXTRV.W */
   3569                      DIP("extrv.w r%u, ac%u, r%u", rt, ac, rs);
   3570                      vassert(!mode64);
   3571                      t0 = newTemp(Ity_I64);
   3572                      t1 = newTemp(Ity_I64);
   3573                      t2 = newTemp(Ity_I32);
   3574                      t3 = newTemp(Ity_I1);
   3575                      t4 = newTemp(Ity_I1);
   3576                      t5 = newTemp(Ity_I1);
   3577                      t6 = newTemp(Ity_I1);
   3578                      t7 = newTemp(Ity_I32);
   3579                      t8 = newTemp(Ity_I64);
   3580                      t9 = newTemp(Ity_I64);
   3581                      t10 = newTemp(Ity_I1);
   3582                      t11 = newTemp(Ity_I1);
   3583                      t12 = newTemp(Ity_I1);
   3584                      t13 = newTemp(Ity_I1);
   3585                      t14 = newTemp(Ity_I32);
   3586                      t15 = newTemp(Ity_I8);
   3587 
   3588                      assign(t15, unop(Iop_32to8,
   3589                                       binop(Iop_And32,
   3590                                             getIReg(rs),
   3591                                             mkU32(0x1f))));
   3592                      assign(t0, getAcc(ac));
   3593                      assign(t1, binop(Iop_Sar64, mkexpr(t0), mkexpr(t15)));
   3594                      putIReg(rt, IRExpr_ITE(binop(Iop_CmpEQ32,
   3595                                                         unop(Iop_8Uto32,
   3596                                                              mkexpr(t15)),
   3597                                                         mkU32(0)),
   3598                                                   unop(Iop_64to32, mkexpr(t0)),
   3599                                                   unop(Iop_64to32, mkexpr(t1))));
   3600 
   3601                      /* Check if bits 63..31 of the result in t1 aren't 0. */
   3602                      assign(t3, binop(Iop_CmpNE32,
   3603                                       unop(Iop_64HIto32,
   3604                                            mkexpr(t1)),
   3605                                       mkU32(0)));
   3606                      assign(t4, binop(Iop_CmpNE32,
   3607                                       binop(Iop_And32,
   3608                                             unop(Iop_64to32,
   3609                                                  mkexpr(t1)),
   3610                                             mkU32(0x80000000)),
   3611                                       mkU32(0)));
   3612                      /* Check if bits 63..31 of the result in t1 aren't
   3613                         0x1ffffffff. */
   3614                      assign(t5, binop(Iop_CmpNE32,
   3615                                       unop(Iop_64HIto32,
   3616                                            mkexpr(t1)),
   3617                                       mkU32(0xffffffff)));
   3618                      assign(t6, binop(Iop_CmpNE32,
   3619                                       binop(Iop_And32,
   3620                                             unop(Iop_64to32,
   3621                                                  mkexpr(t1)),
   3622                                             mkU32(0x80000000)),
   3623                                       mkU32(0x80000000)));
   3624                      /* If bits 63..31 aren't 0 nor 0x1ffffffff, set DSP
   3625                         control register. */
   3626                      assign(t7, binop(Iop_And32,
   3627                                       binop(Iop_Or32,
   3628                                             unop(Iop_1Sto32, mkexpr(t3)),
   3629                                             unop(Iop_1Sto32, mkexpr(t4))),
   3630                                       binop(Iop_Or32,
   3631                                             unop(Iop_1Sto32, mkexpr(t5)),
   3632                                             unop(Iop_1Sto32, mkexpr(t6)))));
   3633                      putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32,
   3634                                                     mkexpr(t7),
   3635                                                     mkU32(0)),
   3636                                               binop(Iop_Or32,
   3637                                                     getDSPControl(),
   3638                                                     mkU32(0x00800000)),
   3639                                               getDSPControl()));
   3640 
   3641                      /* If the last discarded bit is 1, there would be carry
   3642                         when rounding, otherwise there wouldn't. We use that
   3643                         fact and just add the value of the last discarded bit
   3644                         to the least sifgnificant bit of the shifted value
   3645                         from acc. */
   3646                      assign(t8,
   3647                             IRExpr_ITE(binop(Iop_CmpEQ32,
   3648                                              unop(Iop_8Uto32,
   3649                                                   mkexpr(t15)),
   3650                                              mkU32(0)),
   3651                                        mkU64(0x0ULL),
   3652                                        binop(Iop_And64,
   3653                                              binop(Iop_Shr64,
   3654                                                    mkexpr(t0),
   3655                                                    unop(Iop_32to8,
   3656                                                         binop(Iop_Sub32,
   3657                                                               unop(Iop_8Uto32,
   3658                                                                    mkexpr(t15)),
   3659                                                                    mkU32(1)))),
   3660                                              mkU64(0x1ULL))));
   3661 
   3662                      assign(t9, binop(Iop_Add64, mkexpr(t1), mkexpr(t8)));
   3663 
   3664                      /* Repeat previous steps for the rounded value. */
   3665                      assign(t10, binop(Iop_CmpNE32,
   3666                                       unop(Iop_64HIto32,
   3667                                            mkexpr(t9)),
   3668                                       mkU32(0)));
   3669                      assign(t11, binop(Iop_CmpNE32,
   3670                                       binop(Iop_And32,
   3671                                             unop(Iop_64to32,
   3672                                                  mkexpr(t9)),
   3673                                             mkU32(0x80000000)),
   3674                                       mkU32(0)));
   3675 
   3676                      assign(t12, binop(Iop_CmpNE32,
   3677                                       unop(Iop_64HIto32,
   3678                                            mkexpr(t9)),
   3679                                       mkU32(0xffffffff)));
   3680                      assign(t13, binop(Iop_CmpNE32,
   3681                                       binop(Iop_And32,
   3682                                             unop(Iop_64to32,
   3683                                                  mkexpr(t9)),
   3684                                             mkU32(0x80000000)),
   3685                                       mkU32(0x80000000)));
   3686 
   3687                      assign(t14, binop(Iop_And32,
   3688                                       binop(Iop_Or32,
   3689                                             unop(Iop_1Sto32, mkexpr(t10)),
   3690                                             unop(Iop_1Sto32, mkexpr(t11))),
   3691                                       binop(Iop_Or32,
   3692                                             unop(Iop_1Sto32, mkexpr(t12)),
   3693                                             unop(Iop_1Sto32, mkexpr(t13)))));
   3694                      putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32,
   3695                                                     mkexpr(t14),
   3696                                                     mkU32(0)),
   3697                                               binop(Iop_Or32,
   3698                                                     getDSPControl(),
   3699                                                     mkU32(0x00800000)),
   3700                                               getDSPControl()));
   3701                      break;
   3702                   }
   3703                   case 0x2: {  /* EXTP */
   3704                      DIP("extp r%u, ac%u, %u", rt, ac, rs);
   3705                      vassert(!mode64);
   3706                      t0 = newTemp(Ity_I64);
   3707                      t1 = newTemp(Ity_I32);
   3708                      t2 = newTemp(Ity_I1);
   3709                      t3 = newTemp(Ity_I1);
   3710                      t4 = newTemp(Ity_I8);
   3711                      t5 = newTemp(Ity_I64);
   3712                      t6 = newTemp(Ity_I64);
   3713                      t7 = newTemp(Ity_I32);
   3714 
   3715                      assign(t0, getAcc(ac));
   3716                      /* Extract pos field of DSPControl register. */
   3717                      assign(t1, binop(Iop_And32, getDSPControl(), mkU32(0x3f)));
   3718 
   3719                      /* Check if (pos - size) >= 0 [size <= pos]
   3720                         if (pos < size)
   3721                            put 1 to EFI field of DSPControl register
   3722                         else
   3723                            extract bits from acc and put 0 to EFI field of
   3724                            DSPCtrl */
   3725                      assign(t2, binop(Iop_CmpLT32U, mkexpr(t1), mkU32(rs)));
   3726 
   3727                      putDSPControl(IRExpr_ITE(mkexpr(t2),
   3728                                               binop(Iop_Or32,
   3729                                                     binop(Iop_And32,
   3730                                                           getDSPControl(),
   3731                                                           mkU32(0xffffbfff)),
   3732                                                     mkU32(0x4000)),
   3733                                               binop(Iop_And32,
   3734                                                     getDSPControl(),
   3735                                                     mkU32(0xffffbfff))));
   3736 
   3737                      /* If pos <= 31, shift right the value from the acc
   3738                         (pos-size) times and take (size+1) bits from the least
   3739                         significant positions. Otherwise, shift left the value
   3740                         (63-pos) times, take (size+1) bits from the most
   3741                         significant positions and shift right (31-size) 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), mkU32(rs))),
   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                                                   mkU8(rs+1))),
   3766                                        unop(Iop_Not64,
   3767                                             binop(Iop_Shr64,
   3768                                                   mkU64(0xffffffffffffffffULL),
   3769                                                   mkU8(rs+1)))));
   3770 
   3771                      assign(t7, IRExpr_ITE(mkexpr(t3),
   3772                                            unop(Iop_64to32,
   3773                                                 binop(Iop_And64,
   3774                                                       mkexpr(t5),
   3775                                                       mkexpr(t6))),
   3776                                            binop(Iop_Shr32,
   3777                                                  unop(Iop_64HIto32,
   3778                                                       binop(Iop_And64,
   3779                                                             mkexpr(t5),
   3780                                                             mkexpr(t6))),
   3781                                                  mkU8(31-rs))));
   3782 
   3783                      putIReg(rt, mkexpr(t7));
   3784                      break;
   3785                   }
   3786                   case 0x3: {  /* EXTPV */
   3787                      DIP("extpv r%u, ac%u, r%u", rt, ac, rs);
   3788                      vassert(!mode64);
   3789                      t0 = newTemp(Ity_I64);
   3790                      t1 = newTemp(Ity_I32);
   3791                      t2 = newTemp(Ity_I1);
   3792                      t3 = newTemp(Ity_I1);
   3793                      t4 = newTemp(Ity_I8);
   3794                      t5 = newTemp(Ity_I64);
   3795                      t6 = newTemp(Ity_I64);
   3796                      t7 = newTemp(Ity_I32);
   3797                      t8 = newTemp(Ity_I32);
   3798 
   3799                      assign(t8, binop(Iop_And32, getIReg(rs), mkU32(0x1f)));
   3800                      assign(t0, getAcc(ac));
   3801                      /* Extract pos field of DSPControl register. */
   3802                      assign(t1, binop(Iop_And32, getDSPControl(), mkU32(0x3f)));
   3803 
   3804                      /* Check if (pos - size) >= 0 [size <= pos]
   3805                         if (pos < size)
   3806                            put 1 to EFI field of DSPControl register
   3807                         else
   3808                            extract bits from acc and put 0 to EFI field of
   3809                            DSPCtrl */
   3810                      assign(t2, binop(Iop_CmpLT32U, mkexpr(t1), mkexpr(t8)));
   3811 
   3812                      putDSPControl(IRExpr_ITE(mkexpr(t2),
   3813                                               binop(Iop_Or32,
   3814                                                     binop(Iop_And32,
   3815                                                           getDSPControl(),
   3816                                                           mkU32(0xffffbfff)),
   3817                                                     mkU32(0x4000)),
   3818                                               binop(Iop_And32,
   3819                                                     getDSPControl(),
   3820                                                     mkU32(0xffffbfff))));
   3821 
   3822                      /* If pos <= 31, shift right the value from the acc
   3823                         (pos-size) times and take (size+1) bits from the least
   3824                         significant positions. Otherwise, shift left the value
   3825                         (63-pos) times, take (size+1) bits from the most
   3826                         significant positions and shift right (31-size)
   3827                         times. */
   3828                      assign(t3, binop(Iop_CmpLE32U, mkexpr(t1), mkU32(31)));
   3829 
   3830                      assign(t4,
   3831                            IRExpr_ITE(mkexpr(t3),
   3832                                       unop(Iop_32to8,
   3833                                            binop(Iop_Sub32,
   3834                                                  mkexpr(t1), mkexpr(t8))),
   3835                                       unop(Iop_32to8,
   3836                                            binop(Iop_Sub32,
   3837                                                  mkU32(63), mkexpr(t1)))));
   3838 
   3839                      assign(t5, IRExpr_ITE(mkexpr(t3),
   3840                                            binop(Iop_Shr64,
   3841                                                  mkexpr(t0), mkexpr(t4)),
   3842                                            binop(Iop_Shl64,
   3843                                                  mkexpr(t0), mkexpr(t4))));
   3844 
   3845                      /* t6 holds a mask for bit extraction. */
   3846                      assign(t6,
   3847                             IRExpr_ITE(mkexpr(t3),
   3848                                        unop(Iop_Not64,
   3849                                             binop(Iop_Shl64,
   3850                                                   mkU64(0xffffffffffffffffULL),
   3851                                                   unop(Iop_32to8,
   3852                                                        binop(Iop_Add32,
   3853                                                              mkexpr(t8),
   3854                                                              mkU32(1))))),
   3855                                        unop(Iop_Not64,
   3856                                             binop(Iop_Shr64,
   3857                                                   mkU64(0xffffffffffffffffULL),
   3858                                                   unop(Iop_32to8,
   3859                                                        binop(Iop_Add32,
   3860                                                              mkexpr(t8),
   3861                                                              mkU32(1)))))));
   3862 
   3863                      assign(t7, IRExpr_ITE(mkexpr(t3),
   3864                                            unop(Iop_64to32,
   3865                                                 binop(Iop_And64,
   3866                                                       mkexpr(t5),
   3867                                                       mkexpr(t6))),
   3868                                            binop(Iop_Shr32,
   3869                                                  unop(Iop_64HIto32,
   3870                                                       binop(Iop_And64,
   3871                                                             mkexpr(t5),
   3872                                                             mkexpr(t6))),
   3873                                                  unop(Iop_32to8,
   3874                                                       binop(Iop_Sub32,
   3875                                                             mkU32(31),
   3876                                                             mkexpr(t8))))));
   3877 
   3878                      putIReg(rt, mkexpr(t7));
   3879                      break;
   3880                   }
   3881                   case 0x4: {  /* EXTR_R.W */
   3882                      DIP("extr_r.w r%u, ac%u, %u", rt, ac, rs);
   3883                      vassert(!mode64);
   3884                      t0 = newTemp(Ity_I64);
   3885                      t1 = newTemp(Ity_I64);
   3886                      t2 = newTemp(Ity_I32);
   3887                      t3 = newTemp(Ity_I1);
   3888                      t4 = newTemp(Ity_I1);
   3889                      t5 = newTemp(Ity_I1);
   3890                      t6 = newTemp(Ity_I1);
   3891                      t7 = newTemp(Ity_I32);
   3892                      t8 = newTemp(Ity_I64);
   3893                      t9 = newTemp(Ity_I64);
   3894                      t10 = newTemp(Ity_I1);
   3895                      t11 = newTemp(Ity_I1);
   3896                      t12 = newTemp(Ity_I1);
   3897                      t13 = newTemp(Ity_I1);
   3898                      t14 = newTemp(Ity_I32);
   3899                      t15 = newTemp(Ity_I64);
   3900                      t16 = newTemp(Ity_I1);
   3901 
   3902                      assign(t0, getAcc(ac));
   3903                      assign(t16, binop(Iop_CmpEQ32,
   3904                                        mkU32(rs),
   3905                                        mkU32(0)));
   3906                      assign(t1, IRExpr_ITE(mkexpr(t16),
   3907                                            mkexpr(t0),
   3908                                            binop(Iop_Sar64,
   3909                                                  mkexpr(t0),
   3910                                                  mkU8(rs))));
   3911                      /* If the last discarded bit is 1, there would be carry
   3912                         when rounding, otherwise there wouldn't. We use that
   3913                         fact and just add the value of the last discarded bit
   3914                         to the least significant bit of the shifted value
   3915                         from acc. */
   3916                      assign(t15, binop(Iop_Shr64,
   3917                                        mkexpr(t0),
   3918                                        unop(Iop_32to8,
   3919                                             binop(Iop_Sub32,
   3920                                                   binop(Iop_And32,
   3921                                                         mkU32(rs),
   3922                                                         mkU32(0x1f)),
   3923                                                   mkU32(1)))));
   3924 
   3925                      assign(t8,
   3926                             IRExpr_ITE(mkexpr(t16),
   3927                                        mkU64(0x0ULL),
   3928                                        binop(Iop_And64,
   3929                                              mkexpr(t15),
   3930                                              mkU64(0x0000000000000001ULL))));
   3931                      assign(t9, binop(Iop_Add64, mkexpr(t1), mkexpr(t8)));
   3932                      putIReg(rt, unop(Iop_64to32, mkexpr(t9)));
   3933 
   3934                      /* Check if bits 63..31 of the result in t1 aren't 0. */
   3935                      assign(t3, binop(Iop_CmpNE32,
   3936                                       unop(Iop_64HIto32,
   3937                                            mkexpr(t1)),
   3938                                       mkU32(0)));
   3939                      assign(t4, binop(Iop_CmpNE32,
   3940                                       binop(Iop_And32,
   3941                                             unop(Iop_64to32,
   3942                                                  mkexpr(t1)),
   3943                                             mkU32(0x80000000)),
   3944                                       mkU32(0)));
   3945 
   3946                      /* Check if bits 63..31 of the result in t1 aren't
   3947                         0x1ffffffff. */
   3948                      assign(t5, binop(Iop_CmpNE32,
   3949                                       unop(Iop_64HIto32,
   3950                                            mkexpr(t1)),
   3951                                       mkU32(0xffffffff)));
   3952                      assign(t6, binop(Iop_CmpNE32,
   3953                                       binop(Iop_And32,
   3954                                             unop(Iop_64to32,
   3955                                                  mkexpr(t1)),
   3956                                             mkU32(0x80000000)),
   3957                                       mkU32(0x80000000)));
   3958                      /* If bits 63..31 aren't 0 nor 0x1ffffffff, set DSP
   3959                         control register. */
   3960                      assign(t7, binop(Iop_And32,
   3961                                       binop(Iop_Or32,
   3962                                             unop(Iop_1Sto32, mkexpr(t3)),
   3963                                             unop(Iop_1Sto32, mkexpr(t4))),
   3964                                       binop(Iop_Or32,
   3965                                             unop(Iop_1Sto32, mkexpr(t5)),
   3966                                             unop(Iop_1Sto32, mkexpr(t6)))));
   3967                      putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32,
   3968                                                     mkexpr(t7),
   3969                                                     mkU32(0)),
   3970                                               binop(Iop_Or32,
   3971                                                     getDSPControl(),
   3972                                                     mkU32(0x00800000)),
   3973                                               getDSPControl()));
   3974 
   3975                      /* Repeat previous steps for the rounded value. */
   3976                      assign(t10, binop(Iop_CmpNE32,
   3977                                       unop(Iop_64HIto32,
   3978                                            mkexpr(t9)),
   3979                                       mkU32(0)));
   3980                      assign(t11, binop(Iop_CmpNE32,
   3981                                       binop(Iop_And32,
   3982                                             unop(Iop_64to32,
   3983                                                  mkexpr(t9)),
   3984                                             mkU32(0x80000000)),
   3985                                       mkU32(0)));
   3986 
   3987                      assign(t12, binop(Iop_CmpNE32,
   3988                                       unop(Iop_64HIto32,
   3989                                            mkexpr(t9)),
   3990                                       mkU32(0xffffffff)));
   3991                      assign(t13, binop(Iop_CmpNE32,
   3992                                       binop(Iop_And32,
   3993                                             unop(Iop_64to32,
   3994                                                  mkexpr(t9)),
   3995                                             mkU32(0x80000000)),
   3996                                       mkU32(0x80000000)));
   3997 
   3998                      assign(t14, binop(Iop_And32,
   3999                                       binop(Iop_Or32,
   4000                                             unop(Iop_1Sto32, mkexpr(t10)),
   4001                                             unop(Iop_1Sto32, mkexpr(t11))),
   4002                                       binop(Iop_Or32,
   4003                                             unop(Iop_1Sto32, mkexpr(t12)),
   4004                                             unop(Iop_1Sto32, mkexpr(t13)))));
   4005                      putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32,
   4006                                                     mkexpr(t14),
   4007                                                     mkU32(0)),
   4008                                               binop(Iop_Or32,
   4009                                                     getDSPControl(),
   4010                                                     mkU32(0x00800000)),
   4011                                               getDSPControl()));
   4012                      break;
   4013                   }
   4014                   case 0x5: {  /* EXTRV_R.W */
   4015                      DIP("extrv_r.w r%u, ac%u, r%u", rt, ac, rs);
   4016                      vassert(!mode64);
   4017                      t0 = newTemp(Ity_I64);
   4018                      t1 = newTemp(Ity_I64);
   4019                      t2 = newTemp(Ity_I32);
   4020                      t3 = newTemp(Ity_I1);
   4021                      t4 = newTemp(Ity_I1);
   4022                      t5 = newTemp(Ity_I1);
   4023                      t6 = newTemp(Ity_I1);
   4024                      t7 = newTemp(Ity_I32);
   4025                      t8 = newTemp(Ity_I64);
   4026                      t9 = newTemp(Ity_I64);
   4027                      t10 = newTemp(Ity_I1);
   4028                      t11 = newTemp(Ity_I1);
   4029                      t12 = newTemp(Ity_I1);
   4030                      t13 = newTemp(Ity_I1);
   4031                      t14 = newTemp(Ity_I32);
   4032                      t15 = newTemp(Ity_I8);
   4033 
   4034                      assign(t15, unop(Iop_32to8,
   4035                                       binop(Iop_And32,
   4036                                             getIReg(rs),
   4037                                             mkU32(0x1f))));
   4038                      assign(t0, getAcc(ac));
   4039                      assign(t1, binop(Iop_Sar64, mkexpr(t0), mkexpr(t15)));
   4040 
   4041                      /* Check if bits 63..31 of the result in t1 aren't 0. */
   4042                      assign(t3, binop(Iop_CmpNE32,
   4043                                       unop(Iop_64HIto32,
   4044                                            mkexpr(t1)),
   4045                                       mkU32(0)));
   4046                      assign(t4, binop(Iop_CmpNE32,
   4047                                       binop(Iop_And32,
   4048                                             unop(Iop_64to32,
   4049                                                  mkexpr(t1)),
   4050                                             mkU32(0x80000000)),
   4051                                       mkU32(0)));
   4052                      /* Check if bits 63..31 of the result in t1 aren't
   4053                         0x1ffffffff. */
   4054                      assign(t5, binop(Iop_CmpNE32,
   4055                                       unop(Iop_64HIto32,
   4056                                            mkexpr(t1)),
   4057                                       mkU32(0xffffffff)));
   4058                      assign(t6, binop(Iop_CmpNE32,
   4059                                       binop(Iop_And32,
   4060                                             unop(Iop_64to32,
   4061                                                  mkexpr(t1)),
   4062                                             mkU32(0x80000000)),
   4063                                       mkU32(0x80000000)));
   4064                      /* If bits 63..31 aren't 0 nor 0x1ffffffff, set DSP
   4065                         control register. */
   4066                      assign(t7, binop(Iop_And32,
   4067                                       binop(Iop_Or32,
   4068                                             unop(Iop_1Sto32, mkexpr(t3)),
   4069                                             unop(Iop_1Sto32, mkexpr(t4))),
   4070                                       binop(Iop_Or32,
   4071                                             unop(Iop_1Sto32, mkexpr(t5)),
   4072                                             unop(Iop_1Sto32, mkexpr(t6)))));
   4073                      putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32,
   4074                                                     mkexpr(t7),
   4075                                                     mkU32(0)),
   4076                                               binop(Iop_Or32,
   4077                                                     getDSPControl(),
   4078                                                     mkU32(0x00800000)),
   4079                                               getDSPControl()));
   4080 
   4081                      /* If the last discarded bit is 1, there would be carry
   4082                         when rounding, otherwise there wouldn't. We use that
   4083                         fact and just add the value of the last discarded bit
   4084                         to the least sifgnificant bit of the shifted value
   4085                         from acc. */
   4086                      assign(t8,
   4087                             IRExpr_ITE(binop(Iop_CmpEQ32,
   4088                                              unop(Iop_8Uto32,
   4089                                                   mkexpr(t15)),
   4090                                              mkU32(0)),
   4091                                        mkU64(0x0ULL),
   4092                                        binop(Iop_And64,
   4093                                              binop(Iop_Shr64,
   4094                                                    mkexpr(t0),
   4095                                                    unop(Iop_32to8,
   4096                                                         binop(Iop_Sub32,
   4097                                                               unop(Iop_8Uto32,
   4098                                                                    mkexpr(t15)),
   4099                                                                    mkU32(1)))),
   4100                                              mkU64(0x1ULL))));
   4101 
   4102                      assign(t9, binop(Iop_Add64, mkexpr(t1), mkexpr(t8)));
   4103                      /* Put rounded value in destination register. */
   4104                      putIReg(rt, unop(Iop_64to32, mkexpr(t9)));
   4105 
   4106                      /* Repeat previous steps for the rounded value. */
   4107                      assign(t10, binop(Iop_CmpNE32,
   4108                                       unop(Iop_64HIto32,
   4109                                            mkexpr(t9)),
   4110                                       mkU32(0)));
   4111                      assign(t11, binop(Iop_CmpNE32,
   4112                                       binop(Iop_And32,
   4113                                             unop(Iop_64to32,
   4114                                                  mkexpr(t9)),
   4115                                             mkU32(0x80000000)),
   4116                                       mkU32(0)));
   4117 
   4118                      assign(t12, binop(Iop_CmpNE32,
   4119                                       unop(Iop_64HIto32,
   4120                                            mkexpr(t9)),
   4121                                       mkU32(0xffffffff)));
   4122                      assign(t13, binop(Iop_CmpNE32,
   4123                                       binop(Iop_And32,
   4124                                             unop(Iop_64to32,
   4125                                                  mkexpr(t9)),
   4126                                             mkU32(0x80000000)),
   4127                                       mkU32(0x80000000)));
   4128 
   4129                      assign(t14, binop(Iop_And32,
   4130                                       binop(Iop_Or32,
   4131                                             unop(Iop_1Sto32, mkexpr(t10)),
   4132                                             unop(Iop_1Sto32, mkexpr(t11))),
   4133                                       binop(Iop_Or32,
   4134                                             unop(Iop_1Sto32, mkexpr(t12)),
   4135                                             unop(Iop_1Sto32, mkexpr(t13)))));
   4136                      putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32,
   4137                                                     mkexpr(t14),
   4138                                                     mkU32(0)),
   4139                                               binop(Iop_Or32,
   4140                                                     getDSPControl(),
   4141                                                     mkU32(0x00800000)),
   4142                                               getDSPControl()));
   4143                      break;
   4144                   }
   4145                   case 0x6: {  /* EXTR_RS.W */
   4146                      DIP("extr_rs.w r%u, ac%u, %u", rt, ac, rs);
   4147                      vassert(!mode64);
   4148                      t0 = newTemp(Ity_I64);
   4149                      t1 = newTemp(Ity_I64);
   4150                      t2 = newTemp(Ity_I32);
   4151                      t3 = newTemp(Ity_I1);
   4152                      t4 = newTemp(Ity_I1);
   4153                      t5 = newTemp(Ity_I1);
   4154                      t6 = newTemp(Ity_I1);
   4155                      t7 = newTemp(Ity_I32);
   4156                      t8 = newTemp(Ity_I64);
   4157                      t9 = newTemp(Ity_I64);
   4158                      t10 = newTemp(Ity_I1);
   4159                      t11 = newTemp(Ity_I1);
   4160                      t12 = newTemp(Ity_I1);
   4161                      t13 = newTemp(Ity_I1);
   4162                      t14 = newTemp(Ity_I32);
   4163                      t16 = newTemp(Ity_I32);
   4164 
   4165                      assign(t0, getAcc(ac));
   4166                      if (0 == rs) {
   4167                         assign(t1, mkexpr(t0));
   4168                      } else {
   4169                         assign(t1, binop(Iop_Sar64, mkexpr(t0), mkU8(rs)));
   4170                      }
   4171 
   4172                      /* Check if bits 63..31 of the result in t1 aren't 0. */
   4173                      assign(t3, binop(Iop_CmpNE32,
   4174                                       unop(Iop_64HIto32,
   4175                                            mkexpr(t1)),
   4176                                       mkU32(0)));
   4177                      assign(t4, binop(Iop_CmpNE32,
   4178                                       binop(Iop_And32,
   4179                                             unop(Iop_64to32,
   4180                                                  mkexpr(t1)),
   4181                                             mkU32(0x80000000)),
   4182                                       mkU32(0)));
   4183                      /* Check if bits 63..31 of the result in t1 aren't
   4184                         0x1ffffffff. */
   4185                      assign(t5, binop(Iop_CmpNE32,
   4186                                       unop(Iop_64HIto32,
   4187                                            mkexpr(t1)),
   4188                                       mkU32(0xffffffff)));
   4189                      assign(t6, binop(Iop_CmpNE32,
   4190                                       binop(Iop_And32,
   4191                                             unop(Iop_64to32,
   4192                                                  mkexpr(t1)),
   4193                                             mkU32(0x80000000)),
   4194                                       mkU32(0x80000000)));
   4195                      /* If bits 63..31 aren't 0 nor 0x1ffffffff, set DSP
   4196                         control register. */
   4197                      assign(t7, binop(Iop_And32,
   4198                                       binop(Iop_Or32,
   4199                                             unop(Iop_1Sto32, mkexpr(t3)),
   4200                                             unop(Iop_1Sto32, mkexpr(t4))),
   4201                                       binop(Iop_Or32,
   4202                                             unop(Iop_1Sto32, mkexpr(t5)),
   4203                                             unop(Iop_1Sto32, mkexpr(t6)))));
   4204                      putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32,
   4205                                                     mkexpr(t7),
   4206                                                     mkU32(0)),
   4207                                               binop(Iop_Or32,
   4208                                                     getDSPControl(),
   4209                                                     mkU32(0x00800000)),
   4210                                               getDSPControl()));
   4211 
   4212                      /* If the last discarded bit is 1, there would be carry
   4213                         when rounding, otherwise there wouldn't. We use that
   4214                         fact and just add the value of the last discarded bit
   4215                         to the least sifgnificant bit of the shifted value
   4216                         from acc. */
   4217                      if (0 == rs) {
   4218                         assign(t8, mkU64(0x0ULL));
   4219                      } else {
   4220                         assign(t8, binop(Iop_And64,
   4221                                          binop(Iop_Shr64,
   4222                                                mkexpr(t0),
   4223                                                mkU8(rs-1)),
   4224                                          mkU64(0x1ULL)));
   4225                      }
   4226 
   4227                      assign(t9, binop(Iop_Add64, mkexpr(t1), mkexpr(t8)));
   4228 
   4229                      /* Repeat previous steps for the rounded value. */
   4230                      assign(t10, binop(Iop_CmpNE32,
   4231                                       unop(Iop_64HIto32,
   4232                                            mkexpr(t9)),
   4233                                       mkU32(0)));
   4234                      assign(t11, binop(Iop_CmpNE32,
   4235                                       binop(Iop_And32,
   4236                                             unop(Iop_64to32,
   4237                                                  mkexpr(t9)),
   4238                                             mkU32(0x80000000)),
   4239                                       mkU32(0)));
   4240 
   4241                      assign(t12, binop(Iop_CmpNE32,
   4242                                       unop(Iop_64HIto32,
   4243                                            mkexpr(t9)),
   4244                                       mkU32(0xffffffff)));
   4245                      assign(t13, binop(Iop_CmpNE32,
   4246                                       binop(Iop_And32,
   4247                                             unop(Iop_64to32,
   4248                                                  mkexpr(t9)),
   4249                                             mkU32(0x80000000)),
   4250                                       mkU32(0x80000000)));
   4251 
   4252                      assign(t14, binop(Iop_And32,
   4253                                       binop(Iop_Or32,
   4254                                             unop(Iop_1Sto32, mkexpr(t10)),
   4255                                             unop(Iop_1Sto32, mkexpr(t11))),
   4256                                       binop(Iop_Or32,
   4257                                             unop(Iop_1Sto32, mkexpr(t12)),
   4258                                             unop(Iop_1Sto32, mkexpr(t13)))));
   4259                      putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32,
   4260                                                     mkexpr(t14),
   4261                                                     mkU32(0)),
   4262                                               binop(Iop_Or32,
   4263                                                     getDSPControl(),
   4264                                                     mkU32(0x00800000)),
   4265                                               getDSPControl()));
   4266 
   4267                      assign(t16, binop(Iop_And32,
   4268                                        unop(Iop_64HIto32,
   4269                                             mkexpr(t9)),
   4270                                        mkU32(0x80000000)));
   4271                      putIReg(rt, IRExpr_ITE(binop(Iop_CmpNE32,
   4272                                                   mkexpr(t14),
   4273                                                   mkU32(0)),
   4274                                             IRExpr_ITE(binop(Iop_CmpEQ32,
   4275                                                              mkexpr(t16),
   4276                                                              mkU32(0)),
   4277                                                        mkU32(0x7fffffff),
   4278                                                        mkU32(0x80000000)),
   4279                                             unop(Iop_64to32, mkexpr(t9))));
   4280                      break;
   4281                   }
   4282                   case 0x7: {  /* EXTRV_RS.W */
   4283                      DIP("extrv_rs.w r%u, ac%u, r%u", rt, ac, rs);
   4284                      vassert(!mode64);
   4285                      t0 = newTemp(Ity_I64);
   4286                      t1 = newTemp(Ity_I64);
   4287                      t2 = newTemp(Ity_I32);
   4288                      t3 = newTemp(Ity_I1);
   4289                      t4 = newTemp(Ity_I1);
   4290                      t5 = newTemp(Ity_I1);
   4291                      t6 = newTemp(Ity_I1);
   4292                      t7 = newTemp(Ity_I32);
   4293                      t8 = newTemp(Ity_I64);
   4294                      t9 = newTemp(Ity_I64);
   4295                      t10 = newTemp(Ity_I1);
   4296                      t11 = newTemp(Ity_I1);
   4297                      t12 = newTemp(Ity_I1);
   4298                      t13 = newTemp(Ity_I1);
   4299                      t14 = newTemp(Ity_I32);
   4300                      t15 = newTemp(Ity_I32);
   4301                      t16 = newTemp(Ity_I32);
   4302                      t17 = newTemp(Ity_I1);
   4303 
   4304                      assign(t15, binop(Iop_And32,
   4305                                        getIReg(rs),
   4306                                        mkU32(0x1f)));
   4307                      assign(t17, binop(Iop_CmpEQ32,
   4308                                        mkexpr(t15),
   4309                                        mkU32(0)));
   4310                      assign(t0, getAcc(ac));
   4311                      assign(t1, IRExpr_ITE(mkexpr(t17),
   4312                                            mkexpr(t0),
   4313                                            binop(Iop_Sar64,
   4314                                                  mkexpr(t0),
   4315                                                  unop(Iop_32to8,
   4316                                                       mkexpr(t15)))));
   4317 
   4318                      /* Check if bits 63..31 of the result in t1 aren't 0. */
   4319                      assign(t3, binop(Iop_CmpNE32,
   4320                                       unop(Iop_64HIto32,
   4321                                            mkexpr(t1)),
   4322                                       mkU32(0)));
   4323                      assign(t4, binop(Iop_CmpNE32,
   4324                                       binop(Iop_And32,
   4325                                             unop(Iop_64to32,
   4326                                                  mkexpr(t1)),
   4327                                             mkU32(0x80000000)),
   4328                                       mkU32(0)));
   4329                      /* Check if bits 63..31 of the result in t1 aren't
   4330                         0x1ffffffff. */
   4331                      assign(t5, binop(Iop_CmpNE32,
   4332                                       unop(Iop_64HIto32,
   4333                                            mkexpr(t1)),
   4334                                       mkU32(0xffffffff)));
   4335                      assign(t6, binop(Iop_CmpNE32,
   4336                                       binop(Iop_And32,
   4337                                             unop(Iop_64to32,
   4338                                                  mkexpr(t1)),
   4339                                             mkU32(0x80000000)),
   4340                                       mkU32(0x80000000)));
   4341                      /* If bits 63..31 aren't 0 nor 0x1ffffffff, set DSP
   4342                         control register. */
   4343                      assign(t7, binop(Iop_And32,
   4344                                       binop(Iop_Or32,
   4345                                             unop(Iop_1Sto32, mkexpr(t3)),
   4346                                             unop(Iop_1Sto32, mkexpr(t4))),
   4347                                       binop(Iop_Or32,
   4348                                             unop(Iop_1Sto32, mkexpr(t5)),
   4349                                             unop(Iop_1Sto32, mkexpr(t6)))));
   4350                      putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32,
   4351                                                     mkexpr(t7),
   4352                                                     mkU32(0)),
   4353                                               binop(Iop_Or32,
   4354                                                     getDSPControl(),
   4355                                                     mkU32(0x00800000)),
   4356                                               getDSPControl()));
   4357 
   4358                      /* If the last discarded bit is 1, there would be carry
   4359                         when rounding, otherwise there wouldn't. We use that
   4360                         fact and just add the value of the last discarded bit
   4361                         to the least sifgnificant bit of the shifted value
   4362                         from acc. */
   4363                      assign(t8,
   4364                             IRExpr_ITE(mkexpr(t17),
   4365                                        mkU64(0x0ULL),
   4366                                        binop(Iop_And64,
   4367                                              binop(Iop_Shr64,
   4368                                                    mkexpr(t0),
   4369                                                    unop(Iop_32to8,
   4370                                                         binop(Iop_Sub32,
   4371                                                               mkexpr(t15),
   4372                                                               mkU32(1)))),
   4373                                              mkU64(0x1ULL))));
   4374 
   4375                      assign(t9, binop(Iop_Add64, mkexpr(t1), mkexpr(t8)));
   4376 
   4377                      /* Repeat previous steps for the rounded value. */
   4378                      assign(t10, binop(Iop_CmpNE32,
   4379                                       unop(Iop_64HIto32,
   4380                                            mkexpr(t9)),
   4381                                       mkU32(0)));
   4382                      assign(t11, binop(Iop_CmpNE32,
   4383                                       binop(Iop_And32,
   4384                                             unop(Iop_64to32,
   4385                                                  mkexpr(t9)),
   4386                                             mkU32(0x80000000)),
   4387                                       mkU32(0)));
   4388 
   4389                      assign(t12, binop(Iop_CmpNE32,
   4390                                       unop(Iop_64HIto32,
   4391                                            mkexpr(t9)),
   4392                                       mkU32(0xffffffff)));
   4393                      assign(t13, binop(Iop_CmpNE32,
   4394                                       binop(Iop_And32,
   4395                                             unop(Iop_64to32,
   4396                                                  mkexpr(t9)),
   4397                                             mkU32(0x80000000)),
   4398                                       mkU32(0x80000000)));
   4399 
   4400                      assign(t14, binop(Iop_And32,
   4401                                       binop(Iop_Or32,
   4402                                             unop(Iop_1Sto32, mkexpr(t10)),
   4403                                             unop(Iop_1Sto32, mkexpr(t11))),
   4404                                       binop(Iop_Or32,
   4405                                             unop(Iop_1Sto32, mkexpr(t12)),
   4406                                             unop(Iop_1Sto32, mkexpr(t13)))));
   4407                      putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32,
   4408                                                     mkexpr(t14),
   4409                                                     mkU32(0)),
   4410                                               binop(Iop_Or32,
   4411                                                     getDSPControl(),
   4412                                                     mkU32(0x00800000)),
   4413                                               getDSPControl()));
   4414 
   4415                      assign(t16, binop(Iop_And32,
   4416                                        unop(Iop_64HIto32,
   4417                                             mkexpr(t9)),
   4418                                        mkU32(0x80000000)));
   4419                      putIReg(rt, IRExpr_ITE(binop(Iop_CmpNE32,
   4420                                                   mkexpr(t14),
   4421                                                   mkU32(0)),
   4422                                             IRExpr_ITE(binop(Iop_CmpEQ32,
   4423                                                              mkexpr(t16),
   4424                                                              mkU32(0)),
   4425                                                        mkU32(0x7fffffff),
   4426                                                        mkU32(0x80000000)),
   4427                                             unop(Iop_64to32, mkexpr(t9))));
   4428                      break;
   4429                   }
   4430                   case 0xA: {  /* EXTPDP */
   4431                      DIP("extpdp r%u, ac%u, %u", rt, ac, rs);
   4432                      vassert(!mode64);
   4433                      t0 = newTemp(Ity_I64);
   4434                      t1 = newTemp(Ity_I32);
   4435                      t2 = newTemp(Ity_I1);
   4436                      t3 = newTemp(Ity_I1);
   4437                      t4 = newTemp(Ity_I8);
   4438                      t5 = newTemp(Ity_I64);
   4439                      t6 = newTemp(Ity_I64);
   4440                      t7 = newTemp(Ity_I32);
   4441                      t8 = newTemp(Ity_I32);
   4442 
   4443                      assign(t0, getAcc(ac));
   4444                      /* Extract pos field of DSPControl register. */
   4445                      assign(t1, binop(Iop_And32, getDSPControl(), mkU32(0x3f)));
   4446 
   4447                      /* Check if (pos - size) >= 0 [size <= pos]
   4448                         if (pos < size)
   4449                            put 1 to EFI field of DSPControl register
   4450                         else
   4451                            extract bits from acc and put 0 to EFI field of
   4452                            DSPCtrl */
   4453                      assign(t2, binop(Iop_CmpLT32U, mkexpr(t1), mkU32(rs)));
   4454 
   4455                      assign(t8, binop(Iop_Or32,
   4456                                       binop(Iop_And32,
   4457                                             getDSPControl(),
   4458                                             mkU32(0xffffbfc0)),
   4459                                       binop(Iop_And32,
   4460                                             binop(Iop_Sub32,
   4461                                                   binop(Iop_And32,
   4462                                                         getDSPControl(),
   4463                                                         mkU32(0x3f)),
   4464                                                   mkU32(rs+1)),
   4465                                             mkU32(0x3f))));
   4466                      putDSPControl(IRExpr_ITE(mkexpr(t2),
   4467                                               binop(Iop_Or32,
   4468                                                      binop(Iop_And32,
   4469                                                            getDSPControl(),
   4470                                                            mkU32(0xffffbfff)),
   4471                                                      mkU32(0x4000)),
   4472                                               mkexpr(t8)));
   4473 
   4474                      /* If pos <= 31, shift right the value from the acc
   4475                         (pos-size) times and take (size+1) bits from the least
   4476                         significant positions. Otherwise, shift left the value
   4477                         (63-pos) times, take (size+1) bits from the most
   4478                         significant positions and shift right (31-size) times.
   4479                      */
   4480                      assign(t3, binop(Iop_CmpLE32U, mkexpr(t1), mkU32(31)));
   4481 
   4482                      assign(t4,
   4483                             IRExpr_ITE(mkexpr(t3),
   4484                                        unop(Iop_32to8,
   4485                                             binop(Iop_Sub32,
   4486                                                   mkexpr(t1), mkU32(rs))),
   4487                                        unop(Iop_32to8,
   4488                                             binop(Iop_Sub32,
   4489                                                   mkU32(63), mkexpr(t1)))));
   4490 
   4491                      assign(t5, IRExpr_ITE(mkexpr(t3),
   4492                                            binop(Iop_Shr64,
   4493                                                  mkexpr(t0), mkexpr(t4)),
   4494                                            binop(Iop_Shl64,
   4495                                                  mkexpr(t0), mkexpr(t4))));
   4496 
   4497                      /* t6 holds a mask for bit extraction. */
   4498                      assign(t6,
   4499                             IRExpr_ITE(mkexpr(t3),
   4500                                        unop(Iop_Not64,
   4501                                             binop(Iop_Shl64,
   4502                                                   mkU64(0xffffffffffffffffULL),
   4503                                                   mkU8(rs+1))),
   4504                                        unop(Iop_Not64,
   4505                                             binop(Iop_Shr64,
   4506                                                   mkU64(0xffffffffffffffffULL),
   4507                                                   mkU8(rs+1)))));
   4508 
   4509                      assign(t7, IRExpr_ITE(mkexpr(t3),
   4510                                            unop(Iop_64to32,
   4511                                                 binop(Iop_And64,
   4512                                                       mkexpr(t5),
   4513                                                       mkexpr(t6))),
   4514                                            binop(Iop_Shr32,
   4515                                                  unop(Iop_64HIto32,
   4516                                                       binop(Iop_And64,
   4517                                                             mkexpr(t5),
   4518                                                             mkexpr(t6))),
   4519                                                  mkU8(31-rs))));
   4520 
   4521                      putIReg(rt, mkexpr(t7));
   4522                      break;
   4523                   }
   4524                   case 0xB: {  /* EXTPDPV */
   4525                      DIP("extpdpv r%u, ac%u, r%u", rt, ac, rs);
   4526                      vassert(!mode64);
   4527                      t0 = newTemp(Ity_I64);
   4528                      t1 = newTemp(Ity_I32);
   4529                      t2 = newTemp(Ity_I1);
   4530                      t3 = newTemp(Ity_I1);
   4531                      t4 = newTemp(Ity_I8);
   4532                      t5 = newTemp(Ity_I64);
   4533                      t6 = newTemp(Ity_I64);
   4534                      t7 = newTemp(Ity_I32);
   4535                      t8 = newTemp(Ity_I32);
   4536                      t9 = newTemp(Ity_I32);
   4537 
   4538                      assign(t8, binop(Iop_And32, getIReg(rs), mkU32(0x1f)));
   4539                      assign(t0, getAcc(ac));
   4540                      /* Extract pos field of DSPControl register. */
   4541                      assign(t1, binop(Iop_And32, getDSPControl(), mkU32(0x3f)));
   4542 
   4543                      /* Check if (pos - size) >= 0 [size <= pos]
   4544                         if (pos < size)
   4545                            put 1 to EFI field of DSPControl register
   4546                         else
   4547                            extract bits from acc and put 0 to EFI field of
   4548                            DSPCtrl */
   4549                      assign(t2, binop(Iop_CmpLT32U, mkexpr(t1), mkexpr(t8)));
   4550 
   4551                      assign(t9, binop(Iop_Or32,
   4552                                       binop(Iop_And32,
   4553                                             getDSPControl(),
   4554                                             mkU32(0xffffbfc0)),
   4555                                       binop(Iop_And32,
   4556                                             binop(Iop_Sub32,
   4557                                                   binop(Iop_And32,
   4558                                                         getDSPControl(),
   4559                                                         mkU32(0x3f)),
   4560                                                   binop(Iop_Add32,
   4561                                                         mkexpr(t8),
   4562                                                         mkU32(0x1))),
   4563                                             mkU32(0x3f))));
   4564                      putDSPControl(IRExpr_ITE(mkexpr(t2),
   4565                                               binop(Iop_Or32,
   4566                                                     binop(Iop_And32,
   4567                                                           getDSPControl(),
   4568                                                           mkU32(0xffffbfff)),
   4569                                                     mkU32(0x4000)),
   4570                                               mkexpr(t9)));
   4571 
   4572                      /* If pos <= 31, shift right the value from the acc
   4573                         (pos-size) times and take (size+1) bits from the least
   4574                         significant positions. Otherwise, shift left the value
   4575                         (63-pos) times, take (size+1) bits from the most
   4576                         significant positions and shift right (31-size) times.
   4577                      */
   4578                      assign(t3, binop(Iop_CmpLE32U, mkexpr(t1), mkU32(31)));
   4579 
   4580                      assign(t4,
   4581                             IRExpr_ITE(mkexpr(t3),
   4582                                       unop(Iop_32to8,
   4583                                            binop(Iop_Sub32,
   4584                                                  mkexpr(t1), mkexpr(t8))),
   4585                                       unop(Iop_32to8,
   4586                                            binop(Iop_Sub32,
   4587                                                  mkU32(63), mkexpr(t1)))));
   4588 
   4589                      assign(t5, IRExpr_ITE(mkexpr(t3),
   4590                                            binop(Iop_Shr64,
   4591                                                  mkexpr(t0), mkexpr(t4)),
   4592                                            binop(Iop_Shl64,
   4593                                                  mkexpr(t0), mkexpr(t4))));
   4594 
   4595                      /* t6 holds a mask for bit extraction. */
   4596                      assign(t6,
   4597                             IRExpr_ITE(mkexpr(t3),
   4598                                        unop(Iop_Not64,
   4599                                             binop(Iop_Shl64,
   4600                                                   mkU64(0xffffffffffffffffULL),
   4601                                                   unop(Iop_32to8,
   4602                                                        binop(Iop_Add32,
   4603                                                              mkexpr(t8),
   4604                                                              mkU32(1))))),
   4605                                        unop(Iop_Not64,
   4606                                             binop(Iop_Shr64,
   4607                                                   mkU64(0xffffffffffffffffULL),
   4608                                                   unop(Iop_32to8,
   4609                                                        binop(Iop_Add32,
   4610                                                              mkexpr(t8),
   4611                                                              mkU32(1)))))));
   4612 
   4613                      assign(t7, IRExpr_ITE(mkexpr(t3),
   4614                                            unop(Iop_64to32,
   4615                                                 binop(Iop_And64,
   4616                                                       mkexpr(t5),
   4617                                                       mkexpr(t6))),
   4618                                            binop(Iop_Shr32,
   4619                                                  unop(Iop_64HIto32,
   4620                                                       binop(Iop_And64,
   4621                                                             mkexpr(t5),
   4622                                                             mkexpr(t6))),
   4623                                                  unop(Iop_32to8,
   4624                                                       binop(Iop_Sub32,
   4625                                                             mkU32(31),
   4626                                                             mkexpr(t8))))));
   4627 
   4628                      putIReg(rt, mkexpr(t7));
   4629                      break;
   4630                   }
   4631                   case 0xE: {  /* EXTR_S.H */
   4632                      DIP("extr_s.h r%u, ac%u, %u", rt, ac, rs);
   4633                      vassert(!mode64);
   4634                      t0 = newTemp(Ity_I64);
   4635                      t1 = newTemp(Ity_I64);
   4636                      t2 = newTemp(Ity_I32);
   4637                      t3 = newTemp(Ity_I64);
   4638                      t4 = newTemp(Ity_I32);
   4639                      t5 = newTemp(Ity_I32);
   4640                      t6 = newTemp(Ity_I64);
   4641                      t7 = newTemp(Ity_I32);
   4642                      t9 = newTemp(Ity_I32);
   4643 
   4644                      assign(t0, getAcc(ac));
   4645 
   4646                      assign(t1, binop(Iop_Sar64, mkexpr(t0), mkU8(rs)));
   4647 
   4648                      assign(t2, binop(Iop_Or32,
   4649                                       getDSPControl(), mkU32(0x00800000)));
   4650 
   4651                      assign(t9, binop(Iop_And32,
   4652                                       unop(Iop_64to32,
   4653                                            mkexpr(t1)),
   4654                                       mkU32(0x80000000)));
   4655                      putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32,
   4656                                                     mkexpr(t9),
   4657                                                     binop(Iop_And32,
   4658                                                           unop(Iop_64HIto32,
   4659                                                                mkexpr(t0)),
   4660                                                           mkU32(0x80000000))),
   4661                                               mkexpr(t2),
   4662                                               getDSPControl()));
   4663 
   4664                      /* Check if t1 > 0x7fff ((t1 - 0x7fff) > 0)
   4665                         1. subtract 0x7fff from t1
   4666                         2. if the resulting number is positive (sign bit = 0)
   4667                            and any of the other bits is 1, the value is > 0. */
   4668                      assign(t3, binop(Iop_Sub64,
   4669                                       mkexpr(t1),
   4670                                       mkU64(0x0000000000007fffULL)));
   4671                      assign(t4, binop(Iop_And32,
   4672                                        binop(Iop_Or32,
   4673                                             unop(Iop_1Sto32,
   4674                                                  binop(Iop_CmpNE32,
   4675                                                        mkU32(0),
   4676                                                        binop(Iop_And32,
   4677                                                              unop(Iop_64HIto32,
   4678                                                                   mkexpr(t3)),
   4679                                                              mkU32(0x7fffffff)))),
   4680                                             unop(Iop_1Sto32,
   4681                                                  binop(Iop_CmpNE32,
   4682                                                        mkU32(0),
   4683                                                        unop(Iop_64to32,
   4684                                                             mkexpr(t3))))),
   4685                                        unop(Iop_1Sto32,
   4686                                             binop(Iop_CmpEQ32,
   4687                                                   binop(Iop_And32,
   4688                                                         unop(Iop_64HIto32,
   4689                                                                   mkexpr(t3)),
   4690                                                              mkU32(0x80000000)),
   4691                                                   mkU32(0)))));
   4692                      putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32,
   4693                                                     mkU32(0),
   4694                                                     mkexpr(t4)),
   4695                                               binop(Iop_Or32,
   4696                                                     getDSPControl(),
   4697                                                     mkU32(0x00800000)),
   4698                                               getDSPControl()));
   4699                      /* Check if t1<0xffffffffffff8000 (0xffffffffffff8000-t1)>0
   4700                         1. subtract t1 from 0xffffffffffff8000
   4701                         2. if the resulting number is positive (sign bit = 0)
   4702                             and any of the other bits is 1, the value is > 0 */
   4703                      assign(t6, binop(Iop_Sub64,
   4704                                        mkU64(0xffffffffffff8000ULL),
   4705                                        mkexpr(t1)));
   4706                      assign(t7, binop(Iop_And32,
   4707                                       binop(Iop_Or32,
   4708                                             unop(Iop_1Sto32,
   4709                                                  binop(Iop_CmpNE32,
   4710                                                        mkU32(0),
   4711                                                        binop(Iop_And32,
   4712                                                              unop(Iop_64HIto32,
   4713                                                                   mkexpr(t6)),
   4714                                                              mkU32(0x7fffffff)))),
   4715                                             unop(Iop_1Sto32,
   4716                                                  binop(Iop_CmpNE32,
   4717                                                        mkU32(0),
   4718                                                        unop(Iop_64to32,
   4719                                                             mkexpr(t6))))),
   4720                                       unop(Iop_1Sto32,
   4721                                             binop(Iop_CmpEQ32,
   4722                                                   binop(Iop_And32,
   4723                                                         unop(Iop_64HIto32,
   4724                                                                   mkexpr(t6)),
   4725                                                              mkU32(0x80000000)),
   4726                                                   mkU32(0)))));
   4727                      putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32,
   4728                                                     mkU32(0),
   4729                                                     mkexpr(t7)),
   4730                                               binop(Iop_Or32,
   4731                                                     getDSPControl(),
   4732                                                     mkU32(0x00800000)),
   4733                                               getDSPControl()));
   4734                      putIReg(rt, IRExpr_ITE(binop(Iop_CmpNE32,
   4735                                                     mkU32(0),
   4736                                                     mkexpr(t4)),
   4737                                             mkU32(0x00007fff),
   4738                                             IRExpr_ITE(binop(Iop_CmpNE32,
   4739                                                              mkU32(0),
   4740                                                              mkexpr(t7)),
   4741                                                        mkU32(0xffff8000),
   4742                                                        unop(Iop_64to32,
   4743                                                             mkexpr(t1)))));
   4744                      break;
   4745                   }
   4746                   case 0xF: {  /* EXTRV_S.H */
   4747                      DIP("extrv_s.h r%u, ac%u, %u", rt, ac, rs);
   4748                      vassert(!mode64);
   4749                      t0 = newTemp(Ity_I64);
   4750                      t1 = newTemp(Ity_I64);
   4751                      t2 = newTemp(Ity_I32);
   4752                      t3 = newTemp(Ity_I64);
   4753                      t4 = newTemp(Ity_I32);
   4754                      t5 = newTemp(Ity_I32);
   4755                      t6 = newTemp(Ity_I64);
   4756                      t7 = newTemp(Ity_I32);
   4757                      t9 = newTemp(Ity_I32);
   4758 
   4759                      assign(t0, getAcc(ac));
   4760 
   4761                      assign(t1, binop(Iop_Sar64,
   4762                                       mkexpr(t0),
   4763                                       unop(Iop_32to8,
   4764                                            binop(Iop_And32,
   4765                                                  getIReg(rs),
   4766                                                  mkU32(0x1f)))));
   4767 
   4768                      assign(t2, binop(Iop_Or32,
   4769                                       getDSPControl(), mkU32(0x00800000)));
   4770 
   4771                      assign(t9, binop(Iop_And32,
   4772                                       unop(Iop_64to32,
   4773                                            mkexpr(t1)),
   4774                                       mkU32(0x80000000)));
   4775                      putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32,
   4776                                                     mkexpr(t9),
   4777                                                     binop(Iop_And32,
   4778                                                           unop(Iop_64HIto32,
   4779                                                                mkexpr(t0)),
   4780                                                           mkU32(0x80000000))),
   4781                                               mkexpr(t2),
   4782                                               getDSPControl()));
   4783 
   4784                      /* Check if t1 > 0x7fff ((t1 - 0x7fff) > 0)
   4785                         1. subtract 0x7fff from t1
   4786                         2. if the resulting number is positive (sign bit = 0)
   4787                            and any of the other bits is 1, the value is > 0. */
   4788                      assign(t3, binop(Iop_Sub64,
   4789                                       mkexpr(t1),
   4790                                       mkU64(0x0000000000007fffULL)));
   4791                      assign(t4, binop(Iop_And32,
   4792                                        binop(Iop_Or32,
   4793                                             unop(Iop_1Sto32,
   4794                                                  binop(Iop_CmpNE32,
   4795                                                        mkU32(0),
   4796                                                        binop(Iop_And32,
   4797                                                              unop(Iop_64HIto32,
   4798                                                                   mkexpr(t3)),
   4799                                                              mkU32(0x7fffffff)))),
   4800                                             unop(Iop_1Sto32,
   4801                                                  binop(Iop_CmpNE32,
   4802                                                        mkU32(0),
   4803                                                        unop(Iop_64to32,
   4804                                                             mkexpr(t3))))),
   4805                                        unop(Iop_1Sto32,
   4806                                             binop(Iop_CmpEQ32,
   4807                                                   binop(Iop_And32,
   4808                                                         unop(Iop_64HIto32,
   4809                                                                   mkexpr(t3)),
   4810                                                              mkU32(0x80000000)),
   4811                                                   mkU32(0)))));
   4812                      putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32,
   4813                                                     mkU32(0),
   4814                                                     mkexpr(t4)),
   4815                                               binop(Iop_Or32,
   4816                                                     getDSPControl(),
   4817                                                     mkU32(0x00800000)),
   4818                                               getDSPControl()));
   4819                      /* Check if t1<0xffffffffffff8000 (0xffffffffffff8000-t1)>0
   4820                         1. subtract t1 from 0xffffffffffff8000
   4821                         2. if the resulting number is positive (sign bit = 0)
   4822                             and any of the other bits is 1, the value is > 0 */
   4823                      assign(t6, binop(Iop_Sub64,
   4824                                        mkU64(0xffffffffffff8000ULL),
   4825                                        mkexpr(t1)));
   4826                      assign(t7, binop(Iop_And32,
   4827                                       binop(Iop_Or32,
   4828                                             unop(Iop_1Sto32,
   4829                                                  binop(Iop_CmpNE32,
   4830                                                        mkU32(0),
   4831                                                        binop(Iop_And32,
   4832                                                              unop(Iop_64HIto32,
   4833                                                                   mkexpr(t6)),
   4834                                                              mkU32(0x7fffffff)))),
   4835                                             unop(Iop_1Sto32,
   4836                                                  binop(Iop_CmpNE32,
   4837                                                        mkU32(0),
   4838                                                        unop(Iop_64to32,
   4839                                                             mkexpr(t6))))),
   4840                                       unop(Iop_1Sto32,
   4841                                             binop(Iop_CmpEQ32,
   4842                                                   binop(Iop_And32,
   4843                                                         unop(Iop_64HIto32,
   4844                                                                   mkexpr(t6)),
   4845                                                              mkU32(0x80000000)),
   4846                                                   mkU32(0)))));
   4847                      putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32,
   4848                                                     mkU32(0),
   4849                                                     mkexpr(t7)),
   4850                                               binop(Iop_Or32,
   4851                                                     getDSPControl(),
   4852                                                     mkU32(0x00800000)),
   4853                                               getDSPControl()));
   4854                      putIReg(rt, IRExpr_ITE(binop(Iop_CmpNE32,
   4855                                                     mkU32(0),
   4856                                                     mkexpr(t4)),
   4857                                             mkU32(0x00007fff),
   4858                                             IRExpr_ITE(binop(Iop_CmpNE32,
   4859                                                              mkU32(0),
   4860                                                              mkexpr(t7)),
   4861                                                        mkU32(0xffff8000),
   4862                                                        unop(Iop_64to32,
   4863                                                             mkexpr(t1)))));
   4864                      break;
   4865                   }
   4866                   case 0x12: {  /* RDDSP*/
   4867                      DIP("rddsp r%u, mask 0x%x", rd, rddsp_mask);
   4868                      vassert(!mode64);
   4869 
   4870                      putIReg(rd, mkU32(0x0));
   4871 
   4872                      if ((rddsp_mask & 0x1) == 0x1) {
   4873                         /* Read pos field (bits 5-0) of DSPControl register. */
   4874                         putIReg(rd, binop(Iop_Or32,
   4875                                           getIReg(rd),
   4876                                           binop(Iop_And32,
   4877                                                 getDSPControl(),
   4878                                                 mkU32(0x0000003F))));
   4879                      }
   4880 
   4881                      if ((rddsp_mask & 0x2) == 0x2) {
   4882                         /* Read scount field (bits 12-7) of DSPControl
   4883                            register. */
   4884                         putIReg(rd, binop(Iop_Or32,
   4885                                           getIReg(rd),
   4886                                           binop(Iop_And32,
   4887                                                 getDSPControl(),
   4888                                                 mkU32(0x00001F80))));
   4889                      }
   4890 
   4891                      if ((rddsp_mask & 0x4) == 0x4) {
   4892                         /* Read C field (bit 13) of DSPControl register. */
   4893                         putIReg(rd, binop(Iop_Or32,
   4894                                           getIReg(rd),
   4895                                           binop(Iop_And32,
   4896                                                 getDSPControl(),
   4897                                                 mkU32(0x00002000))));
   4898                      }
   4899 
   4900                      if ((rddsp_mask & 0x8) == 0x8) {
   4901                         /* Read outflag field (bit s 23-16) of DSPControl
   4902                            register. */
   4903                         putIReg(rd, binop(Iop_Or32,
   4904                                           getIReg(rd),
   4905                                           binop(Iop_And32,
   4906                                                 getDSPControl(),
   4907                                                 mkU32(0x00FF0000))));
   4908                      }
   4909 
   4910                      if ((rddsp_mask & 0x10) == 0x10) {
   4911                         /* Read ccond field (bits 31-24) of DSPControl
   4912                            register. */
   4913                         putIReg(rd, binop(Iop_Or32,
   4914                                           getIReg(rd),
   4915                                           binop(Iop_And32,
   4916                                                 getDSPControl(),
   4917                                                 mkU32(0xFF000000))));
   4918                      }
   4919 
   4920                      if ((rddsp_mask & 0x20) == 0x20) {
   4921                         /* Read EFI field (bit 14) of DSPControl register. */
   4922                         putIReg(rd, binop(Iop_Or32,
   4923                                           getIReg(rd),
   4924                                           binop(Iop_And32,
   4925                                                 getDSPControl(),
   4926                                                 mkU32(0x00004000))));
   4927                      }
   4928 
   4929                      if ((rddsp_mask & 0x3f) == 0x3f) {
   4930                         /* Read all fields of DSPControl register. */
   4931                         putIReg(rd, getDSPControl());
   4932                      }
   4933                      break;
   4934                   }
   4935                   case 0x13: {  /* WRDSP */
   4936                      DIP("wrdsp r%u, mask 0x%x", rs, wrdsp_mask);
   4937                      vassert(!mode64);
   4938 
   4939                      if ((wrdsp_mask & 0x3f) == 0x3f) {
   4940                         /* If mips64 put all fields of rs, except bit 15 and bit
   4941                            6, to DSPControl register, otherwise put all except
   4942                            bits 15, 6 and bits 31..28. */
   4943                         putDSPControl(mode64 ?
   4944                                       binop(Iop_And32,
   4945                                             getIReg(rs),
   4946                                             mkU32(0xffff7fbf)) :
   4947                                       binop(Iop_And32,
   4948                                             getIReg(rs),
   4949                                             mkU32(0x0fff7fbf)));
   4950                      } else {
   4951                         if ((wrdsp_mask & 0x1) == 0x1) {
   4952                            /* Put bits 5-0 of rs to DSPControl register pos
   4953                               field. */
   4954                            putDSPControl(binop(Iop_Or32,
   4955                                                binop(Iop_And32,
   4956                                                      getDSPControl(),
   4957                                                      mkU32(0xFFFF7F40)),
   4958                                                binop(Iop_And32,
   4959                                                      getIReg(rs),
   4960                                                      mkU32(0x0000003F))));
   4961                         }
   4962 
   4963                         if ((wrdsp_mask & 0x2) == 0x2) {
   4964                            /* Put bits 12-7 of rs to DSPControl scount field. */
   4965                            putDSPControl(binop(Iop_Or32,
   4966                                                binop(Iop_And32,
   4967                                                      getDSPControl(),
   4968                                                      mkU32(0xFFFFE03F)),
   4969                                                binop(Iop_And32,
   4970                                                      getIReg(rs),
   4971                                                      mkU32(0x00001F80))));
   4972                         }
   4973 
   4974                         if ((wrdsp_mask & 0x4) == 0x4) {
   4975                            /* Put bit 13 of rs to DSPControl register C
   4976                               field. */
   4977                            putDSPControl(binop(Iop_Or32,
   4978                                                binop(Iop_And32,
   4979                                                      getDSPControl(),
   4980                                                      mkU32(0xFFFF5FBF)),
   4981                                                binop(Iop_And32,
   4982                                                      getIReg(rs),
   4983                                                      mkU32(0x00002000))));
   4984                         }
   4985 
   4986                         if ((wrdsp_mask & 0x8) == 0x8) {
   4987                            /* Put bits 23-16 of rs to DSPControl reg outflag
   4988                               field. */
   4989                            putDSPControl(binop(Iop_Or32,
   4990                                                binop(Iop_And32,
   4991                                                      getDSPControl(),
   4992                                                      mkU32(0xFF007FBF)),
   4993                                                binop(Iop_And32,
   4994                                                      getIReg(rs),
   4995                                                      mkU32(0x00FF0000))));
   4996                         }
   4997 
   4998                         if ((wrdsp_mask & 0x10) == 0x10) {
   4999                            /* Put bits 31-24 of rs to DSPControl reg ccond
   5000                               field. */
   5001                            putDSPControl(binop(Iop_Or32,
   5002                                                binop(Iop_And32,
   5003                                                      getDSPControl(),
   5004                                                      mkU32(0x00FF7FBF)),
   5005                                                binop(Iop_And32,
   5006                                                      getIReg(rs),
   5007                                                      mode64 ? mkU32(0xFF000000)
   5008                                                             : mkU32(0x0F000000))
   5009                                                )
   5010                                         );
   5011                         }
   5012 
   5013                         if ((wrdsp_mask & 0x20) == 0x20) {
   5014                            /* Put bit 14 of rs to DSPControl register EFI
   5015                               field. */
   5016                            putDSPControl(binop(Iop_Or32,
   5017                                                binop(Iop_And32,
   5018                                                      getDSPControl(),
   5019                                                      mkU32(0xFFFF3FBF)),
   5020                                                binop(Iop_And32,
   5021                                                      getIReg(rs),
   5022                                                      mkU32(0x00004000))));
   5023                         }
   5024                      }
   5025                      break;
   5026                   }
   5027                   case 0x1A: {  /* SHILO */
   5028                      DIP("shilo ac%u, %u", ac, shift);
   5029                      vassert(!mode64);
   5030                      t0 = newTemp(Ity_I64);
   5031                      t1 = newTemp(Ity_I64);
   5032 
   5033                      assign(t0, getAcc(ac));
   5034 
   5035                      putAcc(ac, mkexpr(t0));
   5036 
   5037                      if (0x20 == (shift & 0x3f)) {
   5038                         putAcc(ac, binop(Iop_32HLto64,
   5039                                          unop(Iop_64to32, mkexpr(t0)),
   5040                                          mkU32(0x0)));
   5041                      } else if (0x20 == (shift & 0x20)) {
   5042                         assign(t1, binop(Iop_Shl64,
   5043                                          mkexpr(t0),
   5044                                          unop(Iop_32to8,
   5045                                               binop(Iop_Add32,
   5046                                                     unop(Iop_Not32,
   5047                                                          mkU32(shift)),
   5048                                                     mkU32(0x1)))));
   5049 
   5050                         putAcc(ac, mkexpr(t1));
   5051                      } else {
   5052                         assign(t1, binop(Iop_Shr64, mkexpr(t0), mkU8(shift)));
   5053 
   5054                         putAcc(ac, mkexpr(t1));
   5055                      }
   5056                      break;
   5057                   }
   5058                   case 0x1B: {  /* SHILOV */
   5059                      DIP("shilov ac%u, r%u", ac, rs);
   5060                      vassert(!mode64);
   5061                      t0 = newTemp(Ity_I64);
   5062                      t1 = newTemp(Ity_I32);
   5063                      t2 = newTemp(Ity_I1);
   5064                      t3 = newTemp(Ity_I64);
   5065                      t4 = newTemp(Ity_I64);
   5066 
   5067                      assign(t0, getAcc(ac));
   5068                      assign(t1, binop(Iop_And32, getIReg(rs), mkU32(0x3f)));
   5069                      assign(t2, binop(Iop_CmpEQ32, mkexpr(t1), mkU32(0x20)));
   5070                      assign(t3, binop(Iop_Shl64,
   5071                                       mkexpr(t0),
   5072                                       unop(Iop_32to8,
   5073                                            binop(Iop_Add32,
   5074                                                  unop(Iop_Not32,
   5075                                                       mkexpr(t1)),
   5076                                                  mkU32(0x1)))));
   5077                      assign(t4, binop(Iop_Shr64,
   5078                                       mkexpr(t0),
   5079                                       unop(Iop_32to8,
   5080                                            mkexpr(t1))));
   5081 
   5082                      putAcc(ac,
   5083                             IRExpr_ITE(mkexpr(t2),
   5084                                        binop(Iop_32HLto64,
   5085                                              unop(Iop_64to32, mkexpr(t0)),
   5086                                              mkU32(0x0)),
   5087                                        IRExpr_ITE(binop(Iop_CmpEQ32,
   5088                                                         binop(Iop_And32,
   5089                                                               mkexpr(t1),
   5090                                                               mkU32(0x20)),
   5091                                                         mkU32(0x20)),
   5092                                                   mkexpr(t3),
   5093                                                   mkexpr(t4))));
   5094                      break;
   5095                   }
   5096                   case 0x1F: {  /* MTHLIP */
   5097                      DIP("mthlip r%u, ac%u", rs, ac);
   5098                      vassert(!mode64);
   5099                      t0 = newTemp(Ity_I64);
   5100                      t1 = newTemp(Ity_I32);
   5101                      t2 = newTemp(Ity_I32);
   5102                      t3 = newTemp(Ity_I1);
   5103 
   5104                      assign(t0, getAcc(ac));
   5105                      putAcc(ac, binop(Iop_32HLto64,
   5106                                       unop(Iop_64to32, mkexpr(t0)),
   5107                                       getIReg(rs)));
   5108                      assign(t1, binop(Iop_And32, getDSPControl(), mkU32(0x3f)));
   5109                      putDSPControl(IRExpr_ITE(binop(Iop_CmpLE32U,
   5110                                                     mkU32(32),
   5111                                                     mkexpr(t1)),
   5112                                               binop(Iop_Or32,
   5113                                                     binop(Iop_Sub32,
   5114                                                           mkexpr(t1),
   5115                                                           mkU32(32)),
   5116                                                    binop(Iop_And32,
   5117                                                          getDSPControl(),
   5118                                                          mkU32(0xffffffc0))),
   5119                                               binop(Iop_Or32,
   5120                                                     binop(Iop_Add32,
   5121                                                           mkexpr(t1),
   5122                                                           mkU32(32)),
   5123                                                     binop(Iop_And32,
   5124                                                           getDSPControl(),
   5125                                                           mkU32(0xffffffc0)))));
   5126                      break;
   5127                   }
   5128                   default:
   5129                      return -1;
   5130                }
   5131                break;  /* end of EXTR.W */
   5132             }
   5133             case 0xA: {  /* LX */
   5134                switch(sa) {
   5135                   case 0x0: {  /* LWX */
   5136                      DIP("lwx r%u, r%u(r%u)", rd, rt, rs);
   5137                      vassert(!mode64);
   5138                      t0 = newTemp(Ity_I32);
   5139 
   5140                      assign(t0, binop(Iop_Add32, getIReg(rt), getIReg(rs)));
   5141 
   5142                      putIReg(rd, load(Ity_I32, mkexpr(t0)));
   5143                      break;
   5144                   }
   5145                   case 0x4: {  /* LHX */
   5146                      DIP("lhx r%u, r%u(r%u)", rd, rt, rs);
   5147                      vassert(!mode64);
   5148                      t0 = newTemp(Ity_I32);
   5149 
   5150                      assign(t0, binop(Iop_Add32, getIReg(rt), getIReg(rs)));
   5151 
   5152                      putIReg(rd, unop(Iop_16Sto32, load(Ity_I16, mkexpr(t0))));
   5153                      break;
   5154                   }
   5155                   case 0x6: {  /* LBUX */
   5156                      DIP("lbux r%u, r%u(r%u)", rd, rt, rs);
   5157                      vassert(!mode64);
   5158                      t0 = newTemp(Ity_I32);
   5159 
   5160                      assign(t0, binop(Iop_Add32, getIReg(rt), getIReg(rs)));
   5161 
   5162                      putIReg(rd, unop(Iop_8Uto32, load(Ity_I8, mkexpr(t0))));
   5163                      break;
   5164                   }
   5165                   default:
   5166                      return -1;
   5167                }
   5168                break;  /* end of LX */
   5169             }
   5170             case 0xC: {  /* INSV */
   5171                switch(sa) {
   5172                   case 0x0: {  /* INSV */
   5173                      DIP("insv r%u, r%u", rt, rs);
   5174                      vassert(!mode64);
   5175 
   5176                      t0 = newTemp(Ity_I32);
   5177                      t1 = newTemp(Ity_I32);
   5178                      t2 = newTemp(Ity_I8);
   5179                      t3 = newTemp(Ity_I8);
   5180                      t4 = newTemp(Ity_I32);
   5181                      t5 = newTemp(Ity_I1);
   5182                      t6 = newTemp(Ity_I32);
   5183                      t7 = newTemp(Ity_I32);
   5184                      t8 = newTemp(Ity_I32);
   5185                      t9 = newTemp(Ity_I32);
   5186 
   5187                      /* t0 <- pos field of DSPControl register. */
   5188                      assign(t0, binop(Iop_And32, getDSPControl(), mkU32(0x3f)));
   5189                      /* t1 <- scount field of DSPControl register. */
   5190                      assign(t1, binop(Iop_Shr32,
   5191                                       binop(Iop_And32,
   5192                                             getDSPControl(),
   5193                                             mkU32(0x1f80)),
   5194                                       mkU8(7)));
   5195 
   5196                      assign(t2, unop(Iop_32to8,
   5197                                      binop(Iop_Add32,
   5198                                            mkexpr(t1),
   5199                                            mkexpr(t0))));
   5200 
   5201                      /* 32-(pos+size) most significant bits of rt. */
   5202                      assign(t6, binop(Iop_Shl32,
   5203                                       binop(Iop_Shr32,
   5204                                             getIReg(rt),
   5205                                             mkexpr(t2)),
   5206                                       mkexpr(t2)));
   5207 
   5208                      assign(t3, unop(Iop_32to8,
   5209                                      binop(Iop_Sub32,
   5210                                            mkU32(32),
   5211                                            mkexpr(t0))));
   5212                      /* Pos least significant bits of rt. */
   5213                      assign(t7, binop(Iop_Shr32,
   5214                                       binop(Iop_Shl32,
   5215                                             getIReg(rt),
   5216                                             mkexpr(t3)),
   5217                                       mkexpr(t3)));
   5218 
   5219                      /* Size least significant bits of rs,
   5220                         shifted to appropriate position. */
   5221                      assign(t8, binop(Iop_Shl32,
   5222                                       binop(Iop_And32,
   5223                                             getIReg(rs),
   5224                                             unop(Iop_Not32,
   5225                                                  binop(Iop_Shl32,
   5226                                                        mkU32(0xffffffff),
   5227                                                        unop(Iop_32to8,
   5228                                                             mkexpr(t1))))),
   5229                                       unop(Iop_32to8,
   5230                                            mkexpr(t0))));
   5231 
   5232                      putIReg(rt, IRExpr_ITE(binop(Iop_CmpEQ32,
   5233                                                   mkexpr(t0),
   5234                                                   mkU32(0)),
   5235                                             IRExpr_ITE(binop(Iop_CmpEQ32,
   5236                                                              mkexpr(t1),
   5237                                                              mkU32(32)),
   5238                                                        getIReg(rs),
   5239                                                        binop(Iop_Or32,
   5240                                                              mkexpr(t6),
   5241                                                              mkexpr(t8))),
   5242                                             IRExpr_ITE(binop(Iop_CmpEQ32,
   5243                                                              unop(Iop_8Uto32,
   5244                                                                   mkexpr(t2)),
   5245                                                              mkU32(32)),
   5246                                                        binop(Iop_Or32,
   5247                                                              mkexpr(t7),
   5248                                                              mkexpr(t8)),
   5249                                                        binop(Iop_Or32,
   5250                                                              binop(Iop_Or32,
   5251                                                                    mkexpr(t6),
   5252                                                                    mkexpr(t7)),
   5253                                                              mkexpr(t8)))));
   5254                      break;
   5255                   }
   5256                   default:
   5257                      return -1;
   5258                }
   5259                break;  /* enf of INSV */
   5260             }
   5261             case 0x10: {  /* ADDU.QB */
   5262                switch(sa) {
   5263                   case 0x00: {  /* ADDU.QB */
   5264                      DIP("addu.qb r%u, r%u, r%u", rd, rs, rt);
   5265                      vassert(!mode64);
   5266                      t0 = newTemp(Ity_I32);
   5267                      t1 = newTemp(Ity_I1);
   5268                      t2 = newTemp(Ity_I32);
   5269                      t3 = newTemp(Ity_I1);
   5270                      t4 = newTemp(Ity_I32);
   5271                      t5 = newTemp(Ity_I1);
   5272                      t6 = newTemp(Ity_I32);
   5273                      t7 = newTemp(Ity_I1);
   5274                      t8 = newTemp(Ity_I32);
   5275 
   5276                      /* Add rightmost bytes of rs and rt. */
   5277                      assign(t0,
   5278                             binop(Iop_Add32,
   5279                                   unop(Iop_8Uto32,
   5280                                        unop(Iop_16to8,
   5281                                             unop(Iop_32to16, getIReg(rs)))),
   5282                                   unop(Iop_8Uto32,
   5283                                        unop(Iop_16to8,
   5284                                             unop(Iop_32to16, getIReg(rt))))));
   5285                      /* t1 will be 1 if there is overflow, 0 otherwise. */
   5286                      assign(t1, binop(Iop_CmpEQ32,
   5287                                       binop(Iop_And32,
   5288                                             mkexpr(t0),
   5289                                             mkU32(0x00000100)),
   5290                                       mkU32(0x00000100)));
   5291 
   5292                      /* Add bits 15-8 of rs and rt. */
   5293                      assign(t2,
   5294                             binop(Iop_Add32,
   5295                                   unop(Iop_8Uto32,
   5296                                        unop(Iop_16HIto8,
   5297                                             unop(Iop_32to16, getIReg(rs)))),
   5298                                   unop(Iop_8Uto32,
   5299                                        unop(Iop_16HIto8,
   5300                                             unop(Iop_32to16, getIReg(rt))))));
   5301                      /* t3 will be 1 if there is overflow, 0 otherwise. */
   5302                      assign(t3, binop(Iop_CmpEQ32,
   5303                                       binop(Iop_And32,
   5304                                             mkexpr(t2),
   5305                                             mkU32(0x00000100)),
   5306                                       mkU32(0x00000100)));
   5307 
   5308                      /* Add bits 15-8 of rs and rt. */
   5309                      assign(t4,
   5310                             binop(Iop_Add32,
   5311                                   unop(Iop_8Uto32,
   5312                                        unop(Iop_16to8,
   5313                                             unop(Iop_32HIto16, getIReg(rs)))),
   5314                                   unop(Iop_8Uto32,
   5315                                        unop(Iop_16to8,
   5316                                             unop(Iop_32HIto16, getIReg(rt))))));
   5317                      /* t5 will be 1 if there is overflow, 0 otherwise. */
   5318                      assign(t5, binop(Iop_CmpEQ32,
   5319                                       binop(Iop_And32,
   5320                                             mkexpr(t4),
   5321                                             mkU32(0x00000100)),
   5322                                       mkU32(0x00000100)));
   5323 
   5324                      /* Add bits 15-8 of rs and rt. */
   5325                      assign(t6,
   5326                             binop(Iop_Add32,
   5327                                   unop(Iop_8Uto32,
   5328                                        unop(Iop_16HIto8,
   5329                                             unop(Iop_32HIto16, getIReg(rs)))),
   5330                                   unop(Iop_8Uto32,
   5331                                        unop(Iop_16HIto8,
   5332                                             unop(Iop_32HIto16, getIReg(rt))))));
   5333                      /* t7 will be 1 if there is overflow, 0 otherwise. */
   5334                      assign(t7, binop(Iop_CmpEQ32,
   5335                                       binop(Iop_And32,
   5336                                             mkexpr(t6),
   5337                                             mkU32(0x00000100)),
   5338                                       mkU32(0x00000100)));
   5339 
   5340                      assign(t8,
   5341                             binop(Iop_Or32,
   5342                                   binop(Iop_Or32,
   5343                                         binop(Iop_Or32,
   5344                                               unop(Iop_1Sto32, mkexpr(t7)),
   5345                                               unop(Iop_1Sto32,  mkexpr(t5))),
   5346                                         unop(Iop_1Sto32, mkexpr(t3))),
   5347                                   unop(Iop_1Sto32, mkexpr(t1))));
   5348 
   5349                      putDSPControl(IRExpr_ITE(binop(Iop_CmpEQ32,
   5350                                                     mkexpr(t8),
   5351                                                     mkU32(0x0)),
   5352                                               getDSPControl(),
   5353                                               binop(Iop_Or32,
   5354                                                     getDSPControl(),
   5355                                                     mkU32(0x00100000))));
   5356 
   5357                      putIReg(rd, binop(Iop_16HLto32,
   5358                                        binop(Iop_8HLto16,
   5359                                              unop(Iop_32to8, mkexpr(t6)),
   5360                                              unop(Iop_32to8, mkexpr(t4))),
   5361                                        binop(Iop_8HLto16,
   5362                                              unop(Iop_32to8, mkexpr(t2)),
   5363                                              unop(Iop_32to8, mkexpr(t0)))));
   5364                      break;
   5365                   }
   5366                   case 0x1: {  /* SUBU.QB */
   5367                      DIP("subu.qb r%u, r%u, r%u", rd, rs, rt);
   5368                      vassert(!mode64);
   5369                      t0 = newTemp(Ity_I32);
   5370                      t1 = newTemp(Ity_I1);
   5371                      t2 = newTemp(Ity_I32);
   5372                      t3 = newTemp(Ity_I1);
   5373                      t4 = newTemp(Ity_I32);
   5374                      t5 = newTemp(Ity_I1);
   5375                      t6 = newTemp(Ity_I32);
   5376                      t7 = newTemp(Ity_I1);
   5377                      t8 = newTemp(Ity_I32);
   5378 
   5379                      /* Subtract rightmost bytes of rs and rt. */
   5380                      assign(t0,
   5381                             binop(Iop_Sub32,
   5382                                   unop(Iop_8Uto32,
   5383                                        unop(Iop_16to8,
   5384                                             unop(Iop_32to16, getIReg(rs)))),
   5385                                   unop(Iop_8Uto32,
   5386                                        unop(Iop_16to8,
   5387                                             unop(Iop_32to16, getIReg(rt))))));
   5388                      /* t1 will be 1 if there is overflow, 0 otherwise. */
   5389                      assign(t1, binop(Iop_CmpEQ32,
   5390                                       binop(Iop_And32,
   5391                                             mkexpr(t0),
   5392                                             mkU32(0x00000100)),
   5393                                       mkU32(0x00000100)));
   5394 
   5395                      /* Subtract bits 15-8 of rs and rt. */
   5396                      assign(t2,
   5397                             binop(Iop_Sub32,
   5398                                   unop(Iop_8Uto32,
   5399                                        unop(Iop_16HIto8,
   5400                                             unop(Iop_32to16, getIReg(rs)))),
   5401                                   unop(Iop_8Uto32,
   5402                                        unop(Iop_16HIto8,
   5403                                             unop(Iop_32to16, getIReg(rt))))));
   5404                      /* t3 will be 1 if there is overflow, 0 otherwise. */
   5405                      assign(t3, binop(Iop_CmpEQ32,
   5406                                       binop(Iop_And32,
   5407                                             mkexpr(t2),
   5408                                             mkU32(0x00000100)),
   5409                                       mkU32(0x00000100)));
   5410 
   5411                      /* Subtract bits 15-8 of rs and rt. */
   5412                      assign(t4,
   5413                             binop(Iop_Sub32,
   5414                                   unop(Iop_8Uto32,
   5415                                        unop(Iop_16to8,
   5416                                             unop(Iop_32HIto16, getIReg(rs)))),
   5417                                   unop(Iop_8Uto32,
   5418                                        unop(Iop_16to8,
   5419                                             unop(Iop_32HIto16, getIReg(rt))))));
   5420                      /* t5 will be 1 if there is overflow, 0 otherwise. */
   5421                      assign(t5, binop(Iop_CmpEQ32,
   5422                                       binop(Iop_And32,
   5423                                             mkexpr(t4),
   5424                                             mkU32(0x00000100)),
   5425                                       mkU32(0x00000100)));
   5426 
   5427                      /* Subtract bits 15-8 of rs and rt. */
   5428                      assign(t6,
   5429                             binop(Iop_Sub32,
   5430                                   unop(Iop_8Uto32,
   5431                                        unop(Iop_16HIto8,
   5432                                             unop(Iop_32HIto16, getIReg(rs)))),
   5433                                   unop(Iop_8Uto32,
   5434                                        unop(Iop_16HIto8,
   5435                                             unop(Iop_32HIto16, getIReg(rt))))));
   5436                      /* t7 will be 1 if there is overflow, 0 otherwise. */
   5437                      assign(t7, binop(Iop_CmpEQ32,
   5438                                       binop(Iop_And32,
   5439                                             mkexpr(t6),
   5440                                             mkU32(0x00000100)),
   5441                                       mkU32(0x00000100)));
   5442 
   5443                      assign(t8, binop(Iop_Or32,
   5444                                       binop(Iop_Or32,
   5445                                             binop(Iop_Or32,
   5446                                                   unop(Iop_1Sto32, mkexpr(t7)),
   5447                                                   unop(Iop_1Sto32, mkexpr(t5))),
   5448                                             unop(Iop_1Sto32, mkexpr(t3))),
   5449                                       unop(Iop_1Sto32, mkexpr(t1))));
   5450 
   5451                      putDSPControl(IRExpr_ITE(binop(Iop_CmpEQ32,
   5452                                                      mkexpr(t8),
   5453                                                      mkU32(0x0)),
   5454                                               getDSPControl(),
   5455                                               binop(Iop_Or32,
   5456                                                     getDSPControl(),
   5457                                                     mkU32(0x00100000))));
   5458 
   5459                      putIReg(rd, binop(Iop_16HLto32,
   5460                                        binop(Iop_8HLto16,
   5461                                              unop(Iop_32to8, mkexpr(t6)),
   5462                                              unop(Iop_32to8, mkexpr(t4))),
   5463                                        binop(Iop_8HLto16,
   5464                                              unop(Iop_32to8, mkexpr(t2)),
   5465                                              unop(Iop_32to8, mkexpr(t0)))));
   5466                      break;
   5467                   }
   5468                   case 0x04: {  /* ADDU_S.QB */
   5469                      DIP("addu_s.qb r%u, r%u, r%u", rd, rs, rt);
   5470                      vassert(!mode64);
   5471                      t0 = newTemp(Ity_I32);
   5472                      t1 = newTemp(Ity_I1);
   5473                      t2 = newTemp(Ity_I8);
   5474                      t3 = newTemp(Ity_I32);
   5475                      t4 = newTemp(Ity_I1);
   5476                      t5 = newTemp(Ity_I8);
   5477                      t6 = newTemp(Ity_I32);
   5478                      t7 = newTemp(Ity_I1);
   5479                      t8 = newTemp(Ity_I8);
   5480                      t9 = newTemp(Ity_I32);
   5481                      t10 = newTemp(Ity_I1);
   5482                      t11 = newTemp(Ity_I8);
   5483                      t12 = newTemp(Ity_I32);
   5484 
   5485                      /* Add rightmost bytes of rs and rt. */
   5486                      assign(t0,
   5487                             binop(Iop_Add32,
   5488                                   unop(Iop_8Uto32,
   5489                                        unop(Iop_16to8,
   5490                                             unop(Iop_32to16, getIReg(rs)))),
   5491                                   unop(Iop_8Uto32,
   5492                                        unop(Iop_16to8,
   5493                                             unop(Iop_32to16, getIReg(rt))))));
   5494                      /* t1 will be 1 if there is overflow, 0 otherwise. */
   5495                      assign(t1, binop(Iop_CmpEQ32,
   5496                                       binop(Iop_And32,
   5497                                             mkexpr(t0),
   5498                                             mkU32(0x00000100)),
   5499                                       mkU32(0x00000100)));
   5500                      /* Saturate if necessary. */
   5501                      assign(t2, IRExpr_ITE(mkexpr(t1),
   5502                                            mkU8(0xff),
   5503                                            unop(Iop_32to8, mkexpr(t0))));
   5504 
   5505                      /* Add bits 15-8 of rs and rt. */
   5506                      assign(t3,
   5507                             binop(Iop_Add32,
   5508                                   unop(Iop_8Uto32,
   5509                                        unop(Iop_16HIto8,
   5510                                             unop(Iop_32to16, getIReg(rs)))),
   5511                                   unop(Iop_8Uto32,
   5512                                        unop(Iop_16HIto8,
   5513                                             unop(Iop_32to16, getIReg(rt))))));
   5514                      /* t4 will be 1 if there is overflow, 0 otherwise. */
   5515                      assign(t4, binop(Iop_CmpEQ32,
   5516                                       binop(Iop_And32,
   5517                                             mkexpr(t3),
   5518                                             mkU32(0x00000100)),
   5519                                       mkU32(0x00000100)));
   5520                      /* Saturate if necessary. */
   5521                      assign(t5, IRExpr_ITE(mkexpr(t4),
   5522                                            mkU8(0xff),
   5523                                            unop(Iop_32to8, mkexpr(t3))));
   5524 
   5525                      /* Add bits 15-8 of rs and rt. */
   5526                      assign(t6,
   5527                             binop(Iop_Add32,
   5528                                   unop(Iop_8Uto32,
   5529                                        unop(Iop_16to8,
   5530                                             unop(Iop_32HIto16, getIReg(rs)))),
   5531                                   unop(Iop_8Uto32,
   5532                                        unop(Iop_16to8,
   5533                                             unop(Iop_32HIto16, getIReg(rt))))));
   5534                      /* t7 will be 1 if there is overflow, 0 otherwise. */
   5535                      assign(t7, binop(Iop_CmpEQ32,
   5536                                       binop(Iop_And32,
   5537                                             mkexpr(t6),
   5538                                             mkU32(0x00000100)),
   5539                                       mkU32(0x00000100)));
   5540                      /* Saturate if necessary. */
   5541                      assign(t8, IRExpr_ITE(mkexpr(t7),
   5542                                            mkU8(0xff),
   5543                                            unop(Iop_32to8, mkexpr(t6))));
   5544 
   5545                      /* Add bits 15-8 of rs and rt. */
   5546                      assign(t9,
   5547                             binop(Iop_Add32,
   5548                                   unop(Iop_8Uto32,
   5549                                        unop(Iop_16HIto8,
   5550                                             unop(Iop_32HIto16, getIReg(rs)))),
   5551                                   unop(Iop_8Uto32,
   5552                                        unop(Iop_16HIto8,
   5553                                             unop(Iop_32HIto16, getIReg(rt))))));
   5554                      /* t10 will be 1 if there is overflow, 0 otherwise. */
   5555                      assign(t10, binop(Iop_CmpEQ32,
   5556                                        binop(Iop_And32,
   5557                                              mkexpr(t9),
   5558                                              mkU32(0x00000100)),
   5559                                        mkU32(0x00000100)));
   5560                      /* Saturate if necessary. */
   5561                      assign(t11, IRExpr_ITE(mkexpr(t10),
   5562                                             mkU8(0xff),
   5563                                             unop(Iop_32to8, mkexpr(t9))));
   5564 
   5565                      assign(t12,
   5566                             binop(Iop_Or32,
   5567                                   binop(Iop_Or32,
   5568                                         binop(Iop_Or32,
   5569                                               unop(Iop_1Sto32, mkexpr(t10)),
   5570                                               unop(Iop_1Sto32, mkexpr(t7))),
   5571                                         unop(Iop_1Sto32, mkexpr(t4))),
   5572                                   unop(Iop_1Sto32, mkexpr(t1))));
   5573 
   5574                      putDSPControl(IRExpr_ITE(binop(Iop_CmpEQ32,
   5575                                                     mkexpr(t12),
   5576                                                     mkU32(0x0)),
   5577                                               getDSPControl(),
   5578                                               binop(Iop_Or32,
   5579                                                     getDSPControl(),
   5580                                                     mkU32(0x00100000))));
   5581 
   5582                      putIReg(rd,
   5583                              binop(Iop_16HLto32,
   5584                                    binop(Iop_8HLto16, mkexpr(t11), mkexpr(t8)),
   5585                                    binop(Iop_8HLto16, mkexpr(t5), mkexpr(t2))));
   5586                      break;
   5587                   }
   5588                   case 0x05: {  /* SUBU_S.QB */
   5589                      DIP("subu_s.qb r%u, r%u, r%u", rd, rs, rt);
   5590                      vassert(!mode64);
   5591                      t1 = newTemp(Ity_I32);
   5592                      t2 = newTemp(Ity_I1);
   5593                      t3 = newTemp(Ity_I1);
   5594                      t4 = newTemp(Ity_I1);
   5595                      t5 = newTemp(Ity_I1);
   5596                      t6 = newTemp(Ity_I32);
   5597                      t7 = newTemp(Ity_I32);
   5598                      t8 = newTemp(Ity_I32);
   5599                      t9 = newTemp(Ity_I32);
   5600 
   5601                      /* Use C function to easily calculate the result
   5602                         and write it in the register more conveniently
   5603                         Underflow is checked using step by step subtraction. */
   5604                      assign(t1, binop(Iop_QSub8Ux4, getIReg(rs), getIReg(rt)));
   5605 
   5606                      /* Subtract each byte of rs and rt. */
   5607                      assign(t6,
   5608                             binop(Iop_Sub32,
   5609                                   unop(Iop_8Uto32,
   5610                                        unop(Iop_16to8,
   5611                                             unop(Iop_32to16, getIReg(rs)))),
   5612                                   unop(Iop_8Uto32,
   5613                                        unop(Iop_16to8,
   5614                                             unop(Iop_32to16, getIReg(rt))))));
   5615                      assign(t7,
   5616                             binop(Iop_Sub32,
   5617                                   unop(Iop_8Uto32,
   5618                                        unop(Iop_16HIto8,
   5619                                             unop(Iop_32to16, getIReg(rs)))),
   5620                                   unop(Iop_8Uto32,
   5621                                        unop(Iop_16HIto8,
   5622                                             unop(Iop_32to16, getIReg(rt))))));
   5623                      assign(t8,
   5624                             binop(Iop_Sub32,
   5625                                   unop(Iop_8Uto32,
   5626                                        unop(Iop_16to8,
   5627                                             unop(Iop_32HIto16, getIReg(rs)))),
   5628                                   unop(Iop_8Uto32,
   5629                                        unop(Iop_16to8,
   5630                                             unop(Iop_32HIto16, getIReg(rt))))));
   5631                      assign(t9,
   5632                             binop(Iop_Sub32,
   5633                                   unop(Iop_8Uto32,
   5634                                        unop(Iop_16HIto8,
   5635                                             unop(Iop_32HIto16, getIReg(rs)))),
   5636                                   unop(Iop_8Uto32,
   5637                                        unop(Iop_16HIto8,
   5638                                             unop(Iop_32HIto16, getIReg(rt))))));
   5639 
   5640                      /* Put 1 to bit 20 in DSPControl if there is underflow
   5641                         in either byte. */
   5642                      assign(t2, binop(Iop_CmpEQ32,
   5643                                       binop(Iop_And32,
   5644                                             mkexpr(t6),
   5645                                             mkU32(0x00000100)),
   5646                                       mkU32(0x00000100)));
   5647                      putDSPControl(IRExpr_ITE(mkexpr(t2),
   5648                                               binop(Iop_Or32,
   5649                                                     getDSPControl(),
   5650                                                     mkU32(0x00100000)),
   5651                                               getDSPControl()));
   5652                      assign(t3, binop(Iop_CmpEQ32,
   5653                                       binop(Iop_And32,
   5654                                             mkexpr(t7),
   5655                                             mkU32(0x00000100)),
   5656                                       mkU32(0x00000100)));
   5657                      putDSPControl(IRExpr_ITE(mkexpr(t3),
   5658                                               binop(Iop_Or32,
   5659                                                     getDSPControl(),
   5660                                                     mkU32(0x00100000)),
   5661                                               getDSPControl()));
   5662                      assign(t4, binop(Iop_CmpEQ32,
   5663                                       binop(Iop_And32,
   5664                                             mkexpr(t8),
   5665                                             mkU32(0x00000100)),
   5666                                       mkU32(0x00000100)));
   5667                      putDSPControl(IRExpr_ITE(mkexpr(t4),
   5668                                               binop(Iop_Or32,
   5669                                                     getDSPControl(),
   5670                                                     mkU32(0x00100000)),
   5671                                               getDSPControl()));
   5672                      assign(t5, binop(Iop_CmpEQ32,
   5673                                       binop(Iop_And32,
   5674                                             mkexpr(t9),
   5675                                             mkU32(0x00000100)),
   5676                                       mkU32(0x00000100)));
   5677                      putDSPControl(IRExpr_ITE(mkexpr(t5),
   5678                                               binop(Iop_Or32,
   5679                                                     getDSPControl(),
   5680                                                     mkU32(0x00100000)),
   5681                                               getDSPControl()));
   5682                      putIReg(rd, mkexpr(t1));
   5683                      break;
   5684                   }
   5685                   case 0x6: {  /* MULEU_S.PH.QBL */
   5686                      DIP("muleu_s.ph.qbl r%u, r%u, r%u", rd, rs, rt);
   5687                      vassert(!mode64);
   5688                      t0 = newTemp(Ity_I32);
   5689                      t1 = newTemp(Ity_I32);
   5690                      t2 = newTemp(Ity_I1);
   5691                      t3 = newTemp(Ity_I1);
   5692 
   5693                      assign(t0,
   5694                             unop(Iop_64to32,
   5695                                  binop(Iop_MullU32,
   5696                                        unop(Iop_8Uto32,
   5697                                             unop(Iop_16HIto8,
   5698                                                  unop(Iop_32HIto16,
   5699                                                       getIReg(rs)))),
   5700                                        unop(Iop_16Uto32,
   5701                                             unop(Iop_32HIto16, getIReg(rt))))));
   5702                      assign(t1,
   5703                             unop(Iop_64to32,
   5704                                  binop(Iop_MullU32,
   5705                                        unop(Iop_8Uto32,
   5706                                             unop(Iop_16to8,
   5707                                                  unop(Iop_32HIto16,
   5708                                                       getIReg(rs)))),
   5709                                        unop(Iop_16Uto32,
   5710                                             unop(Iop_32to16, getIReg(rt))))));
   5711 
   5712                      assign(t2, binop(Iop_CmpNE32,
   5713                                       mkU32(0x0),
   5714                                       binop(Iop_And32,
   5715                                             mkexpr(t0),
   5716                                             mkU32(0x03ff0000))));
   5717                      assign(t3, binop(Iop_CmpNE32,
   5718                                       mkU32(0x0),
   5719                                       binop(Iop_And32,
   5720                                             mkexpr(t1),
   5721                                             mkU32(0x03ff0000))));
   5722                      putDSPControl(IRExpr_ITE(mkexpr(t2),
   5723                                               binop(Iop_Or32,
   5724                                                     getDSPControl(),
   5725                                                     mkU32(0x200000)),
   5726                                               IRExpr_ITE(mkexpr(t3),
   5727                                                          binop(Iop_Or32,
   5728                                                                getDSPControl(),
   5729                                                                mkU32(0x200000)),
   5730                                                          getDSPControl())));
   5731                      putIReg(rd,
   5732                              binop(Iop_16HLto32,
   5733                                    IRExpr_ITE(mkexpr(t2),
   5734                                               mkU16(0xffff),
   5735                                               unop(Iop_32to16, mkexpr(t0))),
   5736                                    IRExpr_ITE(mkexpr(t3),
   5737                                               mkU16(0xffff),
   5738                                               unop(Iop_32to16, mkexpr(t1)))));
   5739                      break;
   5740                   }
   5741                   case 0x7: {  /* MULEU_S.PH.QBR */
   5742                      DIP("muleu_s.ph.qbr r%u, r%u, r%u", rd, rs, rt);
   5743                      vassert(!mode64);
   5744                      t0 = newTemp(Ity_I32);
   5745                      t1 = newTemp(Ity_I32);
   5746                      t2 = newTemp(Ity_I1);
   5747                      t3 = newTemp(Ity_I1);
   5748 
   5749                      assign(t0, unop(Iop_64to32,
   5750                                      binop(Iop_MullU32,
   5751                                            unop(Iop_8Uto32,
   5752                                                 unop(Iop_16HIto8,
   5753                                                      unop(Iop_32to16,
   5754                                                           getIReg(rs)))),
   5755                                            unop(Iop_16Uto32,
   5756                                                 unop(Iop_32HIto16,
   5757                                                      getIReg(rt))))));
   5758                      assign(t1, unop(Iop_64to32,
   5759                                      binop(Iop_MullU32,
   5760                                            unop(Iop_8Uto32,
   5761                                                 unop(Iop_16to8,
   5762                                                      unop(Iop_32to16,
   5763                                                           getIReg(rs)))),
   5764                                            unop(Iop_16Uto32,
   5765                                                 unop(Iop_32to16,
   5766                                                      getIReg(rt))))));
   5767 
   5768                      assign(t2, binop(Iop_CmpNE32,
   5769                                       mkU32(0x0),
   5770                                       binop(Iop_And32,
   5771                                             mkexpr(t0),
   5772                                             mkU32(0x03ff0000))));
   5773                      assign(t3, binop(Iop_CmpNE32,
   5774                                       mkU32(0x0),
   5775                                       binop(Iop_And32,
   5776                                             mkexpr(t1),
   5777                                             mkU32(0x03ff0000))));
   5778                      putDSPControl(IRExpr_ITE(mkexpr(t2),
   5779                                               binop(Iop_Or32,
   5780                                                     getDSPControl(),
   5781                                                     mkU32(0x200000)),
   5782                                               IRExpr_ITE(mkexpr(t3),
   5783                                                          binop(Iop_Or32,
   5784                                                                getDSPControl(),
   5785                                                                mkU32(0x200000)),
   5786                                                          getDSPControl())));
   5787                      putIReg(rd, binop(Iop_16HLto32,
   5788                                        IRExpr_ITE(mkexpr(t2),
   5789                                                   mkU16(0xffff),
   5790                                                   unop(Iop_32to16,
   5791                                                        mkexpr(t0))),
   5792                                        IRExpr_ITE(mkexpr(t3),
   5793                                                   mkU16(0xffff),
   5794                                                   unop(Iop_32to16,
   5795                                                        mkexpr(t1)))));
   5796                      break;
   5797                   }
   5798                   case 0x08: {  /* ADDU.PH */
   5799                      DIP("addu.ph r%u, r%u, r%u", rd, rs, rt);
   5800                      vassert(!mode64);
   5801                      t0 = newTemp(Ity_I32);
   5802                      t1 = newTemp(Ity_I1);
   5803                      t2 = newTemp(Ity_I32);
   5804                      t3 = newTemp(Ity_I1);
   5805 
   5806                      /* Add lower halves. */
   5807                      assign(t0, binop(Iop_Add32,
   5808                                       unop(Iop_16Uto32,
   5809                                            unop(Iop_32to16, getIReg(rs))),
   5810                                       unop(Iop_16Uto32,
   5811                                            unop(Iop_32to16, getIReg(rt)))));
   5812 
   5813                      /* Detect overflow. */
   5814                      assign(t1, binop(Iop_CmpLT32U,
   5815                                       unop(Iop_16Uto32,
   5816                                            unop(Iop_32to16, mkexpr(t0))),
   5817                                       unop(Iop_16Uto32,
   5818                                            unop(Iop_32to16, getIReg(rs)))));
   5819 
   5820                      putDSPControl(IRExpr_ITE(mkexpr(t1),
   5821                                               binop(Iop_Or32,
   5822                                                     getDSPControl(),
   5823                                                     mkU32(0x00100000)),
   5824                                               getDSPControl()));
   5825 
   5826                      /* Add higher halves. */
   5827                      assign(t2, binop(Iop_Add32,
   5828                                       unop(Iop_16Uto32,
   5829                                            unop(Iop_32HIto16, getIReg(rs))),
   5830                                       unop(Iop_16Uto32,
   5831                                            unop(Iop_32HIto16, getIReg(rt)))));
   5832 
   5833                      /* Detect overflow. */
   5834                      assign(t3, binop(Iop_CmpLT32U,
   5835                                       unop(Iop_16Uto32,
   5836                                            unop(Iop_32to16, mkexpr(t2))),
   5837                                       unop(Iop_16Uto32,
   5838                                            unop(Iop_32HIto16,
   5839                                                 getIReg(rs)))));
   5840 
   5841                      putDSPControl(IRExpr_ITE(mkexpr(t3),
   5842                                               binop(Iop_Or32,
   5843                                                     getDSPControl(),
   5844                                                     mkU32(0x00100000)),
   5845                                               getDSPControl()));
   5846 
   5847                      putIReg(rd, binop(Iop_16HLto32,
   5848                                        unop(Iop_32to16, mkexpr(t2)),
   5849                                        unop(Iop_32to16, mkexpr(t0))));
   5850                      break;
   5851                   }
   5852                   case 0x9: {  /* SUBU.PH */
   5853                      DIP("subu.ph r%u, r%u, r%u", rd, rs, rt);
   5854                      vassert(!mode64);
   5855                      t0 = newTemp(Ity_I32);
   5856                      t1 = newTemp(Ity_I1);
   5857                      t2 = newTemp(Ity_I32);
   5858                      t3 = newTemp(Ity_I1);
   5859 
   5860                      /* Substract lower halves. */
   5861                      assign(t0, binop(Iop_Sub32,
   5862                                       unop(Iop_16Uto32,
   5863                                            unop(Iop_32to16, getIReg(rs))),
   5864                                       unop(Iop_16Uto32,
   5865                                            unop(Iop_32to16, getIReg(rt)))));
   5866 
   5867                      /* Detect underflow. */
   5868                      assign(t1, binop(Iop_CmpNE32,
   5869                                       binop(Iop_And32,
   5870                                             mkexpr(t0),
   5871                                             mkU32(0x00010000)),
   5872                                       mkU32(0x0)));
   5873 
   5874                      putDSPControl(IRExpr_ITE(mkexpr(t1),
   5875                                               binop(Iop_Or32,
   5876                                                     getDSPControl(),
   5877                                                     mkU32(0x00100000)),
   5878                                               getDSPControl()));
   5879 
   5880                      /* Subtract higher halves. */
   5881                      assign(t2, binop(Iop_Sub32,
   5882                                       unop(Iop_16Uto32,
   5883                                            unop(Iop_32HIto16, getIReg(rs))),
   5884                                       unop(Iop_16Uto32,
   5885                                            unop(Iop_32HIto16, getIReg(rt)))));
   5886 
   5887                      /* Detect underflow. */
   5888                      assign(t3, binop(Iop_CmpNE32,
   5889                                       binop(Iop_And32,
   5890                                             mkexpr(t2),
   5891                                             mkU32(0x00010000)),
   5892                                       mkU32(0x0)));
   5893 
   5894                      putDSPControl(IRExpr_ITE(mkexpr(t3),
   5895                                               binop(Iop_Or32,
   5896                                                     getDSPControl(),
   5897                                                     mkU32(0x00100000)),
   5898                                               getDSPControl()));
   5899 
   5900                      putIReg(rd, binop(Iop_16HLto32,
   5901                                        unop(Iop_32to16, mkexpr(t2)),
   5902                                        unop(Iop_32to16, mkexpr(t0))));
   5903                      break;
   5904                   }
   5905                   case 0xA: {  /* ADDQ.PH */
   5906                      DIP("addq.ph r%u, r%u, r%u", rd, rs, rt);
   5907                      vassert(!mode64);
   5908                      t0 = newTemp(Ity_I32);
   5909                      t1 = newTemp(Ity_I1);
   5910                      t2 = newTemp(Ity_I32);
   5911                      t3 = newTemp(Ity_I1);
   5912                      t6 = newTemp(Ity_I32);
   5913                      t7 = newTemp(Ity_I32);
   5914 
   5915                      /* Add lower halves. */
   5916                      assign(t0, binop(Iop_Add32,
   5917                                       unop(Iop_16Sto32,
   5918                                            unop(Iop_32to16, getIReg(rs))),
   5919                                       unop(Iop_16Sto32,
   5920                                            unop(Iop_32to16, getIReg(rt)))));
   5921 
   5922                      /* Bit 16 of the result. */
   5923                      assign(t6, binop(Iop_And32,
   5924                                       unop(Iop_16Uto32,
   5925                                            unop(Iop_32HIto16, mkexpr(t0))),
   5926                                       mkU32(0x1)));
   5927                      /* Detect overflow. */
   5928                      assign(t1, binop(Iop_CmpNE32,
   5929                                       binop(Iop_Shr32,
   5930                                             binop(Iop_And32,
   5931                                                   mkexpr(t0),
   5932                                                   mkU32(0x8000)),
   5933                                             mkU8(15)),
   5934                                       mkexpr(t6)));
   5935 
   5936                      putDSPControl(IRExpr_ITE(mkexpr(t1),
   5937                                               binop(Iop_Or32,
   5938                                                     getDSPControl(),
   5939                                                     mkU32(0x00100000)),
   5940                                               getDSPControl()));
   5941 
   5942                      /* Add higher halves. */
   5943                      assign(t2, binop(Iop_Add32,
   5944                                       unop(Iop_16Sto32,
   5945                                            unop(Iop_32HIto16, getIReg(rs))),
   5946                                       unop(Iop_16Sto32,
   5947                                            unop(Iop_32HIto16, getIReg(rt)))));
   5948 
   5949                      /* Bit 16 of the result. */
   5950                      assign(t7, binop(Iop_And32,
   5951                                       unop(Iop_16Uto32,
   5952                                            unop(Iop_32HIto16, mkexpr(t2))),
   5953                                       mkU32(0x1)));
   5954                      /* Detect overflow. */
   5955                      assign(t3, binop(Iop_CmpNE32,
   5956                                       binop(Iop_Shr32,
   5957                                             binop(Iop_And32,
   5958                                                   mkexpr(t2),
   5959                                                   mkU32(0x00008000)),
   5960                                             mkU8(15)),
   5961                                       mkexpr(t7)));
   5962 
   5963                      putDSPControl(IRExpr_ITE(mkexpr(t3),
   5964                                               binop(Iop_Or32,
   5965                                                     getDSPControl(),
   5966                                                     mkU32(0x00100000)),
   5967                                               getDSPControl()));
   5968 
   5969                      putIReg(rd, binop(Iop_16HLto32,
   5970                                        unop(Iop_32to16, mkexpr(t2)),
   5971                                        unop(Iop_32to16, mkexpr(t0))));
   5972                      break;
   5973                   }
   5974                   case 0xB: {  /* SUBQ.PH */
   5975                      DIP("subq.ph r%u, r%u, r%u", rd, rs, rt);
   5976                      vassert(!mode64);
   5977                      t0 = newTemp(Ity_I32);
   5978                      t1 = newTemp(Ity_I1);
   5979                      t2 = newTemp(Ity_I32);
   5980                      t3 = newTemp(Ity_I1);
   5981                      t6 = newTemp(Ity_I32);
   5982                      t7 = newTemp(Ity_I32);
   5983 
   5984                      /* Subtract lower halves. */
   5985                      assign(t0, binop(Iop_Sub32,
   5986                                       unop(Iop_16Sto32,
   5987                                            unop(Iop_32to16, getIReg(rs))),
   5988                                       unop(Iop_16Sto32,
   5989                                            unop(Iop_32to16, getIReg(rt)))));
   5990 
   5991                      /* Bit 16 of the result. */
   5992                      assign(t6, binop(Iop_And32,
   5993                                       unop(Iop_16Uto32,
   5994                                            unop(Iop_32HIto16, mkexpr(t0))),
   5995                                       mkU32(0x1)));
   5996                      /* Compare the signs of input value and the result. */
   5997                      assign(t1, binop(Iop_CmpNE32,
   5998                                       binop(Iop_Shr32,
   5999                                             binop(Iop_And32,
   6000                                                   mkexpr(t0),
   6001                                                   mkU32(0x8000)),
   6002                                             mkU8(15)),
   6003                                       mkexpr(t6)));
   6004 
   6005                      putDSPControl(IRExpr_ITE(mkexpr(t1),
   6006                                               binop(Iop_Or32,
   6007                                                     getDSPControl(),
   6008                                                     mkU32(0x00100000)),
   6009                                               getDSPControl()));
   6010 
   6011                      /* Subtract higher halves. */
   6012                      assign(t2, binop(Iop_Sub32,
   6013                                       unop(Iop_16Sto32,
   6014                                            unop(Iop_32HIto16, getIReg(rs))),
   6015                                       unop(Iop_16Sto32,
   6016                                            unop(Iop_32HIto16, getIReg(rt)))));
   6017 
   6018                      /* Bit 16 of the result. */
   6019                      assign(t7, binop(Iop_And32,
   6020                                       unop(Iop_16Uto32,
   6021                                            unop(Iop_32HIto16, mkexpr(t2))),
   6022                                       mkU32(0x1)));
   6023                      /* Compare the signs of input value and the result. */
   6024                      assign(t3, binop(Iop_CmpNE32,
   6025                                       binop(Iop_Shr32,
   6026                                             binop(Iop_And32,
   6027                                                   mkexpr(t2),
   6028                                                   mkU32(0x00008000)),
   6029                                             mkU8(15)),
   6030                                       mkexpr(t7)));
   6031 
   6032                      putDSPControl(IRExpr_ITE(mkexpr(t3),
   6033                                               binop(Iop_Or32,
   6034                                                     getDSPControl(),
   6035                                                     mkU32(0x00100000)),
   6036                                               getDSPControl()));
   6037 
   6038                      putIReg(rd, binop(Iop_16HLto32,
   6039                                        unop(Iop_32to16, mkexpr(t2)),
   6040                                        unop(Iop_32to16, mkexpr(t0))));
   6041                      break;
   6042                   }
   6043                   case 0xC: {  /* ADDU_S.PH */
   6044                      DIP("addu_s.ph r%u, r%u, r%u", rd, rs, rt);
   6045                      vassert(!mode64);
   6046                      t0 = newTemp(Ity_I32);
   6047                      t1 = newTemp(Ity_I1);
   6048                      t2 = newTemp(Ity_I32);
   6049                      t3 = newTemp(Ity_I1);
   6050 
   6051                      /* Add lower halves. */
   6052                      assign(t0, binop(Iop_Add32,
   6053                                       unop(Iop_16Uto32,
   6054                                            unop(Iop_32to16, getIReg(rs))),
   6055                                       unop(Iop_16Uto32,
   6056                                            unop(Iop_32to16, getIReg(rt)))));
   6057 
   6058                      /* Detect overflow. */
   6059                      assign(t1, binop(Iop_CmpLT32U,
   6060                                       unop(Iop_16Uto32,
   6061                                            unop(Iop_32to16, mkexpr(t0))),
   6062                                       unop(Iop_16Uto32,
   6063                                            unop(Iop_32to16, getIReg(rs)))));
   6064 
   6065                      putDSPControl(IRExpr_ITE(mkexpr(t1),
   6066                                               binop(Iop_Or32,
   6067                                                     getDSPControl(),
   6068                                                     mkU32(0x00100000)),
   6069                                               getDSPControl()));
   6070 
   6071                      /* Add higher halves. */
   6072                      assign(t2, binop(Iop_Add32,
   6073                                       unop(Iop_16Uto32,
   6074                                            unop(Iop_32HIto16, getIReg(rs))),
   6075                                       unop(Iop_16Uto32,
   6076                                            unop(Iop_32HIto16, getIReg(rt)))));
   6077 
   6078                      /* Detect overflow. */
   6079                      assign(t3, binop(Iop_CmpLT32U,
   6080                                       unop(Iop_16Uto32,
   6081                                            unop(Iop_32to16, mkexpr(t2))),
   6082                                       unop(Iop_16Uto32,
   6083                                            unop(Iop_32HIto16, getIReg(rs)))));
   6084 
   6085                      putDSPControl(IRExpr_ITE(mkexpr(t3),
   6086                                               binop(Iop_Or32,
   6087                                                     getDSPControl(),
   6088                                                     mkU32(0x00100000)),
   6089                                               getDSPControl()));
   6090 
   6091                      putIReg(rd, binop(Iop_16HLto32,
   6092                                        IRExpr_ITE(mkexpr(t3),
   6093                                                   mkU16(0xffff),
   6094                                                   unop(Iop_32to16,
   6095                                                        mkexpr(t2))),
   6096                                        IRExpr_ITE(mkexpr(t1),
   6097                                                   mkU16(0xffff),
   6098                                                   unop(Iop_32to16,
   6099                                                        mkexpr(t0)))));
   6100                      break;
   6101                   }
   6102                   case 0xD: {  /* SUBU_S.PH */
   6103                      DIP("subu_s.ph r%u, r%u, r%u", rd, rs, rt);
   6104                      vassert(!mode64);
   6105                      t0 = newTemp(Ity_I32);
   6106                      t1 = newTemp(Ity_I1);
   6107                      t2 = newTemp(Ity_I32);
   6108                      t3 = newTemp(Ity_I1);
   6109 
   6110                      /* Subtract lower halves. */
   6111                      assign(t0, binop(Iop_Sub32,
   6112                                       unop(Iop_16Uto32,
   6113                                            unop(Iop_32to16, getIReg(rs))),
   6114                                       unop(Iop_16Uto32,
   6115                                            unop(Iop_32to16, getIReg(rt)))));
   6116 
   6117                      /* Detect underflow. */
   6118                      assign(t1, binop(Iop_CmpNE32,
   6119                                       binop(Iop_And32,
   6120                                             mkexpr(t0), mkU32(0x00010000)),
   6121                                       mkU32(0x0)));
   6122 
   6123                      putDSPControl(IRExpr_ITE(mkexpr(t1),
   6124                                               binop(Iop_Or32,
   6125                                                     getDSPControl(),
   6126                                                     mkU32(0x00100000)),
   6127                                               getDSPControl()));
   6128 
   6129                      /* Subtract higher halves. */
   6130                      assign(t2, binop(Iop_Sub32,
   6131                                       unop(Iop_16Uto32,
   6132                                            unop(Iop_32HIto16, getIReg(rs))),
   6133                                       unop(Iop_16Uto32,
   6134                                            unop(Iop_32HIto16, getIReg(rt)))));
   6135 
   6136                      /* Detect underflow. */
   6137                      assign(t3, binop(Iop_CmpNE32,
   6138                                       binop(Iop_And32,
   6139                                             mkexpr(t2), mkU32(0x00010000)),
   6140                                       mkU32(0x0)));
   6141 
   6142                      putDSPControl(IRExpr_ITE(mkexpr(t3),
   6143                                               binop(Iop_Or32,
   6144                                                     getDSPControl(),
   6145                                                     mkU32(0x00100000)),
   6146                                               getDSPControl()));
   6147 
   6148                      putIReg(rd,
   6149                              binop(Iop_16HLto32,
   6150                                    IRExpr_ITE(mkexpr(t3),
   6151                                               mkU16(0x0000),
   6152                                               unop(Iop_32to16, mkexpr(t2))),
   6153                                    IRExpr_ITE(mkexpr(t1),
   6154                                               mkU16(0x0000),
   6155                                               unop(Iop_32to16, mkexpr(t0)))));
   6156                      break;
   6157                   }
   6158                   case 0xE: {  /* ADDQ_S.PH */
   6159                      DIP("addq_s.ph r%u r%u, r%u", rd, rs, rt);
   6160                      vassert(!mode64);
   6161                      t0 = newTemp(Ity_I32);
   6162                      t1 = newTemp(Ity_I1);
   6163                      t2 = newTemp(Ity_I32);
   6164                      t3 = newTemp(Ity_I1);
   6165                      t4 = newTemp(Ity_I16);
   6166                      t5 = newTemp(Ity_I16);
   6167                      t6 = newTemp(Ity_I32);
   6168                      t7 = newTemp(Ity_I32);
   6169 
   6170                      /* Add lower halves. */
   6171                      assign(t0, binop(Iop_Add32,
   6172                                       unop(Iop_16Sto32,
   6173                                            unop(Iop_32to16, getIReg(rs))),
   6174                                       unop(Iop_16Sto32,
   6175                                            unop(Iop_32to16, getIReg(rt)))));
   6176 
   6177                      /* Bit 16 of the result. */
   6178                      assign(t6, binop(Iop_And32,
   6179                                       unop(Iop_16Uto32,
   6180                                            unop(Iop_32HIto16, mkexpr(t0))),
   6181                                       mkU32(0x1)));
   6182                      /* Detect overflow. */
   6183                      assign(t1, binop(Iop_CmpNE32,
   6184                                       binop(Iop_Shr32,
   6185                                             binop(Iop_And32,
   6186                                                   mkexpr(t0),
   6187                                                   mkU32(0x8000)),
   6188                                             mkU8(15)),
   6189                                       mkexpr(t6)));
   6190 
   6191                      putDSPControl(IRExpr_ITE(mkexpr(t1),
   6192                                               binop(Iop_Or32,
   6193                                                     getDSPControl(),
   6194                                                     mkU32(0x00100000)),
   6195                                               getDSPControl()));
   6196                      /* Saturate if needed. */
   6197                      assign(t4, IRExpr_ITE(mkexpr(t1),
   6198                                            IRExpr_ITE(binop(Iop_CmpEQ32,
   6199                                                             mkexpr(t6),
   6200                                                             mkU32(0x0)),
   6201                                                       mkU16(0x7fff),
   6202                                                       mkU16(0x8000)),
   6203                                            unop(Iop_32to16, mkexpr(t0))));
   6204 
   6205                      /* Add higher halves. */
   6206                      assign(t2, binop(Iop_Add32,
   6207                                       unop(Iop_16Sto32,
   6208                                            unop(Iop_32HIto16, getIReg(rs))),
   6209                                       unop(Iop_16Sto32,
   6210                                            unop(Iop_32HIto16, getIReg(rt)))));
   6211 
   6212                      /* Bit 16 of the result. */
   6213                      assign(t7, binop(Iop_And32,
   6214                                       unop(Iop_16Uto32,
   6215                                            unop(Iop_32HIto16, mkexpr(t2))),
   6216                                       mkU32(0x1)));
   6217                      /* Detect overflow. */
   6218                      assign(t3, binop(Iop_CmpNE32,
   6219                                       binop(Iop_Shr32,
   6220                                             binop(Iop_And32,
   6221                                                   mkexpr(t2),
   6222                                                   mkU32(0x00008000)),
   6223                                             mkU8(15)),
   6224                                       mkexpr(t7)));
   6225 
   6226                      putDSPControl(IRExpr_ITE(mkexpr(t3),
   6227                                               binop(Iop_Or32,
   6228                                                     getDSPControl(),
   6229                                                     mkU32(0x00100000)),
   6230                                               getDSPControl()));
   6231                      /* Saturate if needed. */
   6232                      assign(t5, IRExpr_ITE(mkexpr(t3),
   6233                                            IRExpr_ITE(binop(Iop_CmpEQ32,
   6234                                                             mkexpr(t7),
   6235                                                             mkU32(0x0)),
   6236                                                       mkU16(0x7fff),
   6237                                                       mkU16(0x8000)),
   6238                                            unop(Iop_32to16, mkexpr(t2))));
   6239 
   6240                      putIReg(rd, binop(Iop_16HLto32, mkexpr(t5), mkexpr(t4)));
   6241                      break;
   6242                   }
   6243                   case 0xF: {  /* SUBQ_S.PH */
   6244                      DIP("subq_s.ph r%u r%u, r%u", rd, rs, rt);
   6245                      vassert(!mode64);
   6246                      t0 = newTemp(Ity_I32);
   6247                      t1 = newTemp(Ity_I1);
   6248                      t2 = newTemp(Ity_I32);
   6249                      t3 = newTemp(Ity_I1);
   6250                      t4 = newTemp(Ity_I16);
   6251                      t5 = newTemp(Ity_I16);
   6252                      t6 = newTemp(Ity_I32);
   6253                      t7 = newTemp(Ity_I32);
   6254 
   6255                      /* Subtract lower halves. */
   6256                      assign(t0, binop(Iop_Sub32,
   6257                                       unop(Iop_16Sto32,
   6258                                            unop(Iop_32to16, getIReg(rs))),
   6259                                       unop(Iop_16Sto32,
   6260                                            unop(Iop_32to16, getIReg(rt)))));
   6261 
   6262                      /* Bit 16 of the result. */
   6263                      assign(t6, binop(Iop_And32,
   6264                                       unop(Iop_16Uto32,
   6265                                            unop(Iop_32HIto16, mkexpr(t0))),
   6266                                       mkU32(0x1)));
   6267                      /* Detect overflow or underflow. */
   6268                      assign(t1, binop(Iop_CmpNE32,
   6269                                       binop(Iop_Shr32,
   6270                                             binop(Iop_And32,
   6271                                                   mkexpr(t0),
   6272                                                   mkU32(0x8000)),
   6273                                             mkU8(15)),
   6274                                       mkexpr(t6)));
   6275 
   6276                      putDSPControl(IRExpr_ITE(mkexpr(t1),
   6277                                               binop(Iop_Or32,
   6278                                                     getDSPControl(),
   6279                                                     mkU32(0x00100000)),
   6280                                               getDSPControl()));
   6281                      /* Saturate if needed. */
   6282                      assign(t4, IRExpr_ITE(mkexpr(t1),
   6283                                            IRExpr_ITE(binop(Iop_CmpEQ32,
   6284                                                             mkexpr(t6),
   6285                                                             mkU32(0x0)),
   6286                                                       mkU16(0x7fff),
   6287                                                       mkU16(0x8000)),
   6288                                            unop(Iop_32to16, mkexpr(t0))));
   6289 
   6290                      /* Subtract higher halves. */
   6291                      assign(t2, binop(Iop_Sub32,
   6292                                       unop(Iop_16Sto32,
   6293                                            unop(Iop_32HIto16, getIReg(rs))),
   6294                                       unop(Iop_16Sto32,
   6295                                            unop(Iop_32HIto16, getIReg(rt)))));
   6296 
   6297                      /* Bit 16 of the result. */
   6298                      assign(t7, binop(Iop_And32,
   6299                                       unop(Iop_16Uto32,
   6300                                            unop(Iop_32HIto16, mkexpr(t2))),
   6301                                       mkU32(0x1)));
   6302                      /* Detect overflow or underflow. */
   6303                      assign(t3, binop(Iop_CmpNE32,
   6304                                       binop(Iop_Shr32,
   6305                                             binop(Iop_And32,
   6306                                                   mkexpr(t2),
   6307                                                   mkU32(0x00008000)),
   6308                                             mkU8(15)),
   6309                                       mkexpr(t7)));
   6310 
   6311                      putDSPControl(IRExpr_ITE(mkexpr(t3),
   6312                                               binop(Iop_Or32,
   6313                                                     getDSPControl(),
   6314                                                     mkU32(0x00100000)),
   6315                                               getDSPControl()));
   6316                      /* Saturate if needed. */
   6317                      assign(t5, IRExpr_ITE(mkexpr(t3),
   6318                                            IRExpr_ITE(binop(Iop_CmpEQ32,
   6319                                                             mkexpr(t7),
   6320                                                             mkU32(0x0)),
   6321                                                       mkU16(0x7fff),
   6322                                                       mkU16(0x8000)),
   6323                                            unop(Iop_32to16, mkexpr(t2))));
   6324 
   6325                      putIReg(rd, binop(Iop_16HLto32, mkexpr(t5), mkexpr(t4)));
   6326                      break;
   6327                   }
   6328                   case 0x10: {  /* ADDSC */
   6329                      DIP("addsc r%u, r%u, r%u", rd, rs, rt);
   6330                      vassert(!mode64);
   6331                      t0 = newTemp(Ity_I64);
   6332                      t1 = newTemp(Ity_I1);
   6333 
   6334                      /* The carry bit result out of the addition operation is
   6335                         written to bit 13(the c field) of the DSPControl reg. */
   6336                      assign(t0, binop(Iop_Add64,
   6337                                       unop(Iop_32Uto64, getIReg(rs)),
   6338                                       unop(Iop_32Uto64, getIReg(rt))));
   6339 
   6340                      assign(t1, binop(Iop_CmpEQ32,
   6341                                       binop(Iop_And32,
   6342                                             unop(Iop_64HIto32, mkexpr(t0)),
   6343                                             mkU32(0x1)),
   6344                                       mkU32(0x1)));
   6345                      putDSPControl(IRExpr_ITE(mkexpr(t1),
   6346                                               binop(Iop_Or32,
   6347                                                     getDSPControl(),
   6348                                                     mkU32(0x2000)),
   6349                                               binop(Iop_And32,
   6350                                                     getDSPControl(),
   6351                                                     mkU32(0xffffdfff))));
   6352 
   6353                      putIReg(rd, unop(Iop_64to32, mkexpr(t0)));
   6354                      break;
   6355                   }
   6356                   case 0x11: {  /* ADDWC */
   6357                      DIP("addwc r%u, r%u, r%u", rd, rs, rt);
   6358                      vassert(!mode64);
   6359                      t0 = newTemp(Ity_I32);
   6360                      t1 = newTemp(Ity_I64);
   6361                      t2 = newTemp(Ity_I32);
   6362                      t3 = newTemp(Ity_I32);
   6363                      t4 = newTemp(Ity_I1);
   6364 
   6365                      /* Get carry bit from DSPControl register. */
   6366                      assign(t0, binop(Iop_Shr32,
   6367                                        binop(Iop_And32,
   6368                                              getDSPControl(),
   6369                                              mkU32(0x2000)),
   6370                                        mkU8(0xd)));
   6371                      assign(t1, binop(Iop_Add64,
   6372                                       unop(Iop_32Sto64, getIReg(rs)),
   6373                                       unop(Iop_32Sto64,
   6374                                            binop(Iop_Add32,
   6375                                                  getIReg(rt),
   6376                                                  mkexpr(t0)))));
   6377 
   6378                      /* Extract bits 32 and 31. */
   6379                      assign(t2, binop(Iop_And32,
   6380                                       unop(Iop_64HIto32, mkexpr(t1)),
   6381                                       mkU32(0x1)));
   6382                      assign(t3, binop(Iop_Shr32,
   6383                                       binop(Iop_And32,
   6384                                             unop(Iop_64to32, mkexpr(t1)),
   6385                                             mkU32(0x80000000)),
   6386                                       mkU8(31)));
   6387                      assign(t4, binop(Iop_CmpNE32, mkexpr(t2), mkexpr(t3)));
   6388 
   6389                      putDSPControl(IRExpr_ITE(mkexpr(t4),
   6390                                               binop(Iop_Or32,
   6391                                                     getDSPControl(),
   6392                                                     mkU32(0x00100000)),
   6393                                               getDSPControl()));
   6394                      putIReg(rd, unop(Iop_64to32, mkexpr(t1)));
   6395                      break;
   6396                   }
   6397                   case 0x12: {  /* MODSUB */
   6398                      DIP("modsub r%u, r%u, r%u", rd, rs, rt);
   6399                      vassert(!mode64);
   6400                      t0 = newTemp(Ity_I32);
   6401                      t1 = newTemp(Ity_I32);
   6402                      t2 = newTemp(Ity_I32);
   6403 
   6404                      /* decr_7..0 */
   6405                      assign(t0,
   6406                             unop(Iop_8Uto32,
   6407                                  unop(Iop_16to8,
   6408                                       unop(Iop_32to16, getIReg(rt)))));
   6409 
   6410                      /* lastindex_15..0 */
   6411                      assign(t1,
   6412                             unop(Iop_16Uto32,
   6413                                  binop(Iop_8HLto16,
   6414                                        unop(Iop_16to8,
   6415                                             unop(Iop_32HIto16, getIReg(rt))),
   6416                                        unop(Iop_16HIto8,
   6417                                             unop(Iop_32to16, getIReg(rt))))));
   6418                      /* temp_15..0 */
   6419                      assign(t2,
   6420                             IRExpr_ITE(binop(Iop_CmpEQ32,
   6421                                              getIReg(rs),
   6422                                              mkU32(0x00000000)),
   6423                                        mkexpr(t1),
   6424                                        binop(Iop_Sub32,
   6425                                              getIReg(rs), mkexpr(t0))));
   6426                      putIReg(rd, mkexpr(t2));
   6427                      break;
   6428                   }
   6429                   case 0x14: {  /* RADDU.W.QB */
   6430                      DIP("raddu.w.qb r%u, r%u", rd, rs);
   6431                      vassert(!mode64);
   6432                      putIReg(rd, binop(Iop_Add32,
   6433                                        binop(Iop_Add32,
   6434                                              unop(Iop_8Uto32,
   6435                                                   unop(Iop_16to8,
   6436                                                        unop(Iop_32to16,
   6437                                                             getIReg(rs)))),
   6438                                              unop(Iop_8Uto32,
   6439                                                   unop(Iop_16HIto8,
   6440                                                        unop(Iop_32to16,
   6441                                                             getIReg(rs))))),
   6442                                        binop(Iop_Add32,
   6443                                              unop(Iop_8Uto32,
   6444                                                   unop(Iop_16to8,
   6445                                                        unop(Iop_32HIto16,
   6446                                                             getIReg(rs)))),
   6447                                              unop(Iop_8Uto32,
   6448                                                   unop(Iop_16HIto8,
   6449                                                        unop(Iop_32HIto16,
   6450                                                             getIReg(rs)))))));
   6451                      break;
   6452                   }
   6453                   case 0x16: {  /* ADDQ_S.W */
   6454                      DIP("addq_s.w r%u, r%u, r%u", rd, rs, rt);
   6455                      vassert(!mode64);
   6456                      t0 = newTemp(Ity_I64);
   6457                      t1 = newTemp(Ity_I1);
   6458                      t2 = newTemp(Ity_I32);
   6459                      t3 = newTemp(Ity_I32);
   6460 
   6461                      assign(t0, binop(Iop_Add64,
   6462                                       unop(Iop_32Sto64, getIReg(rs)),
   6463                                       unop(Iop_32Sto64, getIReg(rt))));
   6464 
   6465                      assign(t3, binop(Iop_And32,
   6466                                       unop(Iop_64HIto32, mkexpr(t0)),
   6467                                       mkU32(0x1)));
   6468                      assign(t1, binop(Iop_CmpNE32,
   6469                                       binop(Iop_Shr32,
   6470                                             binop(Iop_And32,
   6471                                                   unop(Iop_64to32, mkexpr(t0)),
   6472                                                   mkU32(0x80000000)),
   6473                                             mkU8(31)),
   6474                                       mkexpr(t3)));
   6475 
   6476                      putDSPControl(IRExpr_ITE(mkexpr(t1),
   6477                                               binop(Iop_Or32,
   6478                                                     getDSPControl(),
   6479                                                     mkU32(0x00100000)),
   6480                                               getDSPControl()));
   6481 
   6482                      putIReg(rd, IRExpr_ITE(mkexpr(t1),
   6483                                             IRExpr_ITE(binop(Iop_CmpEQ32,
   6484                                                              mkexpr(t3),
   6485                                                              mkU32(0x0)),
   6486                                                        mkU32(0x7fffffff),
   6487                                                        mkU32(0x80000000)),
   6488                                             unop(Iop_64to32, mkexpr(t0))));
   6489                      break;
   6490                   }
   6491                   case 0x17: {  /* SUBQ_S.W */
   6492                      DIP("subq_s.w r%u, r%u, r%u", rd, rs, rt);
   6493                      vassert(!mode64);
   6494                      t0 = newTemp(Ity_I64);
   6495                      t1 = newTemp(Ity_I1);
   6496                      t2 = newTemp(Ity_I32);
   6497                      t3 = newTemp(Ity_I32);
   6498 
   6499                      assign(t0, binop(Iop_Sub64,
   6500                                       unop(Iop_32Sto64, getIReg(rs)),
   6501                                       unop(Iop_32Sto64, getIReg(rt))));
   6502 
   6503                      assign(t3, binop(Iop_And32,
   6504                                       unop(Iop_64HIto32, mkexpr(t0)),
   6505                                       mkU32(0x1)));
   6506                      assign(t1, binop(Iop_CmpNE32,
   6507                                       binop(Iop_Shr32,
   6508                                             binop(Iop_And32,
   6509                                                   unop(Iop_64to32, mkexpr(t0)),
   6510                                                   mkU32(0x80000000)),
   6511                                             mkU8(31)),
   6512                                       mkexpr(t3)));
   6513 
   6514                      putDSPControl(IRExpr_ITE(mkexpr(t1),
   6515                                               binop(Iop_Or32,
   6516                                                     getDSPControl(),
   6517                                                     mkU32(0x00100000)),
   6518                                               getDSPControl()));
   6519 
   6520                      putIReg(rd, IRExpr_ITE(mkexpr(t1),
   6521                                             IRExpr_ITE(binop(Iop_CmpEQ32,
   6522                                                              mkexpr(t3),
   6523                                                              mkU32(0x0)),
   6524                                                        mkU32(0x7fffffff),
   6525                                                        mkU32(0x80000000)),
   6526                                             unop(Iop_64to32, mkexpr(t0))));
   6527                      break;
   6528                   }
   6529                   case 0x1C: {  /* MULEQ_S.W.PHL */
   6530                      DIP("muleq_s.w.phl r%u, r%u, r%u", rd, rs, rt);
   6531                      vassert(!mode64);
   6532                      t0 = newTemp(Ity_I32);
   6533                      t1 = newTemp(Ity_I1);
   6534                      t2 = newTemp(Ity_I1);
   6535                      t3 = newTemp(Ity_I32);
   6536 
   6537                      assign(t0,
   6538                             binop(Iop_Shl32,
   6539                                   binop(Iop_Mul32,
   6540                                         unop(Iop_16Sto32,
   6541                                              unop(Iop_32HIto16, getIReg(rt))),
   6542                                         unop(Iop_16Sto32,
   6543                                              unop(Iop_32HIto16, getIReg(rs)))),
   6544                                   mkU8(0x1)));
   6545                      assign(t1, binop(Iop_CmpEQ32,
   6546                                       binop(Iop_And32,
   6547                                             getIReg(rt),
   6548                                             mkU32(0xffff0000)),
   6549                                       mkU32(0x80000000)));
   6550                      assign(t2, binop(Iop_CmpEQ32,
   6551                                       binop(Iop_And32,
   6552                                             getIReg(rs),
   6553                                             mkU32(0xffff0000)),
   6554                                       mkU32(0x80000000)));
   6555                      assign(t3, IRExpr_ITE(mkexpr(t1),
   6556                                            IRExpr_ITE(mkexpr(t2),
   6557                                                       binop(Iop_Or32,
   6558                                                             getDSPControl(),
   6559                                                             mkU32(0x00200000)),
   6560                                                       getDSPControl()),
   6561                                            getDSPControl()));
   6562                      putDSPControl(mkexpr(t3));
   6563 
   6564                      putIReg(rd, IRExpr_ITE(mkexpr(t1),
   6565                                             IRExpr_ITE(mkexpr(t2),
   6566                                                        mkU32(0x7fffffff),
   6567                                                        mkexpr(t0)),
   6568                                             mkexpr(t0)));
   6569                      break;
   6570                   }
   6571                   case 0x1D: {  /* MULEQ_S.W.PHR */
   6572                      DIP("muleq_s.w.phr r%u, r%u, r%u", rd, rs, rt);
   6573                      vassert(!mode64);
   6574                      t0 = newTemp(Ity_I32);
   6575                      t1 = newTemp(Ity_I1);
   6576                      t2 = newTemp(Ity_I1);
   6577 
   6578                      assign(t0,
   6579                             binop(Iop_Shl32,
   6580                                   binop(Iop_Mul32,
   6581                                         unop(Iop_16Sto32,
   6582                                              unop(Iop_32to16, getIReg(rt))),
   6583                                         unop(Iop_16Sto32,
   6584                                              unop(Iop_32to16, getIReg(rs)))),
   6585                                   mkU8(0x1)));
   6586                      assign(t1, binop(Iop_CmpEQ32,
   6587                                       binop(Iop_And32,
   6588                                             getIReg(rt),
   6589                                             mkU32(0xffff)),
   6590                                       mkU32(0x8000)));
   6591                      assign(t2, binop(Iop_CmpEQ32,
   6592                                       binop(Iop_And32,
   6593                                             getIReg(rs),
   6594                                             mkU32(0xffff)),
   6595                                       mkU32(0x8000)));
   6596                      putDSPControl(IRExpr_ITE(mkexpr(t1),
   6597                                               IRExpr_ITE(mkexpr(t2),
   6598                                                          binop(Iop_Or32,
   6599                                                                getDSPControl(),
   6600                                                                mkU32(0x00200000)
   6601                                                               ),
   6602                                                          getDSPControl()),
   6603                                               getDSPControl()));
   6604                      putIReg(rd, IRExpr_ITE(mkexpr(t1),
   6605                                             IRExpr_ITE(mkexpr(t2),
   6606                                                        mkU32(0x7fffffff),
   6607                                                        mkexpr(t0)),
   6608                                             mkexpr(t0)));
   6609                      break;
   6610                   }
   6611                   case 0x1E: {  /* MULQ_S.PH */
   6612                      DIP("mulq_s.ph r%u, r%u, r%u", rd, rs, rt);
   6613                      vassert(!mode64);
   6614                      t0 = newTemp(Ity_I32);
   6615                      t1 = newTemp(Ity_I32);
   6616                      t2 = newTemp(Ity_I16);
   6617                      t3 = newTemp(Ity_I16);
   6618                      t5 = newTemp(Ity_I32);
   6619                      t6 = newTemp(Ity_I32);
   6620                      t7 = newTemp(Ity_I32);
   6621                      t8 = newTemp(Ity_I32);
   6622 
   6623                      assign(t5,
   6624                             unop(Iop_16Sto32, unop(Iop_32to16, getIReg(rs))));
   6625                      assign(t6,
   6626                             unop(Iop_16Sto32, unop(Iop_32to16, getIReg(rt))));
   6627 
   6628                      assign(t7,
   6629                             unop(Iop_16Sto32, unop(Iop_32HIto16, getIReg(rs))));
   6630                      assign(t8,
   6631                             unop(Iop_16Sto32, unop(Iop_32HIto16, getIReg(rt))));
   6632 
   6633                      assign(t0, binop(Iop_And32,
   6634                                       unop(Iop_1Sto32,
   6635                                            binop(Iop_CmpEQ32,
   6636                                                  binop(Iop_And32,
   6637                                                        mkexpr(t5),
   6638                                                        mkU32(0xffff)),
   6639                                                  mkU32(0x8000))),
   6640                                       unop(Iop_1Sto32,
   6641                                            binop(Iop_CmpEQ32,
   6642                                                  binop(Iop_And32,
   6643                                                        mkexpr(t6),
   6644                                                        mkU32(0xffff)),
   6645                                                  mkU32(0x8000)))));
   6646                      assign(t1, binop(Iop_And32,
   6647                                       unop(Iop_1Sto32,
   6648                                            binop(Iop_CmpEQ32,
   6649                                                  binop(Iop_And32,
   6650                                                        mkexpr(t7),
   6651                                                        mkU32(0xffff)),
   6652                                                  mkU32(0x8000))),
   6653                                       unop(Iop_1Sto32,
   6654                                            binop(Iop_CmpEQ32,
   6655                                                  binop(Iop_And32,
   6656                                                        mkexpr(t8),
   6657                                                        mkU32(0xffff)),
   6658                                                  mkU32(0x8000)))));
   6659 
   6660                      putDSPControl(IRExpr_ITE(binop(Iop_CmpEQ32,
   6661                                                     binop(Iop_Or32,
   6662                                                           mkexpr(t0),
   6663                                                           mkexpr(t1)),
   6664                                                     mkU32(0x0)),
   6665                                               getDSPControl(),
   6666                                               binop(Iop_Or32,
   6667                                                     getDSPControl(),
   6668                                                     mkU32(0x200000))));
   6669 
   6670                      assign(t2, unop(Iop_32HIto16,
   6671                                      binop(Iop_Shl32,
   6672                                            unop(Iop_64to32,
   6673                                                 binop(Iop_MullS32,
   6674                                                       mkexpr(t7),
   6675                                                       mkexpr(t8))),
   6676                                            mkU8(0x1))));
   6677                      assign(t3, unop(Iop_32HIto16,
   6678                                      binop(Iop_Shl32,
   6679                                            unop(Iop_64to32,
   6680                                                 binop(Iop_MullS32,
   6681                                                       mkexpr(t5),
   6682                                                       mkexpr(t6))),
   6683                                            mkU8(0x1))));
   6684                      putIReg(rd, binop(Iop_16HLto32,
   6685                                        IRExpr_ITE(binop(Iop_CmpEQ32,
   6686                                                         mkexpr(t1),
   6687                                                         mkU32(0x0)),
   6688                                                   mkexpr(t2),
   6689                                                   mkU16(0x7fff)),
   6690                                        IRExpr_ITE(binop(Iop_CmpEQ32,
   6691                                                         mkexpr(t0),
   6692                                                         mkU32(0x0)),
   6693                                                   mkexpr(t3),
   6694                                                   mkU16(0x7fff))));
   6695                      break;
   6696                   }
   6697                   case 0x1F: {  /* MULQ_RS.PH */
   6698                      DIP("mulq_rs.ph r%u, r%u, r%u", rd, rs, rt);
   6699                      vassert(!mode64);
   6700                      t0 = newTemp(Ity_I32);
   6701                      t1 = newTemp(Ity_I1);
   6702                      t2 = newTemp(Ity_I1);
   6703                      t3 = newTemp(Ity_I16);
   6704                      t4 = newTemp(Ity_I32);
   6705                      t5 = newTemp(Ity_I1);
   6706                      t6 = newTemp(Ity_I1);
   6707                      t7 = newTemp(Ity_I16);
   6708 
   6709                      /* Multiply and round lower halfwords. */
   6710                      assign(t0, binop(Iop_Add32,
   6711                                       binop(Iop_Shl32,
   6712                                             binop(Iop_Mul32,
   6713                                                   unop(Iop_16Sto32,
   6714                                                        unop(Iop_32to16,
   6715                                                             getIReg(rt))),
   6716                                                   unop(Iop_16Sto32,
   6717                                                        unop(Iop_32to16,
   6718                                                             getIReg(rs)))),
   6719                                             mkU8(0x1)),
   6720                                       mkU32(0x00008000)));
   6721                      assign(t1, binop(Iop_CmpEQ32,
   6722                                       binop(Iop_And32,
   6723                                             getIReg(rt), mkU32(0xffff)),
   6724                                       mkU32(0x8000)));
   6725                      assign(t2, binop(Iop_CmpEQ32,
   6726                                       binop(Iop_And32,
   6727                                             getIReg(rs), mkU32(0xffff)),
   6728                                       mkU32(0x8000)));
   6729                      putDSPControl(IRExpr_ITE(mkexpr(t1),
   6730                                               IRExpr_ITE(mkexpr(t2),
   6731                                                          binop(Iop_Or32,
   6732                                                                getDSPControl(),
   6733                                                                mkU32(0x00200000)
   6734                                                               ),
   6735                                                          getDSPControl()),
   6736                                               getDSPControl()));
   6737                      assign(t3, IRExpr_ITE(mkexpr(t1),
   6738                                            IRExpr_ITE(mkexpr(t2),
   6739                                                       mkU16(0x7fff),
   6740                                                       unop(Iop_32HIto16,
   6741                                                            mkexpr(t0))),
   6742                                            unop(Iop_32HIto16, mkexpr(t0))));
   6743 
   6744                      /* Multiply and round higher halfwords. */
   6745                      assign(t4, binop(Iop_Add32,
   6746                                       binop(Iop_Shl32,
   6747                                             binop(Iop_Mul32,
   6748                                                   unop(Iop_16Sto32,
   6749                                                        unop(Iop_32HIto16,
   6750                                                             getIReg(rt))),
   6751                                                   unop(Iop_16Sto32,
   6752                                                        unop(Iop_32HIto16,
   6753                                                             getIReg(rs)))),
   6754                                             mkU8(0x1)),
   6755                                       mkU32(0x00008000)));
   6756                      assign(t5, binop(Iop_CmpEQ32,
   6757                                       binop(Iop_And32,
   6758                                             getIReg(rt),
   6759                                             mkU32(0xffff0000)),
   6760                                       mkU32(0x80000000)));
   6761                      assign(t6, binop(Iop_CmpEQ32,
   6762                                       binop(Iop_And32,
   6763                                             getIReg(rs),
   6764                                             mkU32(0xffff0000)),
   6765                                       mkU32(0x80000000)));
   6766                      putDSPControl(IRExpr_ITE(mkexpr(t5),
   6767                                              IRExpr_ITE(mkexpr(t6),
   6768                                                         binop(Iop_Or32,
   6769                                                              getDSPControl(),
   6770                                                              mkU32(0x00200000)),
   6771                                                         getDSPControl()),
   6772                                              getDSPControl()));
   6773                      assign(t7, IRExpr_ITE(mkexpr(t5),
   6774                                            IRExpr_ITE(mkexpr(t6),
   6775                                                       mkU16(0x7fff),
   6776                                                       unop(Iop_32HIto16,
   6777                                                            mkexpr(t4))),
   6778                                            unop(Iop_32HIto16, mkexpr(t4))));
   6779 
   6780                      putIReg(rd, binop(Iop_16HLto32, mkexpr(t7), mkexpr(t3)));
   6781                      break;
   6782                   }
   6783                   default:
   6784                      return -1;
   6785                }
   6786                break;  /* end of ADDU.QB */
   6787             }
   6788             case 0x11: {  /* CMPU.EQ.QB */
   6789                switch(sa) {
   6790                   case 0x0: {  /* CMPU.EQ.QB */
   6791                      DIP("cmpu.eq.qb r%u, r%u", rs, rt);
   6792                      vassert(!mode64);
   6793                      t1 = newTemp(Ity_I1);
   6794                      t2 = newTemp(Ity_I1);
   6795                      t3 = newTemp(Ity_I1);
   6796                      t4 = newTemp(Ity_I1);
   6797 
   6798                      assign(t1,
   6799                             binop(Iop_CmpEQ32,
   6800                                   binop(Iop_And32, getIReg(rs), mkU32(0xff)),
   6801                                   binop(Iop_And32, getIReg(rt), mkU32(0xff))));
   6802                      putDSPControl(IRExpr_ITE(mkexpr(t1),
   6803                                               binop(Iop_Or32,
   6804                                                     getDSPControl(),
   6805                                                     mkU32(0x01000000)),
   6806                                               binop(Iop_And32,
   6807                                                     getDSPControl(),
   6808                                                     mkU32(0xfeffffff))));
   6809 
   6810                      assign(t2, binop(Iop_CmpEQ32,
   6811                                       unop(Iop_8Uto32,
   6812                                            unop(Iop_16HIto8,
   6813                                                 unop(Iop_32to16,
   6814                                                      getIReg(rs)))),
   6815                                       unop(Iop_8Uto32,
   6816                                            unop(Iop_16HIto8,
   6817                                                 unop(Iop_32to16,
   6818                                                      getIReg(rt))))));
   6819                      putDSPControl(IRExpr_ITE(mkexpr(t2),
   6820                                               binop(Iop_Or32,
   6821                                                     getDSPControl(),
   6822                                                     mkU32(0x02000000)),
   6823                                               binop(Iop_And32,
   6824                                                     getDSPControl(),
   6825                                                     mkU32(0xfdffffff))));
   6826 
   6827                      assign(t3, binop(Iop_CmpEQ32,
   6828                                       unop(Iop_8Uto32,
   6829                                            unop(Iop_16to8,
   6830                                                 unop(Iop_32HIto16,
   6831                                                      getIReg(rs)))),
   6832                                       unop(Iop_8Uto32,
   6833                                            unop(Iop_16to8,
   6834                                                 unop(Iop_32HIto16,
   6835                                                      getIReg(rt))))));
   6836                      putDSPControl(IRExpr_ITE(mkexpr(t3),
   6837                                               binop(Iop_Or32,
   6838                                                     getDSPControl(),
   6839                                                     mkU32(0x04000000)),
   6840                                               binop(Iop_And32,
   6841                                                     getDSPControl(),
   6842                                                     mkU32(0xfbffffff))));
   6843 
   6844                      assign(t4, binop(Iop_CmpEQ32,
   6845                                       unop(Iop_8Uto32,
   6846                                            unop(Iop_16HIto8,
   6847                                                 unop(Iop_32HIto16,
   6848                                                      getIReg(rs)))),
   6849                                       unop(Iop_8Uto32,
   6850                                            unop(Iop_16HIto8,
   6851                                                 unop(Iop_32HIto16,
   6852                                                      getIReg(rt))))));
   6853                      putDSPControl(IRExpr_ITE(mkexpr(t4),
   6854                                               binop(Iop_Or32,
   6855                                                     getDSPControl(),
   6856                                                     mkU32(0x08000000)),
   6857                                               binop(Iop_And32,
   6858                                                     getDSPControl(),
   6859                                                     mkU32(0xf7ffffff))));
   6860                      break;
   6861                   }
   6862                   case 0x1: {  /* CMPU.LT.QB */
   6863                      DIP("cmpu.lt.qb r%u, r%u", rs, rt);
   6864                      vassert(!mode64);
   6865                      t1 = newTemp(Ity_I1);
   6866                      t2 = newTemp(Ity_I1);
   6867                      t3 = newTemp(Ity_I1);
   6868                      t4 = newTemp(Ity_I1);
   6869 
   6870                      assign(t1, binop(Iop_CmpLT32U,
   6871                                       unop(Iop_8Uto32,
   6872                                            unop(Iop_16to8,
   6873                                                 unop(Iop_32to16,
   6874                                                      getIReg(rs)))),
   6875                                       unop(Iop_8Uto32,
   6876                                            unop(Iop_16to8,
   6877                                                 unop(Iop_32to16,
   6878                                                      getIReg(rt))))));
   6879                      putDSPControl(IRExpr_ITE(mkexpr(t1),
   6880                                               binop(Iop_Or32,
   6881                                                     getDSPControl(),
   6882                                                     mkU32(0x01000000)),
   6883                                               binop(Iop_And32,
   6884                                                     getDSPControl(),
   6885                                                     mkU32(0xfeffffff))));
   6886 
   6887                      assign(t2, binop(Iop_CmpLT32U,
   6888                                       unop(Iop_8Uto32,
   6889                                            unop(Iop_16HIto8,
   6890                                                 unop(Iop_32to16,
   6891                                                      getIReg(rs)))),
   6892                                       unop(Iop_8Uto32,
   6893                                            unop(Iop_16HIto8,
   6894                                                 unop(Iop_32to16,
   6895                                                      getIReg(rt))))));
   6896                      putDSPControl(IRExpr_ITE(mkexpr(t2),
   6897                                               binop(Iop_Or32,
   6898                                                     getDSPControl(),
   6899                                                     mkU32(0x02000000)),
   6900                                               binop(Iop_And32,
   6901                                                     getDSPControl(),
   6902                                                     mkU32(0xfdffffff))));
   6903 
   6904                      assign(t3, binop(Iop_CmpLT32U,
   6905                                       unop(Iop_8Uto32,
   6906                                            unop(Iop_16to8,
   6907                                                 unop(Iop_32HIto16,
   6908                                                      getIReg(rs)))),
   6909                                       unop(Iop_8Uto32,
   6910                                            unop(Iop_16to8,
   6911                                                 unop(Iop_32HIto16,
   6912                                                      getIReg(rt))))));
   6913                      putDSPControl(IRExpr_ITE(mkexpr(t3),
   6914                                               binop(Iop_Or32,
   6915                                                     getDSPControl(),
   6916                                                     mkU32(0x04000000)),
   6917                                               binop(Iop_And32,
   6918                                                     getDSPControl(),
   6919                                                     mkU32(0xfbffffff))));
   6920 
   6921                      assign(t4, binop(Iop_CmpLT32U,
   6922                                       unop(Iop_8Uto32,
   6923                                            unop(Iop_16HIto8,
   6924                                                 unop(Iop_32HIto16,
   6925                                                      getIReg(rs)))),
   6926                                       unop(Iop_8Uto32,
   6927                                            unop(Iop_16HIto8,
   6928                                                 unop(Iop_32HIto16,
   6929                                                      getIReg(rt))))));
   6930                      putDSPControl(IRExpr_ITE(mkexpr(t4),
   6931                                               binop(Iop_Or32,
   6932                                                     getDSPControl(),
   6933                                                     mkU32(0x08000000)),
   6934                                               binop(Iop_And32,
   6935                                                     getDSPControl(),
   6936                                                     mkU32(0xf7ffffff))));
   6937                      break;
   6938                   }
   6939                   case 0x2: {  /* CMPU.LE.QB */
   6940                      DIP("cmpu.le.qb r%u, r%u", rs, rt);
   6941                      vassert(!mode64);
   6942                      t1 = newTemp(Ity_I1);
   6943                      t2 = newTemp(Ity_I1);
   6944                      t3 = newTemp(Ity_I1);
   6945                      t4 = newTemp(Ity_I1);
   6946 
   6947                      assign(t1, binop(Iop_CmpLE32U,
   6948                                       unop(Iop_8Uto32,
   6949                                            unop(Iop_16to8,
   6950                                                 unop(Iop_32to16,
   6951                                                      getIReg(rs)))),
   6952                                       unop(Iop_8Uto32,
   6953                                            unop(Iop_16to8,
   6954                                                 unop(Iop_32to16,
   6955                                                      getIReg(rt))))));
   6956                      putDSPControl(IRExpr_ITE(mkexpr(t1),
   6957                                               binop(Iop_Or32,
   6958                                                     getDSPControl(),
   6959                                                     mkU32(0x01000000)),
   6960                                               binop(Iop_And32,
   6961                                                     getDSPControl(),
   6962                                                     mkU32(0xfeffffff))));
   6963 
   6964                      assign(t2, binop(Iop_CmpLE32U,
   6965                                       unop(Iop_8Uto32,
   6966                                            unop(Iop_16HIto8,
   6967                                                 unop(Iop_32to16,
   6968                                                      getIReg(rs)))),
   6969                                       unop(Iop_8Uto32,
   6970                                            unop(Iop_16HIto8,
   6971                                                 unop(Iop_32to16,
   6972                                                      getIReg(rt))))));
   6973                      putDSPControl(IRExpr_ITE(mkexpr(t2),
   6974                                               binop(Iop_Or32,
   6975                                                     getDSPControl(),
   6976                                                     mkU32(0x02000000)),
   6977                                               binop(Iop_And32,
   6978                                                     getDSPControl(),
   6979                                                     mkU32(0xfdffffff))));
   6980 
   6981                      assign(t3, binop(Iop_CmpLE32U,
   6982                                       unop(Iop_8Uto32,
   6983                                            unop(Iop_16to8,
   6984                                                 unop(Iop_32HIto16,
   6985                                                      getIReg(rs)))),
   6986                                       unop(Iop_8Uto32,
   6987                                            unop(Iop_16to8,
   6988                                                 unop(Iop_32HIto16,
   6989                                                      getIReg(rt))))));
   6990                      putDSPControl(IRExpr_ITE(mkexpr(t3),
   6991                                               binop(Iop_Or32,
   6992                                                     getDSPControl(),
   6993                                                     mkU32(0x04000000)),
   6994                                               binop(Iop_And32,
   6995                                                     getDSPControl(),
   6996                                                     mkU32(0xfbffffff))));
   6997 
   6998                      assign(t4, binop(Iop_CmpLE32U,
   6999                                       unop(Iop_8Uto32,
   7000                                            unop(Iop_16HIto8,
   7001                                                 unop(Iop_32HIto16,
   7002                                                      getIReg(rs)))),
   7003                                       unop(Iop_8Uto32,
   7004                                            unop(Iop_16HIto8,
   7005                                                 unop(Iop_32HIto16,
   7006                                                      getIReg(rt))))));
   7007                      putDSPControl(IRExpr_ITE(mkexpr(t4),
   7008                                               binop(Iop_Or32,
   7009                                                     getDSPControl(),
   7010                                                     mkU32(0x08000000)),
   7011                                               binop(Iop_And32,
   7012                                                     getDSPControl(),
   7013                                                     mkU32(0xf7ffffff))));
   7014                      break;
   7015                   }
   7016                   case 0x3: {  /* PICK.QB */
   7017                      DIP("pick.qb r%u, r%u, r%u", rd, rs, rt);
   7018                      vassert(!mode64);
   7019                      t0 = newTemp(Ity_I32);
   7020                      t1 = newTemp(Ity_I8);
   7021                      t2 = newTemp(Ity_I8);
   7022                      t3 = newTemp(Ity_I8);
   7023                      t4 = newTemp(Ity_I8);
   7024 
   7025                      assign(t0, getDSPControl());
   7026                      assign(t1, IRExpr_ITE(binop(Iop_CmpNE32,
   7027                                                  binop(Iop_And32,
   7028                                                        mkexpr(t0),
   7029                                                        mkU32(0x01000000)),
   7030                                                  mkU32(0x0)),
   7031                                            unop(Iop_16to8,
   7032                                                  unop(Iop_32to16,
   7033                                                       getIReg(rs))),
   7034                                            unop(Iop_16to8,
   7035                                                 unop(Iop_32to16,
   7036                                                      getIReg(rt)))));
   7037                      assign(t2, IRExpr_ITE(binop(Iop_CmpNE32,
   7038                                                  binop(Iop_And32,
   7039                                                        mkexpr(t0),
   7040                                                        mkU32(0x02000000)),
   7041                                                  mkU32(0x0)),
   7042                                            unop(Iop_16HIto8,
   7043                                                 unop(Iop_32to16, getIReg(rs))),
   7044                                            unop(Iop_16HIto8,
   7045                                                 unop(Iop_32to16,
   7046                                                      getIReg(rt)))));
   7047                      assign(t3, IRExpr_ITE(binop(Iop_CmpNE32,
   7048                                                  binop(Iop_And32,
   7049                                                        mkexpr(t0),
   7050                                                        mkU32(0x04000000)),
   7051                                                  mkU32(0x0)),
   7052                                            unop(Iop_16to8,
   7053                                                 unop(Iop_32HIto16,
   7054                                                      getIReg(rs))),
   7055                                            unop(Iop_16to8,
   7056                                                 unop(Iop_32HIto16,
   7057                                                      getIReg(rt)))));
   7058                      assign(t4, IRExpr_ITE(binop(Iop_CmpNE32,
   7059                                                  binop(Iop_And32,
   7060                                                        mkexpr(t0),
   7061                                                        mkU32(0x08000000)),
   7062                                                  mkU32(0x0)),
   7063                                            unop(Iop_16HIto8,
   7064                                                 unop(Iop_32HIto16,
   7065                                                      getIReg(rs))),
   7066                                            unop(Iop_16HIto8,
   7067                                                 unop(Iop_32HIto16,
   7068                                                      getIReg(rt)))));
   7069                      putIReg(rd,
   7070                              binop(Iop_16HLto32,
   7071                                    binop(Iop_8HLto16, mkexpr(t4), mkexpr(t3)),
   7072                                    binop(Iop_8HLto16, mkexpr(t2), mkexpr(t1))));
   7073                      break;
   7074                   }
   7075                   case 0x4: {  /* CMPGU.EQ.QB */
   7076                      DIP("cmpgu.eq.qb r%u, r%u, r%u", rd, rs, rt);
   7077                      vassert(!mode64);
   7078                      t1 = newTemp(Ity_I1);
   7079                      t2 = newTemp(Ity_I1);
   7080                      t3 = newTemp(Ity_I1);
   7081                      t4 = newTemp(Ity_I1);
   7082                      t5 = newTemp(Ity_I32);
   7083                      t6 = newTemp(Ity_I32);
   7084                      t7 = newTemp(Ity_I32);
   7085                      t8 = newTemp(Ity_I32);
   7086 
   7087                      assign(t1, binop(Iop_CmpEQ32,
   7088                                       unop(Iop_8Uto32,
   7089                                            unop(Iop_16to8,
   7090                                                 unop(Iop_32to16, getIReg(rs)))),
   7091                                       unop(Iop_8Uto32,
   7092                                            unop(Iop_16to8,
   7093                                                 unop(Iop_32to16,
   7094                                                      getIReg(rt))))));
   7095                      assign(t5, IRExpr_ITE(mkexpr(t1),
   7096                                            mkU32(0x00000001), mkU32(0)));
   7097 
   7098                      assign(t2, binop(Iop_CmpEQ32,
   7099                                       unop(Iop_8Uto32,
   7100                                            unop(Iop_16HIto8,
   7101                                                 unop(Iop_32to16, getIReg(rs)))),
   7102                                       unop(Iop_8Uto32,
   7103                                            unop(Iop_16HIto8,
   7104                                                 unop(Iop_32to16,
   7105                                                      getIReg(rt))))));
   7106                      assign(t6, IRExpr_ITE(mkexpr(t2),
   7107                                            mkU32(0x00000002), mkU32(0)));
   7108 
   7109                      assign(t3, binop(Iop_CmpEQ32,
   7110                                       unop(Iop_8Uto32,
   7111                                            unop(Iop_16to8,
   7112                                                 unop(Iop_32HIto16,
   7113                                                      getIReg(rs)))),
   7114                                       unop(Iop_8Uto32,
   7115                                            unop(Iop_16to8,
   7116                                                 unop(Iop_32HIto16,
   7117                                                      getIReg(rt))))));
   7118                      assign(t7, IRExpr_ITE(mkexpr(t3),
   7119                                            mkU32(0x00000004), mkU32(0)));
   7120 
   7121                      assign(t4, binop(Iop_CmpEQ32,
   7122                                       unop(Iop_8Uto32,
   7123                                            unop(Iop_16HIto8,
   7124                                                 unop(Iop_32HIto16,
   7125                                                      getIReg(rs)))),
   7126                                       unop(Iop_8Uto32,
   7127                                            unop(Iop_16HIto8,
   7128                                                 unop(Iop_32HIto16,
   7129                                                      getIReg(rt))))));
   7130                      assign(t8, IRExpr_ITE(mkexpr(t4),
   7131                                            mkU32(0x00000008), mkU32(0)));
   7132 
   7133                      putIReg(rd, binop(Iop_Or32,
   7134                                        binop(Iop_Or32,
   7135                                              binop(Iop_Or32,
   7136                                                    mkexpr(t5), mkexpr(t6)),
   7137                                              mkexpr(t7)),
   7138                                        mkexpr(t8)));
   7139                      break;
   7140                   }
   7141                   case 0x5: {  /* CMPGU.LT.QB */
   7142                      DIP("cmpgu.lt.qb r%u, r%u, r%u", rd, rs, rt);
   7143                      vassert(!mode64);
   7144                      t1 = newTemp(Ity_I1);
   7145                      t2 = newTemp(Ity_I1);
   7146                      t3 = newTemp(Ity_I1);
   7147                      t4 = newTemp(Ity_I1);
   7148                      t5 = newTemp(Ity_I32);
   7149                      t6 = newTemp(Ity_I32);
   7150                      t7 = newTemp(Ity_I32);
   7151                      t8 = newTemp(Ity_I32);
   7152 
   7153                      assign(t1, binop(Iop_CmpLT32U,
   7154                                       unop(Iop_8Uto32,
   7155                                            unop(Iop_16to8,
   7156                                                 unop(Iop_32to16, getIReg(rs)))),
   7157                                       unop(Iop_8Uto32,
   7158                                            unop(Iop_16to8,
   7159                                                 unop(Iop_32to16,
   7160                                                      getIReg(rt))))));
   7161                      assign(t5, IRExpr_ITE(mkexpr(t1),
   7162                                            mkU32(0x00000001), mkU32(0)));
   7163 
   7164                      assign(t2, binop(Iop_CmpLT32U,
   7165                                       unop(Iop_8Uto32,
   7166                                            unop(Iop_16HIto8,
   7167                                                 unop(Iop_32to16, getIReg(rs)))),
   7168                                       unop(Iop_8Uto32,
   7169                                            unop(Iop_16HIto8,
   7170                                                 unop(Iop_32to16,
   7171                                                      getIReg(rt))))));
   7172                      assign(t6, IRExpr_ITE(mkexpr(t2),
   7173                                            mkU32(0x00000002), mkU32(0)));
   7174 
   7175                      assign(t3, binop(Iop_CmpLT32U,
   7176                                       unop(Iop_8Uto32,
   7177                                            unop(Iop_16to8,
   7178                                                 unop(Iop_32HIto16,
   7179                                                      getIReg(rs)))),
   7180                                       unop(Iop_8Uto32,
   7181                                            unop(Iop_16to8,
   7182                                                 unop(Iop_32HIto16,
   7183                                                      getIReg(rt))))));
   7184                      assign(t7, IRExpr_ITE(mkexpr(t3),
   7185                                            mkU32(0x00000004), mkU32(0)));
   7186 
   7187                      assign(t4, binop(Iop_CmpLT32U,
   7188                                       unop(Iop_8Uto32,
   7189                                            unop(Iop_16HIto8,
   7190                                                 unop(Iop_32HIto16,
   7191                                                      getIReg(rs)))),
   7192                                       unop(Iop_8Uto32,
   7193                                            unop(Iop_16HIto8,
   7194                                                 unop(Iop_32HIto16,
   7195                                                      getIReg(rt))))));
   7196                      assign(t8, IRExpr_ITE(mkexpr(t4),
   7197                                            mkU32(0x00000008), mkU32(0)));
   7198                      putIReg(rd, binop(Iop_Or32,
   7199                                        binop(Iop_Or32,
   7200                                              binop(Iop_Or32,
   7201                                                    mkexpr(t5), mkexpr(t6)),
   7202                                              mkexpr(t7)),
   7203                                        mkexpr(t8)));
   7204                      break;
   7205                   }
   7206                   case 0x6: {  /* CMPGU.LE.QB */
   7207                      DIP("cmpgu.le.qb r%u, r%u, r%u", rd, rs, rt);
   7208                      vassert(!mode64);
   7209                      t1 = newTemp(Ity_I1);
   7210                      t2 = newTemp(Ity_I1);
   7211                      t3 = newTemp(Ity_I1);
   7212                      t4 = newTemp(Ity_I1);
   7213                      t5 = newTemp(Ity_I32);
   7214                      t6 = newTemp(Ity_I32);
   7215                      t7 = newTemp(Ity_I32);
   7216                      t8 = newTemp(Ity_I32);
   7217 
   7218                      assign(t1, binop(Iop_CmpLE32U,
   7219                                       unop(Iop_8Uto32,
   7220                                            unop(Iop_16to8,
   7221                                                 unop(Iop_32to16, getIReg(rs)))),
   7222                                       unop(Iop_8Uto32,
   7223                                            unop(Iop_16to8,
   7224                                                 unop(Iop_32to16,
   7225                                                      getIReg(rt))))));
   7226                      assign(t5, IRExpr_ITE(mkexpr(t1),
   7227                                            mkU32(0x00000001), mkU32(0)));
   7228 
   7229                      assign(t2, binop(Iop_CmpLE32U,
   7230                                       unop(Iop_8Uto32,
   7231                                            unop(Iop_16HIto8,
   7232                                                 unop(Iop_32to16, getIReg(rs)))),
   7233                                       unop(Iop_8Uto32,
   7234                                            unop(Iop_16HIto8,
   7235                                                 unop(Iop_32to16,
   7236                                                      getIReg(rt))))));
   7237                      assign(t6, IRExpr_ITE(mkexpr(t2),
   7238                                            mkU32(0x00000002), mkU32(0)));
   7239 
   7240                      assign(t3, binop(Iop_CmpLE32U,
   7241                                       unop(Iop_8Uto32,
   7242                                            unop(Iop_16to8,
   7243                                                 unop(Iop_32HIto16,
   7244                                                      getIReg(rs)))),
   7245                                       unop(Iop_8Uto32,
   7246                                            unop(Iop_16to8,
   7247                                                 unop(Iop_32HIto16,
   7248                                                      getIReg(rt))))));
   7249                      assign(t7, IRExpr_ITE(mkexpr(t3),
   7250                                            mkU32(0x00000004), mkU32(0)));
   7251 
   7252                      assign(t4, binop(Iop_CmpLE32U,
   7253                                       unop(Iop_8Uto32,
   7254                                            unop(Iop_16HIto8,
   7255                                                 unop(Iop_32HIto16,
   7256                                                      getIReg(rs)))),
   7257                                       unop(Iop_8Uto32,
   7258                                            unop(Iop_16HIto8,
   7259                                                 unop(Iop_32HIto16,
   7260                                                      getIReg(rt))))));
   7261                      assign(t8, IRExpr_ITE(mkexpr(t4),
   7262                                            mkU32(0x00000008), mkU32(0)));
   7263                      putIReg(rd, binop(Iop_Or32,
   7264                                        binop(Iop_Or32,
   7265                                              binop(Iop_Or32,
   7266                                                    mkexpr(t5), mkexpr(t6)),
   7267                                              mkexpr(t7)),
   7268                                        mkexpr(t8)));
   7269                      break;
   7270                   }
   7271                   case 0x8: {  /* CMP.EQ.PH */
   7272                      DIP("cmp.eq.ph r%u, r%u", rs, rt);
   7273                      vassert(!mode64);
   7274                      t1 = newTemp(Ity_I1);
   7275                      t2 = newTemp(Ity_I1);
   7276 
   7277                      assign(t1, binop(Iop_CmpEQ16,
   7278                                       unop(Iop_32to16, getIReg(rs)),
   7279                                       unop(Iop_32to16, getIReg(rt))));
   7280                      putDSPControl(IRExpr_ITE(mkexpr(t1),
   7281                                               binop(Iop_Or32,
   7282                                                     getDSPControl(),
   7283                                                     mkU32(0x01000000)),
   7284                                               binop(Iop_And32,
   7285                                                     getDSPControl(),
   7286                                                     mkU32(0xfeffffff))));
   7287                      assign(t2, binop(Iop_CmpEQ16,
   7288                                       unop(Iop_32HIto16, getIReg(rs)),
   7289                                       unop(Iop_32HIto16, getIReg(rt))));
   7290                      putDSPControl(IRExpr_ITE(mkexpr(t2),
   7291                                               binop(Iop_Or32,
   7292                                                     getDSPControl(),
   7293                                                     mkU32(0x02000000)),
   7294                                               binop(Iop_And32,
   7295                                                     getDSPControl(),
   7296                                                     mkU32(0xfdffffff))));
   7297                      break;
   7298                   }
   7299                   case 0x9: {  /* CMP.LT.PH */
   7300                      DIP("cmp.lt.ph r%u, r%u", rs, rt);
   7301                      vassert(!mode64);
   7302                      t1 = newTemp(Ity_I1);
   7303                      t2 = newTemp(Ity_I1);
   7304 
   7305                      assign(t1, binop(Iop_CmpLT32S,
   7306                                       unop(Iop_16Sto32,
   7307                                            unop(Iop_32to16, getIReg(rs))),
   7308                                       unop(Iop_16Sto32,
   7309                                            unop(Iop_32to16, getIReg(rt)))));
   7310                      putDSPControl(IRExpr_ITE(mkexpr(t1),
   7311                                               binop(Iop_Or32,
   7312                                                     getDSPControl(),
   7313                                                     mkU32(0x01000000)),
   7314                                               binop(Iop_And32,
   7315                                                     getDSPControl(),
   7316                                                     mkU32(0xfeffffff))));
   7317 
   7318                      assign(t2, binop(Iop_CmpLT32S,
   7319                                       unop(Iop_16Sto32,
   7320                                            unop(Iop_32HIto16, getIReg(rs))),
   7321                                       unop(Iop_16Sto32,
   7322                                            unop(Iop_32HIto16, getIReg(rt)))));
   7323                      putDSPControl(IRExpr_ITE(mkexpr(t2),
   7324                                               binop(Iop_Or32,
   7325                                                     getDSPControl(),
   7326                                                     mkU32(0x02000000)),
   7327                                               binop(Iop_And32,
   7328                                                     getDSPControl(),
   7329                                                     mkU32(0xfdffffff))));
   7330                      break;
   7331                   }
   7332                   case 0xA: {  /* CMP.LE.PH */
   7333                      DIP("cmp.le.ph r%u, r%u", rs, rt);
   7334                      vassert(!mode64);
   7335                      t1 = newTemp(Ity_I1);
   7336                      t2 = newTemp(Ity_I1);
   7337 
   7338                      assign(t1, binop(Iop_CmpLE32S,
   7339                                       unop(Iop_16Sto32,
   7340                                            unop(Iop_32to16, getIReg(rs))),
   7341                                       unop(Iop_16Sto32,
   7342                                            unop(Iop_32to16, getIReg(rt)))));
   7343                      putDSPControl(IRExpr_ITE(mkexpr(t1),
   7344                                               binop(Iop_Or32,
   7345                                                     getDSPControl(),
   7346                                                     mkU32(0x01000000)),
   7347                                               binop(Iop_And32,
   7348                                                     getDSPControl(),
   7349                                                     mkU32(0xfeffffff))));
   7350 
   7351                      assign(t2, binop(Iop_CmpLE32S,
   7352                                       unop(Iop_16Sto32,
   7353                                            unop(Iop_32HIto16, getIReg(rs))),
   7354                                       unop(Iop_16Sto32,
   7355                                            unop(Iop_32HIto16, getIReg(rt)))));
   7356                      putDSPControl(IRExpr_ITE(mkexpr(t2),
   7357                                               binop(Iop_Or32,
   7358                                                     getDSPControl(),
   7359                                                     mkU32(0x02000000)),
   7360                                               binop(Iop_And32,
   7361                                                     getDSPControl(),
   7362                                                     mkU32(0xfdffffff))));
   7363                      break;
   7364                   }
   7365                   case 0xB: {  /* PICK.PH */
   7366                      DIP("pick.qb r%u, r%u, r%u", rd, rs, rt);
   7367                      vassert(!mode64);
   7368                      t0 = newTemp(Ity_I32);
   7369                      t1 = newTemp(Ity_I16);
   7370                      t2 = newTemp(Ity_I16);
   7371 
   7372                      assign(t0, getDSPControl());
   7373 
   7374                      assign(t1, IRExpr_ITE(binop(Iop_CmpNE32,
   7375                                                  binop(Iop_And32,
   7376                                                        mkexpr(t0),
   7377                                                        mkU32(0x01000000)),
   7378                                                  mkU32(0x0)),
   7379                                            unop(Iop_32to16, getIReg(rs)),
   7380                                            unop(Iop_32to16, getIReg(rt))));
   7381 
   7382                      assign(t2, IRExpr_ITE(binop(Iop_CmpNE32,
   7383                                                  binop(Iop_And32,
   7384                                                        mkexpr(t0),
   7385                                                        mkU32(0x02000000)),
   7386                                                  mkU32(0x0)),
   7387                                            unop(Iop_32HIto16, getIReg(rs)),
   7388                                            unop(Iop_32HIto16, getIReg(rt))));
   7389 
   7390                      putIReg(rd, binop(Iop_16HLto32, mkexpr(t2), mkexpr(t1)));
   7391                      break;
   7392                   }
   7393                   case 0xC: {  /* PRECRQ.QB.PH */
   7394                      DIP("precrq.qb.ph r%u, r%u, %u", rd, rs, rt);
   7395                      vassert(!mode64);
   7396                      putIReg(rd,
   7397                              binop(Iop_16HLto32,
   7398                                    binop(Iop_8HLto16,
   7399                                          unop(Iop_16HIto8,
   7400                                               unop(Iop_32HIto16, getIReg(rs))),
   7401                                          unop(Iop_16HIto8,
   7402                                               unop(Iop_32to16, getIReg(rs)))),
   7403                                    binop(Iop_8HLto16,
   7404                                          unop(Iop_16HIto8,
   7405                                               unop(Iop_32HIto16, getIReg(rt))),
   7406                                          unop(Iop_16HIto8,
   7407                                               unop(Iop_32to16, getIReg(rt))))));
   7408                      break;
   7409                   }
   7410                   case 0xD: {  /* PRECR.QB.PH */
   7411                      DIP("precr.qb.ph r%u, r%u, r%u", rd, rs, rt);
   7412                      vassert(!mode64);
   7413 
   7414                      putIReg(rd,
   7415                              binop(Iop_16HLto32,
   7416                                    binop(Iop_8HLto16,
   7417                                          unop(Iop_16to8,
   7418                                               unop(Iop_32HIto16, getIReg(rs))),
   7419                                          unop(Iop_16to8,
   7420                                               unop(Iop_32to16, getIReg(rs)))),
   7421                                    binop(Iop_8HLto16,
   7422                                          unop(Iop_16to8,
   7423                                               unop(Iop_32HIto16, getIReg(rt))),
   7424                                          unop(Iop_16to8,
   7425                                               unop(Iop_32to16, getIReg(rt))))));
   7426                      break;
   7427                   }
   7428                   case 0xF: {  /* PRECRQU_S.QB.PH */
   7429                      DIP("precrqu_s.qb.ph r%u, r%u, %u", rd, rs, rt);
   7430                      vassert(!mode64);
   7431                      t0 = newTemp(Ity_I8);
   7432                      t1 = newTemp(Ity_I8);
   7433                      t2 = newTemp(Ity_I8);
   7434                      t3 = newTemp(Ity_I8);
   7435                      t4 = newTemp(Ity_I8);
   7436                      t5 = newTemp(Ity_I32);
   7437                      t6 = newTemp(Ity_I1);
   7438                      t7 = newTemp(Ity_I8);
   7439                      t8 = newTemp(Ity_I1);
   7440                      t9 = newTemp(Ity_I32);
   7441                      t10 = newTemp(Ity_I8);
   7442                      t11 = newTemp(Ity_I1);
   7443                      t12 = newTemp(Ity_I32);
   7444                      t13 = newTemp(Ity_I8);
   7445                      t14 = newTemp(Ity_I1);
   7446                      t15 = newTemp(Ity_I32);
   7447 
   7448                      assign(t4, IRExpr_ITE(binop(Iop_CmpLT32U,
   7449                                                  mkU32(0x7f80),
   7450                                                  binop(Iop_And32,
   7451                                                        unop(Iop_16Uto32,
   7452                                                             unop(Iop_32to16,
   7453                                                             getIReg(rs))),
   7454                                                        mkU32(0x7fff))),
   7455                                            mkU8(0xff),
   7456                                            unop(Iop_16HIto8,
   7457                                                 unop(Iop_32to16,
   7458                                                      binop(Iop_Shl32,
   7459                                                            getIReg(rs),
   7460                                                            mkU8(1))))));
   7461                      assign(t0, IRExpr_ITE(binop(Iop_CmpEQ32,
   7462                                                  binop(Iop_And32,
   7463                                                        unop(Iop_16Uto32,
   7464                                                             unop(Iop_32to16,
   7465                                                                  getIReg(rs))),
   7466                                                        mkU32(0x00008000)),
   7467                                                  mkU32(0x0)),
   7468                                            mkexpr(t4),
   7469                                            mkU8(0x0)));
   7470                      assign(t5, binop(Iop_And32,
   7471                                       unop(Iop_16Uto32,
   7472                                             unop(Iop_32to16,
   7473                                                  getIReg(rs))),
   7474                                       mkU32(0x00008000)));
   7475                      assign(t6, binop(Iop_CmpLT32U,
   7476                                       mkU32(0x7f80),
   7477                                       binop(Iop_And32,
   7478                                             unop(Iop_16Uto32,
   7479                                                  unop(Iop_32to16,
   7480                                                  getIReg(rs))),
   7481                                             mkU32(0x7fff))));
   7482                      putDSPControl(IRExpr_ITE(binop(Iop_CmpEQ32,
   7483                                                     mkexpr(t5),
   7484                                                     mkU32(0x0)),
   7485                                               IRExpr_ITE(mkexpr(t6),
   7486                                                          binop(Iop_Or32,
   7487                                                                getDSPControl(),
   7488                                                                mkU32(0x00400000)
   7489                                                               ),
   7490                                                          getDSPControl()),
   7491                                               binop(Iop_Or32,
   7492                                                     getDSPControl(),
   7493                                                     mkU32(0x00400000))));
   7494 
   7495                      assign(t7, IRExpr_ITE(binop(Iop_CmpLT32U,
   7496                                                  mkU32(0x7f80),
   7497                                                  binop(Iop_And32,
   7498                                                        unop(Iop_16Uto32,
   7499                                                             unop(Iop_32HIto16,
   7500                                                                  getIReg(rs))),
   7501                                                        mkU32(0x7fff))),
   7502                                            mkU8(0xff),
   7503                                            unop(Iop_16HIto8,
   7504                                                 unop(Iop_32HIto16,
   7505                                                      binop(Iop_Shl32,
   7506                                                            getIReg(rs),
   7507                                                            mkU8(1))))));
   7508                      assign(t1, IRExpr_ITE(binop(Iop_CmpEQ32,
   7509                                                  binop(Iop_And32,
   7510                                                        unop(Iop_16Uto32,
   7511                                                             unop(Iop_32HIto16,
   7512                                                                  getIReg(rs))),
   7513                                                        mkU32(0x00008000)),
   7514                                                  mkU32(0x0)),
   7515                                            mkexpr(t7),
   7516                                            mkU8(0x0)));
   7517                      assign(t8, binop(Iop_CmpEQ32,
   7518                                       binop(Iop_And32,
   7519                                             unop(Iop_16Uto32,
   7520                                                  unop(Iop_32HIto16,
   7521                                                       getIReg(rs))),
   7522                                             mkU32(0x00008000)),
   7523                                       mkU32(0x0)));
   7524                      assign(t9, IRExpr_ITE(binop(Iop_CmpLT32U,
   7525                                                  mkU32(0x7f80),
   7526                                                  binop(Iop_And32,
   7527                                                        unop(Iop_16Uto32,
   7528                                                             unop(Iop_32HIto16,
   7529                                                                  getIReg(rs))),
   7530                                                        mkU32(0x7fff))),
   7531                                            binop(Iop_Or32,
   7532                                                  getDSPControl(),
   7533                                                  mkU32(0x00400000)),
   7534                                            getDSPControl()));
   7535                      putDSPControl(IRExpr_ITE(mkexpr(t8),
   7536                                               mkexpr(t9),
   7537                                               binop(Iop_Or32,
   7538                                                     getDSPControl(),
   7539                                                     mkU32(0x00400000))));
   7540 
   7541                      assign(t10, IRExpr_ITE(binop(Iop_CmpLT32U,
   7542                                                   mkU32(0x7f80),
   7543                                                   binop(Iop_And32,
   7544                                                         unop(Iop_16Uto32,
   7545                                                              unop(Iop_32to16,
   7546                                                              getIReg(rt))),
   7547                                                         mkU32(0x7fff))),
   7548                                             mkU8(0xff),
   7549                                             unop(Iop_16HIto8,
   7550                                                  unop(Iop_32to16,
   7551                                                       binop(Iop_Shl32,
   7552                                                             getIReg(rt),
   7553                                                             mkU8(1))))));
   7554                      assign(t2, IRExpr_ITE(binop(Iop_CmpEQ32,
   7555                                                  binop(Iop_And32,
   7556                                                        unop(Iop_16Uto32,
   7557                                                             unop(Iop_32to16,
   7558                                                                  getIReg(rt))),
   7559                                                        mkU32(0x00008000)),
   7560                                                  mkU32(0x0)),
   7561                                            mkexpr(t10),
   7562                                            mkU8(0x0)));
   7563                      assign(t11, binop(Iop_CmpEQ32,
   7564                                        binop(Iop_And32,
   7565                                              unop(Iop_16Uto32,
   7566                                                   unop(Iop_32to16,
   7567                                                        getIReg(rt))),
   7568                                              mkU32(0x00008000)),
   7569                                        mkU32(0x0)));
   7570                      assign(t12, IRExpr_ITE(binop(Iop_CmpLT32U,
   7571                                                   mkU32(0x7f80),
   7572                                                   binop(Iop_And32,
   7573                                                         unop(Iop_16Uto32,
   7574                                                              unop(Iop_32to16,
   7575                                                              getIReg(rt))),
   7576                                                         mkU32(0x7fff))),
   7577                                             binop(Iop_Or32,
   7578                                                   getDSPControl(),
   7579                                                   mkU32(0x00400000)),
   7580                                             getDSPControl()));
   7581                      putDSPControl(IRExpr_ITE(mkexpr(t11),
   7582                                               mkexpr(t12),
   7583                                               binop(Iop_Or32,
   7584                                                     getDSPControl(),
   7585                                                     mkU32(0x00400000))));
   7586 
   7587                      assign(t13, IRExpr_ITE(binop(Iop_CmpLT32U,
   7588                                                   mkU32(0x7f80),
   7589                                                   binop(Iop_And32,
   7590                                                         unop(Iop_16Uto32,
   7591                                                              unop(Iop_32HIto16,
   7592                                                                   getIReg(rt))),
   7593                                                         mkU32(0x7fff))),
   7594                                             mkU8(0xff),
   7595                                             unop(Iop_16HIto8,
   7596                                                  unop(Iop_32HIto16,
   7597                                                       binop(Iop_Shl32,
   7598                                                             getIReg(rt),
   7599                                                             mkU8(1))))));
   7600                      assign(t3, IRExpr_ITE(binop(Iop_CmpEQ32,
   7601                                                  binop(Iop_And32,
   7602                                                        unop(Iop_16Uto32,
   7603                                                             unop(Iop_32HIto16,
   7604                                                                  getIReg(rt))),
   7605                                                        mkU32(0x00008000)),
   7606                                                  mkU32(0x0)),
   7607                                            mkexpr(t13),
   7608                                            mkU8(0x0)));
   7609                      assign(t14, binop(Iop_CmpEQ32,
   7610                                        binop(Iop_And32,
   7611                                              unop(Iop_16Uto32,
   7612                                                   unop(Iop_32HIto16,
   7613                                                        getIReg(rt))),
   7614                                              mkU32(0x00008000)),
   7615                                        mkU32(0x0)));
   7616                      assign(t15, IRExpr_ITE(binop(Iop_CmpLT32U,
   7617                                                   mkU32(0x7f80),
   7618                                                   binop(Iop_And32,
   7619                                                         unop(Iop_16Uto32,
   7620                                                              unop(Iop_32HIto16,
   7621                                                                   getIReg(rt))),
   7622                                                         mkU32(0x7fff))),
   7623                                             binop(Iop_Or32,
   7624                                                   getDSPControl(),
   7625                                                   mkU32(0x00400000)),
   7626                                             getDSPControl()));
   7627                      putDSPControl(IRExpr_ITE(mkexpr(t14),
   7628                                               mkexpr(t15),
   7629                                               binop(Iop_Or32,
   7630                                                     getDSPControl(),
   7631                                                     mkU32(0x00400000))));
   7632 
   7633                      putIReg(rd, binop(Iop_16HLto32,
   7634                                        binop(Iop_8HLto16,
   7635                                              mkexpr(t1), mkexpr(t0)),
   7636                                        binop(Iop_8HLto16,
   7637                                              mkexpr(t3), mkexpr(t2))));
   7638                      break;
   7639                   }
   7640                   case 0x14: {  /* PRECRQ.PH.W */
   7641                      DIP("precrq.ph.w r%u, r%u, %u", rd, rs, rt);
   7642                      vassert(!mode64);
   7643                      putIReg(rd, binop(Iop_16HLto32,
   7644                                        unop(Iop_32HIto16, getIReg(rs)),
   7645                                        unop(Iop_32HIto16, getIReg(rt))));
   7646                      break;
   7647                   }
   7648                   case 0x15: {  /* PRECRQ_RS.PH.W */
   7649                      DIP("precrq_rs.ph.w r%u, r%u, %u", rd, rs, rt);
   7650                      vassert(!mode64);
   7651                      t0 = newTemp(Ity_I64);
   7652                      t1 = newTemp(Ity_I1);
   7653                      t2 = newTemp(Ity_I32);
   7654                      t3 = newTemp(Ity_I64);
   7655                      t4 = newTemp(Ity_I1);
   7656                      t5 = newTemp(Ity_I32);
   7657 
   7658                      assign(t0, binop(Iop_Add64,
   7659                                       binop(Iop_32HLto64,
   7660                                             binop(Iop_Shr32,
   7661                                                   binop(Iop_And32,
   7662                                                         getIReg(rs),
   7663                                                         mkU32(0x80000000)),
   7664                                                   mkU8(31)),
   7665                                             getIReg(rs)),
   7666                                       mkU64(0x0000000000008000ULL)));
   7667                      assign(t1, binop(Iop_CmpNE32,
   7668                                       binop(Iop_And32,
   7669                                             unop(Iop_64HIto32, mkexpr(t0)),
   7670                                             mkU32(0x1)),
   7671                                       binop(Iop_And32,
   7672                                             binop(Iop_Shr32,
   7673                                                   unop(Iop_64to32, mkexpr(t0)),
   7674                                                   mkU8(31)),
   7675                                             mkU32(0x1))));
   7676                      assign(t2, IRExpr_ITE(mkexpr(t1),
   7677                                            mkU32(0x7fffffff),
   7678                                            unop(Iop_64to32, mkexpr(t0))));
   7679                      putDSPControl(IRExpr_ITE(mkexpr(t1),
   7680                                               binop(Iop_Or32,
   7681                                                     getDSPControl(),
   7682                                                     mkU32(0x400000)),
   7683                                               getDSPControl()));
   7684                      assign(t3, binop(Iop_Add64,
   7685                                       binop(Iop_32HLto64,
   7686                                             binop(Iop_Shr32,
   7687                                                   binop(Iop_And32,
   7688                                                         getIReg(rt),
   7689                                                         mkU32(0x80000000)),
   7690                                                   mkU8(31)),
   7691                                             getIReg(rt)),
   7692                                       mkU64(0x0000000000008000ULL)));
   7693                      assign(t4, binop(Iop_CmpNE32,
   7694                                       binop(Iop_And32,
   7695                                             unop(Iop_64HIto32, mkexpr(t3)),
   7696                                             mkU32(0x1)),
   7697                                       binop(Iop_And32,
   7698                                             binop(Iop_Shr32,
   7699                                                   unop(Iop_64to32, mkexpr(t3)),
   7700                                                   mkU8(31)),
   7701                                             mkU32(0x1))));
   7702                      assign(t5, IRExpr_ITE(mkexpr(t4),
   7703                                            mkU32(0x7fffffff),
   7704                                            unop(Iop_64to32, mkexpr(t3))));
   7705                      putDSPControl(IRExpr_ITE(mkexpr(t4),
   7706                                               binop(Iop_Or32,
   7707                                                     getDSPControl(),
   7708                                                     mkU32(0x400000)),
   7709                                               getDSPControl()));
   7710                      putIReg(rd, binop(Iop_16HLto32,
   7711                                        unop(Iop_32HIto16, mkexpr(t2)),
   7712                                        unop(Iop_32HIto16, mkexpr(t5))));
   7713                      break;
   7714                   }
   7715                   case 0x1E: {  /* PRECR_SRA.PH.W */
   7716                      DIP("precr_sra.ph.w r%u, r%u, %u", rt, rs, rd);
   7717                      vassert(!mode64);
   7718 
   7719                      if (0 == rd) {
   7720                         putIReg(rt, binop(Iop_16HLto32,
   7721                                           unop(Iop_32to16, getIReg(rt)),
   7722                                           unop(Iop_32to16, getIReg(rs))));
   7723                      } else {
   7724                         putIReg(rt, binop(Iop_16HLto32,
   7725                                           unop(Iop_32to16, binop(Iop_Sar32,
   7726                                                                  getIReg(rt),
   7727                                                                  mkU8(rd))),
   7728                                           unop(Iop_32to16, binop(Iop_Sar32,
   7729                                                                  getIReg(rs),
   7730                                                                  mkU8(rd)))));
   7731                      }
   7732                      break;
   7733                   }
   7734                   case 0x1F: {  /* PRECR_SRA_R.PH.W */
   7735                      DIP("precr_sra_r.ph.w r%u, r%u, %u", rt, rs, rd);
   7736                      vassert(!mode64);
   7737 
   7738                      t0 = newTemp(Ity_I32);
   7739                      t1 = newTemp(Ity_I32);
   7740 
   7741                      if (0 == rd) {
   7742                         putIReg(rt, binop(Iop_16HLto32,
   7743                                           unop(Iop_32to16, getIReg(rt)),
   7744                                           unop(Iop_32to16, getIReg(rs))));
   7745                      } else {
   7746                         assign(t0, binop(Iop_Shr32,
   7747                                          binop(Iop_Add32,
   7748                                                binop(Iop_Sar32,
   7749                                                      getIReg(rt),
   7750                                                      mkU8(rd-1)),
   7751                                                mkU32(0x1)),
   7752                                          mkU8(0x1)));
   7753                         assign(t1, binop(Iop_Shr32,
   7754                                          binop(Iop_Add32,
   7755                                                binop(Iop_Sar32,
   7756                                                      getIReg(rs),
   7757                                                      mkU8(rd-1)),
   7758                                                mkU32(0x1)),
   7759                                          mkU8(0x1)));
   7760                         putIReg(rt, binop(Iop_16HLto32,
   7761                                           unop(Iop_32to16, mkexpr(t0)),
   7762                                           unop(Iop_32to16, mkexpr(t1))));
   7763                      };
   7764                      break;
   7765                   }
   7766                   case 0xE: {  /* PACKRL.PH */
   7767                      DIP("packrl.ph r%u, r%u, r%u", rd, rs, rt);
   7768                      vassert(!mode64);
   7769 
   7770                      putIReg(rd, binop(Iop_16HLto32,
   7771                                        unop(Iop_32to16, getIReg(rs)),
   7772                                        unop(Iop_32HIto16, getIReg(rt))));
   7773                      break;
   7774                   }
   7775                   case 0x18: {  /* CMPGDU.EQ.QB */
   7776                      DIP("cmpgdu.eq.qb r%u, r%u, r%u", rd, rs, rt);
   7777                      vassert(!mode64);
   7778                      t1 = newTemp(Ity_I1);
   7779                      t2 = newTemp(Ity_I1);
   7780                      t3 = newTemp(Ity_I1);
   7781                      t4 = newTemp(Ity_I1);
   7782                      t5 = newTemp(Ity_I32);
   7783                      t6 = newTemp(Ity_I32);
   7784                      t7 = newTemp(Ity_I32);
   7785                      t8 = newTemp(Ity_I32);
   7786 
   7787                      assign(t1,
   7788                             binop(Iop_CmpEQ32,
   7789                                   unop(Iop_8Uto32,
   7790                                        unop(Iop_16to8,
   7791                                             unop(Iop_32to16, getIReg(rs)))),
   7792                                   unop(Iop_8Uto32,
   7793                                        unop(Iop_16to8,
   7794                                             unop(Iop_32to16, getIReg(rt))))));
   7795                      assign(t5, IRExpr_ITE(mkexpr(t1),
   7796                                            mkU32(0x00000001), mkU32(0)));
   7797                      putDSPControl(IRExpr_ITE(mkexpr(t1),
   7798                                               binop(Iop_Or32,
   7799                                                     getDSPControl(),
   7800                                                     mkU32(0x01000000)),
   7801                                               binop(Iop_And32,
   7802                                                     getDSPControl(),
   7803                                                     mkU32(0xfeffffff))));
   7804 
   7805                      assign(t2, binop(Iop_CmpEQ32,
   7806                                       unop(Iop_8Uto32,
   7807                                            unop(Iop_16HIto8,
   7808                                                 unop(Iop_32to16, getIReg(rs)))),
   7809                                       unop(Iop_8Uto32,
   7810                                            unop(Iop_16HIto8,
   7811                                                 unop(Iop_32to16,
   7812                                                      getIReg(rt))))));
   7813                      assign(t6, IRExpr_ITE(mkexpr(t2),
   7814                                            mkU32(0x00000002), mkU32(0)));
   7815                      putDSPControl(IRExpr_ITE(mkexpr(t2),
   7816                                               binop(Iop_Or32,
   7817                                                     getDSPControl(),
   7818                                                     mkU32(0x02000000)),
   7819                                               binop(Iop_And32,
   7820                                                     getDSPControl(),
   7821                                                     mkU32(0xfdffffff))));
   7822 
   7823                      assign(t3, binop(Iop_CmpEQ32,
   7824                                       unop(Iop_8Uto32,
   7825                                            unop(Iop_16to8,
   7826                                                 unop(Iop_32HIto16,
   7827                                                      getIReg(rs)))),
   7828                                       unop(Iop_8Uto32,
   7829                                            unop(Iop_16to8,
   7830                                                 unop(Iop_32HIto16,
   7831                                                      getIReg(rt))))));
   7832                      assign(t7, IRExpr_ITE(mkexpr(t3),
   7833                                            mkU32(0x00000004), mkU32(0)));
   7834                      putDSPControl(IRExpr_ITE(mkexpr(t3),
   7835                                               binop(Iop_Or32,
   7836                                                     getDSPControl(),
   7837                                                     mkU32(0x04000000)),
   7838                                               binop(Iop_And32,
   7839                                                     getDSPControl(),
   7840                                                     mkU32(0xfbffffff))));
   7841 
   7842                      assign(t4, binop(Iop_CmpEQ32,
   7843                                       unop(Iop_8Uto32,
   7844                                            unop(Iop_16HIto8,
   7845                                                 unop(Iop_32HIto16,
   7846                                                      getIReg(rs)))),
   7847                                       unop(Iop_8Uto32,
   7848                                            unop(Iop_16HIto8,
   7849                                                 unop(Iop_32HIto16,
   7850                                                      getIReg(rt))))));
   7851                      assign(t8, IRExpr_ITE(mkexpr(t4),
   7852                                            mkU32(0x00000008), mkU32(0)));
   7853                      putDSPControl(IRExpr_ITE(mkexpr(t4),
   7854                                               binop(Iop_Or32,
   7855                                                     getDSPControl(),
   7856                                                     mkU32(0x08000000)),
   7857                                               binop(Iop_And32,
   7858                                                     getDSPControl(),
   7859                                                     mkU32(0xf7ffffff))));
   7860 
   7861                      putIReg(rd, binop(Iop_Or32,
   7862                                        binop(Iop_Or32,
   7863                                              binop(Iop_Or32,
   7864                                                    mkexpr(t5), mkexpr(t6)),
   7865                                              mkexpr(t7)),
   7866                                        mkexpr(t8)));
   7867                      break;
   7868                   }
   7869                   case 0x19: {  /* CMPGDU.LT.QB */
   7870                      DIP("cmpgdu.lt.qb r%u, r%u, r%u", rd, rs, rt);
   7871                      vassert(!mode64);
   7872                      t1 = newTemp(Ity_I1);
   7873                      t2 = newTemp(Ity_I1);
   7874                      t3 = newTemp(Ity_I1);
   7875                      t4 = newTemp(Ity_I1);
   7876                      t5 = newTemp(Ity_I32);
   7877                      t6 = newTemp(Ity_I32);
   7878                      t7 = newTemp(Ity_I32);
   7879                      t8 = newTemp(Ity_I32);
   7880 
   7881                      assign(t1, binop(Iop_CmpLT32U,
   7882                                       unop(Iop_8Uto32,
   7883                                            unop(Iop_16to8,
   7884                                                 unop(Iop_32to16, getIReg(rs)))),
   7885                                       unop(Iop_8Uto32,
   7886                                            unop(Iop_16to8,
   7887                                                 unop(Iop_32to16,
   7888                                                      getIReg(rt))))));
   7889                      assign(t5, IRExpr_ITE(mkexpr(t1),
   7890                                            mkU32(0x00000001), mkU32(0)));
   7891                      putDSPControl(IRExpr_ITE(mkexpr(t1),
   7892                                               binop(Iop_Or32,
   7893                                                     getDSPControl(),
   7894                                                     mkU32(0x01000000)),
   7895                                               binop(Iop_And32,
   7896                                                     getDSPControl(),
   7897                                                     mkU32(0xfeffffff))));
   7898 
   7899                      assign(t2, binop(Iop_CmpLT32U,
   7900                                       unop(Iop_8Uto32,
   7901                                            unop(Iop_16HIto8,
   7902                                                 unop(Iop_32to16, getIReg(rs)))),
   7903                                       unop(Iop_8Uto32,
   7904                                            unop(Iop_16HIto8,
   7905                                                 unop(Iop_32to16,
   7906                                                      getIReg(rt))))));
   7907                      assign(t6, IRExpr_ITE(mkexpr(t2),
   7908                                            mkU32(0x00000002), mkU32(0)));
   7909                      putDSPControl(IRExpr_ITE(mkexpr(t2),
   7910                                               binop(Iop_Or32,
   7911                                                     getDSPControl(),
   7912                                                     mkU32(0x02000000)),
   7913                                               binop(Iop_And32,
   7914                                                     getDSPControl(),
   7915                                                     mkU32(0xfdffffff))));
   7916 
   7917                      assign(t3, binop(Iop_CmpLT32U,
   7918                                       unop(Iop_8Uto32,
   7919                                            unop(Iop_16to8,
   7920                                                 unop(Iop_32HIto16,
   7921                                                      getIReg(rs)))),
   7922                                       unop(Iop_8Uto32,
   7923                                            unop(Iop_16to8,
   7924                                                 unop(Iop_32HIto16,
   7925                                                      getIReg(rt))))));
   7926                      assign(t7, IRExpr_ITE(mkexpr(t3),
   7927                                            mkU32(0x00000004), mkU32(0)));
   7928                      putDSPControl(IRExpr_ITE(mkexpr(t3),
   7929                                               binop(Iop_Or32,
   7930                                                     getDSPControl(),
   7931                                                     mkU32(0x04000000)),
   7932                                               binop(Iop_And32,
   7933                                                     getDSPControl(),
   7934                                                     mkU32(0xfbffffff))));
   7935 
   7936                      assign(t4, binop(Iop_CmpLT32U,
   7937                                       unop(Iop_8Uto32,
   7938                                            unop(Iop_16HIto8,
   7939                                                 unop(Iop_32HIto16,
   7940                                                      getIReg(rs)))),
   7941                                       unop(Iop_8Uto32,
   7942                                            unop(Iop_16HIto8,
   7943                                                 unop(Iop_32HIto16,
   7944                                                      getIReg(rt))))));
   7945                      assign(t8, IRExpr_ITE(mkexpr(t4),
   7946                                            mkU32(0x00000008), mkU32(0)));
   7947                      putDSPControl(IRExpr_ITE(mkexpr(t4),
   7948                                               binop(Iop_Or32,
   7949                                                     getDSPControl(),
   7950                                                     mkU32(0x08000000)),
   7951                                               binop(Iop_And32,
   7952                                                     getDSPControl(),
   7953                                                     mkU32(0xf7ffffff))));
   7954 
   7955                      putIReg(rd, binop(Iop_Or32,
   7956                                        binop(Iop_Or32,
   7957                                              binop(Iop_Or32,
   7958                                                    mkexpr(t5), mkexpr(t6)),
   7959                                              mkexpr(t7)),
   7960                                        mkexpr(t8)));
   7961                      break;
   7962                   }
   7963                   case 0x1A: {  /* CMPGDU.LE.QB */
   7964                      DIP("cmpgdu.le.qb r%u, r%u, r%u", rd, rs, rt);
   7965                      vassert(!mode64);
   7966                      t1 = newTemp(Ity_I1);
   7967                      t2 = newTemp(Ity_I1);
   7968                      t3 = newTemp(Ity_I1);
   7969                      t4 = newTemp(Ity_I1);
   7970                      t5 = newTemp(Ity_I32);
   7971                      t6 = newTemp(Ity_I32);
   7972                      t7 = newTemp(Ity_I32);
   7973                      t8 = newTemp(Ity_I32);
   7974 
   7975                      assign(t1, binop(Iop_CmpLE32U,
   7976                                       unop(Iop_8Uto32,
   7977                                            unop(Iop_16to8,
   7978                                                 unop(Iop_32to16, getIReg(rs)))),
   7979                                       unop(Iop_8Uto32,
   7980                                            unop(Iop_16to8,
   7981                                                 unop(Iop_32to16,
   7982                                                      getIReg(rt))))));
   7983                      assign(t5, IRExpr_ITE(mkexpr(t1),
   7984                                            mkU32(0x00000001),
   7985                                            mkU32(0)));
   7986                      putDSPControl(IRExpr_ITE(mkexpr(t1),
   7987                                               binop(Iop_Or32,
   7988                                                     getDSPControl(),
   7989                                                     mkU32(0x01000000)),
   7990                                               binop(Iop_And32,
   7991                                                     getDSPControl(),
   7992                                                     mkU32(0xfeffffff))));
   7993 
   7994                      assign(t2, binop(Iop_CmpLE32U,
   7995                                       unop(Iop_8Uto32,
   7996                                            unop(Iop_16HIto8,
   7997                                                 unop(Iop_32to16, getIReg(rs)))),
   7998                                       unop(Iop_8Uto32,
   7999                                            unop(Iop_16HIto8,
   8000                                                 unop(Iop_32to16,
   8001                                                      getIReg(rt))))));
   8002                      assign(t6, IRExpr_ITE(mkexpr(t2),
   8003                                            mkU32(0x00000002), mkU32(0)));
   8004                      putDSPControl(IRExpr_ITE(mkexpr(t2),
   8005                                               binop(Iop_Or32,
   8006                                                     getDSPControl(),
   8007                                                     mkU32(0x02000000)),
   8008                                               binop(Iop_And32,
   8009                                                     getDSPControl(),
   8010                                                     mkU32(0xfdffffff))));
   8011 
   8012                      assign(t3, binop(Iop_CmpLE32U,
   8013                                       unop(Iop_8Uto32,
   8014                                            unop(Iop_16to8,
   8015                                                 unop(Iop_32HIto16,
   8016                                                      getIReg(rs)))),
   8017                                       unop(Iop_8Uto32,
   8018                                            unop(Iop_16to8,
   8019                                                 unop(Iop_32HIto16,
   8020                                                      getIReg(rt))))));
   8021                      assign(t7, IRExpr_ITE(mkexpr(t3),
   8022                                            mkU32(0x00000004), mkU32(0)));
   8023                      putDSPControl(IRExpr_ITE(mkexpr(t3),
   8024                                               binop(Iop_Or32,
   8025                                                     getDSPControl(),
   8026                                                     mkU32(0x04000000)),
   8027                                               binop(Iop_And32,
   8028                                                     getDSPControl(),
   8029                                                     mkU32(0xfbffffff))));
   8030 
   8031                      assign(t4, binop(Iop_CmpLE32U,
   8032                                       unop(Iop_8Uto32,
   8033                                            unop(Iop_16HIto8,
   8034                                                 unop(Iop_32HIto16,
   8035                                                      getIReg(rs)))),
   8036                                       unop(Iop_8Uto32,
   8037                                            unop(Iop_16HIto8,
   8038                                                 unop(Iop_32HIto16,
   8039                                                      getIReg(rt))))));
   8040                      assign(t8, IRExpr_ITE(mkexpr(t4),
   8041                                            mkU32(0x00000008), mkU32(0)));
   8042                      putDSPControl(IRExpr_ITE(mkexpr(t4),
   8043                                               binop(Iop_Or32,
   8044                                                     getDSPControl(),
   8045                                                     mkU32(0x08000000)),
   8046                                               binop(Iop_And32,
   8047                                                     getDSPControl(),
   8048                                                     mkU32(0xf7ffffff))));
   8049 
   8050                      putIReg(rd, binop(Iop_Or32,
   8051                                        binop(Iop_Or32,
   8052                                              binop(Iop_Or32,
   8053                                                    mkexpr(t5), mkexpr(t6)),
   8054                                              mkexpr(t7)),
   8055                                        mkexpr(t8)));
   8056                      break;
   8057                   }
   8058                   default:
   8059                      return -1;
   8060                }
   8061                break;  /* end of CMPU.EQ.QB */
   8062             }
   8063             case 0x13: {  /* SHLL.QB */
   8064                switch(sa) {
   8065                   case 0x0: {  /* SHLL.QB */
   8066                      DIP("shll.qb r%u, r%u, %u", rd, rt, rs);
   8067                      vassert(!mode64);
   8068                      t0 = newTemp(Ity_I32);
   8069                      t1 = newTemp(Ity_I1);
   8070                      t2 = newTemp(Ity_I1);
   8071                      t3 = newTemp(Ity_I32);
   8072                      t4 = newTemp(Ity_I1);
   8073                      t5 = newTemp(Ity_I1);
   8074                      t6 = newTemp(Ity_I32);
   8075                      t7 = newTemp(Ity_I1);
   8076                      t8 = newTemp(Ity_I1);
   8077                      t9 = newTemp(Ity_I1);
   8078                      t10 = newTemp(Ity_I1);
   8079 
   8080                      if (0 == rs) {
   8081                         putIReg(rd, getIReg(rt));
   8082                      } else {
   8083                         /* Shift bits 7..0 and 23..16. */
   8084                         assign(t0, binop(Iop_Shl32,
   8085                                          binop(Iop_And32,
   8086                                                getIReg(rt),
   8087                                                mkU32(0x00ff00ff)),
   8088                                          mkU8(rs)));
   8089                         assign(t1, binop(Iop_CmpNE32,
   8090                                         binop(Iop_And32,
   8091                                               mkexpr(t0),
   8092                                               mkU32(0xff000000)),
   8093                                         mkU32(0x00000000)));
   8094                         assign(t2, binop(Iop_CmpNE32,
   8095                                         binop(Iop_And32,
   8096                                               mkexpr(t0),
   8097                                               mkU32(0xff000000)),
   8098                                         mkU32(0xff000000)));
   8099                         assign(t7, binop(Iop_CmpNE32,
   8100                                         binop(Iop_And32,
   8101                                               mkexpr(t0),
   8102                                               mkU32(0x0000ff00)),
   8103                                         mkU32(0x00000000)));
   8104                         assign(t8, binop(Iop_CmpNE32,
   8105                                         binop(Iop_And32,
   8106                                               mkexpr(t0),
   8107                                               mkU32(0x0000ff00)),
   8108                                         mkU32(0x000ff00)));
   8109                         /* Shift bits 15..8 and 31..24. */
   8110                         assign(t3, binop(Iop_Shl32,
   8111                                          binop(Iop_Shr32,
   8112                                                binop(Iop_And32,
   8113                                                      getIReg(rt),
   8114                                                      mkU32(0xff00ff00)),
   8115                                                mkU8(8)),
   8116                                          mkU8(rs)));
   8117                         assign(t4, binop(Iop_CmpNE32,
   8118                                         binop(Iop_And32,
   8119                                               mkexpr(t3),
   8120                                               mkU32(0xff000000)),
   8121                                         mkU32(0x00000000)));
   8122                         assign(t5, binop(Iop_CmpNE32,
   8123                                         binop(Iop_And32,
   8124                                               mkexpr(t3),
   8125                                               mkU32(0xff000000)),
   8126                                         mkU32(0xff000000)));
   8127                         assign(t9, binop(Iop_CmpNE32,
   8128                                         binop(Iop_And32,
   8129                                               mkexpr(t3),
   8130                                               mkU32(0x0000ff00)),
   8131                                         mkU32(0x00000000)));
   8132                         assign(t10, binop(Iop_CmpNE32,
   8133                                         binop(Iop_And32,
   8134                                               mkexpr(t3),
   8135                                               mkU32(0x0000ff00)),
   8136                                         mkU32(0x0000ff00)));
   8137 
   8138                         assign(t6, binop(Iop_Or32,
   8139                                          binop(Iop_Or32,
   8140                                                binop(Iop_And32,
   8141                                                      unop(Iop_1Uto32,
   8142                                                           mkexpr(t1)),
   8143                                                      unop(Iop_1Uto32,
   8144                                                           mkexpr(t2))),
   8145                                                binop(Iop_And32,
   8146                                                      unop(Iop_1Uto32,
   8147                                                           mkexpr(t7)),
   8148                                                      unop(Iop_1Uto32,
   8149                                                           mkexpr(t8)))),
   8150                                          binop(Iop_Or32,
   8151                                                binop(Iop_And32,
   8152                                                      unop(Iop_1Uto32,
   8153                                                           mkexpr(t4)),
   8154                                                      unop(Iop_1Uto32,
   8155                                                           mkexpr(t5))),
   8156                                                binop(Iop_And32,
   8157                                                      unop(Iop_1Uto32,
   8158                                                           mkexpr(t9)),
   8159                                                      unop(Iop_1Uto32,
   8160                                                           mkexpr(t10))))));
   8161 
   8162                         putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32,
   8163                                                        mkexpr(t6),
   8164                                                        mkU32(0x0)),
   8165                                                  binop(Iop_Or32,
   8166                                                        getDSPControl(),
   8167                                                        mkU32(0x400000)),
   8168                                                  getDSPControl()));
   8169                         putIReg(rd, binop(Iop_Or32,
   8170                                           binop(Iop_Shl32,
   8171                                                 binop(Iop_And32,
   8172                                                       mkexpr(t3),
   8173                                                       mkU32(0x00ff00ff)),
   8174                                                 mkU8(8)),
   8175                                           binop(Iop_And32,
   8176                                                 mkexpr(t0),
   8177                                                 mkU32(0x00ff00ff))));
   8178                      }
   8179                      break;
   8180                   }
   8181                   case 0x3: {  /* SHRL.QB */
   8182                      DIP("shrl.qb r%u, r%u, %u", rd, rt, rs);
   8183                      vassert(!mode64);
   8184                      t0 = newTemp(Ity_I32);
   8185                      t1 = newTemp(Ity_I8);
   8186                      t2 = newTemp(Ity_I32);
   8187                      t3 = newTemp(Ity_I8);
   8188                      t4 = newTemp(Ity_I32);
   8189                      t5 = newTemp(Ity_I8);
   8190                      t6 = newTemp(Ity_I32);
   8191                      t7 = newTemp(Ity_I8);
   8192                      t9 = newTemp(Ity_I32);
   8193 
   8194                      assign(t9, binop(Iop_And32, getIReg(rs), mkU32(0x7)));
   8195                      assign(t0, unop(Iop_8Uto32,
   8196                                      unop(Iop_16to8,
   8197                                           unop(Iop_32to16, getIReg(rt)))));
   8198                      assign(t1, unop(Iop_32to8,
   8199                                      binop(Iop_Shr32,
   8200                                            mkexpr(t0),
   8201                                            unop(Iop_32to8, mkexpr(t9)))));
   8202 
   8203                      assign(t2, unop(Iop_8Uto32,
   8204                                      unop(Iop_16HIto8,
   8205                                           unop(Iop_32to16, getIReg(rt)))));
   8206                      assign(t3, unop(Iop_32to8,
   8207                                      binop(Iop_Shr32,
   8208                                            mkexpr(t2),
   8209                                            unop(Iop_32to8, mkexpr(t9)))));
   8210 
   8211                      assign(t4, unop(Iop_8Uto32,
   8212                                      unop(Iop_16to8,
   8213                                           unop(Iop_32HIto16, getIReg(rt)))));
   8214                      assign(t5, unop(Iop_32to8,
   8215                                      binop(Iop_Shr32,
   8216                                            mkexpr(t4),
   8217                                            unop(Iop_32to8, mkexpr(t9)))));
   8218 
   8219                      assign(t6, unop(Iop_8Uto32,
   8220                                      unop(Iop_16HIto8,
   8221                                           unop(Iop_32HIto16, getIReg(rt)))));
   8222                      assign(t7, unop(Iop_32to8,
   8223                                      binop(Iop_Shr32,
   8224                                            mkexpr(t6),
   8225                                            unop(Iop_32to8, mkexpr(t9)))));
   8226                      putIReg(rd, IRExpr_ITE(binop(Iop_CmpEQ32,
   8227                                                   mkexpr(t9),
   8228                                                   mkU32(0x0)),
   8229                                             getIReg(rt),
   8230                                             binop(Iop_16HLto32,
   8231                                                   binop(Iop_8HLto16,
   8232                                                         mkexpr(t7),
   8233                                                         mkexpr(t5)),
   8234                                                   binop(Iop_8HLto16,
   8235                                                         mkexpr(t3),
   8236                                                         mkexpr(t1)))));
   8237                      break;
   8238                   }
   8239                   case 0x2: {  /* SHLLV.QB */
   8240                      DIP("shllv.qb r%u, r%u, r%u", rd, rt, rs);
   8241                      vassert(!mode64);
   8242                      t0 = newTemp(Ity_I32);
   8243                      t1 = newTemp(Ity_I1);
   8244                      t2 = newTemp(Ity_I1);
   8245                      t3 = newTemp(Ity_I32);
   8246                      t4 = newTemp(Ity_I1);
   8247                      t5 = newTemp(Ity_I1);
   8248                      t6 = newTemp(Ity_I32);
   8249                      t7 = newTemp(Ity_I1);
   8250                      t8 = newTemp(Ity_I1);
   8251                      t9 = newTemp(Ity_I1);
   8252                      t10 = newTemp(Ity_I1);
   8253                      t11 = newTemp(Ity_I8);
   8254 
   8255                      assign(t11, unop(Iop_32to8,
   8256                                       binop(Iop_And32,
   8257                                             getIReg(rs),
   8258                                             mkU32(0x7))));
   8259                      /* Shift bits 7..0 and 23..16. */
   8260                      assign(t0, binop(Iop_Shl32,
   8261                                       binop(Iop_And32,
   8262                                             getIReg(rt),
   8263                                             mkU32(0x00ff00ff)),
   8264                                       mkexpr(t11)));
   8265                      assign(t1, binop(Iop_CmpNE32,
   8266                                      binop(Iop_And32,
   8267                                            mkexpr(t0),
   8268                                            mkU32(0xff000000)),
   8269                                      mkU32(0x00000000)));
   8270                      assign(t2, binop(Iop_CmpNE32,
   8271                                      binop(Iop_And32,
   8272                                            mkexpr(t0),
   8273                                            mkU32(0xff000000)),
   8274                                      mkU32(0xff000000)));
   8275                      assign(t7, binop(Iop_CmpNE32,
   8276                                      binop(Iop_And32,
   8277                                            mkexpr(t0),
   8278                                            mkU32(0x0000ff00)),
   8279                                      mkU32(0x00000000)));
   8280                      assign(t8, binop(Iop_CmpNE32,
   8281                                      binop(Iop_And32,
   8282                                            mkexpr(t0),
   8283                                            mkU32(0x0000ff00)),
   8284                                      mkU32(0x000ff00)));
   8285                      /* Shift bits 15..8 and 31..24. */
   8286                      assign(t3, binop(Iop_Shl32,
   8287                                       binop(Iop_Shr32,
   8288                                             binop(Iop_And32,
   8289                                                   getIReg(rt),
   8290                                                   mkU32(0xff00ff00)),
   8291                                             mkU8(8)),
   8292                                       mkexpr(t11)));
   8293                      assign(t4, binop(Iop_CmpNE32,
   8294                                      binop(Iop_And32,
   8295                                            mkexpr(t3),
   8296                                            mkU32(0xff000000)),
   8297                                      mkU32(0x00000000)));
   8298                      assign(t5, binop(Iop_CmpNE32,
   8299                                      binop(Iop_And32,
   8300                                            mkexpr(t3),
   8301                                            mkU32(0xff000000)),
   8302                                      mkU32(0xff000000)));
   8303                      assign(t9, binop(Iop_CmpNE32,
   8304                                      binop(Iop_And32,
   8305                                            mkexpr(t3),
   8306                                            mkU32(0x0000ff00)),
   8307                                      mkU32(0x00000000)));
   8308                      assign(t10, binop(Iop_CmpNE32,
   8309                                      binop(Iop_And32,
   8310                                            mkexpr(t3),
   8311                                            mkU32(0x0000ff00)),
   8312                                      mkU32(0x0000ff00)));
   8313 
   8314                      assign(t6, binop(Iop_Or32,
   8315                                       binop(Iop_Or32,
   8316                                             binop(Iop_And32,
   8317                                                   unop(Iop_1Uto32,
   8318                                                        mkexpr(t1)),
   8319                                                   unop(Iop_1Uto32,
   8320                                                        mkexpr(t2))),
   8321                                             binop(Iop_And32,
   8322                                                   unop(Iop_1Uto32,
   8323                                                        mkexpr(t7)),
   8324                                                   unop(Iop_1Uto32,
   8325                                                        mkexpr(t8)))),
   8326                                       binop(Iop_Or32,
   8327                                             binop(Iop_And32,
   8328                                                   unop(Iop_1Uto32,
   8329                                                        mkexpr(t4)),
   8330                                                   unop(Iop_1Uto32,
   8331                                                        mkexpr(t5))),
   8332                                             binop(Iop_And32,
   8333                                                   unop(Iop_1Uto32,
   8334                                                        mkexpr(t9)),
   8335                                                   unop(Iop_1Uto32,
   8336                                                        mkexpr(t10))))));
   8337 
   8338                      putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32,
   8339                                                     mkexpr(t6),
   8340                                                     mkU32(0x0)),
   8341                                               binop(Iop_Or32,
   8342                                                     getDSPControl(),
   8343                                                     mkU32(0x400000)),
   8344                                               getDSPControl()));
   8345                      putIReg(rd, IRExpr_ITE(binop(Iop_CmpEQ32,
   8346                                                   unop(Iop_8Uto32, mkexpr(t11)),
   8347                                                   mkU32(0)),
   8348                                             getIReg(rt),
   8349                                             binop(Iop_Or32,
   8350                                                   binop(Iop_Shl32,
   8351                                                         binop(Iop_And32,
   8352                                                               mkexpr(t3),
   8353                                                               mkU32(0xff00ff)),
   8354                                                         mkU8(8)),
   8355                                                   binop(Iop_And32,
   8356                                                         mkexpr(t0),
   8357                                                         mkU32(0x00ff00ff)))));
   8358                      break;
   8359                   }
   8360                   case 0x1: {  /* SHRLV.QB */
   8361                      DIP("shrlv.qb r%u, r%u, r%u", rd, rt, rs);
   8362                      vassert(!mode64);
   8363                      t0 = newTemp(Ity_I8);
   8364                      t1 = newTemp(Ity_I8);
   8365                      t2 = newTemp(Ity_I8);
   8366                      t3 = newTemp(Ity_I8);
   8367 
   8368                      assign(t0, unop(Iop_32to8,
   8369                                      binop(Iop_Shr32,
   8370                                            unop(Iop_8Uto32,
   8371                                                 unop(Iop_32to8, getIReg(rt))),
   8372                                            mkU8(rs))));
   8373                      assign(t1, unop(Iop_32to8,
   8374                                      binop(Iop_Shr32,
   8375                                            unop(Iop_8Uto32,
   8376                                                 unop(Iop_16HIto8,
   8377                                                      unop(Iop_32to16,
   8378                                                           getIReg(rt)))),
   8379                                            mkU8(rs))));
   8380                      assign(t2, unop(Iop_32to8,
   8381                                       binop(Iop_Shr32,
   8382                                             unop(Iop_8Uto32,
   8383                                                  unop(Iop_16to8,
   8384                                                       unop(Iop_32HIto16,
   8385                                                            getIReg(rt)))),
   8386                                             mkU8(rs))));
   8387                      assign(t3, unop(Iop_32to8,
   8388                                      binop(Iop_Shr32,
   8389                                            unop(Iop_8Uto32,
   8390                                                 unop(Iop_16HIto8,
   8391                                                      unop(Iop_32HIto16,
   8392                                                           getIReg(rt)))),
   8393                                            mkU8(rs))));
   8394                      putIReg(rd,
   8395                              binop(Iop_16HLto32,
   8396                                    binop(Iop_8HLto16, mkexpr(t3), mkexpr(t2)),
   8397                                    binop(Iop_8HLto16, mkexpr(t1), mkexpr(t0))));
   8398                      break;
   8399                   }
   8400                   case 0x4: {  /* SHRA.QB */
   8401                      DIP("shra.qb r%u, r%u, %u", rd, rt, rs);
   8402                      vassert(!mode64);
   8403                      t0 = newTemp(Ity_I32);
   8404                      t1 = newTemp(Ity_I32);
   8405                      t2 = newTemp(Ity_I32);
   8406                      t3 = newTemp(Ity_I32);
   8407                      t4 = newTemp(Ity_I32);
   8408                      t5 = newTemp(Ity_I32);
   8409                      t6 = newTemp(Ity_I32);
   8410                      t7 = newTemp(Ity_I32);
   8411                      t8 = newTemp(Ity_I32);
   8412                      t9 = newTemp(Ity_I32);
   8413                      t10 = newTemp(Ity_I32);
   8414                      t11 = newTemp(Ity_I32);
   8415 
   8416                      /* ========== GPR[rt]_31..24 ========== */
   8417                      assign(t1,
   8418                             unop(Iop_8Uto32,
   8419                                  unop(Iop_16HIto8,
   8420                                       unop(Iop_32HIto16, getIReg(rt)))));
   8421                      assign(t2,
   8422                             binop(Iop_Shr32, mkexpr(t1), mkU8(rs)));
   8423                      /* tempD_7..0 */
   8424                      assign(t0,
   8425                             binop(Iop_Or32,
   8426                                   mkexpr(t2),
   8427                                   binop(Iop_Shl32,
   8428                                         IRExpr_ITE(binop(Iop_CmpEQ32,
   8429                                                          binop(Iop_And32,
   8430                                                                mkexpr(t1),
   8431                                                                mkU32(0x00000080)
   8432                                                               ),
   8433                                                          mkU32(0x00000080)),
   8434                                                    mkU32(0xFFFFFFFF),
   8435                                                    mkU32(0x00000000)),
   8436                                         binop(Iop_Sub8, mkU8(0x8), mkU8(rs)))));
   8437 
   8438                      /* ========== GPR[rt]_23..16 ========== */
   8439                      assign(t4,
   8440                             unop(Iop_8Uto32,
   8441                                  unop(Iop_16to8,
   8442                                       unop(Iop_32HIto16, getIReg(rt)))));
   8443                      assign(t5, binop(Iop_Shr32, mkexpr(t4), mkU8(rs)));
   8444                      /* tempC_7..0 */
   8445                      assign(t3,
   8446                             binop(Iop_Or32,
   8447                                   mkexpr(t5),
   8448                                   binop(Iop_Shl32,
   8449                                         IRExpr_ITE(binop(Iop_CmpEQ32,
   8450                                                          binop(Iop_And32,
   8451                                                                mkexpr(t4),
   8452                                                                mkU32(0x00000080)
   8453                                                               ),
   8454                                                          mkU32(0x00000080)),
   8455                                                    mkU32(0xFFFFFFFF),
   8456                                                    mkU32(0x00000000)),
   8457                                         binop(Iop_Sub8, mkU8(0x8), mkU8(rs)))));
   8458 
   8459                      /* ========== GPR[rt]_15..8 ========== */
   8460                      assign(t7,
   8461                             unop(Iop_8Uto32,
   8462                                  unop(Iop_16HIto8,
   8463                                       unop(Iop_32to16, getIReg(rt)))));
   8464                      assign(t8, binop(Iop_Shr32, mkexpr(t7), mkU8(rs)));
   8465                      /* tempB_7..0 */
   8466                      assign(t6,
   8467                             binop(Iop_Or32,
   8468                                   mkexpr(t8),
   8469                                   binop(Iop_Shl32,
   8470                                         IRExpr_ITE(binop(Iop_CmpEQ32,
   8471                                                          binop(Iop_And32,
   8472                                                                mkexpr(t7),
   8473                                                                mkU32(0x00000080)
   8474                                                               ),
   8475                                                          mkU32(0x00000080)),
   8476                                                    mkU32(0xFFFFFFFF),
   8477                                                    mkU32(0x00000000)),
   8478                                         binop(Iop_Sub8, mkU8(0x8), mkU8(rs)))));
   8479 
   8480                      /* ========== GPR[rt]_7..0 ========== */
   8481                      assign(t10,
   8482                             unop(Iop_8Uto32,
   8483                                  unop(Iop_16to8,
   8484                                       unop(Iop_32to16, getIReg(rt)))));
   8485                      assign(t11, binop(Iop_Shr32, mkexpr(t10), mkU8(rs)));
   8486                      /* tempB_7..0 */
   8487                      assign(t9,
   8488                             binop(Iop_Or32,
   8489                                   mkexpr(t11),
   8490                                   binop(Iop_Shl32,
   8491                                         IRExpr_ITE(binop(Iop_CmpEQ32,
   8492                                                          binop(Iop_And32,
   8493                                                                mkexpr(t10),
   8494                                                                mkU32(0x00000080)
   8495                                                               ),
   8496                                                          mkU32(0x00000080)),
   8497                                                    mkU32(0xFFFFFFFF),
   8498                                                    mkU32(0x00000000)),
   8499                                         binop(Iop_Sub8, mkU8(0x8), mkU8(rs)))));
   8500 
   8501                      putIReg(rd,
   8502                              binop(Iop_16HLto32,
   8503                                    binop(Iop_8HLto16,
   8504                                          unop(Iop_32to8, mkexpr(t0)),
   8505                                          unop(Iop_32to8, mkexpr(t3))),
   8506                                    binop(Iop_8HLto16,
   8507                                          unop(Iop_32to8, mkexpr(t6)),
   8508                                          unop(Iop_32to8, mkexpr(t9)))));
   8509                      break;
   8510                   }
   8511                   case 0x5: {  /* SHRA_R.QB */
   8512                      DIP("shra_r.qb r%u, r%u, %u", rd, rt, rs);
   8513                      vassert(!mode64);
   8514                      t0 = newTemp(Ity_I32);
   8515                      t1 = newTemp(Ity_I8);
   8516                      t2 = newTemp(Ity_I32);
   8517                      t3 = newTemp(Ity_I8);
   8518                      t4 = newTemp(Ity_I32);
   8519                      t5 = newTemp(Ity_I8);
   8520                      t6 = newTemp(Ity_I32);
   8521                      t7 = newTemp(Ity_I8);
   8522 
   8523                      if (0 == rs) {
   8524                         putIReg(rd, getIReg(rt));
   8525                      } else {
   8526                         assign(t0, unop(Iop_8Sto32,
   8527                                         unop(Iop_16to8,
   8528                                              unop(Iop_32to16, getIReg(rt)))));
   8529                         assign(t1, unop(Iop_32to8,
   8530                                         binop(Iop_Sar32,
   8531                                               binop(Iop_Add32,
   8532                                                     mkexpr(t0),
   8533                                                     binop(Iop_Shl32,
   8534                                                           mkU32(0x1),
   8535                                                           mkU8(rs-1))),
   8536                                               mkU8(rs))));
   8537 
   8538                         assign(t2, unop(Iop_8Sto32,
   8539                                         unop(Iop_16HIto8,
   8540                                              unop(Iop_32to16, getIReg(rt)))));
   8541                         assign(t3, unop(Iop_32to8,
   8542                                         binop(Iop_Sar32,
   8543                                               binop(Iop_Add32,
   8544                                                     mkexpr(t2),
   8545                                                     binop(Iop_Shl32,
   8546                                                           mkU32(0x1),
   8547                                                           mkU8(rs-1))),
   8548                                               mkU8(rs))));
   8549 
   8550                         assign(t4, unop(Iop_8Sto32,
   8551                                         unop(Iop_16to8,
   8552                                              unop(Iop_32HIto16, getIReg(rt)))));
   8553                         assign(t5, unop(Iop_32to8,
   8554                                         binop(Iop_Sar32,
   8555                                               binop(Iop_Add32,
   8556                                                     mkexpr(t4),
   8557                                                     binop(Iop_Shl32,
   8558                                                           mkU32(0x1),
   8559                                                           mkU8(rs-1))),
   8560                                               mkU8(rs))));
   8561 
   8562                         assign(t6, unop(Iop_8Sto32,
   8563                                         unop(Iop_16HIto8,
   8564                                              unop(Iop_32HIto16, getIReg(rt)))));
   8565                         assign(t7, unop(Iop_32to8,
   8566                                         binop(Iop_Sar32,
   8567                                               binop(Iop_Add32,
   8568                                                     mkexpr(t6),
   8569                                                     binop(Iop_Shl32,
   8570                                                           mkU32(0x1),
   8571                                                           mkU8(rs-1))),
   8572                                               mkU8(rs))));
   8573                         putIReg(rd, binop(Iop_16HLto32,
   8574                                          binop(Iop_8HLto16,
   8575                                                mkexpr(t7), mkexpr(t5)),
   8576                                          binop(Iop_8HLto16,
   8577                                                mkexpr(t3), mkexpr(t1))));
   8578                      }
   8579                      break;
   8580                   }
   8581                   case 0x6: {  /* SHRAV.QB */
   8582                      DIP("shrav.qb r%u, r%u, %u", rd, rt, rs);
   8583                      vassert(!mode64);
   8584 
   8585                      t0 = newTemp(Ity_I32);
   8586                      t1 = newTemp(Ity_I32);
   8587                      t2 = newTemp(Ity_I32);
   8588 
   8589                      t3 = newTemp(Ity_I32);
   8590                      t4 = newTemp(Ity_I32);
   8591                      t5 = newTemp(Ity_I32);
   8592 
   8593                      t6 = newTemp(Ity_I32);
   8594                      t7 = newTemp(Ity_I32);
   8595                      t8 = newTemp(Ity_I32);
   8596 
   8597                      t9 = newTemp(Ity_I32);
   8598                      t10 = newTemp(Ity_I32);
   8599                      t11 = newTemp(Ity_I32);
   8600 
   8601                      /* ========== GPR[rt]_31..24 ========== */
   8602                      assign(t1,
   8603                             unop(Iop_8Uto32,
   8604                                  unop(Iop_16HIto8,
   8605                                       unop(Iop_32HIto16, getIReg(rt)))));
   8606                      assign(t2,
   8607                             binop(Iop_Shr32,
   8608                                   mkexpr(t1),
   8609                                   unop(Iop_32to8, binop(Iop_And32,
   8610                                                         getIReg(rs),
   8611                                                         mkU32(0x7)))));
   8612                      /* tempD_7..0 */
   8613                      assign(t0,
   8614                             binop(Iop_Or32,
   8615                                   mkexpr(t2),
   8616                                   binop(Iop_Shl32,
   8617                                         IRExpr_ITE(binop(Iop_CmpEQ32,
   8618                                                          binop(Iop_And32,
   8619                                                                mkexpr(t1),
   8620                                                                mkU32(0x00000080)
   8621                                                               ),
   8622                                                          mkU32(0x00000080)),
   8623                                                    mkU32(0xFFFFFFFF),
   8624                                                    mkU32(0x00000000)),
   8625                                         binop(Iop_Sub8,
   8626                                               mkU8(0x8),
   8627                                               unop(Iop_32to8, binop(Iop_And32,
   8628                                                                     getIReg(rs),
   8629                                                                     mkU32(0x7)))
   8630                                               ))));
   8631 
   8632                      /* ========== GPR[rt]_23..16 ========== */
   8633                      assign(t4,
   8634                             unop(Iop_8Uto32,
   8635                                  unop(Iop_16to8,
   8636                                       unop(Iop_32HIto16, getIReg(rt)))));
   8637                      assign(t5,
   8638                             binop(Iop_Shr32,
   8639                                   mkexpr(t4),
   8640                                   unop(Iop_32to8, binop(Iop_And32,
   8641                                                         getIReg(rs),
   8642                                                         mkU32(0x7)))));
   8643                      /* tempC_7..0 */
   8644                      assign(t3,
   8645                             binop(Iop_Or32,
   8646                                   mkexpr(t5),
   8647                                   binop(Iop_Shl32,
   8648                                         IRExpr_ITE(binop(Iop_CmpEQ32,
   8649                                                          binop(Iop_And32,
   8650                                                                mkexpr(t4),
   8651                                                                mkU32(0x00000080)
   8652                                                               ),
   8653                                                          mkU32(0x00000080)),
   8654                                                    mkU32(0xFFFFFFFF),
   8655                                                    mkU32(0x00000000)),
   8656                                         binop(Iop_Sub8,
   8657                                               mkU8(0x8),
   8658                                               unop(Iop_32to8, binop(Iop_And32,
   8659                                                                     getIReg(rs),
   8660                                                                     mkU32(0x7)))
   8661                                               ))));
   8662 
   8663                      /* ========== GPR[rt]_15..8 ========== */
   8664                      assign(t7,
   8665                             unop(Iop_8Uto32,
   8666                                  unop(Iop_16HIto8,
   8667                                       unop(Iop_32to16, getIReg(rt)))));
   8668                      assign(t8,
   8669                             binop(Iop_Shr32,
   8670                                   mkexpr(t7),
   8671                                   unop(Iop_32to8, binop(Iop_And32,
   8672                                                         getIReg(rs),
   8673                                                         mkU32(0x7)))));
   8674                      /* tempB_7..0 */
   8675                      assign(t6,
   8676                             binop(Iop_Or32,
   8677                                   mkexpr(t8),
   8678                                   binop(Iop_Shl32,
   8679                                         IRExpr_ITE(binop(Iop_CmpEQ32,
   8680                                                          binop(Iop_And32,
   8681                                                                mkexpr(t7),
   8682                                                                mkU32(0x00000080)
   8683                                                               ),
   8684                                                          mkU32(0x00000080)),
   8685                                                    mkU32(0xFFFFFFFF),
   8686                                                    mkU32(0x00000000)),
   8687                                         binop(Iop_Sub8,
   8688                                               mkU8(0x8),
   8689                                               unop(Iop_32to8, binop(Iop_And32,
   8690                                                                     getIReg(rs),
   8691                                                                     mkU32(0x7)))
   8692                                               ))));
   8693 
   8694                      /* ========== GPR[rt]_7..0 ========== */
   8695                      assign(t10,
   8696                             unop(Iop_8Uto32,
   8697                                  unop(Iop_16to8,
   8698                                       unop(Iop_32to16, getIReg(rt)))));
   8699                      assign(t11,
   8700                             binop(Iop_Shr32,
   8701                                   mkexpr(t10),
   8702                                   unop(Iop_32to8, binop(Iop_And32,
   8703                                                         getIReg(rs),
   8704                                                         mkU32(0x7)))));
   8705                      /* tempB_7..0 */
   8706                      assign(t9,
   8707                             binop(Iop_Or32,
   8708                                   mkexpr(t11),
   8709                                   binop(Iop_Shl32,
   8710                                         IRExpr_ITE(binop(Iop_CmpEQ32,
   8711                                                          binop(Iop_And32,
   8712                                                                mkexpr(t10),
   8713                                                                mkU32(0x00000080)
   8714                                                               ),
   8715                                                          mkU32(0x00000080)),
   8716                                                    mkU32(0xFFFFFFFF),
   8717                                                    mkU32(0x00000000)),
   8718                                         binop(Iop_Sub8,
   8719                                               mkU8(0x8),
   8720                                               unop(Iop_32to8, binop(Iop_And32,
   8721                                                                     getIReg(rs),
   8722                                                                     mkU32(0x7)))
   8723                                               ))));
   8724 
   8725                      putIReg(rd,
   8726                              binop(Iop_16HLto32,
   8727                                    binop(Iop_8HLto16,
   8728                                          unop(Iop_32to8,
   8729                                               IRExpr_ITE(binop(Iop_CmpEQ32,
   8730                                                                binop(Iop_And32,
   8731                                                                      mkU32(rs),
   8732                                                                      mkU32(0x7)
   8733                                                                     ),
   8734                                                                mkU32(0x0)),
   8735                                                          mkexpr(t1),
   8736                                                          mkexpr(t0))),
   8737                                          unop(Iop_32to8,
   8738                                               IRExpr_ITE(binop(Iop_CmpEQ32,
   8739                                                                binop(Iop_And32,
   8740                                                                      mkU32(rs),
   8741                                                                      mkU32(0x7)
   8742                                                                     ),
   8743                                                                mkU32(0x0)),
   8744                                                          mkexpr(t2),
   8745                                                          mkexpr(t3)))),
   8746                                    binop(Iop_8HLto16,
   8747                                          unop(Iop_32to8,
   8748                                               IRExpr_ITE(binop(Iop_CmpEQ32,
   8749                                                                binop(Iop_And32,
   8750                                                                      mkU32(rs),
   8751                                                                      mkU32(0x7)
   8752                                                                     ),
   8753                                                                mkU32(0x0)),
   8754                                                          mkexpr(t5),
   8755                                                          mkexpr(t6))),
   8756                                          unop(Iop_32to8,
   8757                                               IRExpr_ITE(binop(Iop_CmpEQ32,
   8758                                                                binop(Iop_And32,
   8759                                                                      mkU32(rs),
   8760                                                                      mkU32(0x7)
   8761                                                                     ),
   8762                                                                mkU32(0x0)),
   8763                                                          mkexpr(t8),
   8764                                                          mkexpr(t9))))));
   8765                      break;
   8766                   }
   8767                   case 0x7: {  /* SHRAV_R.QB */
   8768                      DIP("shrav_r.qb r%u, r%u, r%u", rd, rt, rs);
   8769                      vassert(!mode64);
   8770                      t0 = newTemp(Ity_I32);
   8771                      t1 = newTemp(Ity_I8);
   8772                      t2 = newTemp(Ity_I32);
   8773                      t3 = newTemp(Ity_I8);
   8774                      t4 = newTemp(Ity_I32);
   8775                      t5 = newTemp(Ity_I8);
   8776                      t6 = newTemp(Ity_I32);
   8777                      t7 = newTemp(Ity_I8);
   8778                      t8 = newTemp(Ity_I8);
   8779                      t9 = newTemp(Ity_I32);
   8780 
   8781                      assign(t9, binop(Iop_And32, getIReg(rs), mkU32(0x7)));
   8782                      assign(t8, unop(Iop_32to8,
   8783                                      binop(Iop_Sub32, mkexpr(t9), mkU32(0x1))));
   8784                      assign(t0, unop(Iop_8Sto32,
   8785                                      unop(Iop_16to8,
   8786                                           unop(Iop_32to16, getIReg(rt)))));
   8787                      assign(t1, unop(Iop_32to8,
   8788                                      binop(Iop_Sar32,
   8789                                            binop(Iop_Add32,
   8790                                                  mkexpr(t0),
   8791                                                  binop(Iop_Shl32,
   8792                                                        mkU32(0x1),
   8793                                                        mkexpr(t8))),
   8794                                            unop(Iop_32to8,
   8795                                                 mkexpr(t9)))));
   8796 
   8797                      assign(t2, unop(Iop_8Sto32,
   8798                                      unop(Iop_16HIto8,
   8799                                           unop(Iop_32to16, getIReg(rt)))));
   8800                      assign(t3, unop(Iop_32to8,
   8801                                      binop(Iop_Sar32,
   8802                                            binop(Iop_Add32,
   8803                                                  mkexpr(t2),
   8804                                                  binop(Iop_Shl32,
   8805                                                        mkU32(0x1),
   8806                                                        mkexpr(t8))),
   8807                                            unop(Iop_32to8, mkexpr(t9)))));
   8808 
   8809                      assign(t4, unop(Iop_8Sto32,
   8810                                      unop(Iop_16to8,
   8811                                           unop(Iop_32HIto16, getIReg(rt)))));
   8812                      assign(t5, unop(Iop_32to8,
   8813                                      binop(Iop_Sar32,
   8814                                            binop(Iop_Add32,
   8815                                                  mkexpr(t4),
   8816                                                  binop(Iop_Shl32,
   8817                                                        mkU32(0x1),
   8818                                                        mkexpr(t8))),
   8819                                            unop(Iop_32to8, mkexpr(t9)))));
   8820 
   8821                      assign(t6, unop(Iop_8Sto32,
   8822                                      unop(Iop_16HIto8,
   8823                                           unop(Iop_32HIto16, getIReg(rt)))));
   8824                      assign(t7, unop(Iop_32to8,
   8825                                      binop(Iop_Sar32,
   8826                                            binop(Iop_Add32,
   8827                                                  mkexpr(t6),
   8828                                                  binop(Iop_Shl32,
   8829                                                        mkU32(0x1),
   8830                                                        mkexpr(t8))),
   8831                                            unop(Iop_32to8, mkexpr(t9)))));
   8832                      putIReg(rd, IRExpr_ITE(binop(Iop_CmpEQ32,
   8833                                                   mkexpr(t9),
   8834                                                   mkU32(0x0)),
   8835                                             getIReg(rt),
   8836                                             binop(Iop_16HLto32,
   8837                                                   binop(Iop_8HLto16,
   8838                                                         mkexpr(t7),
   8839                                                         mkexpr(t5)),
   8840                                                   binop(Iop_8HLto16,
   8841                                                         mkexpr(t3),
   8842                                                         mkexpr(t1)))));
   8843                      break;
   8844                   }
   8845                   case 0x8: {  /* SHLL.PH */
   8846                      DIP("shll.ph r%u, r%u, %u", rd, rt, rs);
   8847                      vassert(!mode64);
   8848                      t0 = newTemp(Ity_I32);
   8849                      t1 = newTemp(Ity_I32);
   8850                      t2 = newTemp(Ity_I32);
   8851                      t3 = newTemp(Ity_I32);
   8852                      t4 = newTemp(Ity_I32);
   8853                      t5 = newTemp(Ity_I32);
   8854                      t6 = newTemp(Ity_I32);
   8855                      t7 = newTemp(Ity_I32);
   8856 
   8857                      if (0 == rs) {
   8858                         putIReg(rd, getIReg(rt));
   8859                      } else {
   8860                         /* Shift lower 16 bits. */
   8861                         assign(t0, binop(Iop_Shl32,
   8862                                          unop(Iop_16Sto32,
   8863                                               unop(Iop_32to16, getIReg(rt))),
   8864                                          mkU8(rs)));
   8865 
   8866                         assign(t1, unop(Iop_1Uto32,
   8867                                         binop(Iop_CmpNE32,
   8868                                                binop(Iop_Sar32,
   8869                                                      mkexpr(t0),
   8870                                                      mkU8(16)),
   8871                                                mkU32(0))));
   8872                         assign(t2, unop(Iop_1Uto32,
   8873                                         binop(Iop_CmpNE32,
   8874                                               binop(Iop_Sar32,
   8875                                                     mkexpr(t0),
   8876                                                     mkU8(16)),
   8877                                               mkU32(0xffffffff))));
   8878                         assign(t3, binop(Iop_And32,
   8879                                          mkexpr(t1),
   8880                                          mkexpr(t2)));
   8881                         putDSPControl(IRExpr_ITE(binop(Iop_CmpEQ32,
   8882                                                        mkexpr(t3),
   8883                                                        mkU32(0x1)),
   8884                                                  binop(Iop_Or32,
   8885                                                        getDSPControl(),
   8886                                                        mkU32(0x400000)),
   8887                                                  getDSPControl()));
   8888                         putDSPControl(IRExpr_ITE(binop(Iop_CmpEQ32,
   8889                                                        binop(Iop_And32,
   8890                                                              getIReg(rt),
   8891                                                              mkU32(0x00008000)),
   8892                                                        binop(Iop_And32,
   8893                                                              mkexpr(t0),
   8894                                                              mkU32(0x00008000))
   8895                                                       ),
   8896                                                  getDSPControl(),
   8897                                                  binop(Iop_Or32,
   8898                                                        getDSPControl(),
   8899                                                        mkU32(0x400000))));
   8900                         /* Shift higher 16 bits. */
   8901                         assign(t4, binop(Iop_Shl32,
   8902                                          unop(Iop_16Sto32,
   8903                                               unop(Iop_32HIto16, getIReg(rt))),
   8904                                          mkU8(rs)));
   8905 
   8906                         assign(t5, unop(Iop_1Uto32,
   8907                                         binop(Iop_CmpNE32,
   8908                                                binop(Iop_Sar32,
   8909                                                      mkexpr(t4),
   8910                                                      mkU8(16)),
   8911                                                mkU32(0))));
   8912                         assign(t6, unop(Iop_1Uto32,
   8913                                         binop(Iop_CmpNE32,
   8914                                               binop(Iop_Sar32,
   8915                                                     mkexpr(t4),
   8916                                                     mkU8(16)),
   8917                                               mkU32(0xffffffff))));
   8918                         assign(t7, binop(Iop_And32,
   8919                                          mkexpr(t5),
   8920                                          mkexpr(t6)));
   8921                         putDSPControl(IRExpr_ITE(binop(Iop_CmpEQ32,
   8922                                                        mkexpr(t7),
   8923                                                        mkU32(0x1)),
   8924                                                  binop(Iop_Or32,
   8925                                                        getDSPControl(),
   8926                                                        mkU32(0x400000)),
   8927                                                  getDSPControl()));
   8928                         putDSPControl(IRExpr_ITE(binop(Iop_CmpEQ32,
   8929                                                        mkexpr(t7),
   8930                                                        mkU32(0x1)),
   8931                                                  binop(Iop_Or32,
   8932                                                        getDSPControl(),
   8933                                                        mkU32(0x400000)),
   8934                                                  getDSPControl()));
   8935                         putDSPControl(IRExpr_ITE(binop(Iop_CmpEQ32,
   8936                                                        binop(Iop_And32,
   8937                                                              getIReg(rt),
   8938                                                              mkU32(0x80000000)),
   8939                                                        binop(Iop_Shl32,
   8940                                                              binop(Iop_And32,
   8941                                                                    mkexpr(t4),
   8942                                                                    mkU32(0x00008000)),
   8943                                                              mkU8(16))
   8944                                                       ),
   8945                                                  getDSPControl(),
   8946                                                  binop(Iop_Or32,
   8947                                                        getDSPControl(),
   8948                                                        mkU32(0x400000))));
   8949                         putIReg(rd, binop(Iop_16HLto32,
   8950                                           unop(Iop_32to16, mkexpr(t4)),
   8951                                           unop(Iop_32to16, mkexpr(t0))));
   8952                      }
   8953                      break;
   8954                   }
   8955                   case 0x9: {  /* SHRA.PH */
   8956                      DIP("shra.ph r%u, r%u, %u", rd, rt, rs);
   8957                      vassert(!mode64);
   8958                      t0 = newTemp(Ity_I32);
   8959                      t1 = newTemp(Ity_I32);
   8960                      if (0 == rs) {
   8961                         putIReg(rd, getIReg(rt));
   8962                      } else {
   8963                         assign(t0, binop(Iop_Sar32,
   8964                                          unop(Iop_16Sto32,
   8965                                               unop(Iop_32to16, getIReg(rt))),
   8966                                          mkU8(rs)));
   8967                         assign(t1, binop(Iop_Sar32,
   8968                                          unop(Iop_16Sto32,
   8969                                               unop(Iop_32HIto16, getIReg(rt))),
   8970                                          mkU8(rs)));
   8971                         putIReg(rd, binop(Iop_16HLto32,
   8972                                           unop(Iop_32to16, mkexpr(t1)),
   8973                                           unop(Iop_32to16, mkexpr(t0))));
   8974                      }
   8975                      break;
   8976                   }
   8977                   case 0xA: {  /* SHLLV.PH */
   8978                      DIP("shllv.ph r%u, r%u, r%u", rd, rt, rs);
   8979                      vassert(!mode64);
   8980                      t0 = newTemp(Ity_I32);
   8981                      t2 = newTemp(Ity_I32);
   8982                      t3 = newTemp(Ity_I1);
   8983                      t4 = newTemp(Ity_I1);
   8984                      t5 = newTemp(Ity_I32);
   8985                      t6 = newTemp(Ity_I32);
   8986                      t7 = newTemp(Ity_I1);
   8987                      t8 = newTemp(Ity_I1);
   8988                      t9 = newTemp(Ity_I32);
   8989                      t10 = newTemp(Ity_I32);
   8990                      t11 = newTemp(Ity_I32);
   8991                      t12 = newTemp(Ity_I1);
   8992                      t13 = newTemp(Ity_I1);
   8993 
   8994                      assign(t0, binop(Iop_And32, getIReg(rs), mkU32(0x0f)));
   8995 
   8996                      /* Shift lower 16 bits. */
   8997                      assign(t2, binop(Iop_Shl32,
   8998                                       unop(Iop_16Sto32,
   8999                                            unop(Iop_32to16, getIReg(rt))),
   9000                                       unop(Iop_32to8, mkexpr(t0))));
   9001 
   9002                      assign(t3, binop(Iop_CmpNE32,
   9003                                       unop(Iop_16Sto32,
   9004                                            unop(Iop_32HIto16, mkexpr(t2))),
   9005                                       mkU32(0x00000000)));
   9006                      assign(t4, binop(Iop_CmpNE32,
   9007                                       unop(Iop_16Sto32,
   9008                                            unop(Iop_32HIto16, mkexpr(t2))),
   9009                                       mkU32(0xffffffff)));
   9010                      assign(t10, binop(Iop_And32,
   9011                                        unop(Iop_1Sto32, mkexpr(t3)),
   9012                                        unop(Iop_1Sto32, mkexpr(t4))));
   9013                      assign(t5, binop(Iop_Shr32,
   9014                                       binop(Iop_And32,
   9015                                             getIReg(rt),
   9016                                             mkU32(0x00008000)),
   9017                                       mkU8(15)));
   9018                      assign(t12, binop(Iop_CmpEQ32,
   9019                                        mkexpr(t5),
   9020                                        binop(Iop_Shr32,
   9021                                              binop(Iop_And32,
   9022                                                    mkexpr(t2),
   9023                                                    mkU32(0x00008000)),
   9024                                              mkU8(15))));
   9025 
   9026                      putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32,
   9027                                                     mkexpr(t10),
   9028                                                     mkU32(0x0)),
   9029                                               binop(Iop_Or32,
   9030                                                     getDSPControl(),
   9031                                                     mkU32(0x400000)),
   9032                                               IRExpr_ITE(mkexpr(t12),
   9033                                                          getDSPControl(),
   9034                                                          binop(Iop_Or32,
   9035                                                                getDSPControl(),
   9036                                                                mkU32(0x400000)))
   9037                                              ));
   9038                      /* Shift higher 16 bits. */
   9039                      assign(t6, binop(Iop_Shl32,
   9040                                       unop(Iop_16Sto32,
   9041                                            unop(Iop_32HIto16, getIReg(rt))),
   9042                                       unop(Iop_32to8, mkexpr(t0))));
   9043 
   9044                      assign(t7, binop(Iop_CmpNE32,
   9045                                       unop(Iop_16Sto32,
   9046                                            unop(Iop_32HIto16, mkexpr(t6))),
   9047                                       mkU32(0x00000000)));
   9048                      assign(t8, binop(Iop_CmpNE32,
   9049                                       unop(Iop_16Sto32,
   9050                                            unop(Iop_32HIto16, mkexpr(t6))),
   9051                                       mkU32(0xffffffff)));
   9052                      assign(t11, binop(Iop_And32,
   9053                                        unop(Iop_1Sto32, mkexpr(t7)),
   9054                                        unop(Iop_1Sto32, mkexpr(t8))));
   9055 
   9056                      assign(t9, binop(Iop_Shr32,
   9057                                       binop(Iop_And32,
   9058                                             getIReg(rt),
   9059                                             mkU32(0x80000000)),
   9060                                       mkU8(31)));
   9061                      assign(t13, binop(Iop_CmpEQ32,
   9062                                        mkexpr(t9),
   9063                                        binop(Iop_Shr32,
   9064                                              binop(Iop_And32,
   9065                                                    mkexpr(t6),
   9066                                                    mkU32(0x00008000)),
   9067                                              mkU8(15))));
   9068 
   9069                      putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32,
   9070                                                     mkexpr(t11),
   9071                                                     mkU32(0x0)),
   9072                                               binop(Iop_Or32,
   9073                                                     getDSPControl(),
   9074                                                     mkU32(0x400000)),
   9075                                               IRExpr_ITE(mkexpr(t13),
   9076                                                          getDSPControl(),
   9077                                                          binop(Iop_Or32,
   9078                                                                getDSPControl(),
   9079                                                                mkU32(0x400000)))
   9080                                              ));
   9081 
   9082                      putIReg(rd, binop(Iop_16HLto32,
   9083                                        unop(Iop_32to16, mkexpr(t6)),
   9084                                        unop(Iop_32to16, mkexpr(t2))));
   9085                      break;
   9086                   }
   9087                   case 0xB: {  /* SHRAV.PH */
   9088                      DIP("shrav.ph r%u, r%u, r%u", rd, rt, rs);
   9089                      vassert(!mode64);
   9090                      t0 = newTemp(Ity_I32);
   9091                      t1 = newTemp(Ity_I1);
   9092                      t2 = newTemp(Ity_I32);
   9093                      t3 = newTemp(Ity_I32);
   9094 
   9095                      assign(t0, binop(Iop_And32, getIReg(rs), mkU32(0x0f)));
   9096                      assign(t1, binop(Iop_CmpEQ32, mkexpr(t0), mkU32(0x0)));
   9097                      assign(t2, binop(Iop_Sar32,
   9098                                       unop(Iop_16Sto32,
   9099                                            unop(Iop_32to16, getIReg(rt))),
   9100                                       unop(Iop_32to8, mkexpr(t0))));
   9101                      assign(t3, binop(Iop_Sar32,
   9102                                       unop(Iop_16Sto32,
   9103                                            unop(Iop_32HIto16, getIReg(rt))),
   9104                                       unop(Iop_32to8, mkexpr(t0))));
   9105                      putIReg(rd,
   9106                              binop(Iop_16HLto32,
   9107                                    IRExpr_ITE(mkexpr(t1),
   9108                                               unop(Iop_32HIto16, getIReg(rt)),
   9109                                               unop(Iop_32to16, mkexpr(t3))),
   9110                                    IRExpr_ITE(mkexpr(t1),
   9111                                               unop(Iop_32to16, getIReg(rt)),
   9112                                               unop(Iop_32to16, mkexpr(t2)))));
   9113                      break;
   9114                   }
   9115                   case 0xC: {  /* SHLL_S.PH */
   9116                      DIP("shll_s.ph r%u, r%u, %u", rd, rt, rs);
   9117                      vassert(!mode64);
   9118                      t0 = newTemp(Ity_I32);
   9119                      t1 = newTemp(Ity_I32);
   9120                      t2 = newTemp(Ity_I32);
   9121                      t3 = newTemp(Ity_I32);
   9122                      t4 = newTemp(Ity_I32);
   9123                      t5 = newTemp(Ity_I32);
   9124                      t6 = newTemp(Ity_I32);
   9125                      t7 = newTemp(Ity_I32);
   9126                      t8 = newTemp(Ity_I32);
   9127                      t9 = newTemp(Ity_I32);
   9128                      t10 = newTemp(Ity_I32);
   9129                      t11 = newTemp(Ity_I32);
   9130                      t12 = newTemp(Ity_I32);
   9131                      t13 = newTemp(Ity_I32);
   9132                      t14 = newTemp(Ity_I32);
   9133 
   9134                      if (0 == rs) {
   9135                         putIReg(rd, getIReg(rt));
   9136                      } else {
   9137                         /* Shift lower 16 bits. */
   9138                         assign(t0, binop(Iop_Shl32,
   9139                                          unop(Iop_16Sto32,
   9140                                               unop(Iop_32to16, getIReg(rt))),
   9141                                          mkU8(rs)));
   9142 
   9143                         assign(t1, unop(Iop_1Uto32,
   9144                                         binop(Iop_CmpNE32,
   9145                                                binop(Iop_Sar32,
   9146                                                      mkexpr(t0),
   9147                                                      mkU8(16)),
   9148                                                mkU32(0))));
   9149                         assign(t2, unop(Iop_1Uto32,
   9150                                         binop(Iop_CmpNE32,
   9151                                               binop(Iop_Sar32,
   9152                                                     mkexpr(t0),
   9153                                                     mkU8(16)),
   9154                                               mkU32(0xffffffff))));
   9155                         assign(t3, binop(Iop_And32,
   9156                                          mkexpr(t1),
   9157                                          mkexpr(t2)));
   9158                         putDSPControl(IRExpr_ITE(binop(Iop_CmpEQ32,
   9159                                                        mkexpr(t3),
   9160                                                        mkU32(0x1)),
   9161                                                  binop(Iop_Or32,
   9162                                                        getDSPControl(),
   9163                                                        mkU32(0x400000)),
   9164                                                  getDSPControl()));
   9165                         putDSPControl(IRExpr_ITE(binop(Iop_CmpEQ32,
   9166                                                        binop(Iop_And32,
   9167                                                              getIReg(rt),
   9168                                                              mkU32(0x00008000)),
   9169                                                        binop(Iop_And32,
   9170                                                              mkexpr(t0),
   9171                                                              mkU32(0x00008000))
   9172                                                       ),
   9173                                                  getDSPControl(),
   9174                                                  binop(Iop_Or32,
   9175                                                        getDSPControl(),
   9176                                                        mkU32(0x400000))));
   9177                         assign(t8,
   9178                                IRExpr_ITE(binop(Iop_CmpEQ32,
   9179                                                 mkexpr(t3),
   9180                                                 mkU32(0x1)),
   9181                                           IRExpr_ITE(binop(Iop_CmpEQ32,
   9182                                                            binop(Iop_And32,
   9183                                                                  getIReg(rt),
   9184                                                                  mkU32(0x8000)),
   9185                                                            mkU32(0)),
   9186                                                      mkU32(0x00007fff),
   9187                                                      mkU32(0x00008000)),
   9188                                           binop(Iop_And32,
   9189                                                 mkexpr(t0),
   9190                                                 mkU32(0x0000ffff))));
   9191                         assign(t10,
   9192                                IRExpr_ITE(binop(Iop_CmpEQ32,
   9193                                                 binop(Iop_And32,
   9194                                                       getIReg(rt),
   9195                                                       mkU32(0x00008000)),
   9196                                                 binop(Iop_And32,
   9197                                                       mkexpr(t0),
   9198                                                       mkU32(0x00008000))),
   9199                                           mkexpr(t8),
   9200                                           IRExpr_ITE(binop(Iop_CmpEQ32,
   9201                                                            binop(Iop_And32,
   9202                                                                  getIReg(rt),
   9203                                                                  mkU32(0x8000)),
   9204                                                            mkU32(0)),
   9205                                                      mkU32(0x00007fff),
   9206                                                      mkU32(0x00008000))));
   9207                         /* Shift higher 16 bits. */
   9208                         assign(t4, binop(Iop_Shl32,
   9209                                          unop(Iop_16Sto32,
   9210                                               unop(Iop_32HIto16, getIReg(rt))),
   9211                                          mkU8(rs)));
   9212 
   9213                         assign(t5, unop(Iop_1Uto32,
   9214                                         binop(Iop_CmpNE32,
   9215                                                binop(Iop_Sar32,
   9216                                                      mkexpr(t4),
   9217                                                      mkU8(16)),
   9218                                                mkU32(0))));
   9219                         assign(t6, unop(Iop_1Uto32,
   9220                                         binop(Iop_CmpNE32,
   9221                                               binop(Iop_Sar32,
   9222                                                     mkexpr(t4),
   9223                                                     mkU8(16)),
   9224                                               mkU32(0xffffffff))));
   9225                         assign(t7, binop(Iop_And32,
   9226                                          mkexpr(t5),
   9227                                          mkexpr(t6)));
   9228                         putDSPControl(IRExpr_ITE(binop(Iop_CmpEQ32,
   9229                                                        mkexpr(t7),
   9230                                                        mkU32(0x1)),
   9231                                                  binop(Iop_Or32,
   9232                                                        getDSPControl(),
   9233                                                        mkU32(0x400000)),
   9234                                                  getDSPControl()));
   9235                         putDSPControl(IRExpr_ITE(binop(Iop_CmpEQ32,
   9236                                                        mkexpr(t7),
   9237                                                        mkU32(0x1)),
   9238                                                  binop(Iop_Or32,
   9239                                                        getDSPControl(),
   9240                                                        mkU32(0x400000)),
   9241                                                  getDSPControl()));
   9242                         assign(t12, binop(Iop_Shl32,
   9243                                           binop(Iop_And32,
   9244                                                 mkexpr(t4),
   9245                                                 mkU32(0x8000)),
   9246                                           mkU8(16)));
   9247                         putDSPControl(IRExpr_ITE(binop(Iop_CmpEQ32,
   9248                                                        binop(Iop_And32,
   9249                                                              getIReg(rt),
   9250                                                              mkU32(0x80000000)),
   9251                                                        mkexpr(t12)),
   9252                                                  getDSPControl(),
   9253                                                  binop(Iop_Or32,
   9254                                                        getDSPControl(),
   9255                                                        mkU32(0x400000))));
   9256                         assign(t13, IRExpr_ITE(binop(Iop_CmpEQ32,
   9257                                                      binop(Iop_And32,
   9258                                                            getIReg(rt),
   9259                                                            mkU32(0x80000000)),
   9260                                                      mkU32(0)),
   9261                                                mkU32(0x7fff0000),
   9262                                                mkU32(0x80000000)));
   9263                         assign(t9,
   9264                                IRExpr_ITE(binop(Iop_CmpEQ32,
   9265                                                 mkexpr(t7),
   9266                                                 mkU32(0x1)),
   9267                                           mkexpr(t13),
   9268                                           binop(Iop_Shl32,
   9269                                                 binop(Iop_And32,
   9270                                                       mkexpr(t4),
   9271                                                       mkU32(0x0000ffff)),
   9272                                                 mkU8(16))));
   9273                         assign(t14, IRExpr_ITE(binop(Iop_CmpEQ32,
   9274                                                      binop(Iop_And32,
   9275                                                            getIReg(rt),
   9276                                                            mkU32(0x80000000)),
   9277                                                      mkU32(0)),
   9278                                                mkU32(0x7fff0000),
   9279                                                mkU32(0x80000000)));
   9280                         assign(t11,
   9281                                IRExpr_ITE(binop(Iop_CmpEQ32,
   9282                                                 binop(Iop_And32,
   9283                                                       getIReg(rt),
   9284                                                       mkU32(0x80000000)),
   9285                                                 binop(Iop_Shl32,
   9286                                                       binop(Iop_And32,
   9287                                                             mkexpr(t4),
   9288                                                             mkU32(0x00008000)),
   9289                                                       mkU8(16))),
   9290                                           mkexpr(t9),
   9291                                           mkexpr(t14)));
   9292                         putIReg(rd, binop(Iop_Or32,
   9293                                           mkexpr(t10),
   9294                                           mkexpr(t11)));
   9295                      }
   9296                      break;
   9297                   }
   9298                   case 0xD: {  /* SHRA_R.PH */
   9299                      DIP("shra.ph r%u, r%u, %u", rd, rt, rs);
   9300                      vassert(!mode64);
   9301                      t0 = newTemp(Ity_I32);
   9302                      t1 = newTemp(Ity_I32);
   9303                      if (0 == rs) {
   9304                         putIReg(rd, getIReg(rt));
   9305                      } else {
   9306                         assign(t0, binop(Iop_Sar32,
   9307                                          binop(Iop_Add32,
   9308                                                unop(Iop_16Sto32,
   9309                                                     unop(Iop_32to16,
   9310                                                          getIReg(rt))),
   9311                                                binop(Iop_Shl32,
   9312                                                      mkU32(0x1),
   9313                                                      mkU8(rs-1))),
   9314                                          mkU8(rs)));
   9315                         assign(t1, binop(Iop_Sar32,
   9316                                          binop(Iop_Add32,
   9317                                                unop(Iop_16Sto32,
   9318                                                     unop(Iop_32HIto16,
   9319                                                          getIReg(rt))),
   9320                                                binop(Iop_Shl32,
   9321                                                      mkU32(0x1),
   9322                                                      mkU8(rs-1))),
   9323                                          mkU8(rs)));
   9324                         putIReg(rd, binop(Iop_16HLto32,
   9325                                           unop(Iop_32to16, mkexpr(t1)),
   9326                                           unop(Iop_32to16, mkexpr(t0))));
   9327                      }
   9328                      break;
   9329                   }
   9330                   case 0xE: {  /* SHLLV_S.PH */
   9331                      DIP("shllv_s.ph r%u, r%u, r%u", rd, rt, rs);
   9332                      vassert(!mode64);
   9333                      t0 = newTemp(Ity_I32);
   9334                      t2 = newTemp(Ity_I32);
   9335                      t3 = newTemp(Ity_I1);
   9336                      t4 = newTemp(Ity_I1);
   9337                      t5 = newTemp(Ity_I32);
   9338                      t6 = newTemp(Ity_I32);
   9339                      t7 = newTemp(Ity_I1);
   9340                      t8 = newTemp(Ity_I1);
   9341                      t9 = newTemp(Ity_I32);
   9342                      t10 = newTemp(Ity_I32);
   9343                      t11 = newTemp(Ity_I32);
   9344                      t12 = newTemp(Ity_I1);
   9345                      t13 = newTemp(Ity_I1);
   9346                      t14 = newTemp(Ity_I16);
   9347                      t15 = newTemp(Ity_I16);
   9348                      t16 = newTemp(Ity_I16);
   9349                      t17 = newTemp(Ity_I16);
   9350 
   9351                      assign(t0, binop(Iop_And32, getIReg(rs), mkU32(0x0f)));
   9352 
   9353                      /* Shift lower 16 bits. */
   9354                      assign(t2, binop(Iop_Shl32,
   9355                                       unop(Iop_16Sto32,
   9356                                            unop(Iop_32to16, getIReg(rt))),
   9357                                       unop(Iop_32to8, mkexpr(t0))));
   9358 
   9359                      assign(t3, binop(Iop_CmpNE32,
   9360                                       unop(Iop_16Sto32,
   9361                                            unop(Iop_32HIto16, mkexpr(t2))),
   9362                                       mkU32(0x00000000)));
   9363                      assign(t4, binop(Iop_CmpNE32,
   9364                                       unop(Iop_16Sto32,
   9365                                            unop(Iop_32HIto16, mkexpr(t2))),
   9366                                       mkU32(0xffffffff)));
   9367                      assign(t10, binop(Iop_And32,
   9368                                        unop(Iop_1Sto32, mkexpr(t3)),
   9369                                        unop(Iop_1Sto32, mkexpr(t4))));
   9370                      assign(t5, binop(Iop_Shr32,
   9371                                        binop(Iop_And32,
   9372                                              getIReg(rt),
   9373                                              mkU32(0x00008000)),
   9374                                        mkU8(15)));
   9375                      assign(t12, binop(Iop_CmpEQ32,
   9376                                        mkexpr(t5),
   9377                                        binop(Iop_Shr32,
   9378                                              binop(Iop_And32,
   9379                                                    mkexpr(t2),
   9380                                                    mkU32(0x00008000)),
   9381                                              mkU8(15))));
   9382 
   9383                      putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32,
   9384                                                     mkexpr(t10),
   9385                                                     mkU32(0x0)),
   9386                                               binop(Iop_Or32,
   9387                                                     getDSPControl(),
   9388                                                     mkU32(0x400000)),
   9389                                               IRExpr_ITE(mkexpr(t12),
   9390                                                          getDSPControl(),
   9391                                                          binop(Iop_Or32,
   9392                                                                getDSPControl(),
   9393                                                                mkU32(0x400000)))
   9394                                              ));
   9395                      assign(t14, IRExpr_ITE(binop(Iop_CmpNE32,
   9396                                                   mkexpr(t5),
   9397                                                   mkU32(0x0)),
   9398                                             mkU16(0x8000),
   9399                                             mkU16(0x7fff)));
   9400                      assign(t15, IRExpr_ITE(binop(Iop_CmpNE32,
   9401                                                   mkexpr(t10),
   9402                                                   mkU32(0x0)),
   9403                                             mkexpr(t14),
   9404                                             IRExpr_ITE(mkexpr(t12),
   9405                                                        unop(Iop_32to16,
   9406                                                             mkexpr(t2)),
   9407                                                        mkexpr(t14))));
   9408                      /* Shift higher 16 bits. */
   9409                      assign(t6, binop(Iop_Shl32,
   9410                                       unop(Iop_16Sto32,
   9411                                            unop(Iop_32HIto16, getIReg(rt))),
   9412                                       unop(Iop_32to8, mkexpr(t0))));
   9413 
   9414                      assign(t7, binop(Iop_CmpNE32,
   9415                                       unop(Iop_16Sto32,
   9416                                            unop(Iop_32HIto16, mkexpr(t6))),
   9417                                       mkU32(0x00000000)));
   9418                      assign(t8, binop(Iop_CmpNE32,
   9419                                       unop(Iop_16Sto32,
   9420                                            unop(Iop_32HIto16, mkexpr(t6))),
   9421                                       mkU32(0xffffffff)));
   9422                      assign(t11, binop(Iop_And32,
   9423                                        unop(Iop_1Sto32, mkexpr(t7)),
   9424                                        unop(Iop_1Sto32, mkexpr(t8))));
   9425 
   9426                      assign(t9, binop(Iop_Shr32,
   9427                                       binop(Iop_And32,
   9428                                             getIReg(rt),
   9429                                             mkU32(0x80000000)),
   9430                                       mkU8(31)));
   9431                      assign(t13, binop(Iop_CmpEQ32,
   9432                                        mkexpr(t9),
   9433                                        binop(Iop_Shr32,
   9434                                              binop(Iop_And32,
   9435                                                    mkexpr(t6),
   9436                                                    mkU32(0x00008000)),
   9437                                              mkU8(15))));
   9438 
   9439                      putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32,
   9440                                                     mkexpr(t11),
   9441                                                     mkU32(0x0)),
   9442                                               binop(Iop_Or32,
   9443                                                     getDSPControl(),
   9444                                                     mkU32(0x400000)),
   9445                                               IRExpr_ITE(mkexpr(t13),
   9446                                                          getDSPControl(),
   9447                                                          binop(Iop_Or32,
   9448                                                                getDSPControl(),
   9449                                                                mkU32(0x400000)))
   9450                                              ));
   9451 
   9452                      assign(t16, IRExpr_ITE(binop(Iop_CmpNE32,
   9453                                                   mkexpr(t9),
   9454                                                   mkU32(0x0)),
   9455                                             mkU16(0x8000),
   9456                                             mkU16(0x7fff)));
   9457                      assign(t17, IRExpr_ITE(binop(Iop_CmpNE32,
   9458                                                   mkexpr(t11),
   9459                                                   mkU32(0x0)),
   9460                                             mkexpr(t16),
   9461                                             IRExpr_ITE(mkexpr(t13),
   9462                                                        unop(Iop_32to16,
   9463                                                             mkexpr(t6)),
   9464                                                        mkexpr(t16))));
   9465 
   9466                      putIReg(rd, binop(Iop_16HLto32, mkexpr(t17), mkexpr(t15)));
   9467                      break;
   9468                   }
   9469                   case 0xF: {  /* SHRAV_R.PH */
   9470                      DIP("shrav_r.ph r%u, r%u, r%u", rd, rt, rs);
   9471                      vassert(!mode64);
   9472                      t0 = newTemp(Ity_I32);
   9473                      t1 = newTemp(Ity_I1);
   9474                      t2 = newTemp(Ity_I8);
   9475                      t3 = newTemp(Ity_I32);
   9476                      t4 = newTemp(Ity_I32);
   9477 
   9478                      assign(t0, binop(Iop_And32, getIReg(rs), mkU32(0x0f)));
   9479                      assign(t1, binop(Iop_CmpEQ32, mkexpr(t0), mkU32(0x0)));
   9480                      assign(t2, unop(Iop_32to8,
   9481                                      binop(Iop_Sub32, mkexpr(t0), mkU32(1))));
   9482 
   9483                      assign(t3, binop(Iop_Sar32,
   9484                                       binop(Iop_Add32,
   9485                                             unop(Iop_16Sto32,
   9486                                                  unop(Iop_32to16, getIReg(rt))),
   9487                                             binop(Iop_Shl32,
   9488                                                   mkU32(0x1),
   9489                                                   mkexpr(t2))),
   9490                                       unop(Iop_32to8, mkexpr(t0))));
   9491                      assign(t4, binop(Iop_Sar32,
   9492                                       binop(Iop_Add32,
   9493                                             unop(Iop_16Sto32,
   9494                                                  unop(Iop_32HIto16,
   9495                                                       getIReg(rt))),
   9496                                             binop(Iop_Shl32,
   9497                                                   mkU32(0x1),
   9498                                                   mkexpr(t2))),
   9499                                       unop(Iop_32to8, mkexpr(t0))));
   9500 
   9501                      putIReg(rd, binop(Iop_16HLto32,
   9502                                        IRExpr_ITE(mkexpr(t1),
   9503                                                   unop(Iop_32HIto16,
   9504                                                        getIReg(rt)),
   9505                                                   unop(Iop_32to16,
   9506                                                        mkexpr(t4))),
   9507                                        IRExpr_ITE(mkexpr(t1),
   9508                                                   unop(Iop_32to16, getIReg(rt)),
   9509                                                   unop(Iop_32to16,
   9510                                                        mkexpr(t3)))));
   9511                      break;
   9512                   }
   9513                   case 0x14: {  /* SHLL_S.W */
   9514                      DIP("shll_s.w r%u, r%u, %u", rd, rt, rs);
   9515                      vassert(!mode64);
   9516                      t0 = newTemp(Ity_I32);
   9517                      t1 = newTemp(Ity_I32);
   9518                      t2 = newTemp(Ity_I32);
   9519                      t3 = newTemp(Ity_I32);
   9520                      t4 = newTemp(Ity_I32);
   9521                      t5 = newTemp(Ity_I32);
   9522 
   9523                      if (0 == rs) {
   9524                         putIReg(rd, getIReg(rt));
   9525                      } else {
   9526                         /* t0-bits that will be discarded, sign extended to
   9527                            32bits. */
   9528                         assign(t0, binop(Iop_Sar32,
   9529                                          binop(Iop_And32,
   9530                                                getIReg(rt),
   9531                                                binop(Iop_Sar32,
   9532                                                      mkU32(0x80000000),
   9533                                                      mkU8(rs-1))),
   9534                                          mkU8(32-rs)));
   9535 
   9536                         assign(t1, IRExpr_ITE(binop(Iop_CmpEQ32,
   9537                                                     binop(Iop_And32,
   9538                                                           getIReg(rt),
   9539                                                           mkU32(0x80000000)),
   9540                                                     mkU32(0x0)),
   9541                                               mkU32(0x7fffffff),
   9542                                               mkU32(0x80000000)));
   9543 
   9544                         assign(t2, binop(Iop_Shl32, getIReg(rt), mkU8(rs)));
   9545                         assign(t3, IRExpr_ITE(binop(Iop_CmpEQ32,
   9546                                                     binop(Iop_And32,
   9547                                                           getIReg(rt),
   9548                                                           mkU32(0x80000000)),
   9549                                                     binop(Iop_And32,
   9550                                                           mkexpr(t2),
   9551                                                           mkU32(0x80000000))),
   9552                                               mkexpr(t2),
   9553                                               mkexpr(t1)));
   9554 
   9555                         assign(t4, IRExpr_ITE(binop(Iop_CmpNE32,
   9556                                                     mkexpr(t0),
   9557                                                     mkU32(0x0)),
   9558                                               IRExpr_ITE(binop(Iop_CmpNE32,
   9559                                                                mkexpr(t0),
   9560                                                                mkU32(0xffffffff)
   9561                                                               ),
   9562                                                          mkexpr(t1),
   9563                                                          mkexpr(t3)),
   9564                                               mkexpr(t3)));
   9565                         assign(t5, IRExpr_ITE(binop(Iop_CmpNE32,
   9566                                                     mkexpr(t0),
   9567                                                     mkU32(0xffffffff)),
   9568                                               binop(Iop_Or32,
   9569                                                     getDSPControl(),
   9570                                                     mkU32(0x400000)),
   9571                                               getDSPControl()));
   9572                         putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32,
   9573                                                        mkexpr(t0),
   9574                                                        mkU32(0x0)),
   9575                                                  mkexpr(t5),
   9576                                                  getDSPControl()));
   9577                         putDSPControl(IRExpr_ITE(binop(Iop_CmpEQ32,
   9578                                                        binop(Iop_And32,
   9579                                                              getIReg(rt),
   9580                                                              mkU32(0x80000000)),
   9581                                                        binop(Iop_And32,
   9582                                                              mkexpr(t2),
   9583                                                              mkU32(0x80000000))
   9584                                                             ),
   9585                                                  getDSPControl(),
   9586                                                  binop(Iop_Or32,
   9587                                                        getDSPControl(),
   9588                                                        mkU32(0x400000))));
   9589                         putIReg(rd, mkexpr(t4));
   9590                      }
   9591                      break;
   9592                   }
   9593                   case 0x15: {  /* SHRA_R.W */
   9594                      DIP("shra_r.w r%u, r%u, %u", rd, rt, rs);
   9595                      vassert(!mode64);
   9596                      if (0 == rs) {
   9597                         putIReg(rd, getIReg(rt));
   9598                      } else {
   9599                         putIReg(rd, binop(Iop_Add32,
   9600                                           binop(Iop_Sar32,
   9601                                                 getIReg(rt), mkU8(rs)),
   9602                                           binop(Iop_Shr32,
   9603                                                 binop(Iop_And32,
   9604                                                       getIReg(rt),
   9605                                                       binop(Iop_Shl32,
   9606                                                             mkU32(0x1),
   9607                                                             mkU8(rs-1))),
   9608                                                 mkU8(rs-1))));
   9609                      }
   9610                      break;
   9611                   }
   9612                   case 0x16: {  /* SHLLV_S.W */
   9613                      DIP("shllv_s.w r%u, r%u, r%u", rd, rt, rs);
   9614                      vassert(!mode64);
   9615                      t0 = newTemp(Ity_I32);
   9616                      t1 = newTemp(Ity_I1);
   9617                      t2 = newTemp(Ity_I32);
   9618                      t3 = newTemp(Ity_I64);
   9619                      t4 = newTemp(Ity_I1);
   9620                      t5 = newTemp(Ity_I1);
   9621                      t6 = newTemp(Ity_I32);
   9622                      t7 = newTemp(Ity_I1);
   9623                      t8 = newTemp(Ity_I32);
   9624 
   9625                      /* Check if shift amount is zero. */
   9626                      assign(t0, binop(Iop_And32, getIReg(rs), mkU32(0x1f)));
   9627                      assign(t1, binop(Iop_CmpEQ32, mkexpr(t0), mkU32(0x0)));
   9628 
   9629                      /* t2 = sign of the input value. */
   9630                      assign(t2, binop(Iop_Shr32,
   9631                                       binop(Iop_And32,
   9632                                             getIReg(rt),
   9633                                             mkU32(0x80000000)),
   9634                                       mkU8(31)));
   9635                      /* Shift left input value and check for overflow. */
   9636                      assign(t3, binop(Iop_Shl64,
   9637                                       unop(Iop_32Sto64, getIReg(rt)),
   9638                                       unop(Iop_32to8, mkexpr(t0))));
   9639                      assign(t4, binop(Iop_CmpNE32,
   9640                                       unop(Iop_64HIto32, mkexpr(t3)),
   9641                                       mkU32(0x00000000)));
   9642                      assign(t5, binop(Iop_CmpNE32,
   9643                                       unop(Iop_64HIto32, mkexpr(t3)),
   9644                                       mkU32(0xffffffff)));
   9645                      assign(t6, binop(Iop_And32,
   9646                                       unop(Iop_1Uto32, mkexpr(t4)),
   9647                                       unop(Iop_1Uto32, mkexpr(t5))));
   9648                      assign(t7, binop(Iop_CmpEQ32,
   9649                                       binop(Iop_Shr32,
   9650                                             binop(Iop_And32,
   9651                                                   getIReg(rt),
   9652                                                   mkU32(0x80000000)),
   9653                                             mkU8(31)),
   9654                                       binop(Iop_Shr32,
   9655                                             binop(Iop_And32,
   9656                                                   unop(Iop_64to32, mkexpr(t3)),
   9657                                                   mkU32(0x80000000)),
   9658                                             mkU8(31))));
   9659 
   9660                      putDSPControl(IRExpr_ITE(unop(Iop_32to1, mkexpr(t6)),
   9661                                                    binop(Iop_Or32,
   9662                                                          getDSPControl(),
   9663                                                          mkU32(0x400000)),
   9664                                               IRExpr_ITE(mkexpr(t7),
   9665                                                          getDSPControl(),
   9666                                                          binop(Iop_Or32,
   9667                                                                getDSPControl(),
   9668                                                                mkU32(0x400000)))
   9669                                              ));
   9670 
   9671                      assign(t8, IRExpr_ITE(unop(Iop_32to1,
   9672                                                 mkexpr(t2)),
   9673                                            mkU32(0x80000000),
   9674                                            mkU32(0x7fffffff)));
   9675                      putIReg(rd, IRExpr_ITE(unop(Iop_32to1, mkexpr(t6)),
   9676                                             IRExpr_ITE(unop(Iop_32to1,
   9677                                                             mkexpr(t2)),
   9678                                                        mkU32(0x80000000),
   9679                                                        mkU32(0x7fffffff)),
   9680                                             IRExpr_ITE(mkexpr(t7),
   9681                                                        unop(Iop_64to32,
   9682                                                             mkexpr(t3)),
   9683                                                        mkexpr(t8))));
   9684                      break;
   9685                   }
   9686                   case 0x17: {  /* SHRAV_R.W */
   9687                      DIP("shrav_r.w r%u, r%u, r%u", rd, rt, rs);
   9688                      vassert(!mode64);
   9689                      t0 = newTemp(Ity_I32);
   9690                      t1 = newTemp(Ity_I1);
   9691                      t2 = newTemp(Ity_I8);
   9692                      t3 = newTemp(Ity_I32);
   9693 
   9694                      assign(t0, binop(Iop_And32, getIReg(rs), mkU32(0x1f)));
   9695                      assign(t1, binop(Iop_CmpEQ32, mkexpr(t0), mkU32(0x0)));
   9696                      assign(t2, unop(Iop_32to8,
   9697                                      binop(Iop_Sub32, mkexpr(t0), mkU32(1))));
   9698 
   9699                      putIReg(rd, IRExpr_ITE(mkexpr(t1),
   9700                                             getIReg(rt),
   9701                                             binop(Iop_Sar32,
   9702                                                   binop(Iop_Add32,
   9703                                                         binop(Iop_Sar32,
   9704                                                               getIReg(rt),
   9705                                                               mkexpr(t2)),
   9706                                                         mkU32(0x1)),
   9707                                                   mkU8(1))));
   9708                      break;
   9709                   }
   9710                   case 0x19: {  /* SHRL.PH */
   9711                      DIP("shrl.ph r%u, r%u, %u", rd, rt, rs);
   9712                      vassert(!mode64);
   9713                      t0 = newTemp(Ity_I32);
   9714                      t1 = newTemp(Ity_I32);
   9715                      assign(t0, binop(Iop_Shr32,
   9716                                       unop(Iop_16Uto32,
   9717                                            unop(Iop_32to16, getIReg(rt))),
   9718                                       mkU8(rs)));
   9719                      assign(t1, binop(Iop_Shr32,
   9720                                       unop(Iop_16Uto32,
   9721                                            unop(Iop_32HIto16, getIReg(rt))),
   9722                                       mkU8(rs)));
   9723                      putIReg(rd, binop(Iop_16HLto32,
   9724                                        unop(Iop_32to16, mkexpr(t1)),
   9725                                        unop(Iop_32to16, mkexpr(t0))));
   9726                      break;
   9727                   }
   9728                   case 0x1B: {  /* SHRLV.PH */
   9729                      DIP("shrlv.ph r%u, r%u, r%u", rd, rt, rs);
   9730                      vassert(!mode64);
   9731                      t0 = newTemp(Ity_I32);
   9732                      t1 = newTemp(Ity_I1);
   9733                      t2 = newTemp(Ity_I32);
   9734                      t3 = newTemp(Ity_I32);
   9735                      t4 = newTemp(Ity_I16);
   9736                      t5 = newTemp(Ity_I16);
   9737 
   9738                      /* Get shift amount from lower 5 bits of rs
   9739                         and check if it is zero. */
   9740                      assign(t0, binop(Iop_And32, getIReg(rs), mkU32(0x0f)));
   9741                      assign(t1, binop(Iop_CmpEQ32, mkexpr(t0), mkU32(0x0)));
   9742 
   9743                      assign(t2, binop(Iop_Shr32,
   9744                                       unop(Iop_16Uto32,
   9745                                            unop(Iop_32to16, getIReg(rt))),
   9746                                       unop(Iop_32to8, mkexpr(t0))));
   9747                      assign(t3, binop(Iop_Shr32,
   9748                                       unop(Iop_16Uto32,
   9749                                            unop(Iop_32HIto16, getIReg(rt))),
   9750                                       unop(Iop_32to8, mkexpr(t0))));
   9751 
   9752                      assign(t4, IRExpr_ITE(mkexpr(t1),
   9753                                            unop(Iop_32HIto16, getIReg(rt)),
   9754                                            unop(Iop_32to16, mkexpr(t3))));
   9755                      assign(t5, IRExpr_ITE(mkexpr(t1),
   9756                                            unop(Iop_32to16, getIReg(rt)),
   9757                                            unop(Iop_32to16, mkexpr(t2))));
   9758                      putIReg(rd, binop(Iop_16HLto32, mkexpr(t4), mkexpr(t5)));
   9759                      break;
   9760                   }
   9761                   default:
   9762                      return -1;
   9763                }
   9764                break;  /* end of SHLL.QB */
   9765             }
   9766             case 0x18: {  /* ADDUH.QB/MUL.PH */
   9767                switch(sa) {
   9768                   case 0x00: {  /* ADDUH.QB */
   9769                      DIP("adduh.qb r%u, r%u, r%u", rd, rs, rt);
   9770                      vassert(!mode64);
   9771                      t0 = newTemp(Ity_I32);
   9772 
   9773                      assign(t0, binop(Iop_HAdd8Ux4, getIReg(rs), getIReg(rt)));
   9774 
   9775                      putIReg(rd, mkexpr(t0));
   9776                      break;
   9777                   }
   9778                   case 0x1: {  /* SUBUH.QB */
   9779                      DIP("subuh.qb r%u, r%u, r%u", rd, rs, rt);
   9780                      vassert(!mode64);
   9781                      t0 = newTemp(Ity_I32);
   9782 
   9783                      assign(t0, binop(Iop_HSub8Ux4, getIReg(rs), getIReg(rt)));
   9784 
   9785                      putIReg(rd, mkexpr(t0));
   9786                      break;
   9787                   }
   9788                   case 0x02: {  /* ADDUH_R.QB */
   9789                      DIP("adduh_r.qb r%u, r%u, r%u", rd, rs, rt);
   9790                      vassert(!mode64);
   9791                      t0 = newTemp(Ity_I32);
   9792                      t1 = newTemp(Ity_I32);
   9793                      t2 = newTemp(Ity_I8);
   9794                      t3 = newTemp(Ity_I32);
   9795                      t4 = newTemp(Ity_I32);
   9796                      t5 = newTemp(Ity_I8);
   9797                      t6 = newTemp(Ity_I32);
   9798                      t7 = newTemp(Ity_I32);
   9799                      t8 = newTemp(Ity_I8);
   9800                      t9 = newTemp(Ity_I32);
   9801                      t10 = newTemp(Ity_I32);
   9802                      t11 = newTemp(Ity_I8);
   9803 
   9804                      /* Extract input bytes, add values, add 1 and half the
   9805                         result. */
   9806                      assign(t0, unop(Iop_8Uto32,
   9807                                      unop(Iop_16to8,
   9808                                           unop(Iop_32to16, getIReg(rs)))));
   9809                      assign(t1, unop(Iop_8Uto32,
   9810                                      unop(Iop_16to8,
   9811                                           unop(Iop_32to16, getIReg(rt)))));
   9812                      assign(t2, unop(Iop_16to8,
   9813                                      unop(Iop_32to16,
   9814                                           binop(Iop_Shr32,
   9815                                                 binop(Iop_Add32,
   9816                                                       binop(Iop_Add32,
   9817                                                             mkexpr(t0),
   9818                                                             mkexpr(t1)),
   9819                                                       mkU32(0x00000001)),
   9820                                                 mkU8(0x01)))));
   9821 
   9822                      assign(t3, unop(Iop_8Uto32,
   9823                                      unop(Iop_16HIto8,
   9824                                           unop(Iop_32to16, getIReg(rs)))));
   9825                      assign(t4, unop(Iop_8Uto32,
   9826                                      unop(Iop_16HIto8,
   9827                                           unop(Iop_32to16, getIReg(rt)))));
   9828                      assign(t5, unop(Iop_16to8,
   9829                                      unop(Iop_32to16,
   9830                                           binop(Iop_Shr32,
   9831                                                 binop(Iop_Add32,
   9832                                                       binop(Iop_Add32,
   9833                                                             mkexpr(t3),
   9834                                                             mkexpr(t4)),
   9835                                                       mkU32(0x00000001)),
   9836                                                 mkU8(0x01)))));
   9837 
   9838                      assign(t6, unop(Iop_8Uto32,
   9839                                      unop(Iop_16to8,
   9840                                           unop(Iop_32HIto16, getIReg(rs)))));
   9841                      assign(t7, unop(Iop_8Uto32,
   9842                                      unop(Iop_16to8,
   9843                                           unop(Iop_32HIto16, getIReg(rt)))));
   9844                      assign(t8, unop(Iop_16to8,
   9845                                      unop(Iop_32to16,
   9846                                           binop(Iop_Shr32,
   9847                                                 binop(Iop_Add32,
   9848                                                       binop(Iop_Add32,
   9849                                                             mkexpr(t7),
   9850                                                             mkexpr(t6)),
   9851                                                       mkU32(0x00000001)),
   9852                                                 mkU8(0x01)))));
   9853 
   9854                      assign(t9, unop(Iop_8Uto32,
   9855                                      unop(Iop_16HIto8,
   9856                                           unop(Iop_32HIto16, getIReg(rs)))));
   9857                      assign(t10, unop(Iop_8Uto32,
   9858                                       unop(Iop_16HIto8,
   9859                                            unop(Iop_32HIto16, getIReg(rt)))));
   9860                      assign(t11, unop(Iop_16to8,
   9861                                       unop(Iop_32to16,
   9862                                            binop(Iop_Shr32,
   9863                                                  binop(Iop_Add32,
   9864                                                        binop(Iop_Add32,
   9865                                                              mkexpr(t9),
   9866                                                              mkexpr(t10)),
   9867                                                        mkU32(0x00000001)),
   9868                                                  mkU8(0x01)))));
   9869 
   9870                      putIReg(rd, binop(Iop_16HLto32,
   9871                                        binop(Iop_8HLto16,
   9872                                              mkexpr(t11), mkexpr(t8)),
   9873                                        binop(Iop_8HLto16,
   9874                                              mkexpr(t5), mkexpr(t2))));
   9875                      break;
   9876                   }
   9877                   case 0x3: {  /* SUBUH_R.QB */
   9878                      DIP("subuh_r.qb r%u, r%u, r%u", rd, rs, rt);
   9879                      vassert(!mode64);
   9880                      t1 = newTemp(Ity_I32);
   9881                      t2 = newTemp(Ity_I32);
   9882                      t3 = newTemp(Ity_I32);
   9883                      t4 = newTemp(Ity_I32);
   9884                      t5 = newTemp(Ity_I32);
   9885                      t6 = newTemp(Ity_I32);
   9886                      t7 = newTemp(Ity_I32);
   9887                      t8 = newTemp(Ity_I32);
   9888                      t9 = newTemp(Ity_I8);
   9889                      t10 = newTemp(Ity_I8);
   9890                      t11 = newTemp(Ity_I8);
   9891                      t12 = newTemp(Ity_I8);
   9892 
   9893                      /* Extract each byte of rs and rt. */
   9894                      assign(t1, unop(Iop_8Uto32,
   9895                                      unop(Iop_16to8,
   9896                                           unop(Iop_32to16, getIReg(rs)))));
   9897                      assign(t2, unop(Iop_8Uto32,
   9898                                      unop(Iop_16HIto8,
   9899                                           unop(Iop_32to16, getIReg(rs)))));
   9900                      assign(t3, unop(Iop_8Uto32,
   9901                                      unop(Iop_16to8,
   9902                                           unop(Iop_32HIto16, getIReg(rs)))));
   9903                      assign(t4, unop(Iop_8Uto32,
   9904                                      unop(Iop_16HIto8,
   9905                                           unop(Iop_32HIto16, getIReg(rs)))));
   9906 
   9907                      assign(t5, unop(Iop_8Uto32,
   9908                                      unop(Iop_16to8,
   9909                                           unop(Iop_32to16, getIReg(rt)))));
   9910                      assign(t6, unop(Iop_8Uto32,
   9911                                      unop(Iop_16HIto8,
   9912                                           unop(Iop_32to16, getIReg(rt)))));
   9913                      assign(t7, unop(Iop_8Uto32,
   9914                                      unop(Iop_16to8,
   9915                                           unop(Iop_32HIto16, getIReg(rt)))));
   9916                      assign(t8, unop(Iop_8Uto32,
   9917                                      unop(Iop_16HIto8,
   9918                                           unop(Iop_32HIto16, getIReg(rt)))));
   9919 
   9920                      /* Add 1 to each resulting byte and half the results. */
   9921                      assign(t9, unop(Iop_16to8,
   9922                                      unop(Iop_32to16,
   9923                                           binop(Iop_Shr32,
   9924                                                 binop(Iop_Add32,
   9925                                                       binop(Iop_Sub32,
   9926                                                             mkexpr(t1),
   9927                                                             mkexpr(t5)),
   9928                                                       mkU32(0x00000001)),
   9929                                                 mkU8(0x01)))));
   9930                      assign(t10, unop(Iop_16to8,
   9931                                       unop(Iop_32to16,
   9932                                            binop(Iop_Shr32,
   9933                                                  binop(Iop_Add32,
   9934                                                        binop(Iop_Sub32,
   9935                                                              mkexpr(t2),
   9936                                                              mkexpr(t6)),
   9937                                                        mkU32(0x00000001)),
   9938                                                  mkU8(0x01)))));
   9939                      assign(t11, unop(Iop_16to8,
   9940                                       unop(Iop_32to16,
   9941                                             binop(Iop_Shr32,
   9942                                                   binop(Iop_Add32,
   9943                                                         binop(Iop_Sub32,
   9944                                                               mkexpr(t3),
   9945                                                               mkexpr(t7)),
   9946                                                         mkU32(0x00000001)),
   9947                                                   mkU8(0x01)))));
   9948                      assign(t12, unop(Iop_16to8,
   9949                                       unop(Iop_32to16,
   9950                                            binop(Iop_Shr32,
   9951                                                  binop(Iop_Add32,
   9952                                                        binop(Iop_Sub32,
   9953                                                              mkexpr(t4),
   9954                                                              mkexpr(t8)),
   9955                                                        mkU32(0x00000001)),
   9956                                                  mkU8(0x01)))));
   9957 
   9958                      putIReg(rd, binop(Iop_16HLto32,
   9959                                        binop(Iop_8HLto16,
   9960                                              mkexpr(t12), mkexpr(t11)),
   9961                                        binop(Iop_8HLto16,
   9962                                              mkexpr(t10), mkexpr(t9))));
   9963                      break;
   9964                   }
   9965                   case 0x8: {  /* ADDQH.PH */
   9966                      DIP("addqh.ph r%u, r%u, r%u", rd, rs, rt);
   9967                      vassert(!mode64);
   9968                      t0 = newTemp(Ity_I32);
   9969                      t1 = newTemp(Ity_I16);
   9970                      t2 = newTemp(Ity_I32);
   9971                      t3 = newTemp(Ity_I16);
   9972 
   9973                      /* Add lower halfs of rs and rt
   9974                         and right shift the result by 1. */
   9975                      assign(t0, binop(Iop_Add32,
   9976                                       unop(Iop_16Sto32,
   9977                                            unop(Iop_32to16, getIReg(rs))),
   9978                                       unop(Iop_16Sto32,
   9979                                            unop(Iop_32to16, getIReg(rt)))));
   9980                      assign(t1, unop(Iop_32to16,
   9981                                      binop(Iop_Shr32,
   9982                                            binop(Iop_And32,
   9983                                                  mkexpr(t0),
   9984                                                  mkU32(0x0001fffe)),
   9985                                            mkU8(0x1))));
   9986                      /* Add higher halfs of rs and rt
   9987                         and right shift the result by 1. */
   9988                      assign(t2, binop(Iop_Add32,
   9989                                       unop(Iop_16Sto32,
   9990                                            unop(Iop_32HIto16, getIReg(rs))),
   9991                                       unop(Iop_16Sto32,
   9992                                            unop(Iop_32HIto16, getIReg(rt)))));
   9993                      assign(t3, unop(Iop_32to16,
   9994                                      binop(Iop_Shr32,
   9995                                            binop(Iop_And32,
   9996                                                  mkexpr(t2),
   9997                                                  mkU32(0x0001fffe)),
   9998                                            mkU8(0x1))));
   9999                      putIReg(rd, binop(Iop_16HLto32, mkexpr(t3), mkexpr(t1)));
   10000                      break;
   10001                   }
   10002                   case 0x9: {  /* SUBQH.PH */
   10003                      DIP("subqh.ph r%u, r%u, r%u", rd, rs, rt);
   10004                      vassert(!mode64);
   10005 
   10006                      putIReg(rd, binop(Iop_HSub16Sx2,
   10007                                        getIReg(rs), getIReg(rt)));
   10008                      break;
   10009                   }
   10010                   case 0xA: {/* ADDQH_R.PH */
   10011                      DIP("addqh_r.ph r%u, r%u, r%u", rd, rs, rt);
   10012                      vassert(!mode64);
   10013                      t0 = newTemp(Ity_I32);
   10014                      t1 = newTemp(Ity_I16);
   10015                      t2 = newTemp(Ity_I32);
   10016                      t3 = newTemp(Ity_I16);
   10017 
   10018                      /* Add lower halfs of rs and rt, add 1
   10019                         and right shift the result by 1. */
   10020                      assign(t0, binop(Iop_Add32,
   10021                                       unop(Iop_16Sto32,
   10022                                            unop(Iop_32to16, getIReg(rs))),
   10023                                       unop(Iop_16Sto32,
   10024                                            unop(Iop_32to16, getIReg(rt)))));
   10025                      assign(t1, unop(Iop_32to16,
   10026                                      binop(Iop_Shr32,
   10027                                            binop(Iop_And32,
   10028                                                  binop(Iop_Add32,
   10029                                                        mkexpr(t0),
   10030                                                        mkU32(0x1)),
   10031                                                  mkU32(0x0001fffe)),
   10032                                            mkU8(0x1))));
   10033                      /* Add higher halfs of rs and rt, add 1
   10034                         and right shift the result by 1. */
   10035                      assign(t2, binop(Iop_Add32,
   10036                                       unop(Iop_16Sto32,
   10037                                            unop(Iop_32HIto16, getIReg(rs))),
   10038                                       unop(Iop_16Sto32,
   10039                                            unop(Iop_32HIto16, getIReg(rt)))));
   10040                      assign(t3, unop(Iop_32to16,
   10041                                      binop(Iop_Shr32,
   10042                                            binop(Iop_And32,
   10043                                                  binop(Iop_Add32,
   10044                                                        mkexpr(t2),
   10045                                                        mkU32(0x1)),
   10046                                                  mkU32(0x0001fffe)),
   10047                                            mkU8(0x1))));
   10048 
   10049                      putIReg(rd, binop(Iop_16HLto32, mkexpr(t3), mkexpr(t1)));
   10050                      break;
   10051                   }
   10052                   case 0xB: {  /* SUBQH_R.PH */
   10053                      DIP("subqh_r.ph r%u, r%u, r%u", rd, rs, rt);
   10054                      vassert(!mode64);
   10055                      t0 = newTemp(Ity_I32);
   10056                      t1 = newTemp(Ity_I16);
   10057                      t2 = newTemp(Ity_I32);
   10058                      t3 = newTemp(Ity_I16);
   10059 
   10060                      /* Sub lower halfs of rs and rt, add 1
   10061                         and right shift the result by 1. */
   10062                      assign(t0, binop(Iop_Sub32,
   10063                                       unop(Iop_16Sto32,
   10064                                            unop(Iop_32to16, getIReg(rs))),
   10065                                       unop(Iop_16Sto32,
   10066                                            unop(Iop_32to16, getIReg(rt)))));
   10067                      assign(t1, unop(Iop_32to16,
   10068                                      binop(Iop_Shr32,
   10069                                            binop(Iop_And32,
   10070                                                  binop(Iop_Add32,
   10071                                                        mkexpr(t0),
   10072                                                        mkU32(0x1)),
   10073                                                  mkU32(0x0001fffe)),
   10074                                            mkU8(0x1))));
   10075                      /* Sub higher halfs of rs and rt, add 1
   10076                         and right shift the result by 1. */
   10077                      assign(t2, binop(Iop_Sub32,
   10078                                       unop(Iop_16Sto32,
   10079                                            unop(Iop_32HIto16, getIReg(rs))),
   10080                                       unop(Iop_16Sto32,
   10081                                            unop(Iop_32HIto16, getIReg(rt)))));
   10082                      assign(t3, unop(Iop_32to16,
   10083                                      binop(Iop_Shr32,
   10084                                            binop(Iop_And32,
   10085                                                  binop(Iop_Add32,
   10086                                                        mkexpr(t2),
   10087                                                        mkU32(0x1)),
   10088                                                  mkU32(0x0001fffe)),
   10089                                            mkU8(0x1))));
   10090 
   10091                      putIReg(rd, binop(Iop_16HLto32, mkexpr(t3), mkexpr(t1)));
   10092                      break;
   10093                   }
   10094                   case 0xC: {  /* MUL.PH */
   10095                      DIP("mul.ph r%u, r%u, r%u", rd, rs, rt);
   10096                      vassert(!mode64);
   10097                      t0 = newTemp(Ity_I32);
   10098                      t1 = newTemp(Ity_I32);
   10099                      t2 = newTemp(Ity_I32);
   10100 
   10101                      assign(t0,
   10102                             binop(Iop_Mul32,
   10103                                   unop(Iop_16Sto32,
   10104                                        unop(Iop_32HIto16, getIReg(rs))),
   10105                                   unop(Iop_16Sto32,
   10106                                        unop(Iop_32HIto16, getIReg(rt)))));
   10107                      /* DSP Control flag. */
   10108                      putDSPControl(IRExpr_ITE(unop(Iop_Not1,
   10109                                                    binop(Iop_CmpLE32S,
   10110                                                          mkexpr(t0),
   10111                                                          mkU32(0x7FFF))),
   10112                                               binop(Iop_Or32,
   10113                                                     getDSPControl(),
   10114                                                     mkU32(0x00200000)),
   10115                                               IRExpr_ITE(binop(Iop_CmpLT32S,
   10116                                                                mkexpr(t0),
   10117                                                                mkU32(0xFFFF8000)
   10118                                                              ),
   10119                                                          binop(Iop_Or32,
   10120                                                                getDSPControl(),
   10121                                                                mkU32(0x00200000)
   10122                                                               ),
   10123                                                          getDSPControl())));
   10124 
   10125                      assign(t1,
   10126                             binop(Iop_Mul32,
   10127                                   unop(Iop_16Sto32,
   10128                                        unop(Iop_32to16, getIReg(rs))),
   10129                                   unop(Iop_16Sto32,
   10130                                        unop(Iop_32to16, getIReg(rt)))));
   10131                      /* DSP Control flag. */
   10132                      putDSPControl(IRExpr_ITE(unop(Iop_Not1,
   10133                                                    binop(Iop_CmpLE32S,
   10134                                                          mkexpr(t1),
   10135                                                          mkU32(0x7FFF))),
   10136                                               binop(Iop_Or32,
   10137                                                     getDSPControl(),
   10138                                                     mkU32(0x00200000)),
   10139                                               IRExpr_ITE(binop(Iop_CmpLT32S,
   10140                                                                mkexpr(t1),
   10141                                                                mkU32(0xFFFF8000)
   10142                                                               ),
   10143                                                          binop(Iop_Or32,
   10144                                                                getDSPControl(),
   10145                                                                mkU32(0x00200000)
   10146                                                               ),
   10147                                                          getDSPControl())));
   10148 
   10149                      assign(t2, binop(Iop_16HLto32,
   10150                                       unop(Iop_32to16, mkexpr(t0)),
   10151                                       unop(Iop_32to16, mkexpr(t1))));
   10152                      putIReg(rd, mkexpr(t2));
   10153                      break;
   10154                   }
   10155                   case 0xE: {  /* MUL_S.PH */
   10156                      DIP("mul_s.ph r%u r%u, r%u", rd, rs, rt);
   10157                      vassert(!mode64);
   10158 
   10159                      t0 = newTemp(Ity_I32);
   10160                      t1 = newTemp(Ity_I32);
   10161                      t2 = newTemp(Ity_I32);
   10162                      t3 = newTemp(Ity_I32);
   10163                      t4 = newTemp(Ity_I32);
   10164 
   10165                      /* t0 - signed intermediate result. */
   10166                      assign(t0,
   10167                            binop(Iop_Mul32,
   10168                                  unop(Iop_16Sto32,
   10169                                       unop(Iop_32HIto16, getIReg(rs))),
   10170                                  unop(Iop_16Sto32,
   10171                                       unop(Iop_32HIto16, getIReg(rt)))));
   10172 
   10173                      assign(t1,
   10174                             IRExpr_ITE(unop(Iop_Not1,
   10175                                             binop(Iop_CmpLE32S,
   10176                                                   mkexpr(t0),
   10177                                                   mkU32(0x7FFF))),
   10178                                        mkU32(0x00007FFF),
   10179                                        IRExpr_ITE(binop(Iop_CmpLT32S,
   10180                                                         mkexpr(t0),
   10181                                                         mkU32(0xFFFF8000)),
   10182                                                   mkU32(0xFFFF8000),
   10183                                                   mkexpr(t0))));
   10184 
   10185                      /* DSP Control flag. */
   10186                      putDSPControl(IRExpr_ITE(unop(Iop_Not1,
   10187                                                    binop(Iop_CmpLE32S,
   10188                                                          mkexpr(t0),
   10189                                                          mkU32(0x7FFF))),
   10190                                               binop(Iop_Or32,
   10191                                                     getDSPControl(),
   10192                                                     mkU32(0x00200000)),
   10193                                               IRExpr_ITE(binop(Iop_CmpLT32S,
   10194                                                                mkexpr(t0),
   10195                                                                mkU32(0xFFFF8000)
   10196                                                               ),
   10197                                                          binop(Iop_Or32,
   10198                                                                getDSPControl(),
   10199                                                                mkU32(0x00200000)
   10200                                                               ),
   10201                                                          getDSPControl())));
   10202 
   10203                      /* t2 - signed intermediate result. */
   10204                      assign(t2, binop(Iop_Mul32,
   10205                                       unop(Iop_16Sto32,
   10206                                            unop(Iop_32to16, getIReg(rs))),
   10207                                       unop(Iop_16Sto32,
   10208                                            unop(Iop_32to16, getIReg(rt)))));
   10209 
   10210                      assign(t3, IRExpr_ITE(unop(Iop_Not1,
   10211                                                 binop(Iop_CmpLE32S,
   10212                                                       mkexpr(t2),
   10213                                                       mkU32(0x7FFF))),
   10214                                            mkU32(0x00007FFF),
   10215                                            IRExpr_ITE(binop(Iop_CmpLT32S,
   10216                                                             mkexpr(t2),
   10217                                                             mkU32(0xFFFF8000)),
   10218                                                       mkU32(0xFFFF8000),
   10219                                                       mkexpr(t2))));
   10220 
   10221                      /* DSP Control flag. */
   10222                      putDSPControl(IRExpr_ITE(unop(Iop_Not1,
   10223                                                    binop(Iop_CmpLE32S,
   10224                                                          mkexpr(t2),
   10225                                                          mkU32(0x7FFF))),
   10226                                               binop(Iop_Or32,
   10227                                                     getDSPControl(),
   10228                                                     mkU32(0x00200000)),
   10229                                               IRExpr_ITE(binop(Iop_CmpLT32S,
   10230                                                                mkexpr(t2),
   10231                                                                mkU32(0xFFFF8000)
   10232                                                               ),
   10233                                                          binop(Iop_Or32,
   10234                                                                getDSPControl(),
   10235                                                                mkU32(0x00200000)
   10236                                                               ),
   10237                                                          getDSPControl())));
   10238 
   10239                      assign(t4, binop(Iop_16HLto32,
   10240                                       unop(Iop_32to16, mkexpr(t1)),
   10241                                       unop(Iop_32to16, mkexpr(t3))));
   10242                      putIReg(rd, mkexpr(t4));
   10243                      break;
   10244                   }
   10245                   case 0x10: {  /* ADDQH.W */
   10246                      DIP("addqh.w r%u, r%u, r%u", rd, rs, rt);
   10247                      vassert(!mode64);
   10248                      t0 = newTemp(Ity_I64);
   10249                      t1 = newTemp(Ity_I64);
   10250 
   10251                      assign(t0, binop(Iop_Add64,
   10252                                       unop(Iop_32Sto64, getIReg(rs)),
   10253                                       unop(Iop_32Sto64, getIReg(rt))));
   10254                      assign(t1, binop(Iop_And64,
   10255                                       mkexpr(t0),
   10256                                       mkU64(0x00000001fffffffeULL)));
   10257                      putIReg(rd, unop(Iop_64to32,
   10258                                       binop(Iop_Shr64, mkexpr(t1), mkU8(0x1))));
   10259                      break;
   10260                   }
   10261                   case 0x11: {  /* SUBQH.W */
   10262                      DIP("subqh.w r%u, r%u, r%u", rd, rs, rt);
   10263                      vassert(!mode64);
   10264                      t0 = newTemp(Ity_I64);
   10265                      t1 = newTemp(Ity_I64);
   10266 
   10267                      assign(t0, binop(Iop_Sub64,
   10268                                       unop(Iop_32Sto64, getIReg(rs)),
   10269                                       unop(Iop_32Sto64, getIReg(rt))));
   10270                      assign(t1, binop(Iop_And64,
   10271                                       mkexpr(t0),
   10272                                       mkU64(0x00000001fffffffeULL)));
   10273                      putIReg(rd, unop(Iop_64to32,
   10274                                       binop(Iop_Shr64, mkexpr(t1), mkU8(0x1))));
   10275                      break;
   10276                   }
   10277                   case 0x12: {  /* ADDQH_R.W */
   10278                      DIP("addqh_r.w r%u, r%u, r%u", rd, rs, rt);
   10279                      vassert(!mode64);
   10280                      t0 = newTemp(Ity_I64);
   10281                      t1 = newTemp(Ity_I64);
   10282                      t2 = newTemp(Ity_I64);
   10283 
   10284                      assign(t0, binop(Iop_Add64,
   10285                                       unop(Iop_32Sto64, getIReg(rs)),
   10286                                       unop(Iop_32Sto64, getIReg(rt))));
   10287                      assign(t1, binop(Iop_Add64,
   10288                                       mkexpr(t0),
   10289                                       mkU64(0x0000000000000001ULL)));
   10290                      assign(t2, binop(Iop_And64,
   10291                                       mkexpr(t1),
   10292                                       mkU64(0x00000001fffffffeULL)));
   10293                      putIReg(rd, unop(Iop_64to32,
   10294                                       binop(Iop_Shr64, mkexpr(t2), mkU8(0x1))));
   10295                      break;
   10296                   }
   10297                   case 0x13: {  /* SUBQH_R.W */
   10298                      DIP("subqh_r.w r%u, r%u, r%u", rd, rs, rt);
   10299                      vassert(!mode64);
   10300                      t0 = newTemp(Ity_I64);
   10301                      t1 = newTemp(Ity_I64);
   10302                      t2 = newTemp(Ity_I64);
   10303 
   10304                      assign(t0, binop(Iop_Sub64,
   10305                                       unop(Iop_32Sto64, getIReg(rs)),
   10306                                       unop(Iop_32Sto64, getIReg(rt))));
   10307                      assign(t1, binop(Iop_Add64,
   10308                                       mkexpr(t0),
   10309                                       mkU64(0x0000000000000001ULL)));
   10310                      assign(t2, binop(Iop_And64,
   10311                                       mkexpr(t1),
   10312                                       mkU64(0x00000001fffffffeULL)));
   10313                      putIReg(rd, unop(Iop_64to32,
   10314                                       binop(Iop_Shr64, mkexpr(t2), mkU8(0x1))));
   10315                      break;
   10316                   }
   10317                   case 0x16: {  /* MULQ_S.W */
   10318                      DIP("mulq_s.w r%u, r%u, r%u", rd, rs, rt);
   10319                      vassert(!mode64);
   10320                      t0 = newTemp(Ity_I64);
   10321                      t1 = newTemp(Ity_I1);
   10322                      t2 = newTemp(Ity_I1);
   10323 
   10324                      assign(t0, binop(Iop_Shl64,
   10325                                       binop(Iop_MullS32,
   10326                                             getIReg(rt), getIReg(rs)),
   10327                                       mkU8(0x1)));
   10328                      assign(t1, binop(Iop_CmpEQ32,
   10329                                       getIReg(rt), mkU32(0x80000000)));
   10330                      assign(t2, binop(Iop_CmpEQ32,
   10331                                       getIReg(rs), mkU32(0x80000000)));
   10332 
   10333                      putDSPControl(IRExpr_ITE(mkexpr(t1),
   10334                                               IRExpr_ITE(mkexpr(t2),
   10335                                                          binop(Iop_Or32,
   10336                                                                getDSPControl(),
   10337                                                                mkU32(0x00200000)
   10338                                                               ),
   10339                                                          getDSPControl()),
   10340                                               getDSPControl()));
   10341                      putIReg(rd, IRExpr_ITE(mkexpr(t1),
   10342                                             IRExpr_ITE(mkexpr(t2),
   10343                                                        mkU32(0x7fffffff),
   10344                                                        unop(Iop_64HIto32,
   10345                                                             mkexpr(t0))),
   10346                                             unop(Iop_64HIto32, mkexpr(t0))));
   10347                      break;
   10348                   }
   10349                   case 0x17: {  /* MULQ_RS.W */
   10350                      DIP("mulq_rs.w r%u, r%u, r%u", rd, rs, rt);
   10351                      vassert(!mode64);
   10352                      t0 = newTemp(Ity_I64);
   10353                      t1 = newTemp(Ity_I1);
   10354                      t2 = newTemp(Ity_I1);
   10355 
   10356                      assign(t0, binop(Iop_Add64,
   10357                                       binop(Iop_Shl64,
   10358                                             binop(Iop_MullS32,
   10359                                                   getIReg(rt),
   10360                                                   getIReg(rs)),
   10361                                             mkU8(0x1)),
   10362                                       mkU64(0x0000000080000000ULL)));
   10363                      assign(t1,
   10364                             binop(Iop_CmpEQ32, getIReg(rt), mkU32(0x80000000)));
   10365                      assign(t2,
   10366                             binop(Iop_CmpEQ32, getIReg(rs), mkU32(0x80000000)));
   10367                      putDSPControl(IRExpr_ITE(mkexpr(t1),
   10368                                               IRExpr_ITE(mkexpr(t2),
   10369                                                          binop(Iop_Or32,
   10370                                                                getDSPControl(),
   10371                                                                mkU32(0x00200000)
   10372                                                               ),
   10373                                                          getDSPControl()),
   10374                                               getDSPControl()));
   10375                      putIReg(rd, IRExpr_ITE(mkexpr(t1),
   10376                                             IRExpr_ITE(mkexpr(t2),
   10377                                                        mkU32(0x7fffffff),
   10378                                                        unop(Iop_64HIto32,
   10379                                                             mkexpr(t0))),
   10380                                             unop(Iop_64HIto32, mkexpr(t0))));
   10381                      break;
   10382                   }
   10383                   default:
   10384                      return -1;
   10385                }
   10386                break;  /* end of ADDUH.QB/MUL.PH */
   10387             }
   10388             case 0x30: {  /* DPAQ.W.PH */
   10389                switch(sa) {
   10390                   case 0x0: {  /* DPA.W.PH */
   10391                      DIP("dpa.w.ph ac%u, r%u, r%u", ac, rs, rt);
   10392                      vassert(!mode64);
   10393 
   10394                      t0 = newTemp(Ity_I64);
   10395                      t1 = newTemp(Ity_I64);
   10396                      t2 = newTemp(Ity_I64);
   10397 
   10398                      assign(t0,
   10399                             unop(Iop_32Sto64,
   10400                                  binop(Iop_Mul32,
   10401                                        unop(Iop_16Sto32,
   10402                                             unop(Iop_32HIto16, getIReg(rs))),
   10403                                        unop(Iop_16Sto32,
   10404                                             unop(Iop_32HIto16, getIReg(rt))))));
   10405                      assign(t1,
   10406                             unop(Iop_32Sto64,
   10407                                  binop(Iop_Mul32,
   10408                                        unop(Iop_16Sto32,
   10409                                             unop(Iop_32to16, getIReg(rs))),
   10410                                        unop(Iop_16Sto32,
   10411                                             unop(Iop_32to16, getIReg(rt))))));
   10412                      assign(t2,
   10413                             binop(Iop_Add64,
   10414                                   getAcc(ac),
   10415                                   binop(Iop_Add64, mkexpr(t0), mkexpr(t1))));
   10416                      putAcc(ac, mkexpr(t2));
   10417                      break;
   10418                   }
   10419                   case 0x1: {  /* DPS.W.PH */
   10420                      DIP("dps.w.ph ac%u, r%u, r%u", ac, rs, rt);
   10421                      vassert(!mode64);
   10422 
   10423                      t0 = newTemp(Ity_I64);
   10424                      t1 = newTemp(Ity_I64);
   10425                      t2 = newTemp(Ity_I64);
   10426 
   10427                      assign(t0,
   10428                             unop(Iop_32Sto64,
   10429                                  binop(Iop_Mul32,
   10430                                        unop(Iop_16Sto32,
   10431                                             unop(Iop_32HIto16, getIReg(rs))),
   10432                                        unop(Iop_16Sto32,
   10433                                             unop(Iop_32HIto16, getIReg(rt))))));
   10434                      assign(t1,
   10435                             unop(Iop_32Sto64,
   10436                                  binop(Iop_Mul32,
   10437                                        unop(Iop_16Sto32,
   10438                                             unop(Iop_32to16, getIReg(rs))),
   10439                                        unop(Iop_16Sto32,
   10440                                             unop(Iop_32to16, getIReg(rt))))));
   10441                      assign(t2,
   10442                             binop(Iop_Sub64,
   10443                                   getAcc(ac),
   10444                                   binop(Iop_Add64, mkexpr(t0), mkexpr(t1))));
   10445                      putAcc(ac, mkexpr(t2));
   10446                      break;
   10447                   }
   10448                   case 0x2: {  /* MULSA.W.PH */
   10449                      DIP("mulsa.w.ph ac%u, r%u, r%u", ac, rs, rt);
   10450                      vassert(!mode64);
   10451                      t0 = newTemp(Ity_I32);
   10452                      t1 = newTemp(Ity_I32);
   10453                      t2 = newTemp(Ity_I32);
   10454                      t3 = newTemp(Ity_I1);
   10455                      t4 = newTemp(Ity_I64);
   10456 
   10457                      assign(t4, getAcc(ac));
   10458                      assign(t0, binop(Iop_Mul32,
   10459                                       unop(Iop_16Sto32,
   10460                                            unop(Iop_32to16, getIReg(rt))),
   10461                                       unop(Iop_16Sto32,
   10462                                            unop(Iop_32to16, getIReg(rs)))));
   10463                      assign(t1, binop(Iop_Mul32,
   10464                                       unop(Iop_16Sto32,
   10465                                            unop(Iop_32HIto16, getIReg(rt))),
   10466                                       unop(Iop_16Sto32,
   10467                                            unop(Iop_32HIto16, getIReg(rs)))));
   10468                      assign(t2, binop(Iop_Sub32, mkexpr(t1), mkexpr(t0)));
   10469                      putAcc(ac, binop(Iop_Add64,
   10470                                       mkexpr(t4),
   10471                                       unop(Iop_32Sto64, mkexpr(t2))));
   10472                      break;
   10473                   }
   10474                   case 0x3: {  /* DPAU.H.QBL */
   10475                      DIP("dpau.h.qbl ac%u, r%u, r%u", ac, rs, rt);
   10476                      vassert(!mode64);
   10477                      t0 = newTemp(Ity_I32);
   10478                      t1 = newTemp(Ity_I32);
   10479                      t2 = newTemp(Ity_I64);
   10480                      t3 = newTemp(Ity_I64);
   10481 
   10482                      assign(t0,
   10483                             binop(Iop_Mul32,
   10484                                   unop(Iop_8Uto32,
   10485                                        unop(Iop_16HIto8,
   10486                                             unop(Iop_32HIto16, getIReg(rs)))),
   10487                                   unop(Iop_8Uto32,
   10488                                        unop(Iop_16HIto8,
   10489                                             unop(Iop_32HIto16, getIReg(rt))))));
   10490                      assign(t1,
   10491                             binop(Iop_Mul32,
   10492                                   unop(Iop_8Uto32,
   10493                                        unop(Iop_16to8,
   10494                                             unop(Iop_32HIto16, getIReg(rs)))),
   10495                                   unop(Iop_8Uto32,
   10496                                        unop(Iop_16to8,
   10497                                             unop(Iop_32HIto16, getIReg(rt))))));
   10498                      assign(t2,
   10499                             unop(Iop_32Uto64,
   10500                                  binop(Iop_Add32,
   10501                                        mkexpr(t0),
   10502                                        mkexpr(t1))));
   10503                      assign(t3,
   10504                             binop(Iop_Add64, getAcc(ac), mkexpr(t2)));
   10505                      putAcc(ac, mkexpr(t3));
   10506                      break;
   10507                   }
   10508                   case 0x4: {  /* DPAQ_S.W.PH */
   10509                      DIP("dpaq_s.w.ph ac%u, r%u, r%u", ac, rs, rt);
   10510                      vassert(!mode64);
   10511                      t0 = newTemp(Ity_I64);
   10512                      t1 = newTemp(Ity_I64);
   10513                      t2 = newTemp(Ity_I1);
   10514                      t3 = newTemp(Ity_I1);
   10515                      t4 = newTemp(Ity_I64);
   10516                      t5 = newTemp(Ity_I64);
   10517                      t6 = newTemp(Ity_I1);
   10518                      t7 = newTemp(Ity_I1);
   10519                      t8 = newTemp(Ity_I64);
   10520                      t9 = newTemp(Ity_I64);
   10521 
   10522                      assign(t0, getAcc(ac));
   10523 
   10524                      assign(t1, binop(Iop_Shl64,
   10525                                       binop(Iop_MullS32,
   10526                                             unop(Iop_16Sto32,
   10527                                                  unop(Iop_32HIto16,
   10528                                                       getIReg(rs))),
   10529                                             unop(Iop_16Sto32,
   10530                                                  unop(Iop_32HIto16,
   10531                                                       getIReg(rt)))),
   10532                                       mkU8(0x1)));
   10533                      assign(t2, binop(Iop_CmpEQ32,
   10534                                       unop(Iop_16Uto32,
   10535                                            unop(Iop_32HIto16, getIReg(rs))),
   10536                                       mkU32(0x00008000)));
   10537                      assign(t3, binop(Iop_CmpEQ32,
   10538                                       unop(Iop_16Uto32,
   10539                                            unop(Iop_32HIto16, getIReg(rt))),
   10540                                       mkU32(0x00008000)));
   10541                      assign(t4,
   10542                             IRExpr_ITE(mkexpr(t2),
   10543                                        IRExpr_ITE(mkexpr(t3),
   10544                                                   mkU64(0x000000007fffffffULL),
   10545                                                   mkexpr(t1)),
   10546                                        mkexpr(t1)));
   10547 
   10548                      putDSPControl(IRExpr_ITE(mkexpr(t2),
   10549                                               IRExpr_ITE(mkexpr(t3),
   10550                                                          binop(Iop_Or32,
   10551                                                                getDSPControl(),
   10552                                                                binop(Iop_Shl32,
   10553                                                                      mkU32(0x1),
   10554                                                                      mkU8(ac+16)
   10555                                                                     )
   10556                                                               ),
   10557                                                          getDSPControl()),
   10558                                               getDSPControl()));
   10559 
   10560                      assign(t5, binop(Iop_Shl64,
   10561                                       binop(Iop_MullS32,
   10562                                             unop(Iop_16Sto32,
   10563                                                  unop(Iop_32to16, getIReg(rs))),
   10564                                             unop(Iop_16Sto32,
   10565                                                  unop(Iop_32to16, getIReg(rt)))
   10566                                            ),
   10567                                       mkU8(0x1)));
   10568                      assign(t6, binop(Iop_CmpEQ32,
   10569                                       unop(Iop_16Uto32,
   10570                                            unop(Iop_32to16, getIReg(rs))),
   10571                                       mkU32(0x00008000)));
   10572                      assign(t7, binop(Iop_CmpEQ32,
   10573                                       unop(Iop_16Uto32,
   10574                                            unop(Iop_32to16, getIReg(rt))),
   10575                                       mkU32(0x00008000)));
   10576                      assign(t8,
   10577                             IRExpr_ITE(mkexpr(t6),
   10578                                        IRExpr_ITE(mkexpr(t7),
   10579                                                   mkU64(0x000000007fffffffULL),
   10580                                                   mkexpr(t5)),
   10581                                        mkexpr(t5)));
   10582 
   10583                      putDSPControl(IRExpr_ITE(mkexpr(t6),
   10584                                               IRExpr_ITE(mkexpr(t7),
   10585                                                          binop(Iop_Or32,
   10586                                                                getDSPControl(),
   10587                                                                binop(Iop_Shl32,
   10588                                                                      mkU32(0x1),
   10589                                                                      mkU8(ac+16)
   10590                                                                     )
   10591                                                               ),
   10592                                                          getDSPControl()),
   10593                                               getDSPControl()));
   10594 
   10595                      assign(t9, binop(Iop_Add64,
   10596                                       binop(Iop_Add64, mkexpr(t4), mkexpr(t8)),
   10597                                       mkexpr(t0)));
   10598                      putAcc(ac, mkexpr(t9));
   10599                      break;
   10600                   }
   10601                   case 0x5: {  /* DPSQ_S.W.PH */
   10602                      DIP("dpsq_s.w.ph ac%u r%u, r%u", ac, rs, rt);
   10603                      vassert(!mode64);
   10604                      t0 = newTemp(Ity_I64);
   10605                      t1 = newTemp(Ity_I64);
   10606                      t2 = newTemp(Ity_I1);
   10607                      t3 = newTemp(Ity_I1);
   10608                      t4 = newTemp(Ity_I64);
   10609                      t5 = newTemp(Ity_I64);
   10610                      t6 = newTemp(Ity_I1);
   10611                      t7 = newTemp(Ity_I1);
   10612                      t8 = newTemp(Ity_I64);
   10613                      t9 = newTemp(Ity_I64);
   10614 
   10615                      assign(t0, getAcc(ac));
   10616 
   10617                      assign(t1, binop(Iop_Shl64,
   10618                                       binop(Iop_MullS32,
   10619                                             unop(Iop_16Sto32,
   10620                                                  unop(Iop_32HIto16,
   10621                                                       getIReg(rs))),
   10622                                             unop(Iop_16Sto32,
   10623                                                  unop(Iop_32HIto16,
   10624                                                       getIReg(rt)))),
   10625                                       mkU8(0x1)));
   10626                      assign(t2, binop(Iop_CmpEQ32,
   10627                                       unop(Iop_16Uto32,
   10628                                            unop(Iop_32HIto16, getIReg(rs))),
   10629                                       mkU32(0x00008000)));
   10630                      assign(t3, binop(Iop_CmpEQ32,
   10631                                       unop(Iop_16Uto32,
   10632                                            unop(Iop_32HIto16, getIReg(rt))),
   10633                                       mkU32(0x00008000)));
   10634                      assign(t4,
   10635                             IRExpr_ITE(mkexpr(t2),
   10636                                        IRExpr_ITE(mkexpr(t3),
   10637                                                   mkU64(0x000000007fffffffULL),
   10638                                                   mkexpr(t1)),
   10639                                        mkexpr(t1)));
   10640 
   10641                      putDSPControl(IRExpr_ITE(mkexpr(t2),
   10642                                               IRExpr_ITE(mkexpr(t3),
   10643                                                          binop(Iop_Or32,
   10644                                                                getDSPControl(),
   10645                                                                binop(Iop_Shl32,
   10646                                                                      mkU32(0x1),
   10647                                                                      mkU8(ac+16)
   10648                                                                     )
   10649                                                               ),
   10650                                                          getDSPControl()),
   10651                                               getDSPControl()));
   10652 
   10653                      assign(t5,
   10654                             binop(Iop_Shl64,
   10655                                   binop(Iop_MullS32,
   10656                                         unop(Iop_16Sto32,
   10657                                              unop(Iop_32to16, getIReg(rs))),
   10658                                         unop(Iop_16Sto32,
   10659                                              unop(Iop_32to16, getIReg(rt)))),
   10660                                   mkU8(0x1)));
   10661                      assign(t6, binop(Iop_CmpEQ32,
   10662                                       unop(Iop_16Uto32,
   10663                                            unop(Iop_32to16, getIReg(rs))),
   10664                                       mkU32(0x00008000)));
   10665                      assign(t7, binop(Iop_CmpEQ32,
   10666                                       unop(Iop_16Uto32,
   10667                                            unop(Iop_32to16, getIReg(rt))),
   10668                                       mkU32(0x00008000)));
   10669                      assign(t8,
   10670                             IRExpr_ITE(mkexpr(t6),
   10671                                        IRExpr_ITE(mkexpr(t7),
   10672                                                   mkU64(0x000000007fffffffULL),
   10673                                                   mkexpr(t5)),
   10674                                        mkexpr(t5)));
   10675 
   10676                      putDSPControl(IRExpr_ITE(mkexpr(t6),
   10677                                               IRExpr_ITE(mkexpr(t7),
   10678                                                          binop(Iop_Or32,
   10679                                                                getDSPControl(),
   10680                                                                binop(Iop_Shl32,
   10681                                                                      mkU32(0x1),
   10682                                                                      mkU8(ac+16)
   10683                                                                     )
   10684                                                               ),
   10685                                                          getDSPControl()),
   10686                                               getDSPControl()));
   10687 
   10688                      assign(t9,
   10689                             binop(Iop_Sub64,
   10690                                   mkexpr(t0),
   10691                                   binop(Iop_Add64, mkexpr(t4), mkexpr(t8))));
   10692                      putAcc(ac, mkexpr(t9));
   10693                      break;
   10694                   }
   10695                   case 0x6: {  /* MULSAQ_S.W.PH */
   10696                      DIP("mulsaq_s.w.ph ac%u r%u, r%u", ac, rs, rt);
   10697                      vassert(!mode64);
   10698 
   10699                      t0 = newTemp(Ity_I32);
   10700                      t1 = newTemp(Ity_I32);
   10701                      t2 = newTemp(Ity_I32);
   10702                      t3 = newTemp(Ity_I32);
   10703                      t4 = newTemp(Ity_I32);
   10704                      t5 = newTemp(Ity_I32);
   10705                      t6 = newTemp(Ity_I64);
   10706                      t7 = newTemp(Ity_I64);
   10707                      t8 = newTemp(Ity_I32);
   10708                      t9 = newTemp(Ity_I32);
   10709 
   10710                      assign(t0, unop(Iop_16Sto32,
   10711                                      unop(Iop_32HIto16, getIReg(rs))));
   10712                      assign(t1, unop(Iop_16Sto32,
   10713                                      unop(Iop_32HIto16, getIReg(rt))));
   10714 
   10715                      assign(t8, binop(Iop_And32,
   10716                                       unop(Iop_1Sto32,
   10717                                            binop(Iop_CmpEQ32,
   10718                                                  unop(Iop_16Uto32,
   10719                                                       unop(Iop_32HIto16,
   10720                                                            getIReg(rs))),
   10721                                                  mkU32(0x8000))),
   10722                                     unop(Iop_1Sto32,
   10723                                          binop(Iop_CmpEQ32,
   10724                                                unop(Iop_16Uto32,
   10725                                                     unop(Iop_32HIto16,
   10726                                                          getIReg(rt))),
   10727                                                mkU32(0x8000)))));
   10728                      /* DSPControl_outflag:16+acc <- 1 */
   10729                      putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32,
   10730                                                     mkexpr(t8),
   10731                                                     mkU32(0x0)),
   10732                                               binop(Iop_Or32,
   10733                                                     getDSPControl(),
   10734                                                     binop(Iop_Shl32,
   10735                                                           mkU32(0x00010000),
   10736                                                           mkU8(ac))),
   10737                                               getDSPControl()));
   10738 
   10739                      /* tempB_31..0 */
   10740                      assign(t2,
   10741                             IRExpr_ITE(binop(Iop_CmpNE32,
   10742                                              mkexpr(t8), mkU32(0x0)),
   10743                                        mkU32(0x7FFFFFFF),
   10744                                        binop(Iop_Shl32,
   10745                                              binop(Iop_Mul32,
   10746                                                    mkexpr(t0), mkexpr(t1)),
   10747                                              mkU8(1))));
   10748 
   10749                      assign(t3, unop(Iop_16Sto32,
   10750                                      unop(Iop_32to16, getIReg(rs))));
   10751                      assign(t4, unop(Iop_16Sto32,
   10752                                      unop(Iop_32to16, getIReg(rt))));
   10753 
   10754                      assign(t9, binop(Iop_And32,
   10755                                       unop(Iop_1Sto32,
   10756                                            binop(Iop_CmpEQ32,
   10757                                                  unop(Iop_16Uto32,
   10758                                                       unop(Iop_32to16,
   10759                                                            getIReg(rs))),
   10760                                                  mkU32(0x8000))),
   10761                                       unop(Iop_1Sto32,
   10762                                            binop(Iop_CmpEQ32,
   10763                                                  unop(Iop_16Uto32,
   10764                                                       unop(Iop_32to16,
   10765                                                            getIReg(rt))),
   10766                                                  mkU32(0x8000)))));
   10767                      /* DSPControl_outflag:16+acc <- 1 */
   10768                      putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32,
   10769                                                     mkexpr(t9),
   10770                                                     mkU32(0x0)),
   10771                                               binop(Iop_Or32,
   10772                                                     getDSPControl(),
   10773                                                     binop(Iop_Shl32,
   10774                                                           mkU32(0x00010000),
   10775                                                           mkU8(ac))),
   10776                                               getDSPControl()));
   10777                      /* tempA_31..0 */
   10778                      assign(t5,
   10779                             IRExpr_ITE(binop(Iop_CmpNE32,
   10780                                              mkexpr(t9),
   10781                                              mkU32(0x0)),
   10782                                        mkU32(0x7FFFFFFF),
   10783                                        binop(Iop_Shl32,
   10784                                              binop(Iop_Mul32,
   10785                                                    mkexpr(t3),
   10786                                                    mkexpr(t4)),
   10787                                              mkU8(1))));
   10788                      /* dotp_63..0 */
   10789                      assign(t6,
   10790                             binop(Iop_Sub64,
   10791                                   unop(Iop_32Sto64, mkexpr(t2)),
   10792                                   unop(Iop_32Sto64, mkexpr(t5))));
   10793                      /* tempC_63..0 */
   10794                      assign(t7, binop(Iop_Add64, getAcc(ac), mkexpr(t6)));
   10795 
   10796                      putAcc(ac, mkexpr(t7));
   10797                      break;
   10798                   }
   10799                   case 0x7: {  /* DPAU.H.QBR */
   10800                      DIP("dpau.h.qbr ac%u, r%u, r%u", ac, rs, rt);
   10801                      vassert(!mode64);
   10802                      t0 = newTemp(Ity_I32);
   10803                      t1 = newTemp(Ity_I32);
   10804                      t2 = newTemp(Ity_I64);
   10805                      t3 = newTemp(Ity_I64);
   10806 
   10807                      assign(t0,
   10808                             binop(Iop_Mul32,
   10809                                   unop(Iop_8Uto32,
   10810                                        unop(Iop_16HIto8,
   10811                                             unop(Iop_32to16, getIReg(rs)))),
   10812                                   unop(Iop_8Uto32,
   10813                                        unop(Iop_16HIto8,
   10814                                             unop(Iop_32to16, getIReg(rt))))));
   10815                      assign(t1,
   10816                             binop(Iop_Mul32,
   10817                                   unop(Iop_8Uto32,
   10818                                        unop(Iop_16to8,
   10819                                             unop(Iop_32to16, getIReg(rs)))),
   10820                                   unop(Iop_8Uto32,
   10821                                        unop(Iop_16to8,
   10822                                             unop(Iop_32to16, getIReg(rt))))));
   10823                      assign(t2, unop(Iop_32Uto64,
   10824                                      binop(Iop_Add32, mkexpr(t0), mkexpr(t1))));
   10825                      assign(t3, binop(Iop_Add64, getAcc(ac), mkexpr(t2)));
   10826                      putAcc(ac, mkexpr(t3));
   10827                      break;
   10828                   }
   10829                   case 0x8: {  /* DPAX.W.PH */
   10830                      DIP("dpax.w.ph ac%u, r%u, r%u", ac, rs, rt);
   10831                      vassert(!mode64);
   10832                      t0 = newTemp(Ity_I64);
   10833                      t1 = newTemp(Ity_I64);
   10834                      t2 = newTemp(Ity_I64);
   10835 
   10836                      assign(t0,
   10837                             unop(Iop_32Sto64,
   10838                                  binop(Iop_Mul32,
   10839                                        unop(Iop_16Sto32,
   10840                                             unop(Iop_32HIto16, getIReg(rs))),
   10841                                        unop(Iop_16Sto32,
   10842                                             unop(Iop_32to16, getIReg(rt))))));
   10843                      assign(t1,
   10844                             unop(Iop_32Sto64,
   10845                                  binop(Iop_Mul32,
   10846                                        unop(Iop_16Sto32,
   10847                                             unop(Iop_32to16, getIReg(rs))),
   10848                                        unop(Iop_16Sto32,
   10849                                             unop(Iop_32HIto16, getIReg(rt))))));
   10850                      assign(t2,
   10851                             binop(Iop_Add64,
   10852                                   getAcc(ac),
   10853                                   binop(Iop_Add64, mkexpr(t0), mkexpr(t1))));
   10854                      putAcc(ac, mkexpr(t2));
   10855                      break;
   10856                   }
   10857                   case 0x9: {  /* DPSX.W.PH */
   10858                      DIP("dpsx.w.ph ac%u r%u, r%u", ac, rs, rt);
   10859                      vassert(!mode64);
   10860 
   10861                      t0 = newTemp(Ity_I64);
   10862                      t1 = newTemp(Ity_I64);
   10863                      t2 = newTemp(Ity_I64);
   10864 
   10865                      assign(t0,
   10866                             unop(Iop_32Sto64,
   10867                                  binop(Iop_Mul32,
   10868                                        unop(Iop_16Sto32,
   10869                                             unop(Iop_32HIto16, getIReg(rs))),
   10870                                        unop(Iop_16Sto32,
   10871                                             unop(Iop_32to16, getIReg(rt))))));
   10872                      assign(t1,
   10873                             unop(Iop_32Sto64,
   10874                                  binop(Iop_Mul32,
   10875                                        unop(Iop_16Sto32,
   10876                                             unop(Iop_32to16, getIReg(rs))),
   10877                                        unop(Iop_16Sto32,
   10878                                             unop(Iop_32HIto16, getIReg(rt))))));
   10879                      assign(t2,
   10880                             binop(Iop_Sub64,
   10881                                   getAcc(ac),
   10882                                   binop(Iop_Add64, mkexpr(t0), mkexpr(t1))));
   10883                      putAcc(ac, mkexpr(t2));
   10884                      break;
   10885                   }
   10886                   case 0xB: {  /* DPSU.H.QBL */
   10887                      DIP("dpsu.h.qbl ac%u, r%u, r%u", ac, rs, rt);
   10888                      vassert(!mode64);
   10889 
   10890                      t0 = newTemp(Ity_I32);
   10891                      t1 = newTemp(Ity_I32);
   10892                      t2 = newTemp(Ity_I64);
   10893                      t3 = newTemp(Ity_I64);
   10894 
   10895                      assign(t0,
   10896                             binop(Iop_Mul32,
   10897                                   unop(Iop_8Uto32,
   10898                                        unop(Iop_16HIto8,
   10899                                             unop(Iop_32HIto16, getIReg(rs)))),
   10900                                   unop(Iop_8Uto32,
   10901                                        unop(Iop_16HIto8,
   10902                                             unop(Iop_32HIto16, getIReg(rt))))));
   10903                      assign(t1,
   10904                             binop(Iop_Mul32,
   10905                                   unop(Iop_8Uto32,
   10906                                        unop(Iop_16to8,
   10907                                             unop(Iop_32HIto16, getIReg(rs)))),
   10908                                   unop(Iop_8Uto32,
   10909                                        unop(Iop_16to8,
   10910                                             unop(Iop_32HIto16, getIReg(rt))))));
   10911                      assign(t2,
   10912                             unop(Iop_32Uto64,
   10913                                  binop(Iop_Add32, mkexpr(t0), mkexpr(t1))));
   10914                      assign(t3,
   10915                             binop(Iop_Sub64, getAcc(ac), mkexpr(t2)));
   10916                      putAcc(ac, mkexpr(t3));
   10917                      break;
   10918                   }
   10919                   case 0xC: {  /* DPAQ_SA.L.W */
   10920                      DIP("dpaq_sa.l.w ac%u, r%u, r%u", ac, rs, rt);
   10921                      vassert(!mode64);
   10922                      t0 = newTemp(Ity_I64);
   10923                      t1 = newTemp(Ity_I64);
   10924                      t2 = newTemp(Ity_I1);
   10925                      t3 = newTemp(Ity_I1);
   10926                      t4 = newTemp(Ity_I64);
   10927                      t5 = newTemp(Ity_I64);
   10928                      t6 = newTemp(Ity_I64);
   10929                      t7 = newTemp(Ity_I64);
   10930                      t8 = newTemp(Ity_I1);
   10931                      t9 = newTemp(Ity_I1);
   10932 
   10933                      assign(t0, getAcc(ac));
   10934 
   10935                      assign(t1, binop(Iop_Shl64,
   10936                                       binop(Iop_MullS32,
   10937                                             getIReg(rs), getIReg(rt)),
   10938                                       mkU8(0x1)));
   10939 
   10940                      assign(t2, binop(Iop_CmpEQ32,
   10941                                       getIReg(rs),
   10942                                       mkU32(0x80000000)));
   10943                      assign(t3, binop(Iop_CmpEQ32,
   10944                                       getIReg(rt),
   10945                                       mkU32(0x80000000)));
   10946 
   10947                      assign(t4,
   10948                             IRExpr_ITE(mkexpr(t2),
   10949                                        IRExpr_ITE(mkexpr(t3),
   10950                                                   mkU64(0x7fffffffffffffffULL),
   10951                                                   mkexpr(t1)),
   10952                                        mkexpr(t1)));
   10953 
   10954                      putDSPControl(IRExpr_ITE(mkexpr(t2),
   10955                                               IRExpr_ITE(mkexpr(t3),
   10956                                                          binop(Iop_Or32,
   10957                                                                getDSPControl(),
   10958                                                                binop(Iop_Shl32,
   10959                                                                      mkU32(0x1),
   10960                                                                      mkU8(ac+16)
   10961                                                                     )
   10962                                                               ),
   10963                                                          getDSPControl()),
   10964                                               getDSPControl()));
   10965 
   10966                      assign(t5, binop(Iop_Add64,
   10967                                       unop(Iop_32Uto64,
   10968                                            unop(Iop_64to32, mkexpr(t0))),
   10969                                       unop(Iop_32Uto64,
   10970                                            unop(Iop_64to32, mkexpr(t4)))));
   10971                      assign(t6,
   10972                             binop(Iop_Add64,
   10973                                   binop(Iop_Add64,
   10974                                         unop(Iop_32Sto64,
   10975                                              unop(Iop_64HIto32, mkexpr(t0))),
   10976                                         unop(Iop_32Sto64,
   10977                                              unop(Iop_64HIto32, mkexpr(t4)))),
   10978                                   unop(Iop_32Uto64,
   10979                                        binop(Iop_And32,
   10980                                              unop(Iop_64HIto32, mkexpr(t5)),
   10981                                              mkU32(0x1)))));
   10982                      assign(t7, binop(Iop_32HLto64,
   10983                                       unop(Iop_64to32, mkexpr(t6)),
   10984                                       unop(Iop_64to32, mkexpr(t5))));
   10985                      assign(t8, binop(Iop_CmpEQ32,
   10986                                       binop(Iop_Shr32,
   10987                                             binop(Iop_And32,
   10988                                                   unop(Iop_64to32, mkexpr(t6)),
   10989                                                   mkU32(0x80000000)),
   10990                                             mkU8(31)),
   10991                                       binop(Iop_And32,
   10992                                             unop(Iop_64HIto32, mkexpr(t6)),
   10993                                             mkU32(0x00000001))));
   10994                      assign(t9, binop(Iop_CmpEQ32,
   10995                                       binop(Iop_And32,
   10996                                             unop(Iop_64HIto32,
   10997                                                  mkexpr(t6)),
   10998                                             mkU32(0x00000001)),
   10999                                       mkU32(0x1)));
   11000                      putDSPControl(IRExpr_ITE(mkexpr(t8),
   11001                                               getDSPControl(),
   11002                                               binop(Iop_Or32,
   11003                                                     getDSPControl(),
   11004                                                     binop(Iop_Shl32,
   11005                                                           mkU32(0x1),
   11006                                                           mkU8(ac+16)))));
   11007                      putAcc(ac,
   11008                             IRExpr_ITE(mkexpr(t8),
   11009                                        mkexpr(t7),
   11010                                        IRExpr_ITE(mkexpr(t9),
   11011                                                   mkU64(0x8000000000000000ULL),
   11012                                                   mkU64(0x7fffffffffffffffULL)))
   11013                            );
   11014                      break;
   11015                   }
   11016                   case 0xD: {  /* DPSQ_SA.L.W */
   11017                      DIP("dpsq_sa.l.w ac%u, r%u, r%u", ac, rs, rt);
   11018                      vassert(!mode64);
   11019                      t0 = newTemp(Ity_I64);
   11020                      t1 = newTemp(Ity_I64);
   11021                      t2 = newTemp(Ity_I1);
   11022                      t3 = newTemp(Ity_I1);
   11023                      t4 = newTemp(Ity_I64);
   11024                      t5 = newTemp(Ity_I64);
   11025                      t6 = newTemp(Ity_I64);
   11026                      t7 = newTemp(Ity_I64);
   11027                      t8 = newTemp(Ity_I1);
   11028                      t9 = newTemp(Ity_I1);
   11029 
   11030                      assign(t0, getAcc(ac));
   11031 
   11032                      assign(t1, binop(Iop_Shl64,
   11033                                       binop(Iop_MullS32,
   11034                                             getIReg(rs), getIReg(rt)),
   11035                                       mkU8(0x1)));
   11036 
   11037                      assign(t2, binop(Iop_CmpEQ32,
   11038                                       getIReg(rs),
   11039                                       mkU32(0x80000000)));
   11040                      assign(t3, binop(Iop_CmpEQ32,
   11041                                       getIReg(rt),
   11042                                       mkU32(0x80000000)));
   11043 
   11044                      assign(t4,
   11045                             IRExpr_ITE(mkexpr(t2),
   11046                                        IRExpr_ITE(mkexpr(t3),
   11047                                                   mkU64(0x7fffffffffffffffULL),
   11048                                                   mkexpr(t1)),
   11049                                        mkexpr(t1)));
   11050 
   11051                      putDSPControl(IRExpr_ITE(mkexpr(t2),
   11052                                               IRExpr_ITE(mkexpr(t3),
   11053                                                          binop(Iop_Or32,
   11054                                                                getDSPControl(),
   11055                                                                binop(Iop_Shl32,
   11056                                                                      mkU32(0x1),
   11057                                                                      mkU8(ac+16)
   11058                                                                     )
   11059                                                               ),
   11060                                                          getDSPControl()),
   11061                                               getDSPControl()));
   11062 
   11063                      assign(t5, binop(Iop_Sub64,
   11064                                       unop(Iop_32Uto64,
   11065                                            unop(Iop_64to32, mkexpr(t0))),
   11066                                       unop(Iop_32Uto64,
   11067                                            unop(Iop_64to32, mkexpr(t4)))));
   11068                      assign(t6, binop(Iop_Sub64,
   11069                                       binop(Iop_Add64,
   11070                                             unop(Iop_32Sto64,
   11071                                                  unop(Iop_64HIto32, mkexpr(t0))
   11072                                                 ),
   11073                                             unop(Iop_32Sto64,
   11074                                                  unop(Iop_1Sto32,
   11075                                                       binop(Iop_CmpLT32U,
   11076                                                             unop(Iop_64to32,
   11077                                                                  mkexpr(t0)),
   11078                                                             unop(Iop_64to32,
   11079                                                                 mkexpr(t4)))))),
   11080                                       unop(Iop_32Sto64,
   11081                                            unop(Iop_64HIto32, mkexpr(t4)))));
   11082                      assign(t7, binop(Iop_32HLto64,
   11083                                       unop(Iop_64to32, mkexpr(t6)),
   11084                                       unop(Iop_64to32, mkexpr(t5))));
   11085                      assign(t8, binop(Iop_CmpEQ32,
   11086                                       binop(Iop_Shr32,
   11087                                             binop(Iop_And32,
   11088                                                   unop(Iop_64to32, mkexpr(t6)),
   11089                                                   mkU32(0x80000000)),
   11090                                             mkU8(31)),
   11091                                       binop(Iop_And32,
   11092                                             unop(Iop_64HIto32, mkexpr(t6)),
   11093                                             mkU32(0x00000001))));
   11094                      assign(t9, binop(Iop_CmpEQ32,
   11095                                       binop(Iop_And32,
   11096                                             unop(Iop_64HIto32, mkexpr(t6)),
   11097                                             mkU32(0x00000001)),
   11098                                       mkU32(0x1)));
   11099                      putDSPControl(IRExpr_ITE(mkexpr(t8),
   11100                                               getDSPControl(),
   11101                                               binop(Iop_Or32,
   11102                                                     getDSPControl(),
   11103                                                     binop(Iop_Shl32,
   11104                                                           mkU32(0x1),
   11105                                                           mkU8(ac+16)))));
   11106                      putAcc(ac,
   11107                             IRExpr_ITE(mkexpr(t8),
   11108                                        mkexpr(t7),
   11109                                        IRExpr_ITE(mkexpr(t9),
   11110                                                   mkU64(0x8000000000000000ULL),
   11111                                                   mkU64(0x7fffffffffffffffULL)))
   11112                            );
   11113                      break;
   11114                   }
   11115                   case 0xF: {  /* DPSU.H.QBR */
   11116                      DIP("dpsu.h.qbr ac%u r%u, r%u", ac, rs, rt);
   11117                      vassert(!mode64);
   11118 
   11119                      t0 = newTemp(Ity_I32);
   11120                      t1 = newTemp(Ity_I32);
   11121                      t2 = newTemp(Ity_I64);
   11122                      t3 = newTemp(Ity_I64);
   11123 
   11124                      assign(t0,
   11125                             binop(Iop_Mul32,
   11126                                   unop(Iop_8Uto32,
   11127                                        unop(Iop_16HIto8,
   11128                                             unop(Iop_32to16, getIReg(rs)))),
   11129                                   unop(Iop_8Uto32,
   11130                                        unop(Iop_16HIto8,
   11131                                             unop(Iop_32to16, getIReg(rt))))));
   11132                      assign(t1,
   11133                             binop(Iop_Mul32,
   11134                                   unop(Iop_8Uto32,
   11135                                        unop(Iop_16to8,
   11136                                             unop(Iop_32to16, getIReg(rs)))),
   11137                                   unop(Iop_8Uto32,
   11138                                        unop(Iop_16to8,
   11139                                             unop(Iop_32to16, getIReg(rt))))));
   11140                      assign(t2, unop(Iop_32Uto64,
   11141                                      binop(Iop_Add32, mkexpr(t0), mkexpr(t1))));
   11142                      assign(t3, binop(Iop_Sub64, getAcc(ac), mkexpr(t2)));
   11143                      putAcc(ac, mkexpr(t3));
   11144 
   11145                      break;
   11146                   }
   11147                   case 0x10: {  /* MAQ_SA.W.PHL */
   11148                      DIP("maq_sa.w.phl ac%u, r%u, r%u", ac, rs, rt);
   11149                      vassert(!mode64);
   11150                      t0 = newTemp(Ity_I64);
   11151                      t1 = newTemp(Ity_I64);
   11152                      t2 = newTemp(Ity_I1);
   11153                      t3 = newTemp(Ity_I1);
   11154                      t4 = newTemp(Ity_I64);
   11155                      t5 = newTemp(Ity_I64);
   11156                      t6 = newTemp(Ity_I1);
   11157                      t7 = newTemp(Ity_I64);
   11158 
   11159                      assign(t0, getAcc(ac));
   11160                      assign(t1, unop(Iop_32Sto64,
   11161                                      binop(Iop_Shl32,
   11162                                            binop(Iop_Mul32,
   11163                                                  unop(Iop_16Sto32,
   11164                                                       unop(Iop_32HIto16,
   11165                                                            getIReg(rs))),
   11166                                                  unop(Iop_16Sto32,
   11167                                                       unop(Iop_32HIto16,
   11168                                                            getIReg(rt)))),
   11169                                            mkU8(0x1))));
   11170 
   11171                      /* If both input arguments are equal 0x8000, saturate
   11172                         intermediate product and write to DSPControl register.
   11173                      */
   11174                      assign(t2, binop(Iop_CmpEQ32,
   11175                                       unop(Iop_16Uto32,
   11176                                            unop(Iop_32HIto16, getIReg(rs))),
   11177                                       mkU32(0x00008000)));
   11178                      assign(t3, binop(Iop_CmpEQ32,
   11179                                       unop(Iop_16Uto32,
   11180                                            unop(Iop_32HIto16, getIReg(rt))),
   11181                                       mkU32(0x00008000)));
   11182 
   11183                      assign(t4,
   11184                             IRExpr_ITE(mkexpr(t2),
   11185                                        IRExpr_ITE(mkexpr(t3),
   11186                                                   mkU64(0x000000007fffffffULL),
   11187                                                   mkexpr(t1)),
   11188                                        mkexpr(t1)));
   11189 
   11190                      putDSPControl(IRExpr_ITE(mkexpr(t2),
   11191                                               IRExpr_ITE(mkexpr(t3),
   11192                                                          binop(Iop_Or32,
   11193                                                                getDSPControl(),
   11194                                                                binop(Iop_Shl32,
   11195                                                                      mkU32(0x1),
   11196                                                                      mkU8(ac+16)
   11197                                                                     )
   11198                                                               ),
   11199                                                          getDSPControl()),
   11200                                               getDSPControl()));
   11201                      /* Add intermediate product and value in the
   11202                         accumulator. */
   11203                      assign(t5, binop(Iop_Add64, mkexpr(t0), mkexpr(t4)));
   11204 
   11205                      /* Compare bits 31 and 32 of the value in t5. */
   11206                      assign(t6, binop(Iop_CmpEQ32,
   11207                                       binop(Iop_Shr32,
   11208                                             binop(Iop_And32,
   11209                                                   unop(Iop_64to32, mkexpr(t5)),
   11210                                                   mkU32(0x80000000)),
   11211                                             mkU8(31)),
   11212                                       binop(Iop_And32,
   11213                                             unop(Iop_64HIto32, mkexpr(t5)),
   11214                                             mkU32(1))));
   11215                      putDSPControl(IRExpr_ITE(mkexpr(t6),
   11216                                               getDSPControl(),
   11217                                               binop(Iop_Or32,
   11218                                                     getDSPControl(),
   11219                                                     binop(Iop_Shl32,
   11220                                                           mkU32(0x1),
   11221                                                           mkU8(ac+16)))));
   11222                      assign(t7,
   11223                             IRExpr_ITE(mkexpr(t6),
   11224                                        mkexpr(t5),
   11225                                        IRExpr_ITE(binop(Iop_CmpEQ32,
   11226                                                         binop(Iop_And32,
   11227                                                               unop(Iop_64HIto32,
   11228                                                                    mkexpr(t5)),
   11229                                                               mkU32(1)),
   11230                                                         mkU32(0x0)),
   11231                                                   mkU64(0x000000007fffffffULL),
   11232                                                   mkU64(0xffffffff80000000ULL)))
   11233                            );
   11234                      putAcc(ac, mkexpr(t7));
   11235                      break;
   11236                   }
   11237                   case 0x12: {  /* MAQ_SA.W.PHR */
   11238                      DIP("maq_sa.w.phr ac%u, r%u, r%u", ac, rs, rt);
   11239                      vassert(!mode64);
   11240                      t0 = newTemp(Ity_I64);
   11241                      t1 = newTemp(Ity_I64);
   11242                      t2 = newTemp(Ity_I1);
   11243                      t3 = newTemp(Ity_I1);
   11244                      t4 = newTemp(Ity_I64);
   11245                      t5 = newTemp(Ity_I64);
   11246                      t6 = newTemp(Ity_I1);
   11247                      t7 = newTemp(Ity_I64);
   11248 
   11249                      assign(t0, getAcc(ac));
   11250                      assign(t1, unop(Iop_32Sto64,
   11251                                      binop(Iop_Shl32,
   11252                                            binop(Iop_Mul32,
   11253                                                  unop(Iop_16Sto32,
   11254                                                       unop(Iop_32to16,
   11255                                                            getIReg(rs))),
   11256                                                  unop(Iop_16Sto32,
   11257                                                       unop(Iop_32to16,
   11258                                                            getIReg(rt)))),
   11259                                            mkU8(0x1))));
   11260 
   11261                      /* If both input arguments are equal 0x8000, saturate
   11262                         intermediate product and write to DSPControl
   11263                         register. */
   11264                      assign(t2, binop(Iop_CmpEQ32,
   11265                                       unop(Iop_16Uto32,
   11266                                            unop(Iop_32to16, getIReg(rs))),
   11267                                       mkU32(0x00008000)));
   11268                      assign(t3, binop(Iop_CmpEQ32,
   11269                                       unop(Iop_16Uto32,
   11270                                            unop(Iop_32to16, getIReg(rt))),
   11271                                       mkU32(0x00008000)));
   11272 
   11273                      assign(t4,
   11274                             IRExpr_ITE(mkexpr(t2),
   11275                                        IRExpr_ITE(mkexpr(t3),
   11276                                                   mkU64(0x000000007fffffffULL),
   11277                                                   mkexpr(t1)),
   11278                                        mkexpr(t1)));
   11279 
   11280                      putDSPControl(IRExpr_ITE(mkexpr(t2),
   11281                                               IRExpr_ITE(mkexpr(t3),
   11282                                                          binop(Iop_Or32,
   11283                                                                getDSPControl(),
   11284                                                                binop(Iop_Shl32,
   11285                                                                      mkU32(0x1),
   11286                                                                      mkU8(ac+16)
   11287                                                                     )
   11288                                                               ),
   11289                                                          getDSPControl()),
   11290                                               getDSPControl()));
   11291                      /* Add intermediate product and value in the
   11292                         accumulator. */
   11293                      assign(t5, binop(Iop_Add64, mkexpr(t0), mkexpr(t4)));
   11294 
   11295                      /* Compare bits 31 and 32 of the value in t5. */
   11296                      assign(t6, binop(Iop_CmpEQ32,
   11297                                       binop(Iop_Shr32,
   11298                                             binop(Iop_And32,
   11299                                                   unop(Iop_64to32, mkexpr(t5)),
   11300                                                   mkU32(0x80000000)),
   11301                                             mkU8(31)),
   11302                                       binop(Iop_And32,
   11303                                             unop(Iop_64HIto32, mkexpr(t5)),
   11304                                             mkU32(1))));
   11305                      putDSPControl(IRExpr_ITE(mkexpr(t6),
   11306                                               getDSPControl(),
   11307                                               binop(Iop_Or32,
   11308                                                     getDSPControl(),
   11309                                                     binop(Iop_Shl32,
   11310                                                           mkU32(0x1),
   11311                                                           mkU8(ac+16)))));
   11312                      assign(t7,
   11313                             IRExpr_ITE(mkexpr(t6),
   11314                                        mkexpr(t5),
   11315                                        IRExpr_ITE(binop(Iop_CmpEQ32,
   11316                                                         binop(Iop_And32,
   11317                                                               unop(Iop_64HIto32,
   11318                                                                    mkexpr(t5)),
   11319                                                               mkU32(1)),
   11320                                                         mkU32(0x0)),
   11321                                                   mkU64(0x000000007fffffffULL),
   11322                                                   mkU64(0xffffffff80000000ULL)))
   11323                            );
   11324                      putAcc(ac, mkexpr(t7));
   11325                      break;
   11326                   }
   11327                   case 0x14: {  /* MAQ_S.W.PHL */
   11328                      DIP("maq_s.w.phl ac%u, r%u, r%u", ac, rs, rt);
   11329                      vassert(!mode64);
   11330                      t0 = newTemp(Ity_I32);
   11331                      t1 = newTemp(Ity_I32);
   11332                      t2 = newTemp(Ity_I32);
   11333                      t3 = newTemp(Ity_I1);
   11334                      t4 = newTemp(Ity_I32);
   11335                      t5 = newTemp(Ity_I64);
   11336 
   11337                      assign(t5, getAcc(ac));
   11338 
   11339                      assign(t0, unop(Iop_16Sto32,
   11340                                      unop(Iop_32HIto16, getIReg(rs))));
   11341                      assign(t1, unop(Iop_16Sto32,
   11342                                      unop(Iop_32HIto16, getIReg(rt))));
   11343 
   11344                      assign(t2, binop(Iop_And32,
   11345                                       unop(Iop_1Sto32,
   11346                                            binop(Iop_CmpEQ32,
   11347                                                  binop(Iop_And32,
   11348                                                        mkexpr(t0),
   11349                                                        mkU32(0xffff)),
   11350                                                  mkU32(0x8000))),
   11351                                       unop(Iop_1Sto32,
   11352                                            binop(Iop_CmpEQ32,
   11353                                                  binop(Iop_And32,
   11354                                                        mkexpr(t1),
   11355                                                        mkU32(0xffff)),
   11356                                                  mkU32(0x8000)))));
   11357 
   11358                      assign(t3, binop(Iop_CmpEQ32, mkexpr(t2), mkU32(0x0)));
   11359 
   11360                      putDSPControl(IRExpr_ITE(mkexpr(t3),
   11361                                               getDSPControl(),
   11362                                               binop(Iop_Or32,
   11363                                                     getDSPControl(),
   11364                                                     binop(Iop_Shl32,
   11365                                                           mkU32(0x1),
   11366                                                           mkU8(ac+16)))));
   11367 
   11368                      assign(t4, unop(Iop_64to32,
   11369                                      binop(Iop_MullS32,
   11370                                            mkexpr(t0), mkexpr(t1))));
   11371                      putAcc(ac, IRExpr_ITE(mkexpr(t3),
   11372                                            binop(Iop_Add64,
   11373                                                  unop(Iop_32Sto64,
   11374                                                       binop(Iop_Shl32,
   11375                                                             mkexpr(t4),
   11376                                                             mkU8(0x1))),
   11377                                                  mkexpr(t5)),
   11378                                            binop(Iop_Add64,
   11379                                                  mkexpr(t5),
   11380                                                  unop(Iop_32Sto64,
   11381                                                       mkU32(0x7fffffff)))));
   11382                      break;
   11383                   }
   11384                   case 0x16: {  /* MAQ_S.W.PHR */
   11385                      DIP("maq_s.w.phr ac%u, r%u, r%u", ac, rs, rt);
   11386                      vassert(!mode64);
   11387                      t0 = newTemp(Ity_I32);
   11388                      t1 = newTemp(Ity_I32);
   11389                      t2 = newTemp(Ity_I32);
   11390                      t3 = newTemp(Ity_I1);
   11391                      t4 = newTemp(Ity_I32);
   11392                      t5 = newTemp(Ity_I64);
   11393 
   11394                      assign(t5, getAcc(ac));
   11395 
   11396                      assign(t0, unop(Iop_16Sto32,
   11397                                      unop(Iop_32to16, getIReg(rs))));
   11398                      assign(t1, unop(Iop_16Sto32,
   11399                                      unop(Iop_32to16, getIReg(rt))));
   11400 
   11401                      assign(t2, binop(Iop_And32,
   11402                                       unop(Iop_1Sto32,
   11403                                            binop(Iop_CmpEQ32,
   11404                                                  binop(Iop_And32,
   11405                                                        mkexpr(t0),
   11406                                                        mkU32(0xffff)),
   11407                                                  mkU32(0x8000))),
   11408                                       unop(Iop_1Sto32,
   11409                                            binop(Iop_CmpEQ32,
   11410                                                  binop(Iop_And32,
   11411                                                        mkexpr(t1),
   11412                                                        mkU32(0xffff)),
   11413                                                  mkU32(0x8000)))));
   11414 
   11415                      assign(t3, binop(Iop_CmpEQ32, mkexpr(t2), mkU32(0x0)));
   11416 
   11417                      putDSPControl(IRExpr_ITE(mkexpr(t3),
   11418                                               getDSPControl(),
   11419                                               binop(Iop_Or32,
   11420                                                     getDSPControl(),
   11421                                                     binop(Iop_Shl32,
   11422                                                           mkU32(0x1),
   11423                                                           mkU8(ac+16)))));
   11424 
   11425                      assign(t4, unop(Iop_64to32,
   11426                                      binop(Iop_MullS32,
   11427                                            mkexpr(t0), mkexpr(t1))));
   11428                      putAcc(ac, IRExpr_ITE(mkexpr(t3),
   11429                                            binop(Iop_Add64,
   11430                                                  unop(Iop_32Sto64,
   11431                                                       binop(Iop_Shl32,
   11432                                                             mkexpr(t4),
   11433                                                             mkU8(0x1))),
   11434                                                  mkexpr(t5)),
   11435                                            binop(Iop_Add64,
   11436                                                  mkexpr(t5),
   11437                                                  unop(Iop_32Sto64,
   11438                                                       mkU32(0x7fffffff)))));
   11439                      break;
   11440                   }
   11441                   case 0x18: {  /* DPAQX_S.W.PH */
   11442                      DIP("dpaqx_s.w.ph ac%u, r%u, r%u", ac, rs, rt);
   11443                      vassert(!mode64);
   11444                      t0 = newTemp(Ity_I64);
   11445                      t1 = newTemp(Ity_I64);
   11446                      t2 = newTemp(Ity_I1);
   11447                      t3 = newTemp(Ity_I1);
   11448                      t4 = newTemp(Ity_I64);
   11449                      t5 = newTemp(Ity_I64);
   11450                      t6 = newTemp(Ity_I1);
   11451                      t7 = newTemp(Ity_I1);
   11452                      t8 = newTemp(Ity_I64);
   11453                      t9 = newTemp(Ity_I64);
   11454 
   11455                      assign(t0, getAcc(ac));
   11456 
   11457                      assign(t1, binop(Iop_Shl64,
   11458                                       binop(Iop_MullS32,
   11459                                             unop(Iop_16Sto32,
   11460                                                  unop(Iop_32HIto16,
   11461                                                       getIReg(rs))),
   11462                                             unop(Iop_16Sto32,
   11463                                                  unop(Iop_32to16,
   11464                                                       getIReg(rt)))),
   11465                                       mkU8(0x1)));
   11466                      assign(t2, binop(Iop_CmpEQ32,
   11467                                       unop(Iop_16Uto32,
   11468                                            unop(Iop_32HIto16, getIReg(rs))),
   11469                                       mkU32(0x00008000)));
   11470                      assign(t3, binop(Iop_CmpEQ32,
   11471                                       unop(Iop_16Uto32,
   11472                                            unop(Iop_32to16, getIReg(rt))),
   11473                                       mkU32(0x00008000)));
   11474                      assign(t4,
   11475                             IRExpr_ITE(mkexpr(t2),
   11476                                        IRExpr_ITE(mkexpr(t3),
   11477                                                   mkU64(0x000000007fffffffULL),
   11478                                                   mkexpr(t1)),
   11479                                        mkexpr(t1)));
   11480 
   11481                      putDSPControl(IRExpr_ITE(mkexpr(t2),
   11482                                               IRExpr_ITE(mkexpr(t3),
   11483                                                          binop(Iop_Or32,
   11484                                                                getDSPControl(),
   11485                                                                binop(Iop_Shl32,
   11486                                                                   mkU32(0x1),
   11487                                                                   mkU8(ac+16))),
   11488                                                          getDSPControl()),
   11489                                               getDSPControl()));
   11490 
   11491                      assign(t5, binop(Iop_Shl64,
   11492                                       binop(Iop_MullS32,
   11493                                             unop(Iop_16Sto32,
   11494                                                  unop(Iop_32to16,
   11495                                                       getIReg(rs))),
   11496                                             unop(Iop_16Sto32,
   11497                                                  unop(Iop_32HIto16,
   11498                                                       getIReg(rt)))),
   11499                                       mkU8(0x1)));
   11500                      assign(t6, binop(Iop_CmpEQ32,
   11501                                       unop(Iop_16Uto32,
   11502                                            unop(Iop_32to16, getIReg(rs))),
   11503                                       mkU32(0x00008000)));
   11504                      assign(t7, binop(Iop_CmpEQ32,
   11505                                       unop(Iop_16Uto32,
   11506                                            unop(Iop_32HIto16, getIReg(rt))),
   11507                                       mkU32(0x00008000)));
   11508                      assign(t8,
   11509                             IRExpr_ITE(mkexpr(t6),
   11510                                        IRExpr_ITE(mkexpr(t7),
   11511                                                   mkU64(0x000000007fffffffULL),
   11512                                                   mkexpr(t5)),
   11513                                        mkexpr(t5)));
   11514 
   11515                      putDSPControl(IRExpr_ITE(mkexpr(t6),
   11516                                               IRExpr_ITE(mkexpr(t7),
   11517                                                          binop(Iop_Or32,
   11518                                                                getDSPControl(),
   11519                                                                binop(Iop_Shl32,
   11520                                                                      mkU32(0x1),
   11521                                                                      mkU8(ac+16)
   11522                                                                     )
   11523                                                               ),
   11524                                                          getDSPControl()),
   11525                                               getDSPControl()));
   11526 
   11527                      assign(t9, binop(Iop_Add64,
   11528                                       binop(Iop_Add64, mkexpr(t4), mkexpr(t8)),
   11529                                       mkexpr(t0)));
   11530                      putAcc(ac, mkexpr(t9));
   11531                      break;
   11532                   }
   11533                   case 0x19: {  /* DPSQX_S.W.PH */
   11534                      DIP("dpsqx_s.w.ph ac%u, r%u, r%u", ac, rs, rt);
   11535                      vassert(!mode64);
   11536                      t0 = newTemp(Ity_I64);
   11537                      t1 = newTemp(Ity_I64);
   11538                      t2 = newTemp(Ity_I1);
   11539                      t3 = newTemp(Ity_I1);
   11540                      t4 = newTemp(Ity_I64);
   11541                      t5 = newTemp(Ity_I64);
   11542                      t6 = newTemp(Ity_I1);
   11543                      t7 = newTemp(Ity_I1);
   11544                      t8 = newTemp(Ity_I64);
   11545                      t9 = newTemp(Ity_I64);
   11546 
   11547                      assign(t0, getAcc(ac));
   11548 
   11549                      assign(t1, binop(Iop_Shl64,
   11550                                       binop(Iop_MullS32,
   11551                                             unop(Iop_16Sto32,
   11552                                                  unop(Iop_32HIto16,
   11553                                                       getIReg(rs))),
   11554                                             unop(Iop_16Sto32,
   11555                                                  unop(Iop_32to16,
   11556                                                       getIReg(rt)))),
   11557                                       mkU8(0x1)));
   11558                      assign(t2, binop(Iop_CmpEQ32,
   11559                                       unop(Iop_16Uto32,
   11560                                            unop(Iop_32HIto16, getIReg(rs))),
   11561                                       mkU32(0x00008000)));
   11562                      assign(t3, binop(Iop_CmpEQ32,
   11563                                       unop(Iop_16Uto32,
   11564                                            unop(Iop_32to16, getIReg(rt))),
   11565                                       mkU32(0x00008000)));
   11566                      assign(t4,
   11567                             IRExpr_ITE(mkexpr(t2),
   11568                                        IRExpr_ITE(mkexpr(t3),
   11569                                                   mkU64(0x000000007fffffffULL),
   11570                                                   mkexpr(t1)),
   11571                                        mkexpr(t1)));
   11572 
   11573                      putDSPControl(IRExpr_ITE(mkexpr(t2),
   11574                                               IRExpr_ITE(mkexpr(t3),
   11575                                                          binop(Iop_Or32,
   11576                                                                getDSPControl(),
   11577                                                                binop(Iop_Shl32,
   11578                                                                      mkU32(0x1),
   11579                                                                      mkU8(ac+16)
   11580                                                                     )
   11581                                                               ),
   11582                                                          getDSPControl()),
   11583                                               getDSPControl()));
   11584 
   11585                      assign(t5, binop(Iop_Shl64,
   11586                                       binop(Iop_MullS32,
   11587                                             unop(Iop_16Sto32,
   11588                                                  unop(Iop_32to16,
   11589                                                       getIReg(rs))),
   11590                                             unop(Iop_16Sto32,
   11591                                                  unop(Iop_32HIto16,
   11592                                                       getIReg(rt)))),
   11593                                       mkU8(0x1)));
   11594                      assign(t6, binop(Iop_CmpEQ32,
   11595                                       unop(Iop_16Uto32,
   11596                                            unop(Iop_32to16, getIReg(rs))),
   11597                                       mkU32(0x00008000)));
   11598                      assign(t7, binop(Iop_CmpEQ32,
   11599                                       unop(Iop_16Uto32,
   11600                                            unop(Iop_32HIto16, getIReg(rt))),
   11601                                       mkU32(0x00008000)));
   11602                      assign(t8,
   11603                             IRExpr_ITE(mkexpr(t6),
   11604                                        IRExpr_ITE(mkexpr(t7),
   11605                                                   mkU64(0x000000007fffffffULL),
   11606                                                   mkexpr(t5)),
   11607                                        mkexpr(t5)));
   11608 
   11609                      putDSPControl(IRExpr_ITE(mkexpr(t6),
   11610                                               IRExpr_ITE(mkexpr(t7),
   11611                                                          binop(Iop_Or32,
   11612                                                                getDSPControl(),
   11613                                                                binop(Iop_Shl32,
   11614                                                                      mkU32(0x1),
   11615                                                                      mkU8(ac+16)
   11616                                                                     )
   11617                                                               ),
   11618                                                          getDSPControl()),
   11619                                               getDSPControl()));
   11620 
   11621                      assign(t9, binop(Iop_Sub64,
   11622                                      mkexpr(t0),
   11623                                      binop(Iop_Add64, mkexpr(t4), mkexpr(t8))));
   11624                      putAcc(ac, mkexpr(t9));
   11625                      break;
   11626                   }
   11627                   case 0x1A: {  /* DPAQX_SA.W.PH */
   11628                      DIP("dpaqx_sa.w.ph ac%u, r%u, r%u", ac, rs, rt);
   11629                      vassert(!mode64);
   11630                      t0 = newTemp(Ity_I64);
   11631                      t1 = newTemp(Ity_I64);
   11632                      t2 = newTemp(Ity_I1);
   11633                      t3 = newTemp(Ity_I1);
   11634                      t4 = newTemp(Ity_I64);
   11635                      t5 = newTemp(Ity_I64);
   11636                      t6 = newTemp(Ity_I1);
   11637                      t7 = newTemp(Ity_I1);
   11638                      t8 = newTemp(Ity_I64);
   11639                      t9 = newTemp(Ity_I64);
   11640                      t10 = newTemp(Ity_I32);
   11641 
   11642                      assign(t0, getAcc(ac));
   11643                      /* Calculate the first cross dot product and saturate if
   11644                         needed. */
   11645                      assign(t1, unop(Iop_32Sto64,
   11646                                      binop(Iop_Shl32,
   11647                                            binop(Iop_Mul32,
   11648                                                  unop(Iop_16Sto32,
   11649                                                       unop(Iop_32HIto16,
   11650                                                            getIReg(rs))),
   11651                                                  unop(Iop_16Sto32,
   11652                                                       unop(Iop_32to16,
   11653                                                            getIReg(rt)))),
   11654                                            mkU8(0x1))));
   11655 
   11656                      /* If both input arguments are equal 0x8000, saturate
   11657                         intermediate product and write to DSPControl
   11658                         register. */
   11659                      assign(t2, binop(Iop_CmpEQ32,
   11660                                       unop(Iop_16Uto32,
   11661                                            unop(Iop_32HIto16, getIReg(rs))),
   11662                                       mkU32(0x00008000)));
   11663                      assign(t3, binop(Iop_CmpEQ32,
   11664                                       unop(Iop_16Uto32,
   11665                                            unop(Iop_32to16, getIReg(rt))),
   11666                                       mkU32(0x00008000)));
   11667 
   11668                      assign(t4, IRExpr_ITE(binop(Iop_CmpNE32,
   11669                                                  binop(Iop_And32,
   11670                                                        unop(Iop_1Sto32,
   11671                                                             mkexpr(t2)),
   11672                                                        unop(Iop_1Sto32,
   11673                                                             mkexpr(t3))),
   11674                                                  mkU32(0)),
   11675                                            mkU64(0x000000007fffffffULL),
   11676                                            mkexpr(t1)));
   11677 
   11678                      putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32,
   11679                                                     binop(Iop_And32,
   11680                                                           unop(Iop_1Sto32,
   11681                                                                mkexpr(t2)),
   11682                                                           unop(Iop_1Sto32,
   11683                                                                mkexpr(t3))),
   11684                                                     mkU32(0)),
   11685                                               binop(Iop_Or32,
   11686                                                     getDSPControl(),
   11687                                                     binop(Iop_Shl32,
   11688                                                           mkU32(0x1),
   11689                                                           mkU8(ac+16))),
   11690                                               getDSPControl()));
   11691                      /* Calculate second cross dot product and saturate if
   11692                         needed. */
   11693                      assign(t5, unop(Iop_32Sto64,
   11694                                      binop(Iop_Shl32,
   11695                                            binop(Iop_Mul32,
   11696                                                  unop(Iop_16Sto32,
   11697                                                       unop(Iop_32to16,
   11698                                                            getIReg(rs))),
   11699                                                  unop(Iop_16Sto32,
   11700                                                       unop(Iop_32HIto16,
   11701                                                            getIReg(rt)))),
   11702                                            mkU8(0x1))));
   11703 
   11704                      /* If both input arguments are equal 0x8000, saturate
   11705                         intermediate product and write to DSPControl
   11706                         register. */
   11707                      assign(t6, binop(Iop_CmpEQ32,
   11708                                       unop(Iop_16Uto32,
   11709                                            unop(Iop_32to16, getIReg(rs))),
   11710                                       mkU32(0x00008000)));
   11711                      assign(t7, binop(Iop_CmpEQ32,
   11712                                       unop(Iop_16Uto32,
   11713                                            unop(Iop_32HIto16, getIReg(rt))),
   11714                                       mkU32(0x00008000)));
   11715 
   11716                      assign(t8, IRExpr_ITE(binop(Iop_CmpNE32,
   11717                                                  binop(Iop_And32,
   11718                                                        unop(Iop_1Sto32,
   11719                                                             mkexpr(t6)),
   11720                                                        unop(Iop_1Sto32,
   11721                                                             mkexpr(t7))),
   11722                                                  mkU32(0)),
   11723                                            mkU64(0x000000007fffffffULL),
   11724                                            mkexpr(t5)));
   11725 
   11726                      putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32,
   11727                                                     binop(Iop_And32,
   11728                                                           unop(Iop_1Sto32,
   11729                                                                mkexpr(t6)),
   11730                                                           unop(Iop_1Sto32,
   11731                                                                mkexpr(t7))),
   11732                                                     mkU32(0)),
   11733                                               binop(Iop_Or32,
   11734                                                     getDSPControl(),
   11735                                                     binop(Iop_Shl32,
   11736                                                           mkU32(0x1),
   11737                                                           mkU8(ac+16))),
   11738                                               getDSPControl()));
   11739                      /* Subtract intermediate products from value in the
   11740                         accumulator. */
   11741                      assign(t9,
   11742                             binop(Iop_Add64,
   11743                                   mkexpr(t0),
   11744                                   binop(Iop_Add64, mkexpr(t8), mkexpr(t4))));
   11745 
   11746                      putAcc(ac,
   11747                             IRExpr_ITE(binop(Iop_CmpEQ32,
   11748                                              binop(Iop_And32,
   11749                                                    unop(Iop_64HIto32,
   11750                                                         mkexpr(t9)),
   11751                                                    mkU32(0x80000000)),
   11752                                              mkU32(0x0)),
   11753                                        IRExpr_ITE(binop(Iop_CmpNE32,
   11754                                                         unop(Iop_64HIto32,
   11755                                                              binop(Iop_Shl64,
   11756                                                                    mkexpr(t9),
   11757                                                                    mkU8(1))),
   11758                                                         mkU32(0x0)),
   11759                                                   mkU64(0x000000007fffffffULL),
   11760                                                   mkexpr(t9)),
   11761                                        IRExpr_ITE(binop(Iop_CmpNE32,
   11762                                                         unop(Iop_64HIto32,
   11763                                                              binop(Iop_Shl64,
   11764                                                                    mkexpr(t9),
   11765                                                                    mkU8(1))),
   11766                                                         mkU32(0xffffffff)),
   11767                                                   mkU64(0xffffffff80000000ULL),
   11768                                                   mkexpr(t9))));
   11769                      assign(t10, IRExpr_ITE(binop(Iop_CmpEQ32,
   11770                                                   unop(Iop_64to32,
   11771                                                        mkexpr(t9)),
   11772                                                   unop(Iop_64to32,
   11773                                                        getAcc(ac))),
   11774                                            getDSPControl(),
   11775                                            binop(Iop_Or32,
   11776                                                  getDSPControl(),
   11777                                                  binop(Iop_Shl32,
   11778                                                        mkU32(0x1),
   11779                                                        mkU8(ac+16)))));
   11780                      putDSPControl(IRExpr_ITE(binop(Iop_CmpEQ32,
   11781                                                     unop(Iop_64HIto32,
   11782                                                          mkexpr(t9)),
   11783                                                     unop(Iop_64HIto32,
   11784                                                          getAcc(ac))),
   11785                                               mkexpr(t10),
   11786                                               binop(Iop_Or32,
   11787                                                     getDSPControl(),
   11788                                                     binop(Iop_Shl32,
   11789                                                           mkU32(0x1),
   11790                                                           mkU8(ac+16)))));
   11791                      break;
   11792                   }
   11793                   case 0x1B: {  /* DPSQX_SA.W.PH */
   11794                      DIP("dpsqx_sa.w.ph ac%u, r%u, r%u", ac, rs, rt);
   11795                      vassert(!mode64);
   11796                      t0 = newTemp(Ity_I64);
   11797                      t1 = newTemp(Ity_I64);
   11798                      t2 = newTemp(Ity_I1);
   11799                      t3 = newTemp(Ity_I1);
   11800                      t4 = newTemp(Ity_I64);
   11801                      t5 = newTemp(Ity_I64);
   11802                      t6 = newTemp(Ity_I1);
   11803                      t7 = newTemp(Ity_I1);
   11804                      t8 = newTemp(Ity_I64);
   11805                      t9 = newTemp(Ity_I64);
   11806                      t10 = newTemp(Ity_I32);
   11807 
   11808                      assign(t0, getAcc(ac));
   11809                      /* Calculate the first cross dot product and saturate if
   11810                         needed. */
   11811                      assign(t1, unop(Iop_32Sto64,
   11812                                      binop(Iop_Shl32,
   11813                                            binop(Iop_Mul32,
   11814                                                  unop(Iop_16Sto32,
   11815                                                       unop(Iop_32HIto16,
   11816                                                            getIReg(rs))),
   11817                                                  unop(Iop_16Sto32,
   11818                                                       unop(Iop_32to16,
   11819                                                            getIReg(rt)))),
   11820                                            mkU8(0x1))));
   11821 
   11822                      /* If both input arguments are equal 0x8000, saturate
   11823                         intermediate product and write to DSPControl
   11824                         register. */
   11825                      assign(t2, binop(Iop_CmpEQ32,
   11826                                       unop(Iop_16Uto32,
   11827                                            unop(Iop_32HIto16, getIReg(rs))),
   11828                                       mkU32(0x00008000)));
   11829                      assign(t3, binop(Iop_CmpEQ32,
   11830                                       unop(Iop_16Uto32,
   11831                                            unop(Iop_32to16, getIReg(rt))),
   11832                                       mkU32(0x00008000)));
   11833 
   11834                      assign(t4, IRExpr_ITE(binop(Iop_CmpNE32,
   11835                                                  binop(Iop_And32,
   11836                                                        unop(Iop_1Sto32,
   11837                                                             mkexpr(t2)),
   11838                                                        unop(Iop_1Sto32,
   11839                                                             mkexpr(t3))),
   11840                                                  mkU32(0)),
   11841                                            mkU64(0x000000007fffffffULL),
   11842                                            mkexpr(t1)));
   11843 
   11844                      putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32,
   11845                                                     binop(Iop_And32,
   11846                                                           unop(Iop_1Sto32,
   11847                                                                mkexpr(t2)),
   11848                                                           unop(Iop_1Sto32,
   11849                                                                mkexpr(t3))),
   11850                                                     mkU32(0)),
   11851                                               binop(Iop_Or32,
   11852                                                     getDSPControl(),
   11853                                                     binop(Iop_Shl32,
   11854                                                           mkU32(0x1),
   11855                                                           mkU8(ac+16))),
   11856                                               getDSPControl()));
   11857                      /* Calculate second cross dot product and saturate if
   11858                         needed. */
   11859                      assign(t5, unop(Iop_32Sto64,
   11860                                      binop(Iop_Shl32,
   11861                                            binop(Iop_Mul32,
   11862                                                  unop(Iop_16Sto32,
   11863                                                       unop(Iop_32to16,
   11864                                                            getIReg(rs))),
   11865                                                  unop(Iop_16Sto32,
   11866                                                       unop(Iop_32HIto16,
   11867                                                            getIReg(rt)))),
   11868                                            mkU8(0x1))));
   11869 
   11870                      /* If both input arguments are equal 0x8000, saturate
   11871                         intermediate product and write to DSPControl
   11872                         register. */
   11873                      assign(t6, binop(Iop_CmpEQ32,
   11874                                       unop(Iop_16Uto32,
   11875                                            unop(Iop_32to16, getIReg(rs))),
   11876                                       mkU32(0x00008000)));
   11877                      assign(t7, binop(Iop_CmpEQ32,
   11878                                       unop(Iop_16Uto32,
   11879                                            unop(Iop_32HIto16, getIReg(rt))),
   11880                                       mkU32(0x00008000)));
   11881 
   11882                      assign(t8, IRExpr_ITE(binop(Iop_CmpNE32,
   11883                                                  binop(Iop_And32,
   11884                                                        unop(Iop_1Sto32,
   11885                                                             mkexpr(t6)),
   11886                                                        unop(Iop_1Sto32,
   11887                                                             mkexpr(t7))),
   11888                                                  mkU32(0)),
   11889                                            mkU64(0x000000007fffffffULL),
   11890                                            mkexpr(t5)));
   11891 
   11892                      putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32,
   11893                                                     binop(Iop_And32,
   11894                                                           unop(Iop_1Sto32,
   11895                                                                mkexpr(t6)),
   11896                                                           unop(Iop_1Sto32,
   11897                                                                mkexpr(t7))),
   11898                                                     mkU32(0)),
   11899                                               binop(Iop_Or32,
   11900                                                     getDSPControl(),
   11901                                                     binop(Iop_Shl32,
   11902                                                           mkU32(0x1),
   11903                                                           mkU8(ac+16))),
   11904                                               getDSPControl()));
   11905                      /* Subtract intermediate products from value in the
   11906                         accumulator. */
   11907                      assign(t9,
   11908                             binop(Iop_Sub64,
   11909                                   mkexpr(t0),
   11910                                   binop(Iop_Add64, mkexpr(t8), mkexpr(t4))));
   11911 
   11912                      putAcc(ac,
   11913                             IRExpr_ITE(binop(Iop_CmpEQ32,
   11914                                              binop(Iop_And32,
   11915                                                    unop(Iop_64HIto32,
   11916                                                         mkexpr(t9)),
   11917                                                    mkU32(0x80000000)),
   11918                                              mkU32(0x0)),
   11919                                        IRExpr_ITE(binop(Iop_CmpNE32,
   11920                                                         unop(Iop_64HIto32,
   11921                                                              binop(Iop_Shl64,
   11922                                                                    mkexpr(t9),
   11923                                                                    mkU8(1))),
   11924                                                         mkU32(0x0)),
   11925                                                   mkU64(0x000000007fffffffULL),
   11926                                                   mkexpr(t9)),
   11927                                        IRExpr_ITE(binop(Iop_CmpNE32,
   11928                                                         unop(Iop_64HIto32,
   11929                                                              binop(Iop_Shl64,
   11930                                                                    mkexpr(t9),
   11931                                                                    mkU8(1))),
   11932                                                         mkU32(0xffffffff)),
   11933                                                   mkU64(0xffffffff80000000ULL),
   11934                                                   mkexpr(t9))));
   11935                      assign(t10, IRExpr_ITE(binop(Iop_CmpEQ32,
   11936                                                   unop(Iop_64to32,
   11937                                                        mkexpr(t9)),
   11938                                                   unop(Iop_64to32,
   11939                                                        getAcc(ac))),
   11940                                            getDSPControl(),
   11941                                            binop(Iop_Or32,
   11942                                                  getDSPControl(),
   11943                                                  binop(Iop_Shl32,
   11944                                                        mkU32(0x1),
   11945                                                        mkU8(ac+16)))));
   11946                      putDSPControl(IRExpr_ITE(binop(Iop_CmpEQ32,
   11947                                                     unop(Iop_64HIto32,
   11948                                                          mkexpr(t9)),
   11949                                                     unop(Iop_64HIto32,
   11950                                                          getAcc(ac))),
   11951                                               mkexpr(t10),
   11952                                               binop(Iop_Or32,
   11953                                                     getDSPControl(),
   11954                                                     binop(Iop_Shl32,
   11955                                                           mkU32(0x1),
   11956                                                           mkU8(ac+16)))));
   11957                      break;
   11958                   }
   11959                   default:
   11960                      return -1;
   11961                }
   11962                break;  /* end of DPAQ.W.PH */
   11963             }
   11964             case 0x31: {  /* APPEND */
   11965                switch(sa) {
   11966                   case 0x0: {  /* APPEND */
   11967                      DIP("append r%u, r%u, %u", rt, rs, rd);
   11968                      vassert(!mode64);
   11969                      t1 = newTemp(Ity_I32);
   11970                      t2 = newTemp(Ity_I32);
   11971                      t3 = newTemp(Ity_I32);
   11972 
   11973                      assign(t1, binop(Iop_Shl32, getIReg(rt), mkU8(rd)));
   11974 
   11975                      if (31 == rd) {
   11976                         putIReg(rt, binop(Iop_Or32,
   11977                                           mkexpr(t1),
   11978                                           binop(Iop_And32,
   11979                                                 getIReg(rs),
   11980                                                 mkU32(0x7fffffff))));
   11981                      } else if (1 == rd) {
   11982                         putIReg(rt,
   11983                                 binop(Iop_Or32,
   11984                                       mkexpr(t1),
   11985                                       binop(Iop_And32,
   11986                                             getIReg(rs), mkU32(0x1))));
   11987                      } else {
   11988                         assign(t2,
   11989                                unop(Iop_Not32,
   11990                                     binop(Iop_Shl32,
   11991                                           mkU32(0xffffffff), mkU8(rd))));
   11992 
   11993                         putIReg(rt, binop(Iop_Or32,
   11994                                           mkexpr(t1),
   11995                                           binop(Iop_And32,
   11996                                                 getIReg(rs), mkexpr(t2))));
   11997                      }
   11998                      break;
   11999                   }
   12000                   case 0x1: {  /* PREPEND */
   12001                      DIP("prepend r%u, r%u, %u", rt, rs, rd);
   12002                      vassert(!mode64);
   12003                      t1 = newTemp(Ity_I32);
   12004                      t2 = newTemp(Ity_I32);
   12005                      t3 = newTemp(Ity_I32);
   12006 
   12007                      if (0 != rd) {
   12008                         assign(t1, binop(Iop_Shr32, getIReg(rt), mkU8(rd)));
   12009 
   12010                         if (31 == rd) {
   12011                            putIReg(rt, binop(Iop_Or32,
   12012                                              mkexpr(t1),
   12013                                              binop(Iop_Shl32,
   12014                                                    binop(Iop_And32,
   12015                                                          getIReg(rs),
   12016                                                          mkU32(0x7fffffff)),
   12017                                                    mkU8(1))));
   12018                         } else if (1 == rd) {
   12019                            putIReg(rt, binop(Iop_Or32,
   12020                                              mkexpr(t1),
   12021                                              binop(Iop_Shl32,
   12022                                                    binop(Iop_And32,
   12023                                                          getIReg(rs),
   12024                                                          mkU32(0x1)),
   12025                                                    mkU8(31))));
   12026                         } else {
   12027                            assign(t2, binop(Iop_Add32, mkU32(rd), mkU32(0x1)));
   12028 
   12029                            assign(t3, unop(Iop_Not32,
   12030                                            binop(Iop_Shl32,
   12031                                                  mkU32(0xffffffff),
   12032                                                  unop(Iop_32to8, mkexpr(t2)))));
   12033 
   12034                            putIReg(rt, binop(Iop_Or32,
   12035                                              mkexpr(t1),
   12036                                              binop(Iop_Shl32,
   12037                                                    binop(Iop_And32,
   12038                                                          getIReg(rs),
   12039                                                          mkexpr(t3)),
   12040                                                    mkU8(32-rd))));
   12041                         }
   12042                      }
   12043                      break;
   12044                   }
   12045                   case 0x10: {  /* BALIGN */
   12046                      DIP("balign r%u, r%u, %u", rt, rs, rd);
   12047                      vassert(!mode64);
   12048                      t1 = newTemp(Ity_I32);
   12049                      t2 = newTemp(Ity_I32);
   12050                      t3 = newTemp(Ity_I32);
   12051 
   12052                      if ((2 != rd) && (0 != rd)) {
   12053                         assign(t1, binop(Iop_Shl32,
   12054                                          binop(Iop_And32,
   12055                                                mkU32(rd), mkU32(0x3)),
   12056                                          mkU8(0x3)));
   12057                         assign(t2, binop(Iop_Shl32,
   12058                                          getIReg(rt),
   12059                                          unop(Iop_32to8, mkexpr(t1))));
   12060                         assign(t3, binop(Iop_Shr32,
   12061                                          getIReg(rs),
   12062                                          unop(Iop_32to8,
   12063                                               binop(Iop_Shl32,
   12064                                                     binop(Iop_Sub32,
   12065                                                           mkU32(0x4),
   12066                                                           binop(Iop_And32,
   12067                                                                 mkU32(rd),
   12068                                                                 mkU32(0x3))),
   12069                                                     mkU8(0x3)))));
   12070                         putIReg(rt, binop(Iop_Or32, mkexpr(t2), mkexpr(t3)));
   12071                      }
   12072                      break;
   12073                   }
   12074                   default:
   12075                      return -1;
   12076                }
   12077                break;  /* end of APPEND */
   12078             }
   12079             default:
   12080                return -1;
   12081          }
   12082          break;
   12083       }
   12084       default:
   12085             return -1;
   12086    }
   12087    return 0;
   12088 }
   12089 
   12090 /*------------------------------------------------------------*/
   12091 /*---          Disassemble a single instruction            ---*/
   12092 /*------------------------------------------------------------*/
   12093 
   12094 /* Disassemble a single instruction into IR. The instruction is
   12095    located in host memory at guest_instr, and has guest IP of
   12096    guest_PC_curr_instr, which will have been set before the call
   12097    here. */
   12098 
   12099 static DisResult disInstr_MIPS_WRK ( Bool(*resteerOkFn) (/*opaque */void *,
   12100                                                                     Addr),
   12101                                      Bool         resteerCisOk,
   12102                                      void*        callback_opaque,
   12103                                      Long         delta64,
   12104                                      const VexArchInfo* archinfo,
   12105                                      const VexAbiInfo*  abiinfo,
   12106                                      Bool         sigill_diag )
   12107 {
   12108    IRTemp t0, t1 = 0, t2, t3, t4, t5, t6, t7;
   12109 
   12110    UInt opcode, cins, rs, rt, rd, sa, ft, fs, fd, fmt, tf, nd, function,
   12111         trap_code, imm, instr_index, p, msb, lsb, size, rot, sel;
   12112    /* Additional variables for instruction fields in DSP ASE insructions */
   12113    UInt ac;
   12114 
   12115    DisResult dres;
   12116 
   12117    static IRExpr *lastn = NULL;  /* last jump addr */
   12118    static IRStmt *bstmt = NULL;  /* branch (Exit) stmt */
   12119 
   12120    /* The running delta */
   12121    Int delta = (Int) delta64;
   12122 
   12123    /* Holds eip at the start of the insn, so that we can print
   12124       consistent error messages for unimplemented insns. */
   12125    Int delta_start = delta;
   12126 
   12127    /* Are we in a delay slot ? */
   12128    Bool delay_slot_branch, likely_delay_slot, delay_slot_jump;
   12129 
   12130    /* Set result defaults. */
   12131    dres.whatNext = Dis_Continue;
   12132    dres.len = 0;
   12133    dres.continueAt = 0;
   12134    dres.jk_StopHere = Ijk_INVALID;
   12135    dres.hint        = Dis_HintNone;
   12136 
   12137    delay_slot_branch = likely_delay_slot = delay_slot_jump = False;
   12138 
   12139    const UChar *code = guest_code + delta;
   12140    cins = getUInt(code);
   12141    DIP("\t0x%llx:\t0x%08x\t", (Addr64)guest_PC_curr_instr, cins);
   12142 
   12143    if (delta != 0) {
   12144       if (branch_or_jump(guest_code + delta - 4)) {
   12145          if (lastn == NULL && bstmt == NULL) {
   12146             vassert(0);
   12147          } else {
   12148             dres.whatNext = Dis_StopHere;
   12149             if (lastn != NULL) {
   12150                delay_slot_jump = True;
   12151             } else if (bstmt != NULL) {
   12152                delay_slot_branch = True;
   12153             }
   12154          }
   12155       }
   12156 
   12157       if (branch_or_link_likely(guest_code + delta - 4)) {
   12158          likely_delay_slot = True;
   12159       }
   12160    }
   12161 
   12162    /* Spot "Special" instructions (see comment at top of file). */
   12163    {
   12164       /* Spot the 16-byte preamble:
   12165        ****mips32****
   12166        "srl $0, $0, 13
   12167        "srl $0, $0, 29
   12168        "srl $0, $0, 3
   12169        "srl $0, $0, 19
   12170 
   12171        ****mips64****
   12172        dsll $0, $0, 3
   12173        dsll $0, $0, 13
   12174        dsll $0, $0, 29
   12175        dsll $0, $0, 19 */
   12176 
   12177       UInt word1 = mode64 ? 0xF8  : 0x342;
   12178       UInt word2 = mode64 ? 0x378 : 0x742;
   12179       UInt word3 = mode64 ? 0x778 : 0xC2;
   12180       UInt word4 = mode64 ? 0x4F8 : 0x4C2;
   12181       if (getUInt(code + 0) == word1 && getUInt(code + 4) == word2 &&
   12182           getUInt(code + 8) == word3 && getUInt(code + 12) == word4) {
   12183          /* Got a "Special" instruction preamble. Which one is it? */
   12184          if (getUInt(code + 16) == 0x01ad6825 /* or $13, $13, $13 */ ) {
   12185             /* $11 = client_request ( $12 ) */
   12186             DIP("$11 = client_request ( $12 )");
   12187             if (mode64)
   12188                putPC(mkU64(guest_PC_curr_instr + 20));
   12189             else
   12190                putPC(mkU32(guest_PC_curr_instr + 20));
   12191             dres.jk_StopHere = Ijk_ClientReq;
   12192             dres.whatNext    = Dis_StopHere;
   12193 
   12194             goto decode_success;
   12195          } else if (getUInt(code + 16) == 0x01ce7025 /* or $14, $14, $14 */ ) {
   12196             /* $11 = guest_NRADDR */
   12197             DIP("$11 = guest_NRADDR");
   12198             dres.len = 20;
   12199             delta += 20;
   12200             if (mode64)
   12201                putIReg(11, IRExpr_Get(offsetof(VexGuestMIPS64State,
   12202                                                guest_NRADDR), Ity_I64));
   12203             else
   12204                putIReg(11, IRExpr_Get(offsetof(VexGuestMIPS32State,
   12205                                                guest_NRADDR), Ity_I32));
   12206             goto decode_success;
   12207          } else if (getUInt(code + 16) == 0x01ef7825 /* or $15, $15, $15 */ ) {
   12208             /*  branch-and-link-to-noredir $25 */
   12209             DIP("branch-and-link-to-noredir $25");
   12210             if (mode64)
   12211                putIReg(31, mkU64(guest_PC_curr_instr + 20));
   12212             else
   12213                putIReg(31, mkU32(guest_PC_curr_instr + 20));
   12214             putPC(getIReg(25));
   12215             dres.jk_StopHere = Ijk_NoRedir;
   12216             dres.whatNext    = Dis_StopHere;
   12217             goto decode_success;
   12218          } else if (getUInt(code + 16) == 0x016b5825 /* or $11,$11,$11 */ ) {
   12219            /* IR injection */
   12220             DIP("IR injection");
   12221 #if defined (_MIPSEL)
   12222             vex_inject_ir(irsb, Iend_LE);
   12223 #elif defined (_MIPSEB)
   12224             vex_inject_ir(irsb, Iend_BE);
   12225 #endif
   12226             if (mode64) {
   12227                stmt(IRStmt_Put(offsetof(VexGuestMIPS64State, guest_CMSTART),
   12228                                mkU64(guest_PC_curr_instr)));
   12229                stmt(IRStmt_Put(offsetof(VexGuestMIPS64State, guest_CMLEN),
   12230                                mkU64(20)));
   12231 
   12232                putPC(mkU64(guest_PC_curr_instr + 20));
   12233             } else {
   12234                stmt(IRStmt_Put(offsetof(VexGuestMIPS32State, guest_CMSTART),
   12235                                mkU32(guest_PC_curr_instr)));
   12236                stmt(IRStmt_Put(offsetof(VexGuestMIPS32State, guest_CMLEN),
   12237                                mkU32(20)));
   12238 
   12239                putPC(mkU32(guest_PC_curr_instr + 20));
   12240             }
   12241             dres.whatNext    = Dis_StopHere;
   12242             dres.jk_StopHere = Ijk_InvalICache;
   12243             dres.len = 20;
   12244             delta += 20;
   12245             goto decode_success;
   12246          }
   12247 
   12248          /* We don't know what it is.  Set opc1/opc2 so decode_failure
   12249             can print the insn following the Special-insn preamble. */
   12250          delta += 16;
   12251          goto decode_failure;
   12252        /*NOTREACHED*/}
   12253    }
   12254 
   12255    opcode = get_opcode(cins);
   12256    imm = get_imm(cins);
   12257    rs = get_rs(cins);
   12258    rt = get_rt(cins);
   12259    rd = get_rd(cins);
   12260    sa = get_sa(cins);
   12261    fs = get_fs(cins);
   12262    fd = get_fd(cins);
   12263    ft = get_ft(cins);
   12264    tf = get_tf(cins);
   12265    nd = get_nd(cins);
   12266    sel = get_sel(cins);
   12267    fmt = get_fmt(cins);
   12268    instr_index = get_instr_index(cins);
   12269    trap_code = get_code(cins);
   12270    function = get_function(cins);
   12271    IRType ty = mode64 ? Ity_I64 : Ity_I32;
   12272    IRType tyF = fp_mode64 ? Ity_F64 : Ity_F32;
   12273 
   12274    ac = get_acNo(cins);
   12275 
   12276    switch (opcode) {
   12277 
   12278    case 0x03:     /* JAL */
   12279       DIP("jal 0x%x", instr_index);
   12280       if (mode64) {
   12281          putIReg(31, mkU64(guest_PC_curr_instr + 8));
   12282          t0 = newTemp(ty);
   12283          assign(t0, mkU64((guest_PC_curr_instr & 0xFFFFFFFFF0000000ULL) |
   12284                           (instr_index << 2)));
   12285       } else {
   12286          putIReg(31, mkU32(guest_PC_curr_instr + 8));
   12287          t0 = newTemp(ty);
   12288          assign(t0, mkU32((guest_PC_curr_instr & 0xF0000000) |
   12289                           (instr_index << 2)));
   12290       }
   12291       lastn = mkexpr(t0);
   12292       break;
   12293    case 0x02:     /* J */
   12294       DIP("j 0x%x", instr_index);
   12295       t0 = newTemp(ty);
   12296       if (mode64)
   12297          assign(t0, mkU64((guest_PC_curr_instr & 0xFFFFFFFFF0000000ULL) |
   12298                           (instr_index << 2)));
   12299       else
   12300          assign(t0, mkU32((guest_PC_curr_instr & 0xF0000000) |
   12301                           (instr_index << 2)));
   12302       lastn = mkexpr(t0);
   12303       break;
   12304 
   12305    case 0x11: {  /* COP1 */
   12306       if (fmt == 0x3 && fd == 0 && function == 0) {  /* MFHC1 */
   12307          DIP("mfhc1 r%u, f%u", rt, fs);
   12308          if (VEX_MIPS_CPU_HAS_MIPS32R2(archinfo->hwcaps)) {
   12309             if (fp_mode64) {
   12310                t0 = newTemp(Ity_I64);
   12311                t1 = newTemp(Ity_I32);
   12312                assign(t0, unop(Iop_ReinterpF64asI64, getDReg(fs)));
   12313                assign(t1, unop(Iop_64HIto32, mkexpr(t0)));
   12314                putIReg(rt, mkWidenFrom32(ty, mkexpr(t1), True));
   12315                break;
   12316             } else {
   12317                putIReg(rt, mkWidenFrom32(ty, unop(Iop_ReinterpF32asI32,
   12318                                                   getFReg(fs | 1)), True));
   12319                break;
   12320             }
   12321          }
   12322          ILLEGAL_INSTRUCTON;
   12323          break;
   12324       } else if (fmt == 0x7 && fd == 0 && function == 0) {  /* MTHC1 */
   12325          DIP("mthc1 r%u, f%u", rt, fs);
   12326          if (VEX_MIPS_CPU_HAS_MIPS32R2(archinfo->hwcaps)) {
   12327             if (fp_mode64) {
   12328                t0 = newTemp(Ity_I64);
   12329                assign(t0, binop(Iop_32HLto64, mkNarrowTo32(ty, getIReg(rt)),
   12330                                 unop(Iop_ReinterpF32asI32,
   12331                                      getLoFromF64(Ity_F64, getDReg(fs)))));
   12332                putDReg(fs, unop(Iop_ReinterpI64asF64, mkexpr(t0)));
   12333                break;
   12334             } else {
   12335                putFReg(fs | 1, unop(Iop_ReinterpI32asF32,
   12336                                     mkNarrowTo32(ty, getIReg(rt))));
   12337                break;
   12338             }
   12339          }
   12340          ILLEGAL_INSTRUCTON;
   12341          break;
   12342       } else if (fmt == 0x8) {  /* BC */
   12343          /* FcConditionalCode(bc1_cc) */
   12344          UInt bc1_cc = get_bc1_cc(cins);
   12345          t1 = newTemp(Ity_I1);
   12346          t2 = newTemp(Ity_I32);
   12347          t3 = newTemp(Ity_I1);
   12348 
   12349          assign(t1, binop(Iop_CmpEQ32, mkU32(0), mkU32(bc1_cc)));
   12350          assign(t2, IRExpr_ITE(mkexpr(t1),
   12351                                binop(Iop_And32,
   12352                                      binop(Iop_Shr32, getFCSR(), mkU8(23)),
   12353                                      mkU32(0x1)),
   12354                                binop(Iop_And32,
   12355                                      binop(Iop_Shr32, getFCSR(),
   12356                                            mkU8(24 + bc1_cc)),
   12357                                      mkU32(0x1))));
   12358 
   12359          if (tf == 1 && nd == 0) {
   12360             /* branch on true */
   12361             DIP("bc1t %u, %u", bc1_cc, imm);
   12362             assign(t3, binop(Iop_CmpEQ32, mkU32(1), mkexpr(t2)));
   12363             dis_branch(False, mkexpr(t3), imm, &bstmt);
   12364             break;
   12365          } else if (tf == 0 && nd == 0) {
   12366             /* branch on false */
   12367             DIP("bc1f %u, %u", bc1_cc, imm);
   12368             assign(t3, binop(Iop_CmpEQ32, mkU32(0), mkexpr(t2)));
   12369             dis_branch(False, mkexpr(t3), imm, &bstmt);
   12370             break;
   12371          } else if (nd == 1 && tf == 0) {
   12372             DIP("bc1fl %u, %u", bc1_cc, imm);
   12373             lastn = dis_branch_likely(binop(Iop_CmpNE32, mkexpr(t2),
   12374                                             mkU32(0x0)), imm);
   12375             break;
   12376          } else if (nd == 1 && tf == 1) {
   12377             DIP("bc1tl %u, %u", bc1_cc, imm);
   12378             lastn = dis_branch_likely(binop(Iop_CmpEQ32, mkexpr(t2),
   12379                                             mkU32(0x0)), imm);
   12380             break;
   12381          } else
   12382             goto decode_failure;
   12383       } else {
   12384          switch (function) {
   12385             case 0x4: {  /* SQRT.fmt */
   12386                switch (fmt) {
   12387                   case 0x10: {  /* S */
   12388                      IRExpr *rm = get_IR_roundingmode();
   12389                      putFReg(fd, mkWidenFromF32(tyF, binop(Iop_SqrtF32, rm,
   12390                                  getLoFromF64(tyF, getFReg(fs)))));
   12391                      break;
   12392                   }
   12393                   case 0x11: {  /* D */
   12394                      IRExpr *rm = get_IR_roundingmode();
   12395                      putDReg(fd, binop(Iop_SqrtF64, rm, getDReg(fs)));
   12396                      break;
   12397                   }
   12398                   default:
   12399                      goto decode_failure;
   12400                   }
   12401                }
   12402                break;
   12403             case 0x5:  /* abs.fmt */
   12404                switch (fmt) {
   12405                   case 0x10:  /* S */
   12406                      DIP("abs.s f%u, f%u", fd, fs);
   12407                      putFReg(fd, mkWidenFromF32(tyF, unop(Iop_AbsF32,
   12408                                  getLoFromF64(tyF, getFReg(fs)))));
   12409                      break;
   12410                   case 0x11:  /* D  */
   12411                      DIP("abs.d f%u, f%u", fd, fs);
   12412                      putDReg(fd, unop(Iop_AbsF64, getDReg(fs)));
   12413                      break;
   12414                   default:
   12415                      goto decode_failure;
   12416                }
   12417                break;  /* case 0x5 */
   12418 
   12419             case 0x02:  /* MUL.fmt */
   12420                switch (fmt) {
   12421                   case 0x11: {  /* D */
   12422                      DIP("mul.d f%u, f%u, f%u", fd, fs, ft);
   12423                      IRExpr *rm = get_IR_roundingmode();
   12424                      putDReg(fd, triop(Iop_MulF64, rm, getDReg(fs),
   12425                                        getDReg(ft)));
   12426                      break;
   12427                   }
   12428                   case 0x10: {  /* S */
   12429                      DIP("mul.s f%u, f%u, f%u", fd, fs, ft);
   12430                      IRExpr *rm = get_IR_roundingmode();
   12431                      putFReg(fd, mkWidenFromF32(tyF, triop(Iop_MulF32, rm,
   12432                                  getLoFromF64(tyF, getFReg(fs)),
   12433                                  getLoFromF64(tyF, getFReg(ft)))));
   12434                      break;
   12435                   }
   12436                   default:
   12437                      goto decode_failure;
   12438                }
   12439                break;  /* MUL.fmt */
   12440 
   12441             case 0x03:  /* DIV.fmt */
   12442                switch (fmt) {
   12443                   case 0x11: {  /* D */
   12444                      DIP("div.d f%u, f%u, f%u", fd, fs, ft);
   12445                      IRExpr *rm = get_IR_roundingmode();
   12446                      putDReg(fd, triop(Iop_DivF64, rm, getDReg(fs),
   12447                                  getDReg(ft)));
   12448                      break;
   12449                   }
   12450                   case 0x10: {  /* S */
   12451                      DIP("div.s f%u, f%u, f%u", fd, fs, ft);
   12452                      calculateFCSR(fs, ft, DIVS, False, 2);
   12453                      IRExpr *rm = get_IR_roundingmode();
   12454                      putFReg(fd, mkWidenFromF32(tyF, triop(Iop_DivF32, rm,
   12455                                  getLoFromF64(tyF, getFReg(fs)),
   12456                                  getLoFromF64(tyF, getFReg(ft)))));
   12457                      break;
   12458                   }
   12459                   default:
   12460                      goto decode_failure;
   12461                }
   12462                break;  /* DIV.fmt */
   12463 
   12464             case 0x01:  /* SUB.fmt */
   12465                switch (fmt) {
   12466                   case 0x11: {  /* D */
   12467                      DIP("sub.d f%u, f%u, f%u", fd, fs, ft);
   12468                      calculateFCSR(fs, ft, SUBD, False, 2);
   12469                      IRExpr *rm = get_IR_roundingmode();
   12470                      putDReg(fd, triop(Iop_SubF64, rm, getDReg(fs),
   12471                                        getDReg(ft)));
   12472                      break;
   12473                   }
   12474                   case 0x10: {  /* S */
   12475                      DIP("sub.s f%u, f%u, f%u", fd, fs, ft);
   12476                      calculateFCSR(fs, ft, SUBS, True, 2);
   12477                      IRExpr *rm = get_IR_roundingmode();
   12478                      putFReg(fd, mkWidenFromF32(tyF, triop(Iop_SubF32, rm,
   12479                                  getLoFromF64(tyF, getFReg(fs)),
   12480                                  getLoFromF64(tyF, getFReg(ft)))));
   12481                      break;
   12482                   }
   12483                   default:
   12484                      goto decode_failure;
   12485                }
   12486                break;  /* SUB.fmt */
   12487 
   12488             case 0x06:  /* MOV.fmt */
   12489                switch (fmt) {
   12490                   case 0x11:  /* D */
   12491                      DIP("mov.d f%u, f%u", fd, fs);
   12492                      if (fp_mode64) {
   12493                         putDReg(fd, getDReg(fs));
   12494                      } else {
   12495                         putFReg(fd, getFReg(fs));
   12496                         putFReg(fd + 1, getFReg(fs + 1));
   12497                      }
   12498                      break;
   12499                   case 0x10:  /* S */
   12500                      DIP("mov.s f%u, f%u", fd, fs);
   12501                      putFReg(fd, getFReg(fs));
   12502                      break;
   12503                   default:
   12504                      goto decode_failure;
   12505                }
   12506                break;  /* MOV.fmt */
   12507 
   12508             case 0x7:  /* neg.fmt */
   12509                switch (fmt) {
   12510                   case 0x10:  /* S */
   12511                      DIP("neg.s f%u, f%u", fd, fs);
   12512                      putFReg(fd, mkWidenFromF32(tyF, unop(Iop_NegF32,
   12513                                  getLoFromF64(tyF, getFReg(fs)))));
   12514                      break;
   12515                   case 0x11:  /* D */
   12516                      DIP("neg.d f%u, f%u", fd, fs);
   12517                      putDReg(fd, unop(Iop_NegF64, getDReg(fs)));
   12518                      break;
   12519                   default:
   12520                      goto decode_failure;
   12521                }
   12522                break;  /* case 0x7 */
   12523 
   12524             case 0x08:  /* ROUND.L.fmt */
   12525                switch (fmt) {
   12526                   case 0x10:  /* S */
   12527                      DIP("round.l.s f%u, f%u", fd, fs);
   12528                      if (fp_mode64) {
   12529                         calculateFCSR(fs, 0, ROUNDLS, True, 1);
   12530                         t0 = newTemp(Ity_I64);
   12531 
   12532                         assign(t0, binop(Iop_F32toI64S, mkU32(0x0),
   12533                                          getLoFromF64(Ity_F64, getFReg(fs))));
   12534 
   12535                         putDReg(fd, unop(Iop_ReinterpI64asF64, mkexpr(t0)));
   12536                      } else {
   12537                         ILLEGAL_INSTRUCTON;
   12538                      }
   12539                      break;
   12540                   case 0x11:  /* D */
   12541                      DIP("round.l.d f%u, f%u", fd, fs);
   12542                      if (fp_mode64) {
   12543                         calculateFCSR(fs, 0, ROUNDLD, False, 1);
   12544                         putDReg(fd, binop(Iop_RoundF64toInt, mkU32(0x0),
   12545                                           getDReg(fs)));
   12546                      } else {
   12547                         ILLEGAL_INSTRUCTON;
   12548                      }
   12549                      break;
   12550                   default:
   12551                     goto decode_failure;
   12552 
   12553                }
   12554                break;  /* ROUND.L.fmt */
   12555 
   12556             case 0x09:  /* TRUNC.L.fmt */
   12557                switch (fmt) {
   12558                   case 0x10:  /* S */
   12559                      DIP("trunc.l.s f%u, f%u", fd, fs);
   12560                      if (fp_mode64) {
   12561                         calculateFCSR(fs, 0, TRUNCLS, True, 1);
   12562                         t0 = newTemp(Ity_I64);
   12563                         assign(t0, binop(Iop_F32toI64S, mkU32(0x3),
   12564                                          getLoFromF64(Ity_F64, getFReg(fs))));
   12565 
   12566                         putDReg(fd, unop(Iop_ReinterpI64asF64, mkexpr(t0)));
   12567                      } else {
   12568                         ILLEGAL_INSTRUCTON;
   12569                      }
   12570                      break;
   12571                   case 0x11:  /* D */
   12572                      DIP("trunc.l.d f%u, f%u", fd, fs);
   12573                      if (fp_mode64) {
   12574                         calculateFCSR(fs, 0, TRUNCLD, False, 1);
   12575                         putDReg(fd, binop(Iop_RoundF64toInt, mkU32(0x3),
   12576                                           getDReg(fs)));
   12577                      } else {
   12578                         ILLEGAL_INSTRUCTON;
   12579                      }
   12580                      break;
   12581                   default:
   12582                      goto decode_failure;
   12583                  }
   12584               break;  /* TRUNC.L.fmt */
   12585 
   12586             case 0x15:  /* RECIP.fmt */
   12587                switch (fmt) {
   12588                   case 0x10: {  /* S */
   12589                      DIP("recip.s f%u, f%u", fd, fs);
   12590                      IRExpr *rm = get_IR_roundingmode();
   12591                      putFReg(fd, mkWidenFromF32(tyF, triop(Iop_DivF32,
   12592                                  rm, unop(Iop_ReinterpI32asF32,
   12593                                  mkU32(ONE_SINGLE)), getLoFromF64(tyF,
   12594                                  getFReg(fs)))));
   12595                      break;
   12596                   }
   12597                   case 0x11: {  /* D */
   12598                      DIP("recip.d f%u, f%u", fd, fs);
   12599                      IRExpr *rm = get_IR_roundingmode();
   12600                      /* putDReg(fd, 1.0/getDreg(fs)); */
   12601                      putDReg(fd, triop(Iop_DivF64, rm,
   12602                                  unop(Iop_ReinterpI64asF64,
   12603                                  mkU64(ONE_DOUBLE)), getDReg(fs)));
   12604                      break;
   12605                   }
   12606                default:
   12607                   goto decode_failure;
   12608 
   12609                }
   12610                break;  /* case 0x15 */
   12611 
   12612             case 0x13:  /* MOVN.fmt */
   12613                switch (fmt) {
   12614                case 0x10:  /* S */
   12615                   DIP("movn.s f%u, f%u, r%u", fd, fs, rt);
   12616                   t1 = newTemp(Ity_I1);
   12617 
   12618                   if (mode64)
   12619                      assign(t1, binop(Iop_CmpNE64, mkU64(0), getIReg(rt)));
   12620                   else
   12621                      assign(t1, binop(Iop_CmpNE32, mkU32(0), getIReg(rt)));
   12622 
   12623                   putFReg(fd, IRExpr_ITE(mkexpr(t1), getFReg(fs), getFReg(fd)));
   12624                   break;
   12625                case 0x11:  /* D */
   12626                   DIP("movn.d f%u, f%u, r%u", fd, fs, rt);
   12627                   t1 = newTemp(Ity_I1);
   12628 
   12629                   if (mode64)
   12630                      assign(t1, binop(Iop_CmpNE64, mkU64(0), getIReg(rt)));
   12631                   else
   12632                      assign(t1, binop(Iop_CmpNE32, mkU32(0), getIReg(rt)));
   12633 
   12634                   putDReg(fd, IRExpr_ITE(mkexpr(t1), getDReg(fs), getDReg(fd)));
   12635                   break;
   12636                default:
   12637                   goto decode_failure;
   12638                }
   12639                break;  /* MOVN.fmt */
   12640 
   12641             case 0x12:  /* MOVZ.fmt */
   12642                switch (fmt) {
   12643                case 0x10:  /* S */
   12644                   DIP("movz.s f%u, f%u, r%u", fd, fs, rt);
   12645                   t1 = newTemp(Ity_I1);
   12646 
   12647                   if (mode64)
   12648                      assign(t1, binop(Iop_CmpEQ64, mkU64(0), getIReg(rt)));
   12649                   else
   12650                      assign(t1, binop(Iop_CmpEQ32, mkU32(0), getIReg(rt)));
   12651 
   12652                   putFReg(fd, IRExpr_ITE(mkexpr(t1), getFReg(fs), getFReg(fd)));
   12653                   break;
   12654                case 0x11:  /* D */
   12655                   DIP("movz.d f%u, f%u, r%u", fd, fs, rt);
   12656                   t1 = newTemp(Ity_I1);
   12657 
   12658                   if (mode64)
   12659                      assign(t1, binop(Iop_CmpEQ64, mkU64(0), getIReg(rt)));
   12660                   else
   12661                      assign(t1, binop(Iop_CmpEQ32, mkU32(0), getIReg(rt)));
   12662 
   12663                   putDReg(fd, IRExpr_ITE(mkexpr(t1), getDReg(fs), getDReg(fd)));
   12664                   break;
   12665                default:
   12666                   goto decode_failure;
   12667                }
   12668                break;  /* MOVZ.fmt */
   12669 
   12670             case 0x11:  /* MOVT.fmt */
   12671                if (tf == 1) {
   12672                   UInt mov_cc = get_mov_cc(cins);
   12673                   switch (fmt) {  /* MOVCF = 010001 */
   12674                   case 0x11:  /* D */
   12675                      DIP("movt.d f%u, f%u, %u", fd, fs, mov_cc);
   12676                      t1 = newTemp(Ity_I1);
   12677                      t2 = newTemp(Ity_I32);
   12678                      t3 = newTemp(Ity_I1);
   12679                      t4 = newTemp(Ity_F64);
   12680 
   12681                      assign(t1, binop(Iop_CmpEQ32, mkU32(0), mkU32(mov_cc)));
   12682                      assign(t2, IRExpr_ITE(mkexpr(t1),
   12683                                            binop(Iop_And32,
   12684                                                  binop(Iop_Shr32, getFCSR(),
   12685                                                        mkU8(23)),
   12686                                                  mkU32(0x1)),
   12687                                            binop(Iop_And32,
   12688                                                  binop(Iop_Shr32, getFCSR(),
   12689                                                        mkU8(24 + mov_cc)),
   12690                                                  mkU32(0x1))
   12691                                            ));
   12692 
   12693                      assign(t3, binop(Iop_CmpEQ32, mkU32(1), mkexpr(t2)));
   12694                      assign(t4, IRExpr_ITE(mkexpr(t3),
   12695                                            getDReg(fs), getDReg(fd)));
   12696                      putDReg(fd, mkexpr(t4));
   12697                      break;
   12698                   case 0x10:  /* S */
   12699                      DIP("movt.s f%u, f%u, %u", fd, fs, mov_cc);
   12700                      t1 = newTemp(Ity_I1);
   12701                      t2 = newTemp(Ity_I32);
   12702                      t3 = newTemp(Ity_I1);
   12703                      t4 = newTemp(Ity_F64);
   12704                      t5 = newTemp(Ity_F64);
   12705                      t6 = newTemp(Ity_F64);
   12706                      t7 = newTemp(Ity_I64);
   12707 
   12708                      if (fp_mode64) {
   12709                         assign(t5, getFReg(fs));
   12710                         assign(t6, getFReg(fd));
   12711                      } else {
   12712                         assign(t5, unop(Iop_F32toF64, getFReg(fs)));
   12713                         assign(t6, unop(Iop_F32toF64, getFReg(fd)));
   12714                      }
   12715 
   12716                      assign(t1, binop(Iop_CmpEQ32, mkU32(0), mkU32(mov_cc)));
   12717                      assign(t2, IRExpr_ITE(mkexpr(t1),
   12718                                            binop(Iop_And32,
   12719                                                  binop(Iop_Shr32, getFCSR(),
   12720                                                        mkU8(23)),
   12721                                                  mkU32(0x1)),
   12722                                            binop(Iop_And32,
   12723                                                  binop(Iop_Shr32, getFCSR(),
   12724                                                        mkU8(24 + mov_cc)),
   12725                                                  mkU32(0x1))
   12726                                            ));
   12727 
   12728                      assign(t3, binop(Iop_CmpEQ32, mkU32(1), mkexpr(t2)));
   12729                      assign(t4, IRExpr_ITE(mkexpr(t3),
   12730                                            mkexpr(t5), mkexpr(t6)));
   12731 
   12732                      if (fp_mode64) {
   12733                         IRTemp f = newTemp(Ity_F64);
   12734                         IRTemp fd_hi = newTemp(Ity_I32);
   12735                         assign(f, getFReg(fd));
   12736                         assign(fd_hi, unop(Iop_64HIto32,
   12737                                       unop(Iop_ReinterpF64asI64, mkexpr(f))));
   12738                         assign(t7, mkWidenFrom32(Ity_I64, unop(Iop_64to32,
   12739                                       unop(Iop_ReinterpF64asI64, mkexpr(t4))),
   12740                                       True));
   12741 
   12742                         putFReg(fd, unop(Iop_ReinterpI64asF64, mkexpr(t7)));
   12743                      } else
   12744                         putFReg(fd, binop(Iop_F64toF32, get_IR_roundingmode(),
   12745                                           mkexpr(t4)));
   12746                      break;
   12747                   default:
   12748                      goto decode_failure;
   12749                   }
   12750                } else if (tf == 0)  /* movf.fmt */
   12751                {
   12752                   UInt mov_cc = get_mov_cc(cins);
   12753                   switch (fmt)  /* MOVCF = 010001 */
   12754                   {
   12755                   case 0x11:  /* D */
   12756                      DIP("movf.d f%u, f%u, %u", fd, fs, mov_cc);
   12757                      t1 = newTemp(Ity_I1);
   12758                      t2 = newTemp(Ity_I32);
   12759                      t3 = newTemp(Ity_I1);
   12760                      t4 = newTemp(Ity_F64);
   12761 
   12762                      assign(t1, binop(Iop_CmpEQ32, mkU32(0), mkU32(mov_cc)));
   12763                      assign(t2, IRExpr_ITE(mkexpr(t1),
   12764                                            binop(Iop_And32,
   12765                                                  binop(Iop_Shr32, getFCSR(),
   12766                                                        mkU8(23)),
   12767                                                  mkU32(0x1)),
   12768                                            binop(Iop_And32,
   12769                                                  binop(Iop_Shr32, getFCSR(),
   12770                                                        mkU8(24 + mov_cc)),
   12771                                                  mkU32(0x1))
   12772                                            ));
   12773 
   12774                      assign(t3, binop(Iop_CmpEQ32, mkU32(0), mkexpr(t2)));
   12775                      assign(t4, IRExpr_ITE(mkexpr(t3),
   12776                                            getDReg(fs), getDReg(fd)));
   12777                      putDReg(fd, mkexpr(t4));
   12778                      break;
   12779                   case 0x10:  /* S */
   12780                      DIP("movf.s f%u, f%u, %u", fd, fs, mov_cc);
   12781                      t1 = newTemp(Ity_I1);
   12782                      t2 = newTemp(Ity_I32);
   12783                      t3 = newTemp(Ity_I1);
   12784                      t4 = newTemp(Ity_F64);
   12785                      t5 = newTemp(Ity_F64);
   12786                      t6 = newTemp(Ity_F64);
   12787 
   12788                      if (fp_mode64) {
   12789                         assign(t5, getFReg(fs));
   12790                         assign(t6, getFReg(fd));
   12791                      } else {
   12792                         assign(t5, unop(Iop_F32toF64, getFReg(fs)));
   12793                         assign(t6, unop(Iop_F32toF64, getFReg(fd)));
   12794                      }
   12795 
   12796                      assign(t1, binop(Iop_CmpEQ32, mkU32(0), mkU32(mov_cc)));
   12797                      assign(t2, IRExpr_ITE(mkexpr(t1),
   12798                                            binop(Iop_And32,
   12799                                                  binop(Iop_Shr32, getFCSR(),
   12800                                                        mkU8(23)),
   12801                                                  mkU32(0x1)),
   12802                                            binop(Iop_And32,
   12803                                                  binop(Iop_Shr32, getFCSR(),
   12804                                                        mkU8(24 + mov_cc)),
   12805                                                  mkU32(0x1))
   12806                                            ));
   12807 
   12808                      assign(t3, binop(Iop_CmpEQ32, mkU32(0), mkexpr(t2)));
   12809                      assign(t4, IRExpr_ITE(mkexpr(t3),
   12810                                            mkexpr(t5), mkexpr(t6)));
   12811 
   12812                      if (fp_mode64) {
   12813                         IRTemp f = newTemp(Ity_F64);
   12814                         IRTemp fd_hi = newTemp(Ity_I32);
   12815                         t7 = newTemp(Ity_I64);
   12816                         assign(f, getFReg(fd));
   12817                         assign(fd_hi, unop(Iop_64HIto32,
   12818                                       unop(Iop_ReinterpF64asI64, mkexpr(f))));
   12819                         assign(t7, mkWidenFrom32(Ity_I64, unop(Iop_64to32,
   12820                                    unop(Iop_ReinterpF64asI64, mkexpr(t4))),
   12821                                    True));
   12822 
   12823                         putFReg(fd, unop(Iop_ReinterpI64asF64, mkexpr(t7)));
   12824                      } else
   12825                         putFReg(fd, binop(Iop_F64toF32, get_IR_roundingmode(),
   12826                                           mkexpr(t4)));
   12827                      break;
   12828                   default:
   12829                      goto decode_failure;
   12830                   }
   12831                }
   12832 
   12833                break;  /* MOVT.fmt */
   12834 
   12835             case 0x0:  /* add.fmt */
   12836                switch (fmt) {
   12837                case 0x10: {  /* S */
   12838                   DIP("add.s f%u, f%u, f%u", fd, fs, ft);
   12839                   calculateFCSR(fs, ft, ADDS, True, 2);
   12840                   IRExpr *rm = get_IR_roundingmode();
   12841                   putFReg(fd, mkWidenFromF32(tyF, triop(Iop_AddF32, rm,
   12842                               getLoFromF64(tyF, getFReg(fs)),
   12843                               getLoFromF64(tyF, getFReg(ft)))));
   12844                   break;
   12845                }
   12846                case 0x11: {  /* D */
   12847                   DIP("add.d f%u, f%u, f%u", fd, fs, ft);
   12848                   calculateFCSR(fs, ft, ADDD, False, 2);
   12849                   IRExpr *rm = get_IR_roundingmode();
   12850                   putDReg(fd, triop(Iop_AddF64, rm, getDReg(fs), getDReg(ft)));
   12851                   break;
   12852                }
   12853 
   12854                case 0x4:  /* MTC1 (Move Word to Floating Point) */
   12855                   DIP("mtc1 r%u, f%u", rt, fs);
   12856                   if (fp_mode64) {
   12857                      t0 = newTemp(Ity_I32);
   12858                      t1 = newTemp(Ity_F32);
   12859                      assign(t0, mkNarrowTo32(ty, getIReg(rt)));
   12860                      assign(t1, unop(Iop_ReinterpI32asF32, mkexpr(t0)));
   12861 
   12862                      putFReg(fs, mkWidenFromF32(tyF, mkexpr(t1)));
   12863                   } else
   12864                      putFReg(fs, unop(Iop_ReinterpI32asF32,
   12865                                       mkNarrowTo32(ty, getIReg(rt))));
   12866                   break;
   12867 
   12868                case 0x5:  /* Doubleword Move to Floating Point DMTC1; MIPS64 */
   12869                   DIP("dmtc1 r%u, f%u", rt, fs);
   12870                   vassert(mode64);
   12871                   putDReg(fs, unop(Iop_ReinterpI64asF64, getIReg(rt)));
   12872                   break;
   12873 
   12874                case 0x0:  /* MFC1 */
   12875                   DIP("mfc1 r%u, f%u", rt, fs);
   12876                   if (fp_mode64) {
   12877                      t0 = newTemp(Ity_I64);
   12878                      t1 = newTemp(Ity_I32);
   12879                      assign(t0, unop(Iop_ReinterpF64asI64, getFReg(fs)));
   12880                      assign(t1, unop(Iop_64to32, mkexpr(t0)));
   12881                      putIReg(rt, mkWidenFrom32(ty, mkexpr(t1), True));
   12882                   } else
   12883                      putIReg(rt, mkWidenFrom32(ty,
   12884                                  unop(Iop_ReinterpF32asI32, getFReg(fs)),
   12885                                  True));
   12886                   break;
   12887 
   12888                case 0x1:  /* Doubleword Move from Floating Point DMFC1;
   12889                              MIPS64 */
   12890                   DIP("dmfc1 r%u, f%u", rt, fs);
   12891                   putIReg(rt, unop(Iop_ReinterpF64asI64, getDReg(fs)));
   12892                   break;
   12893 
   12894                case 0x6:  /* CTC1 */
   12895                   DIP("ctc1 r%u, f%u", rt, fs);
   12896                   t0 = newTemp(Ity_I32);
   12897                   t1 = newTemp(Ity_I32);
   12898                   t2 = newTemp(Ity_I32);
   12899                   t3 = newTemp(Ity_I32);
   12900                   t4 = newTemp(Ity_I32);
   12901                   t5 = newTemp(Ity_I32);
   12902                   t6 = newTemp(Ity_I32);
   12903                   assign(t0, mkNarrowTo32(ty, getIReg(rt)));
   12904                   if (fs == 25) {  /* FCCR */
   12905                      assign(t1, binop(Iop_Shl32, binop(Iop_And32, mkexpr(t0),
   12906                                       mkU32(0x000000FE)), mkU8(24)));
   12907                      assign(t2, binop(Iop_And32, mkexpr(t0),
   12908                                       mkU32(0x01000000)));
   12909                      assign(t3, binop(Iop_Shl32, binop(Iop_And32, mkexpr(t0),
   12910                                       mkU32(0x00000001)), mkU8(23)));
   12911                      assign(t4, binop(Iop_And32, mkexpr(t0),
   12912                                       mkU32(0x007FFFFF)));
   12913                      putFCSR(binop(Iop_Or32, binop(Iop_Or32, mkexpr(t1),
   12914                                    mkexpr(t2)), binop(Iop_Or32, mkexpr(t3),
   12915                                    mkexpr(t4))));
   12916                   } else if (fs == 26) {  /* FEXR */
   12917                      assign(t1, binop(Iop_And32, getFCSR(), mkU32(0xFFFC0000)));
   12918                      assign(t2, binop(Iop_And32, mkexpr(t0),
   12919                                       mkU32(0x0003F000)));
   12920                      assign(t3, binop(Iop_And32, getFCSR(), mkU32(0x00000F80)));
   12921                      assign(t4, binop(Iop_And32, mkexpr(t0),
   12922                                       mkU32(0x0000007C)));
   12923                      assign(t5, binop(Iop_And32, getFCSR(), mkU32(0x00000003)));
   12924                      putFCSR(binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Or32,
   12925                                    mkexpr(t1), mkexpr(t2)), binop(Iop_Or32,
   12926                                    mkexpr(t3), mkexpr(t4))), mkexpr(t5)));
   12927                   } else if (fs == 28) {
   12928                      assign(t1, binop(Iop_And32, getFCSR(), mkU32(0xFE000000)));
   12929                      assign(t2, binop(Iop_Shl32, binop(Iop_And32, mkexpr(t0),
   12930                                 mkU32(0x00000002)), mkU8(22)));
   12931                      assign(t3, binop(Iop_And32, getFCSR(), mkU32(0x00FFF000)));
   12932                      assign(t4, binop(Iop_And32, mkexpr(t0),
   12933                                 mkU32(0x00000F80)));
   12934                      assign(t5, binop(Iop_And32, getFCSR(), mkU32(0x0000007C)));
   12935                      assign(t6, binop(Iop_And32, mkexpr(t0),
   12936                                 mkU32(0x00000003)));
   12937                      putFCSR(binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Or32,
   12938                                    mkexpr(t1), mkexpr(t2)), binop(Iop_Or32,
   12939                                    mkexpr(t3), mkexpr(t4))), binop(Iop_Or32,
   12940                                    mkexpr(t5), mkexpr(t6))));
   12941                   } else if (fs == 31) {
   12942                      putFCSR(mkexpr(t0));
   12943                   }
   12944                   break;
   12945                case 0x2:  /* CFC1 */
   12946                   DIP("cfc1 r%u, f%u", rt, fs);
   12947                   t0 = newTemp(Ity_I32);
   12948                   t1 = newTemp(Ity_I32);
   12949                   t2 = newTemp(Ity_I32);
   12950                   t3 = newTemp(Ity_I32);
   12951                   t4 = newTemp(Ity_I32);
   12952                   t5 = newTemp(Ity_I32);
   12953                   t6 = newTemp(Ity_I32);
   12954                   assign(t0, getFCSR());
   12955                   if (fs == 0) {
   12956                      putIReg(rt, mkWidenFrom32(ty,
   12957                              IRExpr_Get(offsetof(VexGuestMIPS32State,
   12958                                                  guest_FIR),
   12959                                        Ity_I32),
   12960                              False));
   12961                   } else if (fs == 25) {
   12962                      assign(t1, mkU32(0x000000FF));
   12963                      assign(t2, binop(Iop_Shr32, binop(Iop_And32, mkexpr(t0),
   12964                                       mkU32(0xFE000000)), mkU8(25)));
   12965                      assign(t3, binop(Iop_Shr32, binop(Iop_And32, mkexpr(t0),
   12966                                       mkU32(0x00800000)), mkU8(23)));
   12967                      putIReg(rt, mkWidenFrom32(ty, binop(Iop_Or32,
   12968                                  binop(Iop_Or32, mkexpr(t1), mkexpr(t2)),
   12969                                  mkexpr(t3)), False));
   12970                   } else if (fs == 26) {
   12971                      assign(t1, mkU32(0xFFFFF07C));
   12972                      assign(t2, binop(Iop_And32, mkexpr(t0),
   12973                                 mkU32(0x0003F000)));
   12974                      assign(t3, binop(Iop_And32, mkexpr(t0),
   12975                                       mkU32(0x0000007C)));
   12976                      putIReg(rt, mkWidenFrom32(ty, binop(Iop_Or32,
   12977                                  binop(Iop_Or32, mkexpr(t1), mkexpr(t2)),
   12978                                  mkexpr(t3)), False));
   12979                   } else if (fs == 28) {
   12980                      assign(t1, mkU32(0x00000F87));
   12981                      assign(t2, binop(Iop_And32, mkexpr(t0),
   12982                                       mkU32(0x00000F83)));
   12983                      assign(t3, binop(Iop_Shr32, binop(Iop_And32, mkexpr(t0),
   12984                                       mkU32(0x01000000)), mkU8(22)));
   12985                      putIReg(rt, mkWidenFrom32(ty, binop(Iop_Or32,
   12986                                  binop(Iop_Or32, mkexpr(t1), mkexpr(t2)),
   12987                                  mkexpr(t3)), False));
   12988                   } else if (fs == 31) {
   12989                      putIReg(rt, mkWidenFrom32(ty, getFCSR(), False));
   12990                   }
   12991                   break;
   12992                default:
   12993                   goto decode_failure;
   12994                }
   12995                break;
   12996 
   12997             case 0x21:  /* CVT.D */
   12998                switch (fmt) {
   12999                   case 0x10:  /* S */
   13000                      DIP("cvt.d.s f%u, f%u", fd, fs);
   13001                      calculateFCSR(fs, 0, CVTDS, True, 1);
   13002                      if (fp_mode64) {
   13003                         t0 = newTemp(Ity_I64);
   13004                         t1 = newTemp(Ity_I32);
   13005                         t3 = newTemp(Ity_F32);
   13006                         t4 = newTemp(Ity_F32);
   13007                         /* get lo half of FPR */
   13008                         assign(t0, unop(Iop_ReinterpF64asI64, getFReg(fs)));
   13009 
   13010                         assign(t1, unop(Iop_64to32, mkexpr(t0)));
   13011 
   13012                         assign(t3, unop(Iop_ReinterpI32asF32, mkexpr(t1)));
   13013 
   13014                         putFReg(fd, unop(Iop_F32toF64, mkexpr(t3)));
   13015                      } else
   13016                         putDReg(fd, unop(Iop_F32toF64, getFReg(fs)));
   13017                      break;
   13018 
   13019                   case 0x14:
   13020                      DIP("cvt.d.w %u, %u", fd, fs);
   13021                      calculateFCSR(fs, 0, CVTDW, True, 1);
   13022                      if (fp_mode64) {
   13023                         t0 = newTemp(Ity_I64);
   13024                         t1 = newTemp(Ity_I32);
   13025                         t3 = newTemp(Ity_F32);
   13026                         t4 = newTemp(Ity_F32);
   13027                         /* get lo half of FPR */
   13028                         assign(t0, unop(Iop_ReinterpF64asI64, getFReg(fs)));
   13029 
   13030                         assign(t1, unop(Iop_64to32, mkexpr(t0)));
   13031                         putDReg(fd,unop(Iop_I32StoF64, mkexpr(t1)));
   13032                         break;
   13033                      } else {
   13034                         t0 = newTemp(Ity_I32);
   13035                         assign(t0, unop(Iop_ReinterpF32asI32, getFReg(fs)));
   13036                         putDReg(fd, unop(Iop_I32StoF64, mkexpr(t0)));
   13037                         break;
   13038                      }
   13039 
   13040                   case 0x15: {  /* L */
   13041                      if (fp_mode64) {
   13042                         DIP("cvt.d.l %u, %u", fd, fs);
   13043                         calculateFCSR(fs, 0, CVTDL, False, 1);
   13044                         t0 = newTemp(Ity_I64);
   13045                         assign(t0, unop(Iop_ReinterpF64asI64, getFReg(fs)));
   13046 
   13047                         putFReg(fd, binop(Iop_I64StoF64,
   13048                                           get_IR_roundingmode(), mkexpr(t0)));
   13049                         break;
   13050                      } else
   13051                         goto decode_failure;
   13052                   }
   13053                   default:
   13054                      goto decode_failure;
   13055                }
   13056                break;  /* CVT.D */
   13057 
   13058             case 0x20:  /* cvt.s */
   13059                switch (fmt) {
   13060                   case 0x14:  /* W */
   13061                      DIP("cvt.s.w %u, %u", fd, fs);
   13062                      calculateFCSR(fs, 0, CVTSW, True, 1);
   13063                      if (fp_mode64) {
   13064                         t0 = newTemp(Ity_I64);
   13065                         t1 = newTemp(Ity_I32);
   13066                         t3 = newTemp(Ity_F32);
   13067                         t4 = newTemp(Ity_F32);
   13068                         /* get lo half of FPR */
   13069                         assign(t0, unop(Iop_ReinterpF64asI64, getFReg(fs)));
   13070 
   13071                         assign(t1, unop(Iop_64to32, mkexpr(t0)));
   13072                         putFReg(fd, mkWidenFromF32(tyF, binop(Iop_I32StoF32,
   13073                                     get_IR_roundingmode(), mkexpr(t1))));
   13074                      } else {
   13075                         t0 = newTemp(Ity_I32);
   13076                         assign(t0, unop(Iop_ReinterpF32asI32, getFReg(fs)));
   13077                         putFReg(fd, binop(Iop_I32StoF32, get_IR_roundingmode(),
   13078                                     mkexpr(t0)));
   13079                      }
   13080                      break;
   13081 
   13082                   case 0x11:  /* D */
   13083                      DIP("cvt.s.d %u, %u", fd, fs);
   13084                      calculateFCSR(fs, 0, CVTSD, False, 1);
   13085                      t0 = newTemp(Ity_F32);
   13086                      assign(t0, binop(Iop_F64toF32, get_IR_roundingmode(),
   13087                                       getDReg(fs)));
   13088                      putFReg(fd, mkWidenFromF32(tyF, mkexpr(t0)));
   13089                      break;
   13090 
   13091                   case 0x15:  /* L */
   13092                      DIP("cvt.s.l %u, %u", fd, fs);
   13093                      if (fp_mode64) {
   13094                         calculateFCSR(fs, 0, CVTSL, False, 1);
   13095                         t0 = newTemp(Ity_I64);
   13096                         assign(t0, unop(Iop_ReinterpF64asI64, getFReg(fs)));
   13097 
   13098                         putFReg(fd, mkWidenFromF32(tyF, binop(Iop_I64StoF32,
   13099                                     get_IR_roundingmode(), mkexpr(t0))));
   13100                      } else {
   13101                         ILLEGAL_INSTRUCTON;
   13102                      }
   13103                      break;
   13104 
   13105                   default:
   13106                      goto decode_failure;
   13107                }
   13108                break;  /* cvt.s */
   13109 
   13110             case 0x24:  /* cvt.w */
   13111                switch (fmt) {
   13112                case 0x10:  /* S */
   13113                   DIP("cvt.w.s %u, %u", fd, fs);
   13114                   calculateFCSR(fs, 0, CVTWS, True, 1);
   13115                   putFReg(fd,
   13116                           mkWidenFromF32(tyF,
   13117                                          binop(Iop_RoundF32toInt,
   13118                                                get_IR_roundingmode(),
   13119                                                getLoFromF64(tyF, getFReg(fs))))
   13120                          );
   13121                   break;
   13122 
   13123                case 0x11:
   13124                   DIP("cvt.w.d %u, %u", fd, fs);
   13125                   calculateFCSR(fs, 0, CVTWD, False, 1);
   13126                   t0 = newTemp(Ity_I32);
   13127                   t1 = newTemp(Ity_F32);
   13128                   assign(t0, binop(Iop_F64toI32S, get_IR_roundingmode(),
   13129                                    getDReg(fs)));
   13130                   assign(t1, unop(Iop_ReinterpI32asF32, mkexpr(t0)));
   13131                   putFReg(fd, mkWidenFromF32(tyF, mkexpr(t1)));
   13132                   break;
   13133 
   13134                default:
   13135                   goto decode_failure;
   13136 
   13137                }
   13138                break;
   13139 
   13140             case 0x25:  /* cvt.l */
   13141                switch (fmt) {
   13142                   case 0x10:  /* S */
   13143                      DIP("cvt.l.s %u, %u", fd, fs);
   13144                      if (fp_mode64) {
   13145                         calculateFCSR(fs, 0, CVTLS, True, 1);
   13146                         t0 = newTemp(Ity_I64);
   13147 
   13148                         assign(t0, binop(Iop_F32toI64S, get_IR_roundingmode(),
   13149                                          getLoFromF64(tyF, getFReg(fs))));
   13150 
   13151                         putDReg(fd, unop(Iop_ReinterpI64asF64, mkexpr(t0)));
   13152                      } else {
   13153                         ILLEGAL_INSTRUCTON;
   13154                      }
   13155                      break;
   13156 
   13157                   case 0x11: {  /* D */
   13158                      DIP("cvt.l.d %u, %u", fd, fs);
   13159                      if (fp_mode64) {
   13160                         calculateFCSR(fs, 0, CVTLD, False, 1);
   13161                         putDReg(fd, binop(Iop_RoundF64toInt,
   13162                                 get_IR_roundingmode(), getDReg(fs)));
   13163                      } else {
   13164                         ILLEGAL_INSTRUCTON;
   13165                      }
   13166                      break;
   13167                   }
   13168 
   13169                   default:
   13170                      goto decode_failure;
   13171                }
   13172                break;
   13173 
   13174             case 0x0B:  /* FLOOR.L.fmt */
   13175                switch (fmt) {
   13176                   case 0x10:  /* S */
   13177                      DIP("floor.l.s %u, %u", fd, fs);
   13178                      if (fp_mode64) {
   13179                         calculateFCSR(fs, 0, FLOORLS, True, 1);
   13180                         t0 = newTemp(Ity_I64);
   13181 
   13182                         assign(t0, binop(Iop_F32toI64S, mkU32(0x1),
   13183                                          getLoFromF64(tyF, getFReg(fs))));
   13184 
   13185                         putDReg(fd, unop(Iop_ReinterpI64asF64, mkexpr(t0)));
   13186                      } else {
   13187                         ILLEGAL_INSTRUCTON;
   13188                      }
   13189                      break;
   13190 
   13191                   case 0x11:  /* D */
   13192                      DIP("floor.l.d %u, %u", fd, fs);
   13193                      if (fp_mode64) {
   13194                         calculateFCSR(fs, 0, FLOORLD, False, 1);
   13195                         putDReg(fd, binop(Iop_RoundF64toInt, mkU32(0x1),
   13196                                           getDReg(fs)));
   13197                      } else {
   13198                         ILLEGAL_INSTRUCTON;
   13199                      }
   13200                      break;
   13201                   default:
   13202                      goto decode_failure;
   13203                }
   13204                break;
   13205 
   13206             case 0x0C:  /* ROUND.W.fmt */
   13207                switch (fmt) {
   13208                   case 0x10:  /* S */
   13209                      DIP("round.w.s f%u, f%u", fd, fs);
   13210                      calculateFCSR(fs, 0, ROUNDWS, True, 1);
   13211                      if (fp_mode64) {
   13212                         t0 = newTemp(Ity_I64);
   13213                         t1 = newTemp(Ity_I32);
   13214                         t3 = newTemp(Ity_F32);
   13215                         t4 = newTemp(Ity_F32);
   13216                         /* get lo half of FPR */
   13217                         assign(t0, unop(Iop_ReinterpF64asI64, getFReg(fs)));
   13218 
   13219                         assign(t1, unop(Iop_64to32, mkexpr(t0)));
   13220 
   13221                         assign(t3, unop(Iop_ReinterpI32asF32, mkexpr(t1)));
   13222 
   13223                         assign(t4, binop(Iop_RoundF32toInt, mkU32(0x0),
   13224                                          mkexpr(t3)));
   13225 
   13226                         putFReg(fd, mkWidenFromF32(tyF, mkexpr(t4)));
   13227                      } else
   13228                         putFReg(fd, binop(Iop_RoundF32toInt, mkU32(0x0),
   13229                                           getFReg(fs)));
   13230                      break;
   13231 
   13232                   case 0x11:  /* D */
   13233                      DIP("round.w.d f%u, f%u", fd, fs);
   13234                      calculateFCSR(fs, 0, ROUNDWD, False, 1);
   13235                      if (fp_mode64) {
   13236                         t0 = newTemp(Ity_I32);
   13237                         assign(t0, binop(Iop_F64toI32S, mkU32(0x0),
   13238                                          getDReg(fs)));
   13239                         putFReg(fd, mkWidenFromF32(tyF,
   13240                                     unop(Iop_ReinterpI32asF32, mkexpr(t0))));
   13241                      } else {
   13242                         t0 = newTemp(Ity_I32);
   13243 
   13244                         assign(t0, binop(Iop_F64toI32S, mkU32(0x0),
   13245                                          getDReg(fs)));
   13246 
   13247                         putFReg(fd, unop(Iop_ReinterpI32asF32, mkexpr(t0)));
   13248                      }
   13249                      break;
   13250                   default:
   13251                      goto decode_failure;
   13252 
   13253                   }
   13254                   break;  /* ROUND.W.fmt */
   13255 
   13256             case 0x0F:  /* FLOOR.W.fmt */
   13257                switch (fmt) {
   13258                   case 0x10:  /* S */
   13259                      DIP("floor.w.s f%u, f%u", fd, fs);
   13260                      calculateFCSR(fs, 0, FLOORWS, True, 1);
   13261                      if (fp_mode64) {
   13262                         t0 = newTemp(Ity_I64);
   13263                         t1 = newTemp(Ity_I32);
   13264                         t3 = newTemp(Ity_F32);
   13265                         t4 = newTemp(Ity_F32);
   13266                         /* get lo half of FPR */
   13267                         assign(t0, unop(Iop_ReinterpF64asI64, getFReg(fs)));
   13268 
   13269                         assign(t1, unop(Iop_64to32, mkexpr(t0)));
   13270 
   13271                         assign(t3, unop(Iop_ReinterpI32asF32, mkexpr(t1)));
   13272 
   13273                         assign(t4, binop(Iop_RoundF32toInt, mkU32(0x1),
   13274                                          mkexpr(t3)));
   13275 
   13276                         putFReg(fd, mkWidenFromF32(tyF, mkexpr(t4)));
   13277                      } else
   13278                         putFReg(fd, binop(Iop_RoundF32toInt, mkU32(0x1),
   13279                                          getFReg(fs)));
   13280                      break;
   13281 
   13282                   case 0x11:  /* D */
   13283                      DIP("floor.w.d f%u, f%u", fd, fs);
   13284                      calculateFCSR(fs, 0, FLOORWD, False, 1);
   13285                      if (fp_mode64) {
   13286                         t0 = newTemp(Ity_I32);
   13287                         assign(t0, binop(Iop_F64toI32S, mkU32(0x1),
   13288                                          getDReg(fs)));
   13289                         putFReg(fd, mkWidenFromF32(tyF,
   13290                                     unop(Iop_ReinterpI32asF32, mkexpr(t0))));
   13291                         break;
   13292                      } else {
   13293                         t0 = newTemp(Ity_I32);
   13294 
   13295                         assign(t0, binop(Iop_F64toI32S, mkU32(0x1),
   13296                                          getDReg(fs)));
   13297 
   13298                         putFReg(fd, unop(Iop_ReinterpI32asF32, mkexpr(t0)));
   13299                         break;
   13300                      }
   13301                   default:
   13302                      goto decode_failure;
   13303 
   13304                }
   13305                break;  /* FLOOR.W.fmt */
   13306 
   13307             case 0x0D:  /* TRUNC.W */
   13308                switch (fmt) {
   13309                   case 0x10:  /* S */
   13310                      DIP("trunc.w.s %u, %u", fd, fs);
   13311                      calculateFCSR(fs, 0, TRUNCWS, True, 1);
   13312                      if (fp_mode64) {
   13313                         t0 = newTemp(Ity_I64);
   13314                         t1 = newTemp(Ity_I32);
   13315                         t3 = newTemp(Ity_F32);
   13316                         t4 = newTemp(Ity_F32);
   13317                         /* get lo half of FPR */
   13318                         assign(t0, unop(Iop_ReinterpF64asI64, getFReg(fs)));
   13319 
   13320                         assign(t1, unop(Iop_64to32, mkexpr(t0)));
   13321 
   13322                         assign(t3, unop(Iop_ReinterpI32asF32, mkexpr(t1)));
   13323 
   13324                         assign(t4, binop(Iop_RoundF32toInt, mkU32(0x3),
   13325                                          mkexpr(t3)));
   13326 
   13327                         putFReg(fd, mkWidenFromF32(tyF, mkexpr(t4)));
   13328                      } else
   13329                         putFReg(fd, binop(Iop_RoundF32toInt, mkU32(0x3),
   13330                                        getFReg(fs)));
   13331                      break;
   13332                   case 0x11:  /* D */
   13333                      DIP("trunc.w.d %u, %u", fd, fs);
   13334                      calculateFCSR(fs, 0, TRUNCWD, False, 1);
   13335                      if (fp_mode64) {
   13336                         t0 = newTemp(Ity_I32);
   13337 
   13338                         assign(t0, binop(Iop_F64toI32S, mkU32(0x3),
   13339                                          getFReg(fs)));
   13340 
   13341                         putFReg(fd, mkWidenFromF32(tyF,
   13342                                     unop(Iop_ReinterpI32asF32, mkexpr(t0))));
   13343                      } else {
   13344                         t0 = newTemp(Ity_I32);
   13345 
   13346                         assign(t0, binop(Iop_F64toI32S, mkU32(0x3),
   13347                                          getDReg(fs)));
   13348 
   13349                         putFReg(fd, unop(Iop_ReinterpI32asF32, mkexpr(t0)));
   13350                      }
   13351                      break;
   13352                   default:
   13353                      goto decode_failure;
   13354 
   13355                }
   13356                break;
   13357 
   13358             case 0x0E:  /* CEIL.W.fmt */
   13359                switch (fmt) {
   13360                   case 0x10:  /* S */
   13361                      DIP("ceil.w.s %u, %u", fd, fs);
   13362                      calculateFCSR(fs, 0, CEILWS, True, 1);
   13363                      if (fp_mode64) {
   13364                         t0 = newTemp(Ity_I64);
   13365                         t1 = newTemp(Ity_I32);
   13366                         t3 = newTemp(Ity_F32);
   13367                         t4 = newTemp(Ity_F32);
   13368                         /* get lo half of FPR */
   13369                         assign(t0, unop(Iop_ReinterpF64asI64, getFReg(fs)));
   13370 
   13371                         assign(t1, unop(Iop_64to32, mkexpr(t0)));
   13372 
   13373                         assign(t3, unop(Iop_ReinterpI32asF32, mkexpr(t1)));
   13374 
   13375                         assign(t4, binop(Iop_RoundF32toInt, mkU32(0x2),
   13376                                          mkexpr(t3)));
   13377 
   13378                         putFReg(fd, mkWidenFromF32(tyF, mkexpr(t4)));
   13379                      } else
   13380                         putFReg(fd, binop(Iop_RoundF32toInt, mkU32(0x2),
   13381                                           getFReg(fs)));
   13382                      break;
   13383 
   13384                   case 0x11:  /* D */
   13385                      DIP("ceil.w.d %u, %u", fd, fs);
   13386                      calculateFCSR(fs, 0, CEILWD, False, 1);
   13387                      if (!fp_mode64) {
   13388                         t0 = newTemp(Ity_I32);
   13389                         assign(t0, binop(Iop_F64toI32S, mkU32(0x2),
   13390                                          getDReg(fs)));
   13391                         putFReg(fd, unop(Iop_ReinterpI32asF32, mkexpr(t0)));
   13392                      } else {
   13393                         t0 = newTemp(Ity_I32);
   13394                         assign(t0, binop(Iop_F64toI32S, mkU32(0x2),
   13395                                          getDReg(fs)));
   13396                         putFReg(fd, mkWidenFromF32(tyF,
   13397                                     unop(Iop_ReinterpI32asF32, mkexpr(t0))));
   13398                      }
   13399                      break;
   13400                   default:
   13401                      goto decode_failure;
   13402 
   13403                }
   13404                break;
   13405 
   13406             case 0x0A:  /* CEIL.L.fmt */
   13407                switch (fmt) {
   13408                   case 0x10:  /* S */
   13409                      DIP("ceil.l.s %u, %u", fd, fs);
   13410                      if (fp_mode64) {
   13411                         calculateFCSR(fs, 0, CEILLS, True, 1);
   13412                         t0 = newTemp(Ity_I64);
   13413 
   13414                         assign(t0, binop(Iop_F32toI64S, mkU32(0x2),
   13415                                    getLoFromF64(tyF, getFReg(fs))));
   13416 
   13417                         putFReg(fd, unop(Iop_ReinterpI64asF64, mkexpr(t0)));
   13418                      } else {
   13419                         ILLEGAL_INSTRUCTON;
   13420                      }
   13421                      break;
   13422 
   13423                   case 0x11:  /* D */
   13424                      DIP("ceil.l.d %u, %u", fd, fs);
   13425                      if (fp_mode64) {
   13426                         calculateFCSR(fs, 0, CEILLD, False, 1);
   13427                         putDReg(fd, binop(Iop_RoundF64toInt, mkU32(0x2),
   13428                                           getDReg(fs)));
   13429                      } else {
   13430                         ILLEGAL_INSTRUCTON;
   13431                      }
   13432                      break;
   13433 
   13434                   default:
   13435                      goto decode_failure;
   13436 
   13437                }
   13438                break;
   13439 
   13440             case 0x16:  /* RSQRT.fmt */
   13441                switch (fmt) {
   13442                   case 0x10: {  /* S */
   13443                      DIP("rsqrt.s %u, %u", fd, fs);
   13444                      IRExpr *rm = get_IR_roundingmode();
   13445                      putFReg(fd, mkWidenFromF32(tyF, triop(Iop_DivF32, rm,
   13446                                  unop(Iop_ReinterpI32asF32, mkU32(ONE_SINGLE)),
   13447                                  binop(Iop_SqrtF32, rm, getLoFromF64(tyF,
   13448                                  getFReg(fs))))));
   13449                      break;
   13450                   }
   13451                   case 0x11: {  /* D */
   13452                      DIP("rsqrt.d %u, %u", fd, fs);
   13453                      IRExpr *rm = get_IR_roundingmode();
   13454                      putDReg(fd, triop(Iop_DivF64, rm,
   13455                                  unop(Iop_ReinterpI64asF64,
   13456                                  mkU64(ONE_DOUBLE)),
   13457                                  binop(Iop_SqrtF64, rm, getDReg(fs))));
   13458                      break;
   13459                   }
   13460                   default:
   13461                      goto decode_failure;
   13462 
   13463                }
   13464                break;
   13465 
   13466             default:
   13467                if (dis_instr_CCondFmt(cins))
   13468                   break;
   13469                goto decode_failure;
   13470 
   13471             }
   13472 
   13473          }
   13474       }
   13475       break;  /* COP1 */
   13476 
   13477    case 0x31:  /* LWC1 */
   13478       /* Load Word to Floating Point - LWC1 (MIPS32) */
   13479       DIP("lwc1 f%u, %u(r%u)", ft, imm, rs);
   13480       LOAD_STORE_PATTERN;
   13481       if (fp_mode64) {
   13482          t0 = newTemp(Ity_F32);
   13483          t2 = newTemp(Ity_I64);
   13484          assign(t0, load(Ity_F32, mkexpr(t1)));
   13485          assign(t2, mkWidenFrom32(Ity_I64, unop(Iop_ReinterpF32asI32,
   13486                                                 mkexpr(t0)), True));
   13487          putDReg(ft, unop(Iop_ReinterpI64asF64, mkexpr(t2)));
   13488       } else {
   13489          putFReg(ft, load(Ity_F32, mkexpr(t1)));
   13490       }
   13491       break;
   13492 
   13493    case 0x39:  /* SWC1 */
   13494       DIP("swc1 f%u, %u(r%u)", ft, imm, rs);
   13495       if (fp_mode64) {
   13496          t0 = newTemp(Ity_I64);
   13497          t2 = newTemp(Ity_I32);
   13498          LOAD_STORE_PATTERN;
   13499          assign(t0, unop(Iop_ReinterpF64asI64, getFReg(ft)));
   13500          assign(t2, unop(Iop_64to32, mkexpr(t0)));
   13501          store(mkexpr(t1), unop(Iop_ReinterpI32asF32, mkexpr(t2)));
   13502       } else {
   13503          LOAD_STORE_PATTERN;
   13504          store(mkexpr(t1), getFReg(ft));
   13505       }
   13506       break;
   13507 
   13508    case 0x33:  /* PREF */
   13509       DIP("pref");
   13510       break;
   13511 
   13512    case 0x35:
   13513       /* Load Doubleword to Floating Point - LDC1 (MIPS32) */
   13514       DIP("ldc1 f%u, %u(%u)", rt, imm, rs);
   13515       LOAD_STORE_PATTERN;
   13516       putDReg(ft, load(Ity_F64, mkexpr(t1)));
   13517       break;
   13518 
   13519    case 0x3D:
   13520       /* Store Doubleword from Floating Point - SDC1 */
   13521       DIP("sdc1 f%u, %u(%u)", ft, imm, rs);
   13522       LOAD_STORE_PATTERN;
   13523       store(mkexpr(t1), getDReg(ft));
   13524       break;
   13525 
   13526    case 0x23:  /* LW */
   13527       DIP("lw r%u, %u(r%u)", rt, imm, rs);
   13528       LOAD_STORE_PATTERN;
   13529       putIReg(rt, mkWidenFrom32(ty, load(Ity_I32, mkexpr(t1)), True));
   13530       break;
   13531 
   13532    case 0x20:  /* LB */
   13533       DIP("lb r%u, %u(r%u)", rt, imm, rs);
   13534       LOAD_STORE_PATTERN;
   13535       if (mode64)
   13536          putIReg(rt, unop(Iop_8Sto64, load(Ity_I8, mkexpr(t1))));
   13537       else
   13538          putIReg(rt, unop(Iop_8Sto32, load(Ity_I8, mkexpr(t1))));
   13539       break;
   13540 
   13541    case 0x24:  /* LBU */
   13542       DIP("lbu r%u, %u(r%u)", rt, imm, rs);
   13543       LOAD_STORE_PATTERN;
   13544       if (mode64)
   13545          putIReg(rt, unop(Iop_8Uto64, load(Ity_I8, mkexpr(t1))));
   13546       else
   13547          putIReg(rt, unop(Iop_8Uto32, load(Ity_I8, mkexpr(t1))));
   13548       break;
   13549 
   13550    case 0x21:  /* LH */
   13551       DIP("lh r%u, %u(r%u)", rt, imm, rs);
   13552       LOAD_STORE_PATTERN;
   13553       if (mode64)
   13554          putIReg(rt, unop(Iop_16Sto64, load(Ity_I16, mkexpr(t1))));
   13555       else
   13556          putIReg(rt, unop(Iop_16Sto32, load(Ity_I16, mkexpr(t1))));
   13557       break;
   13558 
   13559    case 0x25:  /* LHU */
   13560       DIP("lhu r%u, %u(r%u)", rt, imm, rs);
   13561       LOAD_STORE_PATTERN;
   13562       if (mode64)
   13563          putIReg(rt, unop(Iop_16Uto64, load(Ity_I16, mkexpr(t1))));
   13564       else
   13565          putIReg(rt, unop(Iop_16Uto32, load(Ity_I16, mkexpr(t1))));
   13566       break;
   13567 
   13568    case 0x0F:  /* LUI */
   13569       p = (imm << 16);
   13570       DIP("lui r%u, imm: 0x%x", rt, imm);
   13571       if (mode64)
   13572          putIReg(rt, mkU64(extend_s_32to64(p)));
   13573       else
   13574          putIReg(rt, mkU32(p));
   13575       break;
   13576 
   13577    case 0x13:  /* COP1X */
   13578       switch (function) {
   13579       case 0x0: {  /* LWXC1 */
   13580          /* Load Word  Indexed to Floating Point - LWXC1 (MIPS32r2) */
   13581          DIP("lwxc1 f%u, r%u(r%u)", fd, rt, rs);
   13582          t2 = newTemp(ty);
   13583          assign(t2, binop(mode64 ? Iop_Add64 : Iop_Add32, getIReg(rs),
   13584                           getIReg(rt)));
   13585          if (fp_mode64) {
   13586             t0 = newTemp(Ity_I64);
   13587             t1 = newTemp(Ity_I32);
   13588             t3 = newTemp(Ity_F32);
   13589             t4 = newTemp(Ity_I64);
   13590             assign(t3, load(Ity_F32, mkexpr(t2)));
   13591 
   13592             assign(t4, mkWidenFrom32(Ity_I64, unop(Iop_ReinterpF32asI32,
   13593                                                    mkexpr(t3)), True));
   13594 
   13595             putFReg(fd, unop(Iop_ReinterpI64asF64, mkexpr(t4)));
   13596          } else {
   13597             putFReg(fd, load(Ity_F32, mkexpr(t2)));
   13598          }
   13599          break;
   13600       }
   13601 
   13602       case 0x1: {  /* LDXC1 */
   13603          /* Load Doubleword  Indexed to Floating Point
   13604             LDXC1 (MIPS32r2 and MIPS64) */
   13605          DIP("ldxc1 f%u, r%u(r%u)", fd, rt, rs);
   13606          t0 = newTemp(ty);
   13607          assign(t0, binop(mode64 ? Iop_Add64 : Iop_Add32, getIReg(rs),
   13608                           getIReg(rt)));
   13609          putDReg(fd, load(Ity_F64, mkexpr(t0)));
   13610          break;
   13611       }
   13612 
   13613       case 0x5:  /* Load Doubleword Indexed Unaligned to Floating Point - LUXC1;
   13614                     MIPS32r2 and MIPS64 */
   13615          DIP("luxc1 f%u, r%u(r%u)", fd, rt, rs);
   13616          if ((mode64 || VEX_MIPS_CPU_HAS_MIPS32R2(archinfo->hwcaps))
   13617              && fp_mode64) {
   13618             t0 = newTemp(ty);
   13619             t1 = newTemp(ty);
   13620             assign(t0, binop(mode64 ? Iop_Add64 : Iop_Add32,
   13621                              getIReg(rs), getIReg(rt)));
   13622             assign(t1, binop(mode64 ? Iop_And64 : Iop_And32,
   13623                              mkexpr(t0),
   13624                              mode64 ? mkU64(0xfffffffffffffff8ULL)
   13625                                     : mkU32(0xfffffff8ULL)));
   13626             putFReg(fd, load(Ity_F64, mkexpr(t1)));
   13627          } else {
   13628             ILLEGAL_INSTRUCTON;
   13629          }
   13630          break;
   13631 
   13632       case 0x8: {  /* Store Word Indexed from Floating Point - SWXC1 */
   13633          DIP("swxc1 f%u, r%u(r%u)", ft, rt, rs);
   13634          t0 = newTemp(ty);
   13635          assign(t0, binop(mode64 ? Iop_Add64 : Iop_Add32, getIReg(rs),
   13636                           getIReg(rt)));
   13637          if (fp_mode64) {
   13638             store(mkexpr(t0), getLoFromF64(tyF, getFReg(fs)));
   13639          } else {
   13640             store(mkexpr(t0), getFReg(fs));
   13641          }
   13642          break;
   13643       }
   13644       case 0x9: {  /* Store Doubleword Indexed from Floating Point - SDXC1 */
   13645          DIP("sdxc1 f%u, r%u(r%u)", fs, rt, rs);
   13646          t0 = newTemp(ty);
   13647          assign(t0, binop(mode64 ? Iop_Add64 : Iop_Add32, getIReg(rs),
   13648                           getIReg(rt)));
   13649          store(mkexpr(t0), getDReg(fs));
   13650          break;
   13651       }
   13652       case 0xD:  /* Store Doubleword Indexed Unaligned from Floating Point -
   13653                     SUXC1; MIPS64 MIPS32r2 */
   13654          DIP("suxc1 f%u, r%u(r%u)", fd, rt, rs);
   13655          if ((mode64 || VEX_MIPS_CPU_HAS_MIPS32R2(archinfo->hwcaps))
   13656              && fp_mode64) {
   13657             t0 = newTemp(ty);
   13658             t1 = newTemp(ty);
   13659             assign(t0, binop(mode64 ? Iop_Add64 : Iop_Add32,
   13660                              getIReg(rs), getIReg(rt)));
   13661             assign(t1, binop(mode64 ? Iop_And64 : Iop_And32,
   13662                              mkexpr(t0),
   13663                              mode64 ? mkU64(0xfffffffffffffff8ULL)
   13664                                     : mkU32(0xfffffff8ULL)));
   13665             store(mkexpr(t1), getFReg(fs));
   13666          } else {
   13667             ILLEGAL_INSTRUCTON;
   13668          }
   13669          break;
   13670 
   13671       case 0x0F: {
   13672          DIP("prefx");
   13673          break;
   13674       }
   13675       case 0x20:  {  /* MADD.S */
   13676          DIP("madd.s f%u, f%u, f%u, f%u", fd, fmt, fs, ft);
   13677          IRExpr *rm = get_IR_roundingmode();
   13678          t1 = newTemp(Ity_F32);
   13679          assign(t1, qop(Iop_MAddF32, rm,
   13680                         getLoFromF64(tyF, getFReg(fmt)),
   13681                         getLoFromF64(tyF, getFReg(fs)),
   13682                         getLoFromF64(tyF, getFReg(ft))));
   13683          putFReg(fd, mkWidenFromF32(tyF, mkexpr(t1)));
   13684          break;  /* MADD.S */
   13685       }
   13686       case 0x21: {  /* MADD.D */
   13687          DIP("madd.d f%u, f%u, f%u, f%u", fd, fmt, fs, ft);
   13688          IRExpr *rm = get_IR_roundingmode();
   13689          putDReg(fd, qop(Iop_MAddF64, rm, getDReg(fmt), getDReg(fs),
   13690                          getDReg(ft)));
   13691          break;  /* MADD.D */
   13692       }
   13693       case 0x28: {  /* MSUB.S */
   13694          DIP("msub.s f%u, f%u, f%u, f%u", fd, fmt, fs, ft);
   13695          IRExpr *rm = get_IR_roundingmode();
   13696          t1 = newTemp(Ity_F32);
   13697          assign(t1, qop(Iop_MSubF32, rm,
   13698                         getLoFromF64(tyF, getFReg(fmt)),
   13699                         getLoFromF64(tyF, getFReg(fs)),
   13700                         getLoFromF64(tyF, getFReg(ft))));
   13701          putFReg(fd, mkWidenFromF32(tyF, mkexpr(t1)));
   13702          break;  /* MSUB.S */
   13703       }
   13704       case 0x29: {  /* MSUB.D */
   13705          DIP("msub.d f%u, f%u, f%u, f%u", fd, fmt, fs, ft);
   13706          IRExpr *rm = get_IR_roundingmode();
   13707          putDReg(fd, qop(Iop_MSubF64, rm, getDReg(fmt), getDReg(fs),
   13708                          getDReg(ft)));
   13709          break;  /* MSUB.D */
   13710       }
   13711       case 0x30: {  /* NMADD.S */
   13712          DIP("nmadd.s f%u, f%u, f%u, f%u", fd, fmt, fs, ft);
   13713          IRExpr *rm = get_IR_roundingmode();
   13714          t1 = newTemp(Ity_F32);
   13715          assign(t1, qop(Iop_MAddF32, rm,
   13716                         getLoFromF64(tyF, getFReg(fmt)),
   13717                         getLoFromF64(tyF, getFReg(fs)),
   13718                         getLoFromF64(tyF, getFReg(ft))));
   13719 
   13720          putFReg(fd, mkWidenFromF32(tyF, unop(Iop_NegF32, mkexpr(t1))));
   13721          break;  /* NMADD.S */
   13722       }
   13723       case 0x31: {  /* NMADD.D */
   13724          DIP("nmadd.d f%u, f%u, f%u, f%u", fd, fmt, fs, ft);
   13725          IRExpr *rm = get_IR_roundingmode();
   13726          t1 = newTemp(Ity_F64);
   13727          assign(t1, qop(Iop_MAddF64, rm, getDReg(fmt), getDReg(fs),
   13728                         getDReg(ft)));
   13729          putDReg(fd, unop(Iop_NegF64, mkexpr(t1)));
   13730          break;  /* NMADD.D */
   13731       }
   13732       case 0x38: {  /* NMSUBB.S */
   13733          DIP("nmsub.s f%u, f%u, f%u, f%u", fd, fmt, fs, ft);
   13734          IRExpr *rm = get_IR_roundingmode();
   13735          t1 = newTemp(Ity_F32);
   13736          assign(t1, qop(Iop_MSubF32, rm,
   13737                         getLoFromF64(tyF, getFReg(fmt)),
   13738                         getLoFromF64(tyF, getFReg(fs)),
   13739                         getLoFromF64(tyF, getFReg(ft))));
   13740 
   13741          putFReg(fd, mkWidenFromF32(tyF, unop(Iop_NegF32, mkexpr(t1))));
   13742          break;  /* NMSUBB.S */
   13743       }
   13744       case 0x39: {  /* NMSUBB.D */
   13745          DIP("nmsub.d f%u, f%u, f%u, f%u", fd, fmt, fs, ft);
   13746          IRExpr *rm = get_IR_roundingmode();
   13747          t1 = newTemp(Ity_F64);
   13748          assign(t1, qop(Iop_MSubF64, rm, getDReg(fmt), getDReg(fs),
   13749                         getDReg(ft)));
   13750          putDReg(fd, unop(Iop_NegF64, mkexpr(t1)));
   13751          break;  /* NMSUBB.D */
   13752       }
   13753 
   13754       default:
   13755          goto decode_failure;
   13756       }
   13757       break;
   13758 
   13759    case 0x22:  /* LWL */
   13760       DIP("lwl r%u, %u(r%u)", rt, imm, rs);
   13761       if (mode64) {
   13762          /* t1 = addr */
   13763          t1 = newTemp(Ity_I64);
   13764 #if defined (_MIPSEL)
   13765          assign(t1, binop(Iop_Add64, getIReg(rs), mkU64(extend_s_16to64(imm))));
   13766 #elif defined (_MIPSEB)
   13767          assign(t1, binop(Iop_Xor64,
   13768                           mkU64(0x03),
   13769                           binop(Iop_Add64,
   13770                                 getIReg(rs),
   13771                                 mkU64(extend_s_16to64(imm)))));
   13772 #endif
   13773          /* t2 = word addr */
   13774          /* t4 = addr mod 4 */
   13775          LWX_SWX_PATTERN64;
   13776 
   13777          /* t3 = word content - shifted */
   13778          t3 = newTemp(Ity_I32);
   13779          assign(t3, binop(Iop_Shl32,
   13780                           load(Ity_I32, mkexpr(t2)),
   13781                           narrowTo(Ity_I8,
   13782                                    binop(Iop_Shl32,
   13783                                          binop(Iop_Sub32,
   13784                                                mkU32(0x03),
   13785                                                mkexpr(t4)),
   13786                                          mkU8(3)))));
   13787 
   13788          /* rt content - adjusted */
   13789          t5 = newTemp(Ity_I32);
   13790          assign(t5, binop(Iop_And32,
   13791                           mkNarrowTo32(ty, getIReg(rt)),
   13792                           binop(Iop_Shr32,
   13793                                 mkU32(0x00FFFFFF),
   13794                                       narrowTo(Ity_I8, binop(Iop_Mul32,
   13795                                                              mkU32(0x08),
   13796                                                              mkexpr(t4))))));
   13797 
   13798          putIReg(rt, mkWidenFrom32(ty, binop(Iop_Or32, mkexpr(t5),
   13799                                              mkexpr(t3)), True));
   13800       } else {
   13801          /* t1 = addr */
   13802          t1 = newTemp(Ity_I32);
   13803 #if defined (_MIPSEL)
   13804          assign(t1, binop(Iop_Add32, getIReg(rs), mkU32(extend_s_16to32(imm))));
   13805 #elif defined (_MIPSEB)
   13806          assign(t1, binop(Iop_Xor32, mkU32(0x3), binop(Iop_Add32, getIReg(rs),
   13807                                      mkU32(extend_s_16to32(imm)))));
   13808 #endif
   13809 
   13810          /* t2 = word addr */
   13811          /* t4 = addr mod 4 */
   13812          LWX_SWX_PATTERN;
   13813 
   13814          /* t3 = word content - shifted */
   13815          t3 = newTemp(Ity_I32);
   13816          assign(t3, binop(Iop_Shl32, load(Ity_I32, mkexpr(t2)), narrowTo(Ity_I8,
   13817                     binop(Iop_Shl32, binop(Iop_Sub32, mkU32(0x03), mkexpr(t4)),
   13818                     mkU8(3)))));
   13819 
   13820          /* rt content  - adjusted */
   13821          t5 = newTemp(Ity_I32);
   13822          assign(t5, binop(Iop_And32,
   13823                           getIReg(rt),
   13824                           binop(Iop_Shr32,
   13825                                 mkU32(0x00FFFFFF),
   13826                                       narrowTo(Ity_I8, binop(Iop_Mul32,
   13827                                                              mkU32(0x08),
   13828                                                              mkexpr(t4))))));
   13829 
   13830          putIReg(rt, binop(Iop_Or32, mkexpr(t5), mkexpr(t3)));
   13831       }
   13832       break;
   13833 
   13834    case 0x26:  /* LWR */
   13835       DIP("lwr r%u, %u(r%u)", rt, imm, rs);
   13836       if (mode64) {
   13837          /* t1 = addr */
   13838          t1 = newTemp(Ity_I64);
   13839 #if defined (_MIPSEL)
   13840          assign(t1, binop(Iop_Add64, getIReg(rs), mkU64(extend_s_16to64(imm))));
   13841 #elif defined (_MIPSEB)
   13842          assign(t1, binop(Iop_Xor64,
   13843                           mkU64(0x3),
   13844                           binop(Iop_Add64,
   13845                                 getIReg(rs),
   13846                                 mkU64(extend_s_16to64(imm)))));
   13847 #endif
   13848          /* t2 = word addr */
   13849          /* t4 = addr mod 4 */
   13850          LWX_SWX_PATTERN64;
   13851 
   13852          /* t3 = word content - shifted */
   13853          t3 = newTemp(Ity_I32);
   13854          assign(t3, binop(Iop_Shr32,
   13855                           load(Ity_I32, mkexpr(t2)),
   13856                           narrowTo(Ity_I8,
   13857                                    binop(Iop_Shl32, mkexpr(t4), mkU8(0x03)))));
   13858 
   13859          /* rt content  - adjusted */
   13860          t5 = newTemp(Ity_I32);
   13861          assign(t5, binop(Iop_And32, mkNarrowTo32(ty, getIReg(rt)),
   13862                 unop(Iop_Not32, binop(Iop_Shr32, mkU32(0xFFFFFFFF),
   13863                 narrowTo(Ity_I8, binop(Iop_Shl32, mkexpr(t4), mkU8(0x3)))))));
   13864 
   13865          putIReg(rt, mkWidenFrom32(ty, binop(Iop_Or32, mkexpr(t5),
   13866                                        mkexpr(t3)), True));
   13867 
   13868       } else {
   13869          /* t1 = addr */
   13870          t1 = newTemp(Ity_I32);
   13871 #if defined (_MIPSEL)
   13872          assign(t1, binop(Iop_Add32, getIReg(rs), mkU32(extend_s_16to32(imm))));
   13873 #elif defined (_MIPSEB)
   13874          assign(t1, binop(Iop_Xor32, mkU32(0x3), binop(Iop_Add32, getIReg(rs),
   13875                                      mkU32(extend_s_16to32(imm)))));
   13876 #endif
   13877 
   13878          /* t2 = word addr */
   13879          /* t4 = addr mod 4 */
   13880          LWX_SWX_PATTERN;
   13881 
   13882          /* t3 = word content - shifted */
   13883          t3 = newTemp(Ity_I32);
   13884          assign(t3, binop(Iop_Shr32, load(Ity_I32, mkexpr(t2)),
   13885                     narrowTo(Ity_I8, binop(Iop_Shl32, mkexpr(t4),
   13886                     mkU8(3)))));
   13887 
   13888          /* rt content  - adjusted */
   13889          t5 = newTemp(Ity_I32);
   13890          assign(t5, binop(Iop_And32, getIReg(rt), unop(Iop_Not32,
   13891                     binop(Iop_Shr32, mkU32(0xFFFFFFFF), narrowTo(Ity_I8,
   13892                           binop(Iop_Shl32, mkexpr(t4), mkU8(0x3)))))));
   13893 
   13894          putIReg(rt, binop(Iop_Or32, mkexpr(t5), mkexpr(t3)));
   13895       }
   13896       break;
   13897 
   13898    case 0x2B:  /* SW */
   13899       DIP("sw r%u, %u(r%u)", rt, imm, rs);
   13900       LOAD_STORE_PATTERN;
   13901       store(mkexpr(t1), mkNarrowTo32(ty, getIReg(rt)));
   13902       break;
   13903 
   13904    case 0x2C: {  /* SDL rt, offset(base) MIPS64 */
   13905       DIP("sdl r%u, %u(r%u)", rt, imm, rs);
   13906       vassert(mode64);
   13907       IRTemp A_byte = newTemp(Ity_I8);
   13908       IRTemp B_byte = newTemp(Ity_I8);
   13909       IRTemp C_byte = newTemp(Ity_I8);
   13910       IRTemp D_byte = newTemp(Ity_I8);
   13911       IRTemp E_byte = newTemp(Ity_I8);
   13912       IRTemp F_byte = newTemp(Ity_I8);
   13913       IRTemp G_byte = newTemp(Ity_I8);
   13914       IRTemp H_byte = newTemp(Ity_I8);
   13915       IRTemp B_pos  = newTemp(Ity_I64);
   13916       IRTemp C_pos  = newTemp(Ity_I64);
   13917       IRTemp D_pos  = newTemp(Ity_I64);
   13918       IRTemp E_pos  = newTemp(Ity_I64);
   13919       IRTemp F_pos  = newTemp(Ity_I64);
   13920       IRTemp G_pos  = newTemp(Ity_I64);
   13921 
   13922       /* H byte */
   13923       assign(H_byte, getByteFromReg(rt, 0));
   13924       /* G byte */
   13925       assign(G_byte, getByteFromReg(rt, 1));
   13926       /* F byte */
   13927       assign(F_byte, getByteFromReg(rt, 2));
   13928       /* E byte */
   13929       assign(E_byte, getByteFromReg(rt, 3));
   13930       /* D byte */
   13931       assign(D_byte, getByteFromReg(rt, 4));
   13932       /* C byte */
   13933       assign(C_byte, getByteFromReg(rt, 5));
   13934       /* B byte */
   13935       assign(B_byte, getByteFromReg(rt, 6));
   13936       /* A byte */
   13937       assign(A_byte, getByteFromReg(rt, 7));
   13938 
   13939       /* t1 = addr */
   13940       t1 = newTemp(Ity_I64);
   13941       assign(t1, binop(Iop_Add64, getIReg(rs), mkU64(extend_s_16to64(imm))));
   13942 
   13943       /* t2 = word addr */
   13944       t2 = newTemp(Ity_I64);
   13945       assign(t2, binop(Iop_And64, mkexpr(t1), mkU64(0xFFFFFFFFFFFFFFF8ULL)));
   13946 
   13947       /* t3 = addr mod 7 */
   13948       t3 = newTemp(Ity_I64);
   13949       assign(t3, binop(Iop_And64, mkexpr(t1), mkU64(0x7)));
   13950 
   13951 #if defined (_MIPSEL)
   13952       /* Calculate X_byte position. */
   13953       assign(B_pos, IRExpr_ITE(binop(Iop_CmpLT64U, mkexpr(t3), mkU64(0x1)),
   13954                                mkU64(0x0),
   13955                                mkU64(0x1)));
   13956 
   13957       assign(C_pos, IRExpr_ITE(binop(Iop_CmpLT64U, mkexpr(t3), mkU64(0x2)),
   13958                                mkU64(0x0),
   13959                                mkU64(0x2)));
   13960 
   13961       assign(D_pos, IRExpr_ITE(binop(Iop_CmpLT64U, mkexpr(t3), mkU64(0x3)),
   13962                                mkU64(0x0),
   13963                                mkU64(0x3)));
   13964 
   13965       assign(E_pos, IRExpr_ITE(binop(Iop_CmpLT64U, mkexpr(t3), mkU64(0x4)),
   13966                                mkU64(0x0),
   13967                                mkU64(0x4)));
   13968 
   13969       assign(F_pos, IRExpr_ITE(binop(Iop_CmpLT64U, mkexpr(t3), mkU64(0x5)),
   13970                                mkU64(0x0),
   13971                                mkU64(0x5)));
   13972 
   13973       assign(G_pos, IRExpr_ITE(binop(Iop_CmpEQ64, mkexpr(t3), mkU64(0x7)),
   13974                                mkU64(0x1),
   13975                                mkU64(0x0)));
   13976 
   13977       /* Store X_byte on the right place. */
   13978       store(mkexpr(t2), mkexpr(H_byte));
   13979       store(binop(Iop_Add64, mkexpr(t2), mkexpr(G_pos)), mkexpr(G_byte));
   13980       store(binop(Iop_Sub64, mkexpr(t1), mkexpr(F_pos)), mkexpr(F_byte));
   13981       store(binop(Iop_Sub64, mkexpr(t1), mkexpr(E_pos)), mkexpr(E_byte));
   13982       store(binop(Iop_Sub64, mkexpr(t1), mkexpr(D_pos)), mkexpr(D_byte));
   13983       store(binop(Iop_Sub64, mkexpr(t1), mkexpr(C_pos)), mkexpr(C_byte));
   13984       store(binop(Iop_Sub64, mkexpr(t1), mkexpr(B_pos)), mkexpr(B_byte));
   13985       store(mkexpr(t1), mkexpr(A_byte));
   13986 
   13987 #else /* _MIPSEB */
   13988       /* Calculate X_byte position. */
   13989       assign(B_pos, IRExpr_ITE(binop(Iop_CmpEQ64, mkexpr(t3), mkU64(0x7)),
   13990                                mkU64(0x0),
   13991                                mkU64(0x1)));
   13992 
   13993       assign(C_pos, IRExpr_ITE(binop(Iop_CmpLT64U, mkexpr(t3), mkU64(0x6)),
   13994                                mkU64(0x2),
   13995                                mkU64(0x0)));
   13996 
   13997       assign(D_pos, IRExpr_ITE(binop(Iop_CmpLT64U, mkexpr(t3), mkU64(0x5)),
   13998                                mkU64(0x3),
   13999                                mkU64(0x0)));
   14000 
   14001       assign(E_pos, IRExpr_ITE(binop(Iop_CmpLT64U, mkexpr(t3), mkU64(0x4)),
   14002                                mkU64(0x4),
   14003                                mkU64(0x0)));
   14004 
   14005       assign(F_pos, IRExpr_ITE(binop(Iop_CmpLT64U, mkexpr(t3), mkU64(0x3)),
   14006                                mkU64(0x5),
   14007                                mkU64(0x0)));
   14008 
   14009       assign(G_pos, IRExpr_ITE(binop(Iop_CmpEQ64, mkexpr(t3), mkU64(0x0)),
   14010                                mkU64(0x6),
   14011                                mkU64(0x7)));
   14012 
   14013       /* Store X_byte on the right place. */
   14014       store(binop(Iop_Add64, mkexpr(t2), mkU64(0x7)), mkexpr(H_byte));
   14015       store(binop(Iop_Add64, mkexpr(t2), mkexpr(G_pos)), mkexpr(G_byte));
   14016       store(binop(Iop_Add64, mkexpr(t1), mkexpr(F_pos)), mkexpr(F_byte));
   14017       store(binop(Iop_Add64, mkexpr(t1), mkexpr(E_pos)), mkexpr(E_byte));
   14018       store(binop(Iop_Add64, mkexpr(t1), mkexpr(D_pos)), mkexpr(D_byte));
   14019       store(binop(Iop_Add64, mkexpr(t1), mkexpr(C_pos)), mkexpr(C_byte));
   14020       store(binop(Iop_Add64, mkexpr(t1), mkexpr(B_pos)), mkexpr(B_byte));
   14021       store(mkexpr(t1), mkexpr(A_byte));
   14022 #endif
   14023 
   14024       break;
   14025    }
   14026 
   14027    case 0x2D: {
   14028       /* SDR rt, offset(base) - MIPS64 */
   14029       vassert(mode64);
   14030       DIP("sdr r%u, %u(r%u)", rt, imm, rs);
   14031       IRTemp A_byte = newTemp(Ity_I8);
   14032       IRTemp B_byte = newTemp(Ity_I8);
   14033       IRTemp C_byte = newTemp(Ity_I8);
   14034       IRTemp D_byte = newTemp(Ity_I8);
   14035       IRTemp E_byte = newTemp(Ity_I8);
   14036       IRTemp F_byte = newTemp(Ity_I8);
   14037       IRTemp G_byte = newTemp(Ity_I8);
   14038       IRTemp H_byte = newTemp(Ity_I8);
   14039       IRTemp B_pos  = newTemp(Ity_I64);
   14040       IRTemp C_pos  = newTemp(Ity_I64);
   14041       IRTemp D_pos  = newTemp(Ity_I64);
   14042       IRTemp E_pos  = newTemp(Ity_I64);
   14043       IRTemp F_pos  = newTemp(Ity_I64);
   14044       IRTemp G_pos  = newTemp(Ity_I64);
   14045 
   14046       /* H byte */
   14047       assign(H_byte, getByteFromReg(rt, 0));
   14048       /* G byte */
   14049       assign(G_byte, getByteFromReg(rt, 1));
   14050       /* F byte */
   14051       assign(F_byte, getByteFromReg(rt, 2));
   14052       /* E byte */
   14053       assign(E_byte, getByteFromReg(rt, 3));
   14054       /* D byte */
   14055       assign(D_byte, getByteFromReg(rt, 4));
   14056       /* C byte */
   14057       assign(C_byte, getByteFromReg(rt, 5));
   14058       /* B byte */
   14059       assign(B_byte, getByteFromReg(rt, 6));
   14060       /* A byte */
   14061       assign(A_byte, getByteFromReg(rt, 7));
   14062 
   14063       /* t1 = addr */
   14064       t1 = newTemp(Ity_I64);
   14065       assign(t1, binop(Iop_Add64, getIReg(rs), mkU64(extend_s_16to64(imm))));
   14066 
   14067       /* t2 = word addr */
   14068       t2 = newTemp(Ity_I64);
   14069       assign(t2, binop(Iop_And64, mkexpr(t1), mkU64(0xFFFFFFFFFFFFFFF8ULL)));
   14070 
   14071       /* t3 = addr mod 7 */
   14072       t3 = newTemp(Ity_I64);
   14073       assign(t3, binop(Iop_And64, mkexpr(t1), mkU64(0x7)));
   14074 
   14075 #if defined (_MIPSEL)
   14076       /* Calculate X_byte position. */
   14077       assign(B_pos, IRExpr_ITE(binop(Iop_CmpLT64U, mkU64(0x1), mkexpr(t3)),
   14078                                mkU64(0x0),
   14079                                mkU64(0x6)));
   14080 
   14081       assign(C_pos, IRExpr_ITE(binop(Iop_CmpLT64U, mkU64(0x2), mkexpr(t3)),
   14082                                mkU64(0x0),
   14083                                mkU64(0x5)));
   14084 
   14085       assign(D_pos, IRExpr_ITE(binop(Iop_CmpLT64U, mkU64(0x3), mkexpr(t3)),
   14086                                mkU64(0x0),
   14087                                mkU64(0x4)));
   14088 
   14089       assign(E_pos, IRExpr_ITE(binop(Iop_CmpLT64U, mkU64(0x4), mkexpr(t3)),
   14090                                mkU64(0x0),
   14091                                mkU64(0x3)));
   14092 
   14093       assign(F_pos, IRExpr_ITE(binop(Iop_CmpLT64U, mkU64(0x5), mkexpr(t3)),
   14094                                mkU64(0x0),
   14095                                mkU64(0x2)));
   14096 
   14097       assign(G_pos, IRExpr_ITE(binop(Iop_CmpEQ64, mkexpr(t3), mkU64(0x7)),
   14098                                mkU64(0x0),
   14099                                mkU64(0x1)));
   14100 
   14101       /* Store X_byte on the right place. */
   14102       store(binop(Iop_Add64, mkexpr(t2), mkU64(0x7)), mkexpr(A_byte));
   14103       store(binop(Iop_Add64, mkexpr(t1), mkexpr(B_pos)), mkexpr(B_byte));
   14104       store(binop(Iop_Add64, mkexpr(t1), mkexpr(C_pos)), mkexpr(C_byte));
   14105       store(binop(Iop_Add64, mkexpr(t1), mkexpr(D_pos)), mkexpr(D_byte));
   14106       store(binop(Iop_Add64, mkexpr(t1), mkexpr(E_pos)), mkexpr(E_byte));
   14107       store(binop(Iop_Add64, mkexpr(t1), mkexpr(F_pos)), mkexpr(F_byte));
   14108       store(binop(Iop_Add64, mkexpr(t1), mkexpr(G_pos)), mkexpr(G_byte));
   14109       store(mkexpr(t1), mkexpr(H_byte));
   14110 
   14111 #else /* _MIPSEB */
   14112       /* Calculate X_byte position. */
   14113       assign(B_pos, IRExpr_ITE(binop(Iop_CmpLT64U, mkU64(0x5), mkexpr(t3)),
   14114                                mkU64(0x6),
   14115                                mkU64(0x0)));
   14116 
   14117       assign(C_pos, IRExpr_ITE(binop(Iop_CmpLT64U, mkU64(0x4), mkexpr(t3)),
   14118                                mkU64(0x5),
   14119                                mkU64(0x0)));
   14120 
   14121       assign(D_pos, IRExpr_ITE(binop(Iop_CmpLT64U, mkU64(0x3), mkexpr(t3)),
   14122                                mkU64(0x4),
   14123                                mkU64(0x0)));
   14124 
   14125       assign(E_pos, IRExpr_ITE(binop(Iop_CmpLT64U, mkU64(0x2), mkexpr(t3)),
   14126                                mkU64(0x3),
   14127                                mkU64(0x0)));
   14128 
   14129       assign(F_pos, IRExpr_ITE(binop(Iop_CmpLT64U, mkU64(0x1), mkexpr(t3)),
   14130                                mkU64(0x2),
   14131                                mkU64(0x0)));
   14132 
   14133       assign(G_pos, IRExpr_ITE(binop(Iop_CmpEQ64, mkexpr(t3), mkU64(0x0)),
   14134                                mkU64(0x0),
   14135                                mkU64(0x1)));
   14136 
   14137       /* Store X_byte on the right place. */
   14138       store(mkexpr(t2), mkexpr(A_byte));
   14139       store(binop(Iop_Sub64, mkexpr(t1), mkexpr(B_pos)), mkexpr(B_byte));
   14140       store(binop(Iop_Sub64, mkexpr(t1), mkexpr(C_pos)), mkexpr(C_byte));
   14141       store(binop(Iop_Sub64, mkexpr(t1), mkexpr(D_pos)), mkexpr(D_byte));
   14142       store(binop(Iop_Sub64, mkexpr(t1), mkexpr(E_pos)), mkexpr(E_byte));
   14143       store(binop(Iop_Sub64, mkexpr(t1), mkexpr(F_pos)), mkexpr(F_byte));
   14144       store(binop(Iop_Sub64, mkexpr(t1), mkexpr(G_pos)), mkexpr(G_byte));
   14145       store(mkexpr(t1), mkexpr(H_byte));
   14146 #endif
   14147       break;
   14148    }
   14149 
   14150    case 0x28:  /* SB */
   14151       DIP("sb r%u, %u(r%u)", rt, imm, rs);
   14152       LOAD_STORE_PATTERN;
   14153       store(mkexpr(t1), narrowTo(Ity_I8, getIReg(rt)));
   14154       break;
   14155 
   14156    case 0x29:  /* SH */
   14157       DIP("sh r%u, %u(r%u)", rt, imm, rs);
   14158       LOAD_STORE_PATTERN;
   14159       store(mkexpr(t1), narrowTo(Ity_I16, getIReg(rt)));
   14160       break;
   14161 
   14162    case 0x2A:  /* SWL */
   14163       DIP("swl r%u, %u(r%u)", rt, imm, rs);
   14164       if (mode64) {
   14165          IRTemp E_byte = newTemp(Ity_I8);
   14166          IRTemp F_byte = newTemp(Ity_I8);
   14167          IRTemp G_byte = newTemp(Ity_I8);
   14168          IRTemp H_byte = newTemp(Ity_I8);
   14169          IRTemp F_pos  = newTemp(Ity_I64);
   14170          IRTemp G_pos  = newTemp(Ity_I64);
   14171 
   14172          /* H byte */
   14173          assign(H_byte, getByteFromReg(rt, 0));
   14174          /* G byte */
   14175          assign(G_byte, getByteFromReg(rt, 1));
   14176          /* F byte */
   14177          assign(F_byte, getByteFromReg(rt, 2));
   14178          /* E byte */
   14179          assign(E_byte, getByteFromReg(rt, 3));
   14180 
   14181          /* t1 = addr */
   14182          t1 = newTemp(Ity_I64);
   14183          assign(t1, binop(Iop_Add64, getIReg(rs), mkU64(extend_s_16to64(imm))));
   14184 
   14185          /* t2 = word addr */
   14186          t2 = newTemp(Ity_I64);
   14187          assign(t2, binop(Iop_And64, mkexpr(t1), mkU64(0xFFFFFFFFFFFFFFFCULL)));
   14188 
   14189          /* t3 = addr mod 4 */
   14190          t3 = newTemp(Ity_I64);
   14191          assign(t3, binop(Iop_And64, mkexpr(t1), mkU64(0x3)));
   14192 
   14193 #if defined (_MIPSEL)
   14194          /* Calculate X_byte position. */
   14195          assign(F_pos, IRExpr_ITE(binop(Iop_CmpEQ64, mkexpr(t3), mkU64(0x0)),
   14196                                   mkU64(0x0),
   14197                                   mkU64(0x1)));
   14198 
   14199          assign(G_pos, IRExpr_ITE(binop(Iop_CmpEQ64, mkexpr(t3), mkU64(0x3)),
   14200                                   mkU64(0x1),
   14201                                   mkU64(0x0)));
   14202 
   14203          /* Store X_byte on the right place. */
   14204          store(mkexpr(t2), mkexpr(H_byte));
   14205          store(binop(Iop_Add64, mkexpr(t2), mkexpr(G_pos)), mkexpr(G_byte));
   14206          store(binop(Iop_Sub64, mkexpr(t1), mkexpr(F_pos)), mkexpr(F_byte));
   14207          store(mkexpr(t1), mkexpr(E_byte));
   14208 
   14209 #else    /* _MIPSEB */
   14210          /* Calculate X_byte position. */
   14211          assign(F_pos, IRExpr_ITE(binop(Iop_CmpEQ64, mkexpr(t3), mkU64(0x3)),
   14212                                   mkU64(0x0),
   14213                                   mkU64(0x1)));
   14214 
   14215          assign(G_pos, IRExpr_ITE(binop(Iop_CmpEQ64, mkexpr(t3), mkU64(0x0)),
   14216                                   mkU64(0x2),
   14217                                   mkU64(0x3)));
   14218 
   14219          store(binop(Iop_Add64, mkexpr(t2), mkU64(3)), mkexpr(H_byte));
   14220          store(binop(Iop_Add64, mkexpr(t2), mkexpr(G_pos)), mkexpr(G_byte));
   14221          store(binop(Iop_Add64, mkexpr(t1), mkexpr(F_pos)), mkexpr(F_byte));
   14222          store(mkexpr(t1), mkexpr(E_byte));
   14223 
   14224 #endif
   14225       } else {
   14226          IRTemp E_byte = newTemp(Ity_I8);
   14227          IRTemp F_byte = newTemp(Ity_I8);
   14228          IRTemp G_byte = newTemp(Ity_I8);
   14229          IRTemp H_byte = newTemp(Ity_I8);
   14230          IRTemp F_pos  = newTemp(Ity_I32);
   14231          IRTemp G_pos  = newTemp(Ity_I32);
   14232 
   14233          /* H byte */
   14234          assign(H_byte, getByteFromReg(rt, 0));
   14235          /* G byte */
   14236          assign(G_byte, getByteFromReg(rt, 1));
   14237          /* F byte */
   14238          assign(F_byte, getByteFromReg(rt, 2));
   14239          /* E byte */
   14240          assign(E_byte, getByteFromReg(rt, 3));
   14241 
   14242          /* t1 = addr */
   14243          t1 = newTemp(Ity_I32);
   14244          assign(t1, binop(Iop_Add32, getIReg(rs), mkU32(extend_s_16to32(imm))));
   14245 
   14246          /* t2 = word addr */
   14247          t2 = newTemp(Ity_I32);
   14248          assign(t2, binop(Iop_And32, mkexpr(t1), mkU32(0xFFFFFFFCULL)));
   14249 
   14250          /* t3 = addr mod 4 */
   14251          t3 = newTemp(Ity_I32);
   14252          assign(t3, binop(Iop_And32, mkexpr(t1), mkU32(0x3)));
   14253 
   14254 #if defined (_MIPSEL)
   14255          /* Calculate X_byte position. */
   14256          assign(F_pos, IRExpr_ITE(binop(Iop_CmpEQ32, mkexpr(t3), mkU32(0x0)),
   14257                                   mkU32(0x0),
   14258                                   mkU32(0x1)));
   14259 
   14260          assign(G_pos, IRExpr_ITE(binop(Iop_CmpEQ32, mkexpr(t3), mkU32(0x3)),
   14261                                   mkU32(0x1),
   14262                                   mkU32(0x0)));
   14263 
   14264          /* Store X_byte on the right place. */
   14265          store(mkexpr(t2), mkexpr(H_byte));
   14266          store(binop(Iop_Add32, mkexpr(t2), mkexpr(G_pos)), mkexpr(G_byte));
   14267          store(binop(Iop_Sub32, mkexpr(t1), mkexpr(F_pos)), mkexpr(F_byte));
   14268          store(mkexpr(t1), mkexpr(E_byte));
   14269 
   14270 #else    /* _MIPSEB */
   14271          /* Calculate X_byte position. */
   14272          assign(F_pos, IRExpr_ITE(binop(Iop_CmpEQ32, mkexpr(t3), mkU32(0x3)),
   14273                                   mkU32(0x0),
   14274                                   mkU32(0x1)));
   14275 
   14276          assign(G_pos, IRExpr_ITE(binop(Iop_CmpEQ32, mkexpr(t3), mkU32(0x0)),
   14277                                   mkU32(0x2),
   14278                                   mkU32(0x3)));
   14279 
   14280          store(binop(Iop_Add32, mkexpr(t2), mkU32(3)), mkexpr(H_byte));
   14281          store(binop(Iop_Add32, mkexpr(t2), mkexpr(G_pos)), mkexpr(G_byte));
   14282          store(binop(Iop_Add32, mkexpr(t1), mkexpr(F_pos)), mkexpr(F_byte));
   14283          store(mkexpr(t1), mkexpr(E_byte));
   14284 
   14285 #endif
   14286       }
   14287       break;
   14288 
   14289    case 0x2E:  /* SWR */
   14290       DIP("swr r%u, %u(r%u)", rt, imm, rs);
   14291       if (mode64) {
   14292          IRTemp E_byte = newTemp(Ity_I8);
   14293          IRTemp F_byte = newTemp(Ity_I8);
   14294          IRTemp G_byte = newTemp(Ity_I8);
   14295          IRTemp H_byte = newTemp(Ity_I8);
   14296          IRTemp F_pos  = newTemp(Ity_I64);
   14297          IRTemp G_pos  = newTemp(Ity_I64);
   14298 
   14299          /* H byte */
   14300          assign(H_byte, getByteFromReg(rt, 0));
   14301          /* G byte */
   14302          assign(G_byte, getByteFromReg(rt, 1));
   14303          /* F byte */
   14304          assign(F_byte, getByteFromReg(rt, 2));
   14305          /* E byte */
   14306          assign(E_byte, getByteFromReg(rt, 3));
   14307 
   14308          /* t1 = addr */
   14309          t1 = newTemp(Ity_I64);
   14310          assign(t1, binop(Iop_Add64, getIReg(rs), mkU64(extend_s_16to64(imm))));
   14311 
   14312          /* t2 = word addr */
   14313          t2 = newTemp(Ity_I64);
   14314          assign(t2, binop(Iop_And64, mkexpr(t1), mkU64(0xFFFFFFFFFFFFFFFCULL)));
   14315 
   14316          /* t3 = addr mod 4 */
   14317          t3 = newTemp(Ity_I64);
   14318          assign(t3, binop(Iop_And64, mkexpr(t1), mkU64(0x3)));
   14319 
   14320 #if defined (_MIPSEL)
   14321          /* Calculate X_byte position. */
   14322          assign(F_pos, IRExpr_ITE(binop(Iop_CmpEQ64, mkexpr(t3), mkU64(0x0)),
   14323                                   mkU64(0x2),
   14324                                   mkU64(0x3)));
   14325 
   14326          assign(G_pos, IRExpr_ITE(binop(Iop_CmpEQ64, mkexpr(t3), mkU64(0x3)),
   14327                                   mkU64(0x0),
   14328                                   mkU64(0x1)));
   14329 
   14330          /* Store X_byte on the right place. */
   14331          store(binop(Iop_Add64, mkexpr(t2), mkU64(0x3)), mkexpr(E_byte));
   14332          store(binop(Iop_Add64, mkexpr(t2), mkexpr(F_pos)), mkexpr(F_byte));
   14333          store(binop(Iop_Add64, mkexpr(t1), mkexpr(G_pos)), mkexpr(G_byte));
   14334          store(mkexpr(t1), mkexpr(H_byte));
   14335 
   14336 #else    /* _MIPSEB */
   14337          /* Calculate X_byte position. */
   14338          assign(F_pos, IRExpr_ITE(binop(Iop_CmpEQ64, mkexpr(t3), mkU64(0x3)),
   14339                                   mkU64(0x1),
   14340                                   mkU64(0x0)));
   14341 
   14342          assign(G_pos, IRExpr_ITE(binop(Iop_CmpEQ64, mkexpr(t3), mkU64(0x0)),
   14343                                   mkU64(0x0),
   14344                                   mkU64(0x1)));
   14345 
   14346          /* Store X_byte on the right place. */
   14347          store(mkexpr(t2), mkexpr(E_byte));
   14348          store(binop(Iop_Add64, mkexpr(t2), mkexpr(F_pos)), mkexpr(F_byte));
   14349          store(binop(Iop_Sub64, mkexpr(t1), mkexpr(G_pos)), mkexpr(G_byte));
   14350          store(mkexpr(t1), mkexpr(H_byte));
   14351 #endif
   14352       } else {
   14353          IRTemp E_byte = newTemp(Ity_I8);
   14354          IRTemp F_byte = newTemp(Ity_I8);
   14355          IRTemp G_byte = newTemp(Ity_I8);
   14356          IRTemp H_byte = newTemp(Ity_I8);
   14357          IRTemp F_pos  = newTemp(Ity_I32);
   14358          IRTemp G_pos  = newTemp(Ity_I32);
   14359 
   14360          /* H byte */
   14361          assign(H_byte, getByteFromReg(rt, 0));
   14362          /* G byte */
   14363          assign(G_byte, getByteFromReg(rt, 1));
   14364          /* F byte */
   14365          assign(F_byte, getByteFromReg(rt, 2));
   14366          /* E byte */
   14367          assign(E_byte, getByteFromReg(rt, 3));
   14368 
   14369          /* t1 = addr */
   14370          t1 = newTemp(Ity_I32);
   14371          assign(t1, binop(Iop_Add32, getIReg(rs), mkU32(extend_s_16to32(imm))));
   14372 
   14373          /* t2 = word addr */
   14374          t2 = newTemp(Ity_I32);
   14375          assign(t2, binop(Iop_And32, mkexpr(t1), mkU32(0xFFFFFFFCULL)));
   14376 
   14377          /* t3 = addr mod 4 */
   14378          t3 = newTemp(Ity_I32);
   14379          assign(t3, binop(Iop_And32, mkexpr(t1), mkU32(0x3)));
   14380 
   14381 #if defined (_MIPSEL)
   14382          /* Calculate X_byte position. */
   14383          assign(F_pos, IRExpr_ITE(binop(Iop_CmpEQ32, mkexpr(t3), mkU32(0x0)),
   14384                                   mkU32(0x2),
   14385                                   mkU32(0x3)));
   14386 
   14387          assign(G_pos, IRExpr_ITE(binop(Iop_CmpEQ32, mkexpr(t3), mkU32(0x3)),
   14388                                   mkU32(0x0),
   14389                                   mkU32(0x1)));
   14390 
   14391          /* Store X_byte on the right place. */
   14392          store(binop(Iop_Add32, mkexpr(t2), mkU32(0x3)), mkexpr(E_byte));
   14393          store(binop(Iop_Add32, mkexpr(t2), mkexpr(F_pos)), mkexpr(F_byte));
   14394          store(binop(Iop_Add32, mkexpr(t1), mkexpr(G_pos)), mkexpr(G_byte));
   14395          store(mkexpr(t1), mkexpr(H_byte));
   14396 
   14397 #else    /* _MIPSEB */
   14398          /* Calculate X_byte position. */
   14399          assign(F_pos, IRExpr_ITE(binop(Iop_CmpEQ32, mkexpr(t3), mkU32(0x3)),
   14400                                   mkU32(0x1),
   14401                                   mkU32(0x0)));
   14402 
   14403          assign(G_pos, IRExpr_ITE(binop(Iop_CmpEQ32, mkexpr(t3), mkU32(0x0)),
   14404                                   mkU32(0x0),
   14405                                   mkU32(0x1)));
   14406 
   14407          /* Store X_byte on the right place. */
   14408          store(mkexpr(t2), mkexpr(E_byte));
   14409          store(binop(Iop_Add32, mkexpr(t2), mkexpr(F_pos)), mkexpr(F_byte));
   14410          store(binop(Iop_Sub32, mkexpr(t1), mkexpr(G_pos)), mkexpr(G_byte));
   14411          store(mkexpr(t1), mkexpr(H_byte));
   14412 #endif
   14413       }
   14414       break;
   14415 
   14416    case 0x1C:  /* Special2 */
   14417       switch (function) {
   14418          /* Cavium Specific instructions */
   14419          case 0x03: case 0x32: case 0x33:  /* DMUL, CINS , CINS32 */
   14420          case 0x3A: case 0x3B: case 0x2B:  /* EXT,  EXT32, SNE    */
   14421          /* CVM Compare Instructions */
   14422          case 0x2A: case 0x2E: case 0x2F:  /* SEQ,  SEQI,  SNEI   */
   14423          /* CPU Load, Store, Memory, and Control Instructions */
   14424          case 0x18: case 0x19:             /* SAA, SAAD */
   14425          case 0x1F:                        /* LAA, LAAD, LAI, LAID */
   14426          case 0x28: case 0x2C: case 0x2D:  /* BADDU, POP, DPOP */
   14427             if (VEX_MIPS_COMP_ID(archinfo->hwcaps) == VEX_PRID_COMP_CAVIUM) {
   14428                if (dis_instr_CVM(cins))
   14429                   break;
   14430                goto decode_failure;
   14431             } else {
   14432                goto decode_failure;
   14433             }
   14434          break;
   14435 
   14436          case 0x02: {  /* MUL */
   14437             DIP("mul r%u, r%u, r%u", rd, rs, rt);
   14438             if (mode64) {
   14439                IRTemp tmpRs32 = newTemp(Ity_I32);
   14440                IRTemp tmpRt32 = newTemp(Ity_I32);
   14441                IRTemp tmpRes = newTemp(Ity_I32);
   14442 
   14443                assign(tmpRs32, mkNarrowTo32(ty, getIReg(rs)));
   14444                assign(tmpRt32, mkNarrowTo32(ty, getIReg(rt)));
   14445                assign(tmpRes, binop(Iop_Mul32,
   14446                                     mkexpr(tmpRs32), mkexpr(tmpRt32)));
   14447                putIReg(rd, mkWidenFrom32(ty, mkexpr(tmpRes), True));
   14448             } else
   14449                putIReg(rd, binop(Iop_Mul32, getIReg(rs), getIReg(rt)));
   14450             break;
   14451          }
   14452 
   14453          case 0x00: {  /* MADD */
   14454             if (mode64) {
   14455                DIP("madd r%u, r%u", rs, rt);
   14456                t1 = newTemp(Ity_I32);
   14457                t2 = newTemp(Ity_I32);
   14458                t3 = newTemp(Ity_I64);
   14459                t4 = newTemp(Ity_I64);
   14460                t5 = newTemp(Ity_I64);
   14461                t6 = newTemp(Ity_I32);
   14462 
   14463                assign(t1, mkNarrowTo32(ty, getHI()));
   14464                assign(t2, mkNarrowTo32(ty, getLO()));
   14465 
   14466                assign(t3, binop(Iop_MullS32, mkNarrowTo32(ty, getIReg(rs)),
   14467                                              mkNarrowTo32(ty, getIReg(rt))));
   14468 
   14469                assign(t4, binop(Iop_32HLto64, mkexpr(t1), mkexpr(t2)));
   14470                assign(t5, binop(Iop_Add64, mkexpr(t3), mkexpr(t4)));
   14471 
   14472                putHI(mkWidenFrom32(ty, unop(Iop_64HIto32, mkexpr(t5)), True));
   14473                putLO(mkWidenFrom32(ty, unop(Iop_64to32, mkexpr(t5)), True));
   14474             } else {
   14475                if ( (1 <= ac) && ( 3 >= ac) ) {
   14476                   if (VEX_MIPS_PROC_DSP(archinfo->hwcaps)) {
   14477                      /* If DSP is present -> DSP ASE MADD */
   14478                      UInt retVal = disDSPInstr_MIPS_WRK ( cins );
   14479                      if (0 != retVal ) {
   14480                         goto decode_failure_dsp;
   14481                      }
   14482                      break;
   14483                   } else {
   14484                      goto decode_failure_dsp;
   14485                   }
   14486                } else {
   14487                   DIP("madd r%u, r%u", rs, rt);
   14488                   t1 = newTemp(Ity_I32);
   14489                   t2 = newTemp(Ity_I32);
   14490                   t3 = newTemp(Ity_I64);
   14491                   t4 = newTemp(Ity_I32);
   14492                   t5 = newTemp(Ity_I32);
   14493                   t6 = newTemp(Ity_I32);
   14494 
   14495                   assign(t1, getHI());
   14496                   assign(t2, getLO());
   14497 
   14498                   assign(t3, binop(Iop_MullS32, getIReg(rs), getIReg(rt)));
   14499 
   14500                   assign(t4, binop(Iop_Add32, mkexpr(t2), unop(Iop_64to32,
   14501                                                                mkexpr(t3))));
   14502 
   14503                   assign(t5, unop(Iop_1Uto32, binop(Iop_CmpLT32U, mkexpr(t4),
   14504                                               unop(Iop_64to32, mkexpr(t3)))));
   14505                   assign(t6, binop(Iop_Add32, mkexpr(t5), mkexpr(t1)));
   14506 
   14507                   putHI(binop(Iop_Add32, mkexpr(t6), unop(Iop_64HIto32,
   14508                                                           mkexpr(t3))));
   14509                   putLO(mkexpr(t4));
   14510                   break;
   14511                }
   14512             }
   14513             break;
   14514          }
   14515 
   14516       case 0x01: {  /* MADDU */
   14517          if (mode64) {
   14518             DIP("maddu r%u, r%u", rs, rt);
   14519             t1 = newTemp(Ity_I32);
   14520             t2 = newTemp(Ity_I32);
   14521             t3 = newTemp(Ity_I64);
   14522             t4 = newTemp(Ity_I64);
   14523             t5 = newTemp(Ity_I64);
   14524             t6 = newTemp(Ity_I32);
   14525 
   14526             assign(t1, mkNarrowTo32(ty, getHI()));
   14527             assign(t2, mkNarrowTo32(ty, getLO()));
   14528 
   14529             assign(t3, binop(Iop_MullU32, mkNarrowTo32(ty, getIReg(rs)),
   14530                                           mkNarrowTo32(ty, getIReg(rt))));
   14531 
   14532             assign(t4, binop(Iop_32HLto64, mkexpr(t1), mkexpr(t2)));
   14533             assign(t5, binop(Iop_Add64, mkexpr(t3), mkexpr(t4)));
   14534 
   14535             putHI(mkWidenFrom32(ty, unop(Iop_64HIto32, mkexpr(t5)), True));
   14536             putLO(mkWidenFrom32(ty, unop(Iop_64to32, mkexpr(t5)), True));
   14537          } else {
   14538             if ( (1 <= ac) && ( 3 >= ac) ) {
   14539                if (VEX_MIPS_PROC_DSP(archinfo->hwcaps)) {
   14540                   /* If DSP is present -> DSP ASE MADDU */
   14541                   UInt retVal = disDSPInstr_MIPS_WRK ( cins );
   14542                   if (0 != retVal ) {
   14543                      goto decode_failure_dsp;
   14544                   }
   14545                   break;
   14546                } else {
   14547                   goto decode_failure_dsp;
   14548                }
   14549             } else {
   14550                DIP("maddu r%u, r%u", rs, rt);
   14551                t1 = newTemp(Ity_I32);
   14552                t2 = newTemp(Ity_I32);
   14553                t3 = newTemp(Ity_I64);
   14554                t4 = newTemp(Ity_I32);
   14555                t5 = newTemp(Ity_I32);
   14556                t6 = newTemp(Ity_I32);
   14557 
   14558                assign(t1, getHI());
   14559                assign(t2, getLO());
   14560 
   14561                assign(t3, binop(Iop_MullU32, getIReg(rs), getIReg(rt)));
   14562 
   14563                assign(t4, binop(Iop_Add32, mkexpr(t2), unop(Iop_64to32,
   14564                                                             mkexpr(t3))));
   14565                assign(t5, unop(Iop_1Uto32, binop(Iop_CmpLT32U, mkexpr(t4),
   14566                                            unop(Iop_64to32, mkexpr(t3)))));
   14567                assign(t6, binop(Iop_Add32, mkexpr(t5), mkexpr(t1)));
   14568 
   14569                putHI(binop(Iop_Add32, mkexpr(t6), unop(Iop_64HIto32,
   14570                                                       mkexpr(t3))));
   14571                putLO(mkexpr(t4));
   14572                break;
   14573             }
   14574          }
   14575          break;
   14576       }
   14577 
   14578       case 0x04: {  /* MSUB */
   14579          if (mode64) {
   14580             DIP("msub r%u, r%u", rs, rt);
   14581             t1 = newTemp(Ity_I32);
   14582             t2 = newTemp(Ity_I32);
   14583             t3 = newTemp(Ity_I64);
   14584             t4 = newTemp(Ity_I64);
   14585             t5 = newTemp(Ity_I64);
   14586             t6 = newTemp(Ity_I32);
   14587 
   14588             assign(t1, mkNarrowTo32(ty, getHI()));
   14589             assign(t2, mkNarrowTo32(ty, getLO()));
   14590 
   14591             assign(t3, binop(Iop_MullS32, mkNarrowTo32(ty, getIReg(rs)),
   14592                                           mkNarrowTo32(ty, getIReg(rt))));
   14593 
   14594             assign(t4, binop(Iop_32HLto64, mkexpr(t1), mkexpr(t2)));
   14595             assign(t5, binop(Iop_Sub64, mkexpr(t4), mkexpr(t3)));
   14596 
   14597             putHI(mkWidenFrom32(ty, unop(Iop_64HIto32, mkexpr(t5)), True));
   14598             putLO(mkWidenFrom32(ty, unop(Iop_64to32, mkexpr(t5)), True));
   14599          } else {
   14600             if ( (1 <= ac) && ( 3 >= ac) ) {
   14601                if (VEX_MIPS_PROC_DSP(archinfo->hwcaps)) {
   14602                   /* If DSP is present -> DSP ASE MSUB */
   14603                   UInt retVal = disDSPInstr_MIPS_WRK ( cins );
   14604                   if (0 != retVal ) {
   14605                      goto decode_failure_dsp;
   14606                   }
   14607                   break;
   14608                } else {
   14609                   goto decode_failure_dsp;
   14610                }
   14611             } else {
   14612                DIP("msub r%u, r%u", rs, rt);
   14613                t1 = newTemp(Ity_I32);
   14614                t2 = newTemp(Ity_I32);
   14615                t3 = newTemp(Ity_I64);
   14616                t4 = newTemp(Ity_I32);
   14617                t5 = newTemp(Ity_I1);
   14618                t6 = newTemp(Ity_I32);
   14619 
   14620                assign(t1, getHI());
   14621                assign(t2, getLO());
   14622 
   14623                assign(t3, binop(Iop_MullS32, getIReg(rs), getIReg(rt)));
   14624                assign(t4, unop(Iop_64to32, mkexpr(t3)));  /* new lo */
   14625 
   14626                /* if lo<lo(mul) hi = hi - 1 */
   14627                assign(t5, binop(Iop_CmpLT32U,
   14628                                  mkexpr(t2),
   14629                                  mkexpr(t4)));
   14630 
   14631                assign(t6, IRExpr_ITE(mkexpr(t5),
   14632                                        binop(Iop_Sub32, mkexpr(t1), mkU32(0x1)),
   14633                                        mkexpr(t1)));
   14634 
   14635                putHI(binop(Iop_Sub32, mkexpr(t6), unop(Iop_64HIto32,
   14636                                                       mkexpr(t3))));
   14637                putLO(binop(Iop_Sub32, mkexpr(t2), mkexpr(t4)));
   14638                break;
   14639             }
   14640          }
   14641          break;
   14642       }
   14643 
   14644       case 0x05: {  /* MSUBU */
   14645          if (mode64) {
   14646             DIP("msubu r%u, r%u", rs, rt);
   14647             t1 = newTemp(Ity_I32);
   14648             t2 = newTemp(Ity_I32);
   14649             t3 = newTemp(Ity_I64);
   14650             t4 = newTemp(Ity_I64);
   14651             t5 = newTemp(Ity_I64);
   14652             t6 = newTemp(Ity_I32);
   14653 
   14654             assign(t1, mkNarrowTo32(ty, getHI()));
   14655             assign(t2, mkNarrowTo32(ty, getLO()));
   14656 
   14657             assign(t3, binop(Iop_MullU32, mkNarrowTo32(ty, getIReg(rs)),
   14658                                           mkNarrowTo32(ty, getIReg(rt))));
   14659 
   14660             assign(t4, binop(Iop_32HLto64, mkexpr(t1), mkexpr(t2)));
   14661             assign(t5, binop(Iop_Sub64, mkexpr(t4), mkexpr(t3)));
   14662 
   14663             putHI(mkWidenFrom32(ty, unop(Iop_64HIto32, mkexpr(t5)), True));
   14664             putLO(mkWidenFrom32(ty, unop(Iop_64to32, mkexpr(t5)), True));
   14665          } else {
   14666             if ( (1 <= ac) && ( 3 >= ac) ) {
   14667                if (VEX_MIPS_PROC_DSP(archinfo->hwcaps)) {
   14668                   /* If DSP is present -> DSP ASE MSUBU */
   14669                   UInt retVal = disDSPInstr_MIPS_WRK ( cins );
   14670                   if (0 != retVal ) {
   14671                      goto decode_failure_dsp;
   14672                   }
   14673                   break;
   14674                } else {
   14675                   goto decode_failure_dsp;
   14676                }
   14677             } else {
   14678                DIP("msubu r%u, r%u", rs, rt);
   14679                t1 = newTemp(Ity_I32);
   14680                t2 = newTemp(Ity_I32);
   14681                t3 = newTemp(Ity_I64);
   14682                t4 = newTemp(Ity_I32);
   14683                t5 = newTemp(Ity_I1);
   14684                t6 = newTemp(Ity_I32);
   14685 
   14686                assign(t1, getHI());
   14687                assign(t2, getLO());
   14688 
   14689                assign(t3, binop(Iop_MullU32, getIReg(rs), getIReg(rt)));
   14690                assign(t4, unop(Iop_64to32, mkexpr(t3)));  /* new lo */
   14691 
   14692                /* if lo<lo(mul) hi = hi - 1 */
   14693                assign(t5, binop(Iop_CmpLT32U,
   14694                                  mkexpr(t2),
   14695                                  mkexpr(t4)));
   14696 
   14697                assign(t6, IRExpr_ITE(mkexpr(t5),
   14698                                     binop(Iop_Sub32,
   14699                                           mkexpr(t1),
   14700                                           mkU32(0x1)),
   14701                                     mkexpr(t1)));
   14702 
   14703                putHI(binop(Iop_Sub32, mkexpr(t6), unop(Iop_64HIto32,
   14704                                                       mkexpr(t3))));
   14705                putLO(binop(Iop_Sub32, mkexpr(t2), mkexpr(t4)));
   14706                break;
   14707             }
   14708          }
   14709          break;
   14710       }
   14711 
   14712       case 0x6:  /* dmul MIPS64 - Netlogic */
   14713          DIP("dmul r%u, r%u, r%u", rd, rs, rt);
   14714          t0 = newTemp(Ity_I128);
   14715 
   14716          assign(t0, binop(Iop_MullU64, getIReg(rs), getIReg(rt)));
   14717 
   14718          putIReg(rd, unop(Iop_128to64, mkexpr(t0)));
   14719          break;
   14720 
   14721       case 0x10:  /* LDADDW - Swap Word - Netlogic */
   14722          DIP("ldaddw r%u, r%u", rt, rs);
   14723          t0 = newTemp(Ity_I32);
   14724          t1 = newTemp(Ity_I32);
   14725          t2 = newTemp(Ity_I32);
   14726          t3 = newTemp(Ity_I64);
   14727          t4 = newTemp(Ity_I32);
   14728          t5 = newTemp(Ity_I32);
   14729          t6 = newTemp(Ity_I32);
   14730 
   14731          /* v = GPR[rt] */
   14732          assign(t0, mkNarrowTo32(ty, getIReg(rt)));
   14733 
   14734          /* GPR[rt] = memory[base]; */
   14735          assign(t1, load(Ity_I32, getIReg(rs)));
   14736          putIReg(rt, mkWidenFrom32(ty, mkexpr(t1), True));
   14737 
   14738          /* memory[base] = memory[base] + v; */
   14739          store(getIReg(rs), binop(Iop_Add32, mkexpr(t0), mkexpr(t1)));
   14740          break;
   14741 
   14742       case 0x12:  /* LDADDD - Swap Word - Netlogic */
   14743          DIP("ldaddw r%u, r%u", rt, rs);
   14744          t0 = newTemp(Ity_I64);
   14745          t1 = newTemp(Ity_I64);
   14746 
   14747          /*  v = GPR[rt] */
   14748          assign(t0, getIReg(rt));
   14749 
   14750          /* GPR[rt] = memory[base]; */
   14751          assign(t1, load(Ity_I64, getIReg(rs)));
   14752          putIReg(rt, mkexpr(t1));
   14753 
   14754          /* memory[base] = memory[base] + v; */
   14755          store(getIReg(rs), binop(Iop_Add64, mkexpr(t0), mkexpr(t1)));
   14756          break;
   14757 
   14758       case 0x14:  /* SWAPW - Swap Word - Netlogic */
   14759          DIP("swapw r%u, r%u", rt, rs);
   14760          t0 = newTemp(Ity_I32);
   14761          t1 = newTemp(Ity_I32);
   14762          assign(t0, mkNarrowTo32(ty, getIReg(rt)));
   14763          assign(t1, load(Ity_I32, getIReg(rs)));
   14764          putIReg(rt, mkWidenFrom32(ty, mkexpr(t1), True));
   14765          store(getIReg(rs), mkexpr(t0));
   14766          break;
   14767 
   14768       case 0x16:  /* SWAPD - Swap Double - Netlogic */
   14769          DIP("swapw r%u, r%u", rt, rs);
   14770          t0 = newTemp(Ity_I64);
   14771          t1 = newTemp(Ity_I64);
   14772          assign(t0, getIReg(rt));
   14773          assign(t1, load(Ity_I64, getIReg(rs)));
   14774          putIReg(rt, mkexpr(t1));
   14775          store(getIReg(rs), mkexpr(t0));
   14776          break;
   14777 
   14778       case 0x20: {  /* CLZ */
   14779          DIP("clz r%u, r%u", rd, rs);
   14780          if (mode64) {
   14781             IRTemp tmpClz32 = newTemp(Ity_I32);
   14782             IRTemp tmpRs32 = newTemp(Ity_I32);
   14783 
   14784             assign(tmpRs32, mkNarrowTo32(ty, getIReg(rs)));
   14785             assign(tmpClz32, unop(Iop_Clz32, mkexpr(tmpRs32)));
   14786             putIReg(rd, mkWidenFrom32(ty, mkexpr(tmpClz32), True));
   14787          } else {
   14788             t1 = newTemp(Ity_I1);
   14789             assign(t1, binop(Iop_CmpEQ32, getIReg(rs), mkU32(0)));
   14790             putIReg(rd, IRExpr_ITE(mkexpr(t1),
   14791                                    mkU32(0x00000020),
   14792                                    unop(Iop_Clz32, getIReg(rs))));
   14793          }
   14794          break;
   14795       }
   14796 
   14797       case 0x21: {  /* CLO */
   14798          DIP("clo r%u, r%u", rd, rs);
   14799          if (mode64) {
   14800             IRTemp tmpClo32 = newTemp(Ity_I32);
   14801             IRTemp tmpRs32 = newTemp(Ity_I32);
   14802             assign(tmpRs32, mkNarrowTo32(ty, getIReg(rs)));
   14803 
   14804             t1 = newTemp(Ity_I1);
   14805             assign(t1, binop(Iop_CmpEQ32, mkexpr(tmpRs32), mkU32(0xffffffff)));
   14806             assign(tmpClo32, IRExpr_ITE(mkexpr(t1),
   14807                       mkU32(0x00000020),
   14808                       unop(Iop_Clz32, unop(Iop_Not32, mkexpr(tmpRs32)))));
   14809 
   14810             putIReg(rd, mkWidenFrom32(ty, mkexpr(tmpClo32), True));
   14811             break;
   14812          } else {
   14813             t1 = newTemp(Ity_I1);
   14814             assign(t1, binop(Iop_CmpEQ32, getIReg(rs), mkU32(0xffffffff)));
   14815             putIReg(rd, IRExpr_ITE(mkexpr(t1),
   14816                                    mkU32(0x00000020),
   14817                                    unop(Iop_Clz32,
   14818                                         unop(Iop_Not32, getIReg(rs)))));
   14819             break;
   14820          }
   14821       }
   14822 
   14823       case 0x24:  /* Count Leading Zeros in Doubleword - DCLZ; MIPS64 */
   14824          DIP("dclz r%u, r%u", rd, rs);
   14825          t1 = newTemp(Ity_I1);
   14826          assign(t1, binop(Iop_CmpEQ64, getIReg(rs), mkU64(0)));
   14827          putIReg(rd, IRExpr_ITE(mkexpr(t1),
   14828                      mkU64(0x00000040),
   14829                      unop(Iop_Clz64, getIReg(rs))));
   14830          break;
   14831 
   14832       case 0x25:  /* Count Leading Ones in Doubleword - DCLO; MIPS64 */
   14833          DIP("dclo r%u, r%u", rd, rs);
   14834          t1 = newTemp(Ity_I1);
   14835          assign(t1, binop(Iop_CmpEQ64, getIReg(rs),
   14836                                         mkU64(0xffffffffffffffffULL)));
   14837          putIReg(rd, IRExpr_ITE(mkexpr(t1),
   14838                                 mkU64(0x40),
   14839                                 unop(Iop_Clz64, unop(Iop_Not64,
   14840                                                      getIReg(rs)))));
   14841          break;
   14842 
   14843       default:
   14844          goto decode_failure;
   14845       }
   14846       break;
   14847 
   14848    case 0x1F:  /* Special3 */
   14849       switch (function) {
   14850          case 0x01: {
   14851             /* Doubleword Extract Bit Field - DEXTM; MIPS64r2 */
   14852             msb = get_msb(cins);
   14853             lsb = get_lsb(cins);
   14854             size = msb + 1;
   14855             UInt srcPos = lsb;
   14856             UInt dstSz = msb + 33;
   14857             t1 = newTemp(Ity_I64);
   14858             DIP("dextm r%u, r%u, %u, %u", rt, rs, lsb, msb + 1);
   14859 
   14860             UChar lsAmt = 64 - (srcPos + dstSz);  /* left shift amount; */
   14861             UChar rsAmt = 64 - dstSz;  /* right shift amount; */
   14862 
   14863             assign(t1, binop(Iop_Shl64, getIReg(rs), mkU8(lsAmt)));
   14864             putIReg(rt, binop(Iop_Shr64, mkexpr(t1), mkU8(rsAmt)));
   14865 
   14866             break;
   14867          }
   14868          case 0x02: {
   14869             /* Doubleword Extract Bit Field Upper - DEXTU; MIPS64r2 */
   14870             msb = get_msb(cins);
   14871             lsb = get_lsb(cins);
   14872             size = msb + 1;
   14873             UInt srcPos = lsb + 32;
   14874             UInt dstSz = msb + 1;
   14875             DIP("dextu r%u, r%u, %u, %u", rt, rs, srcPos, dstSz);
   14876             t1 = newTemp(Ity_I64);
   14877 
   14878             vassert(srcPos >= 32 && srcPos < 64);
   14879             vassert(dstSz > 0 && dstSz <= 32);
   14880             vassert((srcPos + dstSz) > 32 && (srcPos + dstSz) <= 64);
   14881 
   14882             UChar lsAmt = 64 - (srcPos + dstSz);  /* left shift amount; */
   14883             UChar rsAmt = 64 - dstSz;  /* right shift amount; */
   14884 
   14885             assign(t1, binop(Iop_Shl64, getIReg(rs), mkU8(lsAmt)));
   14886             putIReg(rt, binop(Iop_Shr64, mkexpr(t1), mkU8(rsAmt)));
   14887             break;
   14888          }
   14889          case 0x05: {
   14890             /* Doubleword Insert Bit Field Middle - DINSM; MIPS64r2 */
   14891             msb = get_msb(cins);
   14892             lsb = get_lsb(cins);
   14893             size = msb + 1;
   14894             UInt dstPos = lsb;
   14895             UInt srcSz = msb - lsb + 33;
   14896             t1 = newTemp(ty);
   14897             t2 = newTemp(ty);
   14898             t3 = newTemp(ty);
   14899             t4 = newTemp(ty);
   14900             IRTemp tmpT1 = newTemp(ty);
   14901             IRTemp tmpT2 = newTemp(ty);
   14902             IRTemp tmpT3 = newTemp(ty);
   14903             IRTemp tmpT4 = newTemp(ty);
   14904             IRTemp tmpT5 = newTemp(ty);
   14905             IRTemp tmpT6 = newTemp(ty);
   14906             IRTemp tmpT7 = newTemp(ty);
   14907             IRTemp tmpRs = newTemp(ty);
   14908             IRTemp tmpRt = newTemp(ty);
   14909             IRTemp tmpRd = newTemp(ty);
   14910 
   14911             assign(tmpRs, getIReg(rs));
   14912             assign(tmpRt, getIReg(rt));
   14913             DIP("dinsm r%u, r%u, %u, %u", rt, rs, lsb, msb);
   14914 
   14915             UChar lsAmt = dstPos + srcSz - 1;   /* left shift amount; */
   14916             UChar rsAmt = dstPos + srcSz - 1;   /* right shift amount; */
   14917 
   14918             assign(t1, binop(Iop_Shr64, mkexpr(tmpRt), mkU8(rsAmt)));
   14919             assign(tmpT1, binop(Iop_Shr64, mkexpr(t1), mkU8(1)));
   14920             assign(t2, binop(Iop_Shl64, mkexpr(tmpT1), mkU8(lsAmt)));
   14921             assign(tmpT2, binop(Iop_Shl64, mkexpr(t2), mkU8(1)));
   14922 
   14923             lsAmt = 63 - dstPos; /* left shift amount; */
   14924             rsAmt = 63 - dstPos; /* right shift amount; */
   14925 
   14926             assign(t3, binop(Iop_Shl64, mkexpr(tmpRt), mkU8(lsAmt)));
   14927             assign(tmpT3, binop(Iop_Shl64, mkexpr(t3), mkU8(1)));
   14928             assign(t4, binop(Iop_Shr64, mkexpr(tmpT3), mkU8(rsAmt)));
   14929             assign(tmpT4, binop(Iop_Shr64, mkexpr(t4), mkU8(1)));
   14930 
   14931             /* extract size from src register */
   14932             lsAmt = 64 - srcSz;  /* left shift amount; */
   14933             rsAmt = 64 - (lsb + srcSz);   /* right shift amount; */
   14934 
   14935             assign(tmpT5, binop(Iop_Shl64, mkexpr(tmpRs), mkU8(lsAmt)));
   14936             assign(tmpT6, binop(Iop_Shr64, mkexpr(tmpT5), mkU8(rsAmt)));
   14937 
   14938             assign(tmpT7, binop(Iop_Or64, mkexpr(tmpT2), mkexpr(tmpT4)));
   14939             assign(tmpRd, binop(Iop_Or64, mkexpr(tmpT6), mkexpr(tmpT7)));
   14940             putIReg(rt, mkexpr(tmpRd));
   14941             break;
   14942          }
   14943          case 0x06: {
   14944             /* Doubleword Insert Bit Field Upper - DINSU; MIPS64r2 */
   14945             msb = get_msb(cins);
   14946             lsb = get_lsb(cins);
   14947             size = msb + 1;
   14948             UInt dstPos = lsb + 32;
   14949             UInt srcSz = msb - lsb + 1;
   14950             IRTemp tmpT1 = newTemp(ty);
   14951             IRTemp tmpT2 = newTemp(ty);
   14952             IRTemp tmpT3 = newTemp(ty);
   14953             IRTemp tmpT4 = newTemp(ty);
   14954             IRTemp tmpT5 = newTemp(ty);
   14955             IRTemp tmpT6 = newTemp(ty);
   14956             IRTemp tmpT7 = newTemp(ty);
   14957             IRTemp tmpT8 = newTemp(ty);
   14958             IRTemp tmpT9 = newTemp(ty);
   14959             IRTemp tmpRs = newTemp(ty);
   14960             IRTemp tmpRt = newTemp(ty);
   14961             IRTemp tmpRd = newTemp(ty);
   14962 
   14963             assign(tmpRs, getIReg(rs));
   14964             assign(tmpRt, getIReg(rt));
   14965             DIP("dinsu r%u, r%u, %u, %u", rt, rs, lsb, msb);
   14966 
   14967             UChar lsAmt = 64 - srcSz;  /* left shift amount; */
   14968             UChar rsAmt = 64 - (dstPos + srcSz);  /* right shift amount; */
   14969             assign(tmpT1, binop(Iop_Shl64, mkexpr(tmpRs), mkU8(lsAmt)));
   14970             assign(tmpT2, binop(Iop_Shr64, mkexpr(tmpT1), mkU8(rsAmt)));
   14971 
   14972             lsAmt = 64 - dstPos;  /* left shift amount; */
   14973             rsAmt = 64 - dstPos;  /* right shift amount; */
   14974             assign(tmpT3, binop(Iop_Shl64, mkexpr(tmpRt), mkU8(lsAmt)));
   14975             assign(tmpT4, binop(Iop_Shr64, mkexpr(tmpT3), mkU8(rsAmt)));
   14976 
   14977             lsAmt = dstPos;  /* left shift amount; */
   14978             rsAmt = srcSz;  /* right shift amount; */
   14979             assign(tmpT5, binop(Iop_Shr64, mkexpr(tmpRt), mkU8(rsAmt)));
   14980             assign(tmpT6, binop(Iop_Shr64, mkexpr(tmpT5), mkU8(lsAmt)));
   14981 
   14982             assign(tmpT7, binop(Iop_Shl64, mkexpr(tmpT6), mkU8(rsAmt)));
   14983             assign(tmpT8, binop(Iop_Shl64, mkexpr(tmpT7), mkU8(lsAmt)));
   14984 
   14985             assign(tmpT9, binop(Iop_Or64, mkexpr(tmpT8), mkexpr(tmpT4)));
   14986             assign(tmpRd, binop(Iop_Or64, mkexpr(tmpT2), mkexpr(tmpT9)));
   14987             putIReg(rt, mkexpr(tmpRd));
   14988             break;
   14989          }
   14990          case 0x07: {
   14991             /* Doubleword Insert Bit Field - DINS; MIPS64r2 */
   14992             IRTemp tmp1 = newTemp(ty);
   14993             IRTemp tmpT1 = newTemp(ty);
   14994             IRTemp tmpT2 = newTemp(ty);
   14995             IRTemp tmpT3 = newTemp(ty);
   14996             IRTemp tmpT4 = newTemp(ty);
   14997             IRTemp tmpT5 = newTemp(ty);
   14998             IRTemp tmpT6 = newTemp(ty);
   14999             IRTemp tmpT7 = newTemp(ty);
   15000             IRTemp tmpT8 = newTemp(ty);
   15001             IRTemp tmpT9 = newTemp(ty);
   15002             IRTemp tmp = newTemp(ty);
   15003             IRTemp tmpRs = newTemp(ty);
   15004             IRTemp tmpRt = newTemp(ty);
   15005             IRTemp tmpRd = newTemp(ty);
   15006 
   15007             assign(tmpRs, getIReg(rs));
   15008             assign(tmpRt, getIReg(rt));
   15009 
   15010             msb = get_msb(cins);
   15011             lsb = get_lsb(cins);
   15012             size = msb + 1;
   15013             DIP("dins r%u, r%u, %u, %u", rt, rs, lsb,
   15014                 msb - lsb + 1);
   15015             UChar lsAmt = 63 - lsb;  /* left shift amount; */
   15016             UChar rsAmt = 63 - lsb;  /* right shift amount; */
   15017             assign(tmp, binop(Iop_Shl64, mkexpr(tmpRt), mkU8(lsAmt)));
   15018             assign(tmpT1, binop(Iop_Shl64, mkexpr(tmp), mkU8(1)));
   15019             assign(tmp1, binop(Iop_Shr64, mkexpr(tmpT1), mkU8(rsAmt)));
   15020             assign(tmpT2, binop(Iop_Shr64, mkexpr(tmp1), mkU8(1)));
   15021 
   15022             lsAmt = msb;  /* left shift amount; */
   15023             rsAmt = 1;  /*right shift amount; */
   15024             assign(tmpT3, binop(Iop_Shr64, mkexpr(tmpRt), mkU8(rsAmt)));
   15025             assign(tmpT4, binop(Iop_Shr64, mkexpr(tmpT3), mkU8(lsAmt)));
   15026             assign(tmpT5, binop(Iop_Shl64, mkexpr(tmpT4), mkU8(rsAmt)));
   15027             assign(tmpT6, binop(Iop_Shl64, mkexpr(tmpT5), mkU8(lsAmt)));
   15028 
   15029             lsAmt = 64 - (msb - lsb + 1);  /* left shift amount; */
   15030             rsAmt = 64 - (msb + 1);  /* right shift amount; */
   15031             assign(tmpT7, binop(Iop_Shl64, mkexpr(tmpRs), mkU8(lsAmt)));
   15032             assign(tmpT8, binop(Iop_Shr64, mkexpr(tmpT7), mkU8(rsAmt)));
   15033 
   15034             assign(tmpT9, binop(Iop_Or64, mkexpr(tmpT2), mkexpr(tmpT8)));
   15035             assign(tmpRd, binop(Iop_Or64, mkexpr(tmpT6), mkexpr(tmpT9)));
   15036             putIReg(rt, mkexpr(tmpRd));
   15037             break;
   15038          }
   15039       case 0x24:  /* DBSHFL */
   15040          lsb = get_lsb(cins);
   15041          IRTemp tmpRs = newTemp(ty);
   15042          IRTemp tmpRt = newTemp(ty);
   15043          IRTemp tmpRd = newTemp(ty);
   15044          assign(tmpRs, getIReg(rs));
   15045          assign(tmpRt, getIReg(rt));
   15046          switch (lsb) {
   15047             case 0x02: {  /* DSBH */
   15048                DIP("dsbh r%u, r%u", rd, rt);
   15049                IRTemp tmpT1 = newTemp(ty);
   15050                IRTemp tmpT2 = newTemp(ty);
   15051                IRTemp tmpT3 = newTemp(ty);
   15052                IRTemp tmpT4 = newTemp(ty);
   15053                IRTemp tmpT5 = newTemp(Ity_I64);
   15054                IRTemp tmpT6 = newTemp(ty);
   15055                assign(tmpT5, mkU64(0xFF00FF00FF00FF00ULL));
   15056                assign(tmpT6, mkU64(0x00FF00FF00FF00FFULL));
   15057                assign(tmpT1, binop(Iop_And64, mkexpr(tmpRt), mkexpr(tmpT5)));
   15058                assign(tmpT2, binop(Iop_Shr64, mkexpr(tmpT1), mkU8(8)));
   15059                assign(tmpT3, binop(Iop_And64, mkexpr(tmpRt), mkexpr(tmpT6)));
   15060                assign(tmpT4, binop(Iop_Shl64, mkexpr(tmpT3), mkU8(8)));
   15061                assign(tmpRd, binop(Iop_Or64, mkexpr(tmpT4), mkexpr(tmpT2)));
   15062                putIReg(rd, mkexpr(tmpRd));
   15063                break;
   15064             }
   15065             case 0x05: {  /* DSHD */
   15066                DIP("dshd r%u, r%u\n", rd, rt);
   15067                IRTemp tmpT1 = newTemp(ty);
   15068                IRTemp tmpT2 = newTemp(ty);
   15069                IRTemp tmpT3 = newTemp(ty);
   15070                IRTemp tmpT4 = newTemp(ty);
   15071                IRTemp tmpT5 = newTemp(Ity_I64);
   15072                IRTemp tmpT6 = newTemp(ty);
   15073                IRTemp tmpT7 = newTemp(ty);
   15074                IRTemp tmpT8 = newTemp(ty);
   15075                IRTemp tmpT9 = newTemp(ty);
   15076                assign(tmpT5, mkU64(0xFFFF0000FFFF0000ULL));
   15077                assign(tmpT6, mkU64(0x0000FFFF0000FFFFULL));
   15078                assign(tmpT1, binop(Iop_And64, mkexpr(tmpRt), mkexpr(tmpT5)));
   15079                assign(tmpT2, binop(Iop_Shr64, mkexpr(tmpT1), mkU8(16)));
   15080                assign(tmpT3, binop(Iop_And64, mkexpr(tmpRt), mkexpr(tmpT6)));
   15081                assign(tmpT4, binop(Iop_Shl64, mkexpr(tmpT3), mkU8(16)));
   15082                assign(tmpT7, binop(Iop_Or64, mkexpr(tmpT4), mkexpr(tmpT2)));
   15083                assign(tmpT8, binop(Iop_Shl64, mkexpr(tmpT7), mkU8(32)));
   15084                assign(tmpT9, binop(Iop_Shr64, mkexpr(tmpT7), mkU8(32)));
   15085                assign(tmpRd, binop(Iop_Or64, mkexpr(tmpT8), mkexpr(tmpT9)));
   15086                putIReg(rd, mkexpr(tmpRd));
   15087                break;
   15088             }
   15089          default:
   15090             vex_printf("\nop6o10 = %u", lsb);
   15091             goto decode_failure;;
   15092          }
   15093          break;
   15094       case 0x3B: /* RDHWR */
   15095          DIP("rdhwr r%u, r%u", rt, rd);
   15096          if (VEX_MIPS_CPU_HAS_MIPS32R2(archinfo->hwcaps) ||
   15097              (VEX_MIPS_COMP_ID(archinfo->hwcaps) == VEX_PRID_COMP_BROADCOM)) {
   15098             if (rd == 29) {
   15099                putIReg(rt, getULR());
   15100             } else if (rd <= 3
   15101                        || (rd == 31
   15102                            && VEX_MIPS_COMP_ID(archinfo->hwcaps)
   15103                                                     == VEX_PRID_COMP_CAVIUM)) {
   15104                IRExpr** arg = mkIRExprVec_1(mkU32(rd));
   15105                IRTemp   val  = newTemp(ty);
   15106                IRDirty *d = unsafeIRDirty_1_N(val,
   15107                                               0,
   15108                                               "mips_dirtyhelper_rdhwr",
   15109                                               &mips_dirtyhelper_rdhwr,
   15110                                               arg);
   15111                stmt(IRStmt_Dirty(d));
   15112                putIReg(rt, mkexpr(val));
   15113             } else
   15114                goto decode_failure;
   15115          } else {
   15116             ILLEGAL_INSTRUCTON;
   15117          }
   15118          break;
   15119       case 0x04:  /* INS */
   15120          msb = get_msb(cins);
   15121          lsb = get_lsb(cins);
   15122          size = msb - lsb + 1;
   15123          DIP("ins size:%u msb:%u lsb:%u", size, msb, lsb);
   15124 
   15125          vassert(lsb + size <= 32);
   15126          vassert(lsb + size > 0);
   15127 
   15128          /* put size bits from rs at the pos in temporary */
   15129          t0 = newTemp(Ity_I32);
   15130          t3 = newTemp(Ity_I32);
   15131          /* shift left for 32 - size to clear leading bits and get zeros
   15132             at the end */
   15133          assign(t0, binop(Iop_Shl32, mkNarrowTo32(ty, getIReg(rs)),
   15134                           mkU8(32 - size)));
   15135          /* now set it at pos */
   15136          t1 = newTemp(Ity_I32);
   15137          assign(t1, binop(Iop_Shr32, mkexpr(t0), mkU8(32 - size - lsb)));
   15138 
   15139          if (lsb > 0) {
   15140             t2 = newTemp(Ity_I32);
   15141             /* clear everything but lower pos bits from rt */
   15142             assign(t2, binop(Iop_Shl32, mkNarrowTo32(ty, getIReg(rt)),
   15143                              mkU8(32 - lsb)));
   15144             assign(t3, binop(Iop_Shr32, mkexpr(t2), mkU8(32 - lsb)));
   15145          } else
   15146             assign(t3, mkU32(0));
   15147 
   15148          if (msb < 31) {
   15149             t4 = newTemp(Ity_I32);
   15150             /* clear everything but upper msb + 1 bits from rt */
   15151             assign(t4, binop(Iop_Shr32, mkNarrowTo32(ty, getIReg(rt)),
   15152                              mkU8(msb + 1)));
   15153             t5 = newTemp(Ity_I32);
   15154             assign(t5, binop(Iop_Shl32, mkexpr(t4), mkU8(msb + 1)));
   15155 
   15156             /* now combine these registers */
   15157             if (lsb > 0) {
   15158                t6 = newTemp(Ity_I32);
   15159                assign(t6, binop(Iop_Or32, mkexpr(t5), mkexpr(t1)));
   15160                putIReg(rt, mkWidenFrom32(ty, binop(Iop_Or32, mkexpr(t6),
   15161                                                    mkexpr(t3)), True));
   15162             } else {
   15163                putIReg(rt, mkWidenFrom32(ty, binop(Iop_Or32, mkexpr(t1),
   15164                                                    mkexpr(t5)), True));
   15165             }
   15166          } else {
   15167             putIReg(rt, mkWidenFrom32(ty, binop(Iop_Or32, mkexpr(t1),
   15168                                                 mkexpr(t3)), True));
   15169          }
   15170          break;
   15171 
   15172       case 0x00:  /* EXT */
   15173          msb = get_msb(cins);
   15174          lsb = get_lsb(cins);
   15175          size = msb + 1;
   15176          DIP("ext size:%u msb:%u lsb:%u", size, msb, lsb);
   15177          vassert(lsb + size <= 32);
   15178          vassert(lsb + size > 0);
   15179          /* put size bits from rs at the top of in temporary */
   15180          if (lsb + size < 32) {
   15181             t0 = newTemp(Ity_I32);
   15182             assign(t0, binop(Iop_Shl32, mkNarrowTo32(ty, getIReg(rs)),
   15183                              mkU8(32 - lsb - size)));
   15184 
   15185             putIReg(rt, mkWidenFrom32(ty, binop(Iop_Shr32, mkexpr(t0),
   15186                                                 mkU8(32 - size)), True));
   15187          } else {
   15188             putIReg(rt, mkWidenFrom32(ty, binop(Iop_Shr32,
   15189                                                 mkNarrowTo32(ty, getIReg(rs)),
   15190                                                 mkU8(32 - size)), True));
   15191          }
   15192          break;
   15193 
   15194       case 0x03:  /* Doubleword Extract Bit Field - DEXT; MIPS64r2 */
   15195          msb = get_msb(cins);
   15196          lsb = get_lsb(cins);
   15197          size = msb + 1;
   15198          DIP("dext r%u, r%u, %u, %u", rt, rs, lsb, msb + 1);
   15199          t1 = newTemp(Ity_I64);
   15200          vassert(lsb >= 0 && lsb < 32);
   15201          vassert(size > 0 && size <= 32);
   15202          vassert((lsb + size) > 0 && (lsb + size) <= 63);
   15203 
   15204          UChar lsAmt = 63 - (lsb + msb);  /* left shift amount; */
   15205          UChar rsAmt = 63 - msb;  /* right shift amount; */
   15206 
   15207          assign(t1, binop(Iop_Shl64, getIReg(rs), mkU8(lsAmt)));
   15208          putIReg(rt, binop(Iop_Shr64, mkexpr(t1), mkU8(rsAmt)));
   15209 
   15210          break;
   15211 
   15212       case 0x20:  /* BSHFL */
   15213          switch (sa) {
   15214             case 0x02:  /* WSBH */
   15215                DIP("wsbh r%u, r%u", rd, rt);
   15216                t0 = newTemp(Ity_I32);
   15217                t1 = newTemp(Ity_I32);
   15218                t2 = newTemp(Ity_I32);
   15219                t3 = newTemp(Ity_I32);
   15220                assign(t0, binop(Iop_Shl32, binop(Iop_And32, mkNarrowTo32(ty,
   15221                                            getIReg(rt)), mkU32(0x00FF0000)),
   15222                                            mkU8(0x8)));
   15223                assign(t1, binop(Iop_Shr32, binop(Iop_And32, mkNarrowTo32(ty,
   15224                                 getIReg(rt)), mkU32(0xFF000000)), mkU8(0x8)));
   15225                assign(t2, binop(Iop_Shl32, binop(Iop_And32, mkNarrowTo32(ty,
   15226                                 getIReg(rt)), mkU32(0x000000FF)), mkU8(0x8)));
   15227                assign(t3, binop(Iop_Shr32, binop(Iop_And32, mkNarrowTo32(ty,
   15228                                 getIReg(rt)), mkU32(0x0000FF00)), mkU8(0x8)));
   15229                putIReg(rd, mkWidenFrom32(ty, binop(Iop_Or32, binop(Iop_Or32,
   15230                                          mkexpr(t0), mkexpr(t1)),
   15231                                          binop(Iop_Or32, mkexpr(t2),
   15232                                          mkexpr(t3))), True));
   15233                break;
   15234 
   15235             case 0x10:  /* SEB */
   15236                DIP("seb r%u, r%u", rd, rt);
   15237                if (mode64)
   15238                   putIReg(rd, unop(Iop_8Sto64, unop(Iop_64to8, getIReg(rt))));
   15239                else
   15240                   putIReg(rd, unop(Iop_8Sto32, unop(Iop_32to8, getIReg(rt))));
   15241                break;
   15242 
   15243             case 0x18:  /* SEH */
   15244                DIP("seh r%u, r%u", rd, rt);
   15245                if (mode64)
   15246                   putIReg(rd, unop(Iop_16Sto64, unop(Iop_64to16, getIReg(rt))));
   15247                else
   15248                   putIReg(rd, unop(Iop_16Sto32, unop(Iop_32to16, getIReg(rt))));
   15249                break;
   15250 
   15251             default:
   15252                goto decode_failure;
   15253 
   15254          }
   15255          break;  /* BSHFL */
   15256 
   15257       /* --- MIPS32(r2) DSP ASE(r2) / Cavium Specfic (LX) instructions --- */
   15258       case 0xA:  /* LX */
   15259          if (VEX_MIPS_COMP_ID(archinfo->hwcaps) == VEX_PRID_COMP_CAVIUM) {
   15260             if (dis_instr_CVM(cins))
   15261                break;
   15262             goto decode_failure;
   15263          }
   15264       case 0xC:  /* INSV */
   15265       case 0x38: {  /* EXTR.W */
   15266          if (VEX_MIPS_PROC_DSP(archinfo->hwcaps)) {
   15267             UInt retVal = disDSPInstr_MIPS_WRK ( cins );
   15268             if (0 != retVal ) {
   15269                goto decode_failure_dsp;
   15270             }
   15271             break;
   15272          } else {
   15273             goto decode_failure_dsp;
   15274          }
   15275          break;
   15276       }
   15277       case 0x10: {  /* ADDU.QB */
   15278          switch(sa) {
   15279             case  0xC:  /* SUBU_S.PH */
   15280             case  0xD:  /* ADDU_S.PH */
   15281             case 0x1E: {  /* MULQ_S.PH */
   15282                if (VEX_MIPS_PROC_DSP2(archinfo->hwcaps)) {
   15283                   UInt retVal = disDSPInstr_MIPS_WRK ( cins );
   15284                   if (0 != retVal ) {
   15285                      goto decode_failure_dsp;
   15286                   }
   15287                   break;
   15288                } else {
   15289                   goto decode_failure_dsp;
   15290                }
   15291                break;
   15292             }
   15293             default: {
   15294                if (VEX_MIPS_PROC_DSP(archinfo->hwcaps)) {
   15295                   UInt retVal = disDSPInstr_MIPS_WRK ( cins );
   15296                   if (0 != retVal ) {
   15297                      goto decode_failure_dsp;
   15298                   }
   15299                   break;
   15300                } else {
   15301                   goto decode_failure_dsp;
   15302                }
   15303                break;
   15304             }
   15305          }
   15306          break;
   15307       }
   15308       case 0x11: {  /* CMPU.EQ.QB */
   15309          switch(sa) {
   15310             case 0x18:  /* CMPGDU.EQ.QB */
   15311             case 0x19:  /* CMPGDU.LT.QB */
   15312             case 0x1A:  /* CMPGDU.LE.QB */
   15313             case 0x0D:  /* PRECR.QB.PH */
   15314             case 0x1E:  /* PRECR_SRA.PH.W */
   15315             case 0x1F: {  /* PRECR_SRA_R.PH.W */
   15316                if (VEX_MIPS_PROC_DSP2(archinfo->hwcaps)) {
   15317                   UInt retVal = disDSPInstr_MIPS_WRK ( cins );
   15318                   if (0 != retVal ) {
   15319                      goto decode_failure_dsp;
   15320                   }
   15321                   break;
   15322                } else {
   15323                   goto decode_failure_dsp;
   15324                }
   15325                break;
   15326             }
   15327             default: {
   15328                if (VEX_MIPS_PROC_DSP(archinfo->hwcaps)) {
   15329                   UInt retVal = disDSPInstr_MIPS_WRK ( cins );
   15330                   if (0 != retVal ) {
   15331                      goto decode_failure_dsp;
   15332                   }
   15333                   break;
   15334                } else {
   15335                   goto decode_failure_dsp;
   15336                }
   15337                break;
   15338             }
   15339          }
   15340          break;
   15341       }
   15342       case 0x12: {  /* ABSQ_S.PH */
   15343          switch(sa){
   15344             case 0x1: {  /* ABSQ_S.QB */
   15345                if (VEX_MIPS_PROC_DSP2(archinfo->hwcaps)) {
   15346                   UInt retVal = disDSPInstr_MIPS_WRK ( cins );
   15347                   if (0 != retVal ) {
   15348                      goto decode_failure_dsp;
   15349                   }
   15350                   break;
   15351                } else {
   15352                   goto decode_failure_dsp;
   15353                }
   15354                break;
   15355             }
   15356             default: {
   15357                if (VEX_MIPS_PROC_DSP(archinfo->hwcaps)) {
   15358                   UInt retVal = disDSPInstr_MIPS_WRK ( cins );
   15359                   if (0 != retVal ) {
   15360                      goto decode_failure_dsp;
   15361                   }
   15362                   break;
   15363                } else {
   15364                   goto decode_failure_dsp;
   15365                }
   15366                break;
   15367             }
   15368          }
   15369          break;
   15370       }
   15371       case 0x13: {  /* SHLL.QB */
   15372          switch(sa) {
   15373             case 0x04:  /* SHRA.QB */
   15374             case 0x05:  /* SHRA_R.QB */
   15375             case 0x06:  /* SHRAV.QB */
   15376             case 0x07:  /* SHRAV_R.QB */
   15377             case 0x19:  /* SHLR.PH */
   15378             case 0x1B: {  /* SHLRV.PH */
   15379                if (VEX_MIPS_PROC_DSP2(archinfo->hwcaps)) {
   15380                   UInt retVal = disDSPInstr_MIPS_WRK ( cins );
   15381                   if (0 != retVal ) {
   15382                      goto decode_failure_dsp;
   15383                   }
   15384                   break;
   15385                } else {
   15386                   goto decode_failure_dsp;
   15387                }
   15388                break;
   15389             }
   15390             default: {
   15391                if (VEX_MIPS_PROC_DSP(archinfo->hwcaps)) {
   15392                   UInt retVal = disDSPInstr_MIPS_WRK ( cins );
   15393                   if (0 != retVal ) {
   15394                      goto decode_failure_dsp;
   15395                   }
   15396                   break;
   15397                } else {
   15398                   goto decode_failure_dsp;
   15399                }
   15400                break;
   15401             }
   15402          }
   15403          break;
   15404       }
   15405       case 0x30: {  /* DPAQ.W.PH */
   15406          switch(sa) {
   15407             case  0x0:  /* DPA.W.PH */
   15408             case 0x18:  /* DPAQX_S.W.PH */
   15409             case 0x1A:  /* DPAQX_SA.W.PH */
   15410             case  0x8:  /* DPAX.W.PH */
   15411             case  0x1:  /* DPS.W.PH */
   15412             case 0x19:  /* DPSQX_S.W.PH */
   15413             case 0x1B:  /* DPSQX_SA.W.PH */
   15414             case  0x9:  /* DPSX.W.PH */
   15415             case  0x2: {  /* MULSA.W.PH */
   15416                if (VEX_MIPS_PROC_DSP2(archinfo->hwcaps)) {
   15417                   UInt retVal = disDSPInstr_MIPS_WRK ( cins );
   15418                   if (0 != retVal ) {
   15419                      goto decode_failure_dsp;
   15420                   }
   15421                   break;
   15422                } else {
   15423                   goto decode_failure_dsp;
   15424                }
   15425                break;
   15426             }
   15427             default: {
   15428                if (VEX_MIPS_PROC_DSP(archinfo->hwcaps)) {
   15429                   UInt retVal = disDSPInstr_MIPS_WRK ( cins );
   15430                   if (0 != retVal ) {
   15431                      goto decode_failure_dsp;
   15432                   }
   15433                   break;
   15434                } else {
   15435                   goto decode_failure_dsp;
   15436                }
   15437                break;
   15438             }
   15439          }
   15440          break;
   15441       }
   15442       case 0x18:  /* ADDUH.QB/MUL.PH */
   15443       case 0x31: {  /* APPEND */
   15444          if (VEX_MIPS_PROC_DSP2(archinfo->hwcaps)) {
   15445             UInt retVal = disDSPInstr_MIPS_WRK ( cins );
   15446             if (0 != retVal ) {
   15447                goto decode_failure_dsp;
   15448             }
   15449             break;
   15450          } else {
   15451             goto decode_failure_dsp;
   15452          }
   15453       }
   15454       default:
   15455          goto decode_failure;
   15456 
   15457    }
   15458       break;  /* Special3 */
   15459 
   15460    case 0x3B:
   15461       if (0x3B == function &&
   15462           (VEX_MIPS_COMP_ID(archinfo->hwcaps) == VEX_PRID_COMP_BROADCOM)) {
   15463          /*RDHWR*/
   15464          DIP("rdhwr r%u, r%u", rt, rd);
   15465          if (rd == 29) {
   15466             putIReg(rt, getULR());
   15467          } else
   15468             goto decode_failure;
   15469          break;
   15470       } else {
   15471          goto decode_failure;
   15472       }
   15473 
   15474    case 0x00:  /* Special */
   15475 
   15476       switch (function) {
   15477       case 0x1: {
   15478          UInt mov_cc = get_mov_cc(cins);
   15479          if (tf == 0) {  /* MOVF */
   15480             DIP("movf r%u, r%u, %u", rd, rs, mov_cc);
   15481             t1 = newTemp(Ity_I1);
   15482             t2 = newTemp(Ity_I32);
   15483             t3 = newTemp(Ity_I1);
   15484 
   15485             assign(t1, binop(Iop_CmpEQ32, mkU32(0), mkU32(mov_cc)));
   15486             assign(t2, IRExpr_ITE(mkexpr(t1),
   15487                                   binop(Iop_And32,
   15488                                         binop(Iop_Shr32, getFCSR(),
   15489                                               mkU8(23)),
   15490                                         mkU32(0x1)),
   15491                                   binop(Iop_And32,
   15492                                         binop(Iop_Shr32, getFCSR(),
   15493                                               mkU8(24 + mov_cc)),
   15494                                         mkU32(0x1))
   15495                                   ));
   15496             assign(t3, binop(Iop_CmpEQ32, mkU32(0), mkexpr(t2)));
   15497             putIReg(rd, IRExpr_ITE(mkexpr(t3), getIReg(rs), getIReg(rd)));
   15498          } else if (tf == 1) {  /* MOVT */
   15499             DIP("movt r%u, r%u, %u", rd, rs, mov_cc);
   15500             t1 = newTemp(Ity_I1);
   15501             t2 = newTemp(Ity_I32);
   15502             t3 = newTemp(Ity_I1);
   15503 
   15504             assign(t1, binop(Iop_CmpEQ32, mkU32(0), mkU32(mov_cc)));
   15505             assign(t2, IRExpr_ITE(mkexpr(t1),
   15506                                   binop(Iop_And32,
   15507                                         binop(Iop_Shr32, getFCSR(),
   15508                                               mkU8(23)),
   15509                                         mkU32(0x1)),
   15510                                   binop(Iop_And32,
   15511                                         binop(Iop_Shr32, getFCSR(),
   15512                                               mkU8(24 + mov_cc)),
   15513                                         mkU32(0x1))
   15514                                   ));
   15515             assign(t3, binop(Iop_CmpEQ32, mkU32(1), mkexpr(t2)));
   15516             putIReg(rd, IRExpr_ITE(mkexpr(t3), getIReg(rs), getIReg(rd)));
   15517          }
   15518          break;
   15519       }
   15520       case 0x0A: {  /* MOVZ */
   15521          DIP("movz r%u, r%u, r%u", rd, rs, rt);
   15522          t1 = newTemp(ty);
   15523          t2 = newTemp(ty);
   15524          if (mode64) {
   15525             assign(t1, unop(Iop_32Sto64, unop(Iop_1Sto32, binop(Iop_CmpEQ64,
   15526                             getIReg(rt), mkU64(0x0)))));
   15527             assign(t2, unop(Iop_32Sto64, unop(Iop_1Sto32, binop(Iop_CmpNE64,
   15528                             getIReg(rt), mkU64(0x0)))));
   15529             putIReg(rd, binop(Iop_Add64, binop(Iop_And64, getIReg(rs),
   15530                         mkexpr(t1)), binop(Iop_And64, getIReg(rd),mkexpr(t2))));
   15531          } else {
   15532             assign(t1, unop(Iop_1Sto32, binop(Iop_CmpEQ32, getIReg(rt),
   15533                                               mkU32(0x0))));
   15534             assign(t2, unop(Iop_1Sto32, binop(Iop_CmpNE32, getIReg(rt),
   15535                                               mkU32(0x0))));
   15536             putIReg(rd, binop(Iop_Add32, binop(Iop_And32, getIReg(rs),
   15537                         mkexpr(t1)), binop(Iop_And32, getIReg(rd),
   15538                         mkexpr(t2))));
   15539          }
   15540          break;
   15541       }
   15542 
   15543       case 0x0B: {  /* MOVN */
   15544          DIP("movn r%u, r%u, r%u", rd, rs, rt);
   15545          t1 = newTemp(ty);
   15546          t2 = newTemp(ty);
   15547          if (mode64) {
   15548             assign(t1, unop(Iop_32Sto64, unop(Iop_1Sto32, binop(Iop_CmpEQ64,
   15549                             getIReg(rt), mkU64(0x0)))));
   15550             assign(t2, unop(Iop_32Sto64, unop(Iop_1Sto32, binop(Iop_CmpNE64,
   15551                             getIReg(rt), mkU64(0x0)))));
   15552             putIReg(rd, binop(Iop_Add64, binop(Iop_And64, getIReg(rs),
   15553                         mkexpr(t2)), binop(Iop_And64, getIReg(rd),
   15554                                            mkexpr(t1))));
   15555          } else {
   15556             assign(t1, unop(Iop_1Sto32, binop(Iop_CmpEQ32, getIReg(rt),
   15557                                               mkU32(0x0))));
   15558             assign(t2, unop(Iop_1Sto32, binop(Iop_CmpNE32, getIReg(rt),
   15559                                               mkU32(0x0))));
   15560             putIReg(rd, binop(Iop_Add32, binop(Iop_And32, getIReg(rs),
   15561                         mkexpr(t2)), binop(Iop_And32, getIReg(rd),
   15562                         mkexpr(t1))));
   15563          }
   15564          break;
   15565       }
   15566 
   15567       case 0x18:  {  /* MULT */
   15568          if ( (1 <= ac) && ( 3 >= ac) ) {
   15569             if (VEX_MIPS_PROC_DSP(archinfo->hwcaps)) {
   15570                /* If DSP is present -> DSP ASE MULT */
   15571                UInt retVal = disDSPInstr_MIPS_WRK ( cins );
   15572                if (0 != retVal ) {
   15573                   goto decode_failure_dsp;
   15574                }
   15575                break;
   15576             } else {
   15577                goto decode_failure_dsp;
   15578             }
   15579          } else {
   15580             DIP("mult r%u, r%u", rs, rt);
   15581             t2 = newTemp(Ity_I64);
   15582 
   15583             assign(t2, binop(Iop_MullS32, mkNarrowTo32(ty, getIReg(rs)),
   15584                                           mkNarrowTo32(ty, getIReg(rt))));
   15585 
   15586             putHI(mkWidenFrom32(ty, unop(Iop_64HIto32, mkexpr(t2)), True));
   15587             putLO(mkWidenFrom32(ty, unop(Iop_64to32, mkexpr(t2)), True));
   15588             break;
   15589          }
   15590       }
   15591       case 0x19:  {  /* MULTU */
   15592          if ( (1 <= ac) && ( 3 >= ac) ) {
   15593             if (VEX_MIPS_PROC_DSP(archinfo->hwcaps)) {
   15594                /* If DSP is present -> DSP ASE MULTU */
   15595                UInt retVal = disDSPInstr_MIPS_WRK ( cins );
   15596                if (0 != retVal ) {
   15597                   goto decode_failure_dsp;
   15598                }
   15599                break;
   15600             } else {
   15601                goto decode_failure_dsp;
   15602             }
   15603          } else {
   15604             DIP("multu r%u, r%u", rs, rt);
   15605             t2 = newTemp(Ity_I64);
   15606 
   15607             assign(t2, binop(Iop_MullU32, mkNarrowTo32(ty, getIReg(rs)),
   15608                                           mkNarrowTo32(ty, getIReg(rt))));
   15609 
   15610             putHI(mkWidenFrom32(ty, unop(Iop_64HIto32, mkexpr(t2)), True));
   15611             putLO(mkWidenFrom32(ty, unop(Iop_64to32, mkexpr(t2)), True));
   15612             break;
   15613          }
   15614       }
   15615       case 0x20: {  /* ADD */
   15616          DIP("add r%u, r%u, r%u", rd, rs, rt);
   15617          IRTemp tmpRs32 = newTemp(Ity_I32);
   15618          IRTemp tmpRt32 = newTemp(Ity_I32);
   15619 
   15620          assign(tmpRs32, mkNarrowTo32(ty, getIReg(rs)));
   15621          assign(tmpRt32, mkNarrowTo32(ty, getIReg(rt)));
   15622 
   15623          t0 = newTemp(Ity_I32);
   15624          t1 = newTemp(Ity_I32);
   15625          t2 = newTemp(Ity_I32);
   15626          t3 = newTemp(Ity_I32);
   15627          t4 = newTemp(Ity_I32);
   15628          /* dst = src0 + src1
   15629             if (sign(src0 ) != sign(src1 ))
   15630             goto no overflow;
   15631             if (sign(dst) == sign(src0 ))
   15632             goto no overflow;
   15633             we have overflow! */
   15634 
   15635          assign(t0, binop(Iop_Add32, mkexpr(tmpRs32), mkexpr(tmpRt32)));
   15636          assign(t1, binop(Iop_Xor32, mkexpr(tmpRs32), mkexpr(tmpRt32)));
   15637          assign(t2, unop(Iop_1Uto32,
   15638                          binop(Iop_CmpEQ32,
   15639                                binop(Iop_And32, mkexpr(t1), mkU32(0x80000000)),
   15640                                mkU32(0x80000000))));
   15641 
   15642          assign(t3, binop(Iop_Xor32, mkexpr(t0), mkexpr(tmpRs32)));
   15643          assign(t4, unop(Iop_1Uto32,
   15644                          binop(Iop_CmpNE32,
   15645                                binop(Iop_And32, mkexpr(t3), mkU32(0x80000000)),
   15646                                mkU32(0x80000000))));
   15647 
   15648          stmt(IRStmt_Exit(binop(Iop_CmpEQ32,
   15649                                 binop(Iop_Or32, mkexpr(t2), mkexpr(t4)),
   15650                                 mkU32(0)),
   15651                           Ijk_SigFPE_IntOvf,
   15652                           mode64 ? IRConst_U64(guest_PC_curr_instr + 4) :
   15653                                    IRConst_U32(guest_PC_curr_instr + 4),
   15654                           OFFB_PC));
   15655 
   15656          putIReg(rd,  mkWidenFrom32(ty, mkexpr(t0), True));
   15657          break;
   15658       }
   15659       case 0x1A:  /* DIV */
   15660          DIP("div r%u, r%u", rs, rt);
   15661          if (mode64) {
   15662             t2 = newTemp(Ity_I64);
   15663 
   15664             assign(t2, binop(Iop_DivModS64to32,
   15665                              getIReg(rs), mkNarrowTo32(ty, getIReg(rt))));
   15666 
   15667             putHI(mkWidenFrom32(ty, unop(Iop_64HIto32, mkexpr(t2)), True));
   15668             putLO(mkWidenFrom32(ty, unop(Iop_64to32, mkexpr(t2)), True));
   15669          } else {
   15670             t1 = newTemp(Ity_I64);
   15671             t2 = newTemp(Ity_I64);
   15672 
   15673             assign(t1, unop(Iop_32Sto64, getIReg(rs)));
   15674             assign(t2, binop(Iop_DivModS64to32, mkexpr(t1), getIReg(rt)));
   15675 
   15676             putHI(unop(Iop_64HIto32, mkexpr(t2)));
   15677             putLO(unop(Iop_64to32, mkexpr(t2)));
   15678          }
   15679          break;
   15680 
   15681       case 0x1B:  /* DIVU */
   15682          DIP("divu r%u, r%u", rs, rt);
   15683          if (mode64) {
   15684             t2 = newTemp(Ity_I64);
   15685 
   15686             assign(t2, binop(Iop_DivModU64to32,
   15687                              getIReg(rs), mkNarrowTo32(ty, getIReg(rt))));
   15688 
   15689             putHI(mkWidenFrom32(ty, unop(Iop_64HIto32, mkexpr(t2)), True));
   15690             putLO(mkWidenFrom32(ty, unop(Iop_64to32, mkexpr(t2)), True));
   15691          } else {
   15692             t1 = newTemp(Ity_I64);
   15693             t2 = newTemp(Ity_I64);
   15694             assign(t1, unop(Iop_32Uto64, getIReg(rs)));
   15695             assign(t2, binop(Iop_DivModU64to32, mkexpr(t1), getIReg(rt)));
   15696             putHI(unop(Iop_64HIto32, mkexpr(t2)));
   15697             putLO(unop(Iop_64to32, mkexpr(t2)));
   15698          }
   15699          break;
   15700 
   15701       case 0x1C:  /* Doubleword Multiply - DMULT; MIPS64 */
   15702          DIP("dmult r%u, r%u", rs, rt);
   15703          t0 = newTemp(Ity_I128);
   15704 
   15705          assign(t0, binop(Iop_MullS64, getIReg(rs), getIReg(rt)));
   15706 
   15707          putHI(unop(Iop_128HIto64, mkexpr(t0)));
   15708          putLO(unop(Iop_128to64, mkexpr(t0)));
   15709          break;
   15710 
   15711       case 0x1D:  /* Doubleword Multiply Unsigned - DMULTU; MIPS64 */
   15712          DIP("dmultu r%u, r%u", rs, rt);
   15713          t0 = newTemp(Ity_I128);
   15714 
   15715          assign(t0, binop(Iop_MullU64, getIReg(rs), getIReg(rt)));
   15716 
   15717          putHI(unop(Iop_128HIto64, mkexpr(t0)));
   15718          putLO(unop(Iop_128to64, mkexpr(t0)));
   15719          break;
   15720 
   15721       case 0x1E:  /* Doubleword Divide DDIV; MIPS64 */
   15722          DIP("ddiv r%u, r%u", rs, rt);
   15723          t1 = newTemp(Ity_I128);
   15724 
   15725          assign(t1, binop(Iop_DivModS64to64, getIReg(rs), getIReg(rt)));
   15726 
   15727          putHI(unop(Iop_128HIto64, mkexpr(t1)));
   15728          putLO(unop(Iop_128to64, mkexpr(t1)));
   15729          break;
   15730 
   15731       case 0x1F:  /* Doubleword Divide Unsigned DDIVU; MIPS64 check this */
   15732          DIP("ddivu r%u, r%u", rs, rt);
   15733          t1 = newTemp(Ity_I128);
   15734          t2 = newTemp(Ity_I128);
   15735 
   15736          assign(t1, binop(Iop_64HLto128, mkU64(0), getIReg(rs)));
   15737 
   15738          assign(t2, binop(Iop_DivModU128to64, mkexpr(t1), getIReg(rt)));
   15739 
   15740          putHI(unop(Iop_128HIto64, mkexpr(t2)));
   15741          putLO(unop(Iop_128to64, mkexpr(t2)));
   15742          break;
   15743 
   15744       case 0x10: {  /* MFHI */
   15745          if (VEX_MIPS_PROC_DSP(archinfo->hwcaps)) {
   15746             /* If DSP is present -> DSP ASE MFHI */
   15747             UInt retVal = disDSPInstr_MIPS_WRK ( cins );
   15748             if (0 != retVal ) {
   15749                goto decode_failure;
   15750             }
   15751             break;
   15752          } else {
   15753             DIP("mfhi r%u", rd);
   15754             putIReg(rd, getHI());
   15755             break;
   15756          }
   15757       }
   15758 
   15759       case 0x11:  {  /* MTHI */
   15760          if (VEX_MIPS_PROC_DSP(archinfo->hwcaps)) {
   15761             /* If DSP is present -> DSP ASE MTHI */
   15762             UInt retVal = disDSPInstr_MIPS_WRK ( cins );
   15763             if (0 != retVal ) {
   15764                goto decode_failure;
   15765             }
   15766             break;
   15767          } else {
   15768             DIP("mthi r%u", rs);
   15769             putHI(getIReg(rs));
   15770             break;
   15771          }
   15772       }
   15773 
   15774       case 0x12:  {  /* MFLO */
   15775          if (VEX_MIPS_PROC_DSP(archinfo->hwcaps)) {
   15776             /* If DSP is present -> DSP ASE MFLO */
   15777             UInt retVal = disDSPInstr_MIPS_WRK ( cins );
   15778             if (0 != retVal ) {
   15779                goto decode_failure;
   15780             }
   15781             break;
   15782          } else {
   15783             DIP("mflo r%u", rd);
   15784             putIReg(rd, getLO());
   15785             break;
   15786          }
   15787       }
   15788 
   15789       case 0x13:  {  /* MTLO */
   15790          if (VEX_MIPS_PROC_DSP(archinfo->hwcaps)) {
   15791             /* If DSP is present -> DSP ASE MTLO */
   15792             UInt retVal = disDSPInstr_MIPS_WRK ( cins );
   15793             if (0 != retVal ) {
   15794                goto decode_failure;
   15795             }
   15796             break;
   15797          } else {
   15798             DIP("mtlo r%u", rs);
   15799             putLO(getIReg(rs));
   15800             break;
   15801          }
   15802       }
   15803 
   15804       case 0x21:  /* ADDU */
   15805          DIP("addu r%u, r%u, r%u", rd, rs, rt);
   15806          if (mode64) {
   15807             ALU_PATTERN64(Iop_Add32);
   15808          } else {
   15809             ALU_PATTERN(Iop_Add32);
   15810          }
   15811          break;
   15812 
   15813       case 0x22: {  /* SUB */
   15814          DIP("sub r%u, r%u, r%u", rd, rs, rt);
   15815          IRTemp tmpRs32 = newTemp(Ity_I32);
   15816          IRTemp tmpRt32 = newTemp(Ity_I32);
   15817 
   15818          assign(tmpRs32, mkNarrowTo32(ty, getIReg(rs)));
   15819          assign(tmpRt32, mkNarrowTo32(ty, getIReg(rt)));
   15820          t0 = newTemp(Ity_I32);
   15821          t1 = newTemp(Ity_I32);
   15822          t2 = newTemp(Ity_I32);
   15823          t3 = newTemp(Ity_I32);
   15824          t4 = newTemp(Ity_I32);
   15825          t5 = newTemp(Ity_I32);
   15826          /* dst = src0 + (-1 * src1)
   15827             if(sign(src0 ) != sign((-1 * src1) ))
   15828             goto no overflow;
   15829             if(sign(dst) == sign(src0 ))
   15830             goto no overflow;
   15831             we have overflow! */
   15832 
   15833          assign(t5, binop(Iop_Mul32, mkexpr(tmpRt32), mkU32(-1)));
   15834          assign(t0, binop(Iop_Add32, mkexpr(tmpRs32), mkexpr(t5)));
   15835          assign(t1, binop(Iop_Xor32, mkexpr(tmpRs32), mkexpr(t5)));
   15836          assign(t2, unop(Iop_1Sto32, binop(Iop_CmpEQ32, binop(Iop_And32,
   15837                          mkexpr(t1), mkU32(0x80000000)), mkU32(0x80000000))));
   15838 
   15839          assign(t3, binop(Iop_Xor32, mkexpr(t0), mkexpr(tmpRs32)));
   15840          assign(t4, unop(Iop_1Sto32, binop(Iop_CmpNE32, binop(Iop_And32,
   15841                          mkexpr(t3), mkU32(0x80000000)), mkU32(0x80000000))));
   15842 
   15843          stmt(IRStmt_Exit(binop(Iop_CmpEQ32, binop(Iop_Or32, mkexpr(t2),
   15844                                 mkexpr(t4)), mkU32(0)), Ijk_SigFPE_IntOvf,
   15845                           mode64 ? IRConst_U64(guest_PC_curr_instr + 4) :
   15846                                    IRConst_U32(guest_PC_curr_instr + 4),
   15847                           OFFB_PC));
   15848 
   15849          putIReg(rd, mkWidenFrom32(ty, mkexpr(t0), True));
   15850          break;
   15851       }
   15852       case 0x23:  /* SUBU */
   15853          DIP("subu r%u, r%u, r%u", rd, rs, rt);
   15854          if (mode64) {
   15855             ALU_PATTERN64(Iop_Sub32);
   15856          } else {
   15857             ALU_PATTERN(Iop_Sub32);
   15858          }
   15859          break;
   15860 
   15861       case 0x24:  /* AND */
   15862          DIP("and r%u, r%u, r%u", rd, rs, rt);
   15863          if (mode64) {
   15864             ALU_PATTERN(Iop_And64);
   15865          } else {
   15866             ALU_PATTERN(Iop_And32);
   15867          }
   15868          break;
   15869 
   15870       case 0x25:  /* OR */
   15871          DIP("or r%u, r%u, r%u", rd, rs, rt);
   15872          if (mode64) {
   15873             ALU_PATTERN(Iop_Or64);
   15874          } else {
   15875             ALU_PATTERN(Iop_Or32);
   15876          }
   15877          break;
   15878 
   15879       case 0x26:  /* XOR */
   15880          DIP("xor r%u, r%u, r%u", rd, rs, rt);
   15881          if (mode64) {
   15882             ALU_PATTERN(Iop_Xor64);
   15883          } else {
   15884             ALU_PATTERN(Iop_Xor32);
   15885          }
   15886          break;
   15887 
   15888       case 0x27:  /* NOR */
   15889          DIP("nor r%u, r%u, r%u", rd, rs, rt);
   15890          if (mode64)
   15891             putIReg(rd, unop(Iop_Not64, binop(Iop_Or64, getIReg(rs),
   15892                                               getIReg(rt))));
   15893          else
   15894             putIReg(rd, unop(Iop_Not32, binop(Iop_Or32, getIReg(rs),
   15895                                               getIReg(rt))));
   15896          break;
   15897 
   15898       case 0x08:  /* JR */
   15899          DIP("jr r%u", rs);
   15900          t0 = newTemp(ty);
   15901          assign(t0, getIReg(rs));
   15902          lastn = mkexpr(t0);
   15903          break;
   15904 
   15905       case 0x09:  /* JALR */
   15906          DIP("jalr r%u r%u", rd, rs);
   15907          if (mode64) {
   15908             putIReg(rd, mkU64(guest_PC_curr_instr + 8));
   15909             t0 = newTemp(Ity_I64);
   15910             assign(t0, getIReg(rs));
   15911             lastn = mkexpr(t0);
   15912          } else {
   15913             putIReg(rd, mkU32(guest_PC_curr_instr + 8));
   15914             t0 = newTemp(Ity_I32);
   15915             assign(t0, getIReg(rs));
   15916             lastn = mkexpr(t0);
   15917          }
   15918          break;
   15919 
   15920       case 0x0C:  /* SYSCALL */
   15921          DIP("syscall");
   15922          if (mode64)
   15923             putPC(mkU64(guest_PC_curr_instr + 4));
   15924          else
   15925             putPC(mkU32(guest_PC_curr_instr + 4));
   15926          dres.jk_StopHere = Ijk_Sys_syscall;
   15927          dres.whatNext    = Dis_StopHere;
   15928          break;
   15929 
   15930       case 0x2A:  /* SLT */
   15931          DIP("slt r%u, r%u, r%u", rd, rs, rt);
   15932          if (mode64)
   15933             putIReg(rd, unop(Iop_1Uto64, binop(Iop_CmpLT64S, getIReg(rs),
   15934                                                getIReg(rt))));
   15935          else
   15936             putIReg(rd, unop(Iop_1Uto32, binop(Iop_CmpLT32S, getIReg(rs),
   15937                                                getIReg(rt))));
   15938          break;
   15939 
   15940       case 0x2B:  /* SLTU */
   15941          DIP("sltu r%u, r%u, r%u", rd, rs, rt);
   15942          if (mode64)
   15943             putIReg(rd, unop(Iop_1Uto64, binop(Iop_CmpLT64U, getIReg(rs),
   15944                                          getIReg(rt))));
   15945          else
   15946             putIReg(rd, unop(Iop_1Uto32, binop(Iop_CmpLT32U, getIReg(rs),
   15947                                          getIReg(rt))));
   15948          break;
   15949 
   15950       case 0x00: {  /* SLL */
   15951          DIP("sll r%u, r%u, %u", rd, rt, sa);
   15952          IRTemp tmpRt32 = newTemp(Ity_I32);
   15953          IRTemp tmpSh32 = newTemp(Ity_I32);
   15954          IRTemp tmpRd = newTemp(Ity_I64);
   15955          if (mode64) {
   15956             assign(tmpRt32, mkNarrowTo32(ty, getIReg(rt)));
   15957             assign(tmpSh32, binop(Iop_Shl32, mkexpr(tmpRt32), mkU8(sa)));
   15958             assign(tmpRd, mkWidenFrom32(ty, mkexpr(tmpSh32), True));
   15959             putIReg(rd, mkexpr(tmpRd));
   15960          } else
   15961             SXX_PATTERN(Iop_Shl32);
   15962          break;
   15963       }
   15964 
   15965       case 0x04: {  /* SLLV */
   15966          DIP("sllv r%u, r%u, r%u", rd, rt, rs);
   15967          if (mode64) {
   15968             IRTemp tmpRs8 = newTemp(Ity_I8);
   15969             IRTemp tmpRt32 = newTemp(Ity_I32);
   15970             IRTemp tmpSh32 = newTemp(Ity_I32);
   15971             IRTemp tmp = newTemp(ty);
   15972             assign(tmp, binop(mkSzOp(ty, Iop_And8), getIReg(rs),
   15973                               mkSzImm(ty, 31)));
   15974             assign(tmpRs8, mkNarrowTo8(ty, mkexpr(tmp)));
   15975             assign(tmpRt32, mkNarrowTo32(ty, getIReg(rt)));
   15976             assign(tmpSh32, binop(Iop_Shl32, mkexpr(tmpRt32), mkexpr(tmpRs8)));
   15977             putIReg(rd, mkWidenFrom32(ty, mkexpr(tmpSh32), True));
   15978          } else {
   15979             SXXV_PATTERN(Iop_Shl32);
   15980          }
   15981          break;
   15982       }
   15983 
   15984       case 0x03:  /* SRA */
   15985          DIP("sra r%u, r%u, %u", rd, rt, sa);
   15986          if (mode64) {
   15987             IRTemp tmpRt32 = newTemp(Ity_I32);
   15988             IRTemp tmpSh32 = newTemp(Ity_I32);
   15989 
   15990             t1 = newTemp(Ity_I64);
   15991             t2 = newTemp(Ity_I64);
   15992             t3 = newTemp(Ity_I64);
   15993 
   15994             assign(t1, binop(Iop_And64, getIReg(rt),  /* hi */
   15995                              mkU64(0xFFFFFFFF00000000ULL)));
   15996 
   15997             assign(t2, binop(Iop_Sar64, mkexpr(t1), mkU8(sa)));
   15998 
   15999             assign(tmpRt32, mkNarrowTo32(ty, getIReg(rt)));
   16000             assign(tmpSh32, binop(Iop_Sar32, mkexpr(tmpRt32), mkU8(sa)));
   16001 
   16002             putIReg(rd, mkWidenFrom32(ty, mkexpr(tmpSh32), True));
   16003          } else {
   16004             SXX_PATTERN(Iop_Sar32);
   16005          }
   16006          break;
   16007 
   16008       case 0x07:  /* SRAV */
   16009          DIP("srav r%u, r%u, r%u", rd, rt, rs);
   16010          if (mode64) {
   16011             IRTemp tmpRt32 = newTemp(Ity_I32);
   16012             IRTemp tmpSh32 = newTemp(Ity_I32);
   16013 
   16014             t1 = newTemp(Ity_I64);
   16015             t2 = newTemp(Ity_I64);
   16016             t3 = newTemp(Ity_I64);
   16017             t4 = newTemp(Ity_I8);
   16018 
   16019             assign(t4, unop(Iop_32to8, binop(Iop_And32,
   16020                        mkNarrowTo32(ty, getIReg(rs)), mkU32(0x0000001F))));
   16021 
   16022             assign(t1, binop(Iop_And64, getIReg(rt),  /* hi */
   16023                    mkU64(0xFFFFFFFF00000000ULL)));
   16024 
   16025             assign(t2, binop(Iop_Sar64, mkexpr(t1), mkexpr(t4)));
   16026 
   16027             assign(tmpRt32, mkNarrowTo32(ty, getIReg(rt)));
   16028             assign(tmpSh32, binop(Iop_Sar32, mkexpr(tmpRt32), mkexpr(t4)));
   16029 
   16030             putIReg(rd, mkWidenFrom32(ty, mkexpr(tmpSh32), True));
   16031          } else {
   16032             SXXV_PATTERN(Iop_Sar32);
   16033          }
   16034          break;
   16035 
   16036       case 0x02: {  /* SRL */
   16037          rot = get_rot(cins);
   16038          if (rot) {
   16039             DIP("rotr r%u, r%u, %u", rd, rt, sa);
   16040             putIReg(rd, mkWidenFrom32(ty, genROR32(mkNarrowTo32(ty,
   16041                         getIReg(rt)), sa), True));
   16042          } else {
   16043             DIP("srl r%u, r%u, %u", rd, rt, sa);
   16044             if (mode64) {
   16045                IRTemp tmpSh32 = newTemp(Ity_I32);
   16046                IRTemp tmpRt32 = newTemp(Ity_I32);
   16047 
   16048                assign(tmpRt32, mkNarrowTo32(ty, getIReg(rt)));
   16049                assign(tmpSh32, binop(Iop_Shr32, mkexpr(tmpRt32), mkU8(sa)));
   16050                putIReg(rd, mkWidenFrom32(ty, mkexpr(tmpSh32), True));
   16051             } else {
   16052                SXX_PATTERN(Iop_Shr32);
   16053             }
   16054          }
   16055       break;
   16056       }
   16057 
   16058       case 0x06: {
   16059          rot = get_rotv(cins);
   16060          if (rot) {
   16061             DIP("rotrv r%u, r%u, r%u", rd, rt, rs);
   16062             putIReg(rd, mkWidenFrom32(ty, genRORV32(mkNarrowTo32(ty,
   16063                         getIReg(rt)), mkNarrowTo32(ty, getIReg(rs))), True));
   16064             break;
   16065          } else {  /* SRLV */
   16066             DIP("srlv r%u, r%u, r%u", rd, rt, rs);
   16067             if (mode64) {
   16068                SXXV_PATTERN64(Iop_Shr32);
   16069             } else {
   16070                SXXV_PATTERN(Iop_Shr32);
   16071             }
   16072             break;
   16073          }
   16074       }
   16075 
   16076       case 0x0D:  /* BREAK */
   16077          DIP("break 0x%x", trap_code);
   16078          if (mode64)
   16079             jmp_lit64(&dres, Ijk_SigTRAP, (guest_PC_curr_instr + 4));
   16080          else
   16081             jmp_lit32(&dres, Ijk_SigTRAP, (guest_PC_curr_instr + 4));
   16082          vassert(dres.whatNext == Dis_StopHere);
   16083          break;
   16084 
   16085       case 0x30: {  /* TGE */
   16086          DIP("tge r%u, r%u %u", rs, rt, trap_code);
   16087          if (mode64) {
   16088             if (trap_code == 7)
   16089                stmt (IRStmt_Exit (unop (Iop_Not1,
   16090                                         binop (Iop_CmpLT64S,
   16091                                                getIReg (rs),
   16092                                                getIReg (rt))),
   16093                                 Ijk_SigFPE_IntDiv,
   16094                                 IRConst_U64(guest_PC_curr_instr + 4),
   16095                                 OFFB_PC));
   16096             else if (trap_code == 6)
   16097                stmt (IRStmt_Exit (unop (Iop_Not1,
   16098                                         binop (Iop_CmpLT64S,
   16099                                                getIReg (rs),
   16100                                                getIReg (rt))),
   16101                                 Ijk_SigFPE_IntOvf,
   16102                                 IRConst_U64(guest_PC_curr_instr + 4),
   16103                                 OFFB_PC));
   16104             else
   16105                stmt (IRStmt_Exit (unop (Iop_Not1,
   16106                                         binop (Iop_CmpLT64S,
   16107                                                getIReg (rs),
   16108                                                getIReg (rt))),
   16109                                 Ijk_SigTRAP,
   16110                                 IRConst_U64(guest_PC_curr_instr + 4),
   16111                                 OFFB_PC));
   16112          } else {
   16113             if (trap_code == 7)
   16114                stmt (IRStmt_Exit (unop (Iop_Not1,
   16115                                         binop (Iop_CmpLT32S,
   16116                                                getIReg (rs),
   16117                                                getIReg (rt))),
   16118                                   Ijk_SigFPE_IntDiv,
   16119                                   IRConst_U32(guest_PC_curr_instr + 4),
   16120                                   OFFB_PC));
   16121             else if (trap_code == 6)
   16122                stmt (IRStmt_Exit (unop (Iop_Not1,
   16123                                         binop (Iop_CmpLT32S,
   16124                                                getIReg (rs),
   16125                                                getIReg (rt))),
   16126                                   Ijk_SigFPE_IntOvf,
   16127                                   IRConst_U32(guest_PC_curr_instr + 4),
   16128                                   OFFB_PC));
   16129             else
   16130                stmt (IRStmt_Exit (unop (Iop_Not1,
   16131                                         binop (Iop_CmpLT32S,
   16132                                                getIReg (rs),
   16133                                                getIReg (rt))),
   16134                                   Ijk_SigTRAP,
   16135                                   IRConst_U32(guest_PC_curr_instr + 4),
   16136                                   OFFB_PC));
   16137          }
   16138          break;
   16139       }
   16140       case 0x31: {  /* TGEU */
   16141          DIP("tgeu r%u, r%u %u", rs, rt, trap_code);
   16142          if (mode64) {
   16143             if (trap_code == 7)
   16144                stmt (IRStmt_Exit (unop (Iop_Not1,
   16145                                         binop (Iop_CmpLT64U,
   16146                                                getIReg (rs),
   16147                                                getIReg (rt))),
   16148                                   Ijk_SigFPE_IntDiv,
   16149                                   IRConst_U64(guest_PC_curr_instr + 4),
   16150                                   OFFB_PC));
   16151             else if (trap_code == 6)
   16152                stmt (IRStmt_Exit (unop (Iop_Not1,
   16153                                         binop (Iop_CmpLT64U,
   16154                                                getIReg (rs),
   16155                                                getIReg (rt))),
   16156                                   Ijk_SigFPE_IntOvf,
   16157                                   IRConst_U64(guest_PC_curr_instr + 4),
   16158                                   OFFB_PC));
   16159             else
   16160                stmt (IRStmt_Exit (unop (Iop_Not1,
   16161                                         binop (Iop_CmpLT64U,
   16162                                                getIReg (rs),
   16163                                                getIReg (rt))),
   16164                                   Ijk_SigTRAP,
   16165                                   IRConst_U64(guest_PC_curr_instr + 4),
   16166                                   OFFB_PC));
   16167          } else {
   16168             if (trap_code == 7)
   16169                stmt (IRStmt_Exit (unop (Iop_Not1,
   16170                                         binop (Iop_CmpLT32U,
   16171                                                getIReg (rs),
   16172                                                getIReg (rt))),
   16173                                   Ijk_SigFPE_IntDiv,
   16174                                   IRConst_U32(guest_PC_curr_instr + 4),
   16175                                   OFFB_PC));
   16176             else if (trap_code == 6)
   16177                stmt (IRStmt_Exit (unop (Iop_Not1,
   16178                                         binop (Iop_CmpLT32U,
   16179                                                getIReg (rs),
   16180                                                getIReg (rt))),
   16181                                   Ijk_SigFPE_IntOvf,
   16182                                   IRConst_U32(guest_PC_curr_instr + 4),
   16183                                   OFFB_PC));
   16184             else
   16185                stmt (IRStmt_Exit (unop (Iop_Not1,
   16186                                         binop (Iop_CmpLT32U,
   16187                                                getIReg (rs),
   16188                                                getIReg (rt))),
   16189                                   Ijk_SigTRAP,
   16190                                   IRConst_U32(guest_PC_curr_instr + 4),
   16191                                   OFFB_PC));
   16192          }
   16193          break;
   16194       }
   16195       case 0x32: {  /* TLT */
   16196          DIP("tlt r%u, r%u %u", rs, rt, trap_code);
   16197          if (mode64) {
   16198             if (trap_code == 7)
   16199                stmt(IRStmt_Exit(binop(Iop_CmpLT64S, getIReg(rs),
   16200                                       getIReg(rt)), Ijk_SigFPE_IntDiv,
   16201                                 IRConst_U64(guest_PC_curr_instr + 4),
   16202                                 OFFB_PC));
   16203             else if (trap_code == 6)
   16204                stmt(IRStmt_Exit(binop(Iop_CmpLT64S, getIReg(rs),
   16205                                       getIReg(rt)), Ijk_SigFPE_IntOvf,
   16206                                 IRConst_U64(guest_PC_curr_instr + 4),
   16207                                 OFFB_PC));
   16208             else
   16209                stmt(IRStmt_Exit(binop(Iop_CmpLT64S, getIReg(rs),
   16210                                       getIReg(rt)), Ijk_SigTRAP,
   16211                                 IRConst_U64(guest_PC_curr_instr + 4),
   16212                                 OFFB_PC));
   16213          } else {
   16214             if (trap_code == 7)
   16215                stmt(IRStmt_Exit(binop(Iop_CmpLT32S, getIReg(rs),
   16216                                       getIReg(rt)), Ijk_SigFPE_IntDiv,
   16217                                 IRConst_U32(guest_PC_curr_instr + 4),
   16218                                 OFFB_PC));
   16219             else if (trap_code == 6)
   16220                stmt(IRStmt_Exit(binop(Iop_CmpLT32S, getIReg(rs),
   16221                                       getIReg(rt)), Ijk_SigFPE_IntOvf,
   16222                                 IRConst_U32(guest_PC_curr_instr + 4),
   16223                                 OFFB_PC));
   16224             else
   16225                stmt(IRStmt_Exit(binop(Iop_CmpLT32S, getIReg(rs),
   16226                                       getIReg(rt)), Ijk_SigTRAP,
   16227                                 IRConst_U32(guest_PC_curr_instr + 4),
   16228                                 OFFB_PC));
   16229          }
   16230          break;
   16231       }
   16232       case 0x33: {  /* TLTU */
   16233          DIP("tltu r%u, r%u %u", rs, rt, trap_code);
   16234          if (mode64) {
   16235             if (trap_code == 7)
   16236                stmt(IRStmt_Exit(binop(Iop_CmpLT64U, getIReg(rs),
   16237                                       getIReg(rt)), Ijk_SigFPE_IntDiv,
   16238                                 IRConst_U64(guest_PC_curr_instr + 4),
   16239                                 OFFB_PC));
   16240             else if (trap_code == 6)
   16241                stmt(IRStmt_Exit(binop(Iop_CmpLT64U, getIReg(rs),
   16242                                       getIReg(rt)), Ijk_SigFPE_IntOvf,
   16243                                 IRConst_U64(guest_PC_curr_instr + 4),
   16244                                 OFFB_PC));
   16245             else
   16246                stmt(IRStmt_Exit(binop(Iop_CmpLT64U, getIReg(rs),
   16247                                       getIReg(rt)), Ijk_SigTRAP,
   16248                                 IRConst_U64(guest_PC_curr_instr + 4),
   16249                                 OFFB_PC));
   16250          } else {
   16251             if (trap_code == 7)
   16252                stmt(IRStmt_Exit(binop(Iop_CmpLT32U, getIReg(rs),
   16253                                       getIReg(rt)), Ijk_SigFPE_IntDiv,
   16254                                 IRConst_U32(guest_PC_curr_instr + 4),
   16255                                 OFFB_PC));
   16256             else if (trap_code == 6)
   16257                stmt(IRStmt_Exit(binop(Iop_CmpLT32U, getIReg(rs),
   16258                                       getIReg(rt)), Ijk_SigFPE_IntOvf,
   16259                                 IRConst_U32(guest_PC_curr_instr + 4),
   16260                                 OFFB_PC));
   16261             else
   16262                stmt(IRStmt_Exit(binop(Iop_CmpLT32U, getIReg(rs),
   16263                                       getIReg (rt)), Ijk_SigTRAP,
   16264                                 IRConst_U32(guest_PC_curr_instr + 4),
   16265                                 OFFB_PC));
   16266          }
   16267          break;
   16268       }
   16269       case 0x34: {  /* TEQ */
   16270          DIP("teq r%u, r%u, %u", rs, rt, trap_code);
   16271          if (mode64) {
   16272             if (trap_code == 7)
   16273                stmt(IRStmt_Exit(binop(Iop_CmpEQ64, getIReg(rs),
   16274                                       getIReg(rt)), Ijk_SigFPE_IntDiv,
   16275                                 IRConst_U64(guest_PC_curr_instr + 4),
   16276                                 OFFB_PC));
   16277             else if (trap_code == 6)
   16278                stmt(IRStmt_Exit(binop(Iop_CmpEQ64, getIReg(rs),
   16279                                       getIReg(rt)), Ijk_SigFPE_IntOvf,
   16280                                 IRConst_U64(guest_PC_curr_instr + 4),
   16281                                 OFFB_PC));
   16282             else
   16283                stmt(IRStmt_Exit(binop(Iop_CmpEQ64, getIReg(rs),
   16284                                       getIReg(rt)), Ijk_SigTRAP,
   16285                                 IRConst_U64(guest_PC_curr_instr + 4),
   16286                                 OFFB_PC));
   16287          } else {
   16288             if (trap_code == 7)
   16289                stmt(IRStmt_Exit(binop(Iop_CmpEQ32, getIReg(rs),
   16290                                       getIReg(rt)), Ijk_SigFPE_IntDiv,
   16291                                 IRConst_U32(guest_PC_curr_instr + 4),
   16292                                 OFFB_PC));
   16293             else if (trap_code == 6)
   16294                stmt(IRStmt_Exit(binop(Iop_CmpEQ32, getIReg(rs),
   16295                                       getIReg(rt)), Ijk_SigFPE_IntOvf,
   16296                                 IRConst_U32(guest_PC_curr_instr + 4),
   16297                                 OFFB_PC));
   16298             else
   16299                stmt(IRStmt_Exit(binop(Iop_CmpEQ32, getIReg(rs),
   16300                                       getIReg(rt)), Ijk_SigTRAP,
   16301                                 IRConst_U32(guest_PC_curr_instr + 4),
   16302                                 OFFB_PC));
   16303          }
   16304          break;
   16305       }
   16306       case 0x36: {  /* TNE */
   16307          DIP("tne r%u, r%u %u", rs, rt, trap_code);
   16308          if (mode64) {
   16309             if (trap_code == 7)
   16310                stmt(IRStmt_Exit(binop(Iop_CmpNE64, getIReg(rs),
   16311                                       getIReg(rt)), Ijk_SigFPE_IntDiv,
   16312                                 IRConst_U64(guest_PC_curr_instr + 4),
   16313                                 OFFB_PC));
   16314             else if (trap_code == 6)
   16315                stmt(IRStmt_Exit(binop(Iop_CmpNE64, getIReg(rs),
   16316                                       getIReg(rt)), Ijk_SigFPE_IntOvf,
   16317                                 IRConst_U64(guest_PC_curr_instr + 4),
   16318                                 OFFB_PC));
   16319             else
   16320                stmt(IRStmt_Exit(binop(Iop_CmpNE64, getIReg(rs),
   16321                                       getIReg(rt)), Ijk_SigTRAP,
   16322                                 IRConst_U64(guest_PC_curr_instr + 4),
   16323                                 OFFB_PC));
   16324          } else {
   16325             if (trap_code == 7)
   16326                stmt(IRStmt_Exit(binop(Iop_CmpNE32, getIReg(rs),
   16327                                       getIReg(rt)), Ijk_SigFPE_IntDiv,
   16328                                 IRConst_U32(guest_PC_curr_instr + 4),
   16329                                 OFFB_PC));
   16330             else if (trap_code == 6)
   16331                stmt(IRStmt_Exit(binop(Iop_CmpNE32, getIReg(rs),
   16332                                       getIReg(rt)), Ijk_SigFPE_IntOvf,
   16333                                 IRConst_U32(guest_PC_curr_instr + 4),
   16334                                 OFFB_PC));
   16335             else
   16336                stmt(IRStmt_Exit(binop(Iop_CmpNE32, getIReg(rs),
   16337                                       getIReg(rt)), Ijk_SigTRAP,
   16338                                 IRConst_U32(guest_PC_curr_instr + 4),
   16339                                 OFFB_PC));
   16340          }
   16341          break;
   16342       }
   16343       case 0x14:
   16344       case 0x16:
   16345       case 0x17:  /* DSLLV, DROTRV:DSRLV, DSRAV */
   16346       case 0x38:
   16347       case 0x3A:
   16348       case 0x3B:  /* DSLL, DROTL:DSRL, DSRA  */
   16349       case 0x3C:
   16350       case 0x3E:
   16351       case 0x3F:  /* DSLL32, DROTR32:DSRL32, DSRA32 */
   16352          if (dis_instr_shrt(cins))
   16353             break;
   16354          goto decode_failure;
   16355 
   16356       case 0x0F:  /* SYNC */
   16357          DIP("sync 0x%x", sel);
   16358          /* Just ignore it. */
   16359          break;
   16360 
   16361       case 0x2C: {  /* Doubleword Add - DADD; MIPS64 */
   16362          DIP("dadd r%u, r%u, r%u", rd, rs, rt);
   16363          IRTemp tmpRs64 = newTemp(Ity_I64);
   16364          IRTemp tmpRt64 = newTemp(Ity_I64);
   16365 
   16366          assign(tmpRs64, getIReg(rs));
   16367          assign(tmpRt64, getIReg(rt));
   16368 
   16369          t0 = newTemp(Ity_I64);
   16370          t1 = newTemp(Ity_I64);
   16371          t2 = newTemp(Ity_I64);
   16372          t3 = newTemp(Ity_I64);
   16373          t4 = newTemp(Ity_I64);
   16374          /* dst = src0 + src1
   16375             if(sign(src0 ) != sign(src1 ))
   16376             goto no overflow;
   16377             if(sign(dst) == sign(src0 ))
   16378             goto no overflow;
   16379             we have overflow! */
   16380 
   16381          assign(t0, binop(Iop_Add64, mkexpr(tmpRs64), mkexpr(tmpRt64)));
   16382          assign(t1, binop(Iop_Xor64, mkexpr(tmpRs64), mkexpr(tmpRt64)));
   16383          assign(t2, unop(Iop_1Uto64,
   16384                          binop(Iop_CmpEQ64,
   16385                                binop(Iop_And64, mkexpr(t1),
   16386                                      mkU64(0x8000000000000000ULL)),
   16387                                mkU64(0x8000000000000000ULL))));
   16388 
   16389          assign(t3, binop(Iop_Xor64, mkexpr(t0), mkexpr(tmpRs64)));
   16390          assign(t4, unop(Iop_1Uto64,
   16391                          binop(Iop_CmpNE64,
   16392                                binop(Iop_And64, mkexpr(t3),
   16393                                      mkU64(0x8000000000000000ULL)),
   16394                                mkU64(0x8000000000000000ULL))));
   16395 
   16396          stmt(IRStmt_Exit(binop(Iop_CmpEQ64,
   16397                                 binop(Iop_Or64, mkexpr(t2), mkexpr(t4)),
   16398                                 mkU64(0)),
   16399                           Ijk_SigFPE_IntOvf,
   16400                           IRConst_U64(guest_PC_curr_instr + 4),
   16401                           OFFB_PC));
   16402 
   16403          putIReg(rd,  mkexpr(t0));
   16404          break;
   16405       }
   16406 
   16407       case 0x2D:  /* Doubleword Add Unsigned - DADDU; MIPS64 */
   16408          DIP("daddu r%u, r%u, r%u", rd, rs, rt);
   16409          ALU_PATTERN(Iop_Add64);
   16410          break;
   16411 
   16412       case 0x2E: {  /* Doubleword Subtract - DSUB; MIPS64 */
   16413          DIP("dsub r%u, r%u, r%u", rd, rs, rt);
   16414          IRTemp tmpRs64 = newTemp(Ity_I64);
   16415          IRTemp tmpRt64 = newTemp(Ity_I64);
   16416 
   16417          assign(tmpRs64, getIReg(rs));
   16418          assign(tmpRt64, getIReg(rt));
   16419          t0 = newTemp(Ity_I64);
   16420          t1 = newTemp(Ity_I64);
   16421          t2 = newTemp(Ity_I64);
   16422          t3 = newTemp(Ity_I64);
   16423          t4 = newTemp(Ity_I64);
   16424          t5 = newTemp(Ity_I64);
   16425          /* dst = src0 + (-1 * src1)
   16426             if(sign(src0 ) != sign((-1 * src1) ))
   16427             goto no overflow;
   16428             if(sign(dst) == sign(src0 ))
   16429             goto no overflow;
   16430             we have overflow! */
   16431 
   16432          assign(t5, binop(Iop_Mul64,
   16433                           mkexpr(tmpRt64),
   16434                           mkU64(0xffffffffffffffffULL)));
   16435          assign(t0, binop(Iop_Add64, mkexpr(tmpRs64), mkexpr(t5)));
   16436          assign(t1, binop(Iop_Xor64, mkexpr(tmpRs64), mkexpr(t5)));
   16437          assign(t2, unop(Iop_1Sto64,
   16438                          binop(Iop_CmpEQ64,
   16439                                binop(Iop_And64,
   16440                                      mkexpr(t1),
   16441                                      mkU64(0x8000000000000000ULL)),
   16442                                mkU64(0x8000000000000000ULL))));
   16443 
   16444          assign(t3, binop(Iop_Xor64, mkexpr(t0), mkexpr(tmpRs64)));
   16445          assign(t4, unop(Iop_1Sto64,
   16446                          binop(Iop_CmpNE64,
   16447                                binop(Iop_And64,
   16448                                      mkexpr(t3),
   16449                                      mkU64(0x8000000000000000ULL)),
   16450                                mkU64(0x8000000000000000ULL))));
   16451 
   16452          stmt(IRStmt_Exit(binop(Iop_CmpEQ64, binop(Iop_Or64, mkexpr(t2),
   16453                                 mkexpr(t4)), mkU64(0)), Ijk_SigFPE_IntOvf,
   16454                           IRConst_U64(guest_PC_curr_instr + 4),
   16455                           OFFB_PC));
   16456 
   16457          putIReg(rd, binop(Iop_Sub64, getIReg(rs), getIReg(rt)));
   16458          break;
   16459       }
   16460 
   16461       case 0x2F:  /* Doubleword Subtract Unsigned - DSUBU; MIPS64 */
   16462          DIP("dsub r%u, r%u,r%u", rd, rt, rt);
   16463          ALU_PATTERN(Iop_Sub64);
   16464          break;
   16465 
   16466       default:
   16467          goto decode_failure;
   16468       }
   16469       break;
   16470 
   16471    case 0x01:  /* Regimm */
   16472 
   16473       switch (rt) {
   16474       case 0x00:  /* BLTZ */
   16475          DIP("bltz r%u, %u", rs, imm);
   16476          if (mode64) {
   16477             if (!dis_instr_branch(cins, &dres, resteerOkFn,
   16478                         callback_opaque, &bstmt))
   16479                goto decode_failure;
   16480          } else
   16481             dis_branch(False, binop(Iop_CmpEQ32, binop(Iop_And32, getIReg(rs),
   16482                        mkU32(0x80000000)), mkU32(0x80000000)), imm, &bstmt);
   16483          break;
   16484 
   16485       case 0x01:  /* BGEZ */
   16486          DIP("bgez r%u, %u", rs, imm);
   16487          if (mode64) {
   16488             if (!dis_instr_branch(cins, &dres, resteerOkFn,
   16489                                   callback_opaque, &bstmt))
   16490                goto decode_failure;
   16491          } else
   16492             dis_branch(False, binop(Iop_CmpEQ32, binop(Iop_And32, getIReg(rs),
   16493                               mkU32(0x80000000)), mkU32(0x0)), imm, &bstmt);
   16494          break;
   16495 
   16496       case 0x02:  /* BLTZL */
   16497          DIP("bltzl r%u, %u", rs, imm);
   16498          lastn = dis_branch_likely(binop(mode64 ? Iop_CmpNE64 : Iop_CmpNE32,
   16499                      binop(mode64 ? Iop_And64 : Iop_And32, getIReg(rs),
   16500                      mode64 ? mkU64(0x8000000000000000ULL) : mkU32(0x80000000)),
   16501                      mode64 ? mkU64(0x8000000000000000ULL) : mkU32(0x80000000)),
   16502                      imm);
   16503          break;
   16504 
   16505       case 0x03:  /* BGEZL */
   16506          DIP("bgezl r%u, %u", rs, imm);
   16507          lastn = dis_branch_likely(binop(mode64 ? Iop_CmpNE64 : Iop_CmpNE32,
   16508                      binop(mode64 ? Iop_And64 : Iop_And32, getIReg(rs),
   16509                      mode64 ? mkU64(0x8000000000000000ULL) : mkU32(0x80000000)),
   16510                      mode64 ? mkU64(0x0) : mkU32(0x0)), imm);
   16511          break;
   16512 
   16513       case 0x10:  /* BLTZAL */
   16514          DIP("bltzal r%u, %u", rs, imm);
   16515          if (mode64) {
   16516             if (!dis_instr_branch(cins, &dres, resteerOkFn,
   16517                         callback_opaque, &bstmt))
   16518                goto decode_failure;
   16519          } else
   16520             dis_branch(True, binop(Iop_CmpEQ32, binop(Iop_And32, getIReg(rs),
   16521                        mkU32(0x80000000)), mkU32(0x80000000)), imm, &bstmt);
   16522          break;
   16523 
   16524       case 0x12:  /* BLTZALL */
   16525          DIP("bltzall r%u, %u", rs, imm);
   16526          putIReg(31, mode64 ? mkU64(guest_PC_curr_instr + 8) :
   16527                               mkU32(guest_PC_curr_instr + 8));
   16528          lastn = dis_branch_likely(binop(mode64 ? Iop_CmpNE64 : Iop_CmpNE32,
   16529                      binop(mode64 ? Iop_And64 : Iop_And32, getIReg(rs),
   16530                      mode64 ? mkU64(0x8000000000000000ULL) : mkU32(0x80000000)),
   16531                      mode64 ? mkU64(0x8000000000000000ULL) : mkU32(0x80000000)),
   16532                      imm);
   16533          break;
   16534 
   16535       case 0x11:  /* BGEZAL */
   16536          DIP("bgezal r%u, %u", rs, imm);
   16537          if (mode64) {
   16538             if (!dis_instr_branch(cins, &dres, resteerOkFn,
   16539                         callback_opaque, &bstmt))
   16540                goto decode_failure;
   16541          } else
   16542             dis_branch(True, binop(Iop_CmpEQ32, binop(Iop_And32, getIReg(rs),
   16543                        mkU32(0x80000000)), mkU32(0x0)), imm, &bstmt);
   16544          break;
   16545 
   16546       case 0x13:  /* BGEZALL */
   16547          DIP("bgezall r%u, %u", rs, imm);
   16548          if (mode64) {
   16549             putIReg(31, mkU64(guest_PC_curr_instr + 8));
   16550             lastn = dis_branch_likely(binop(Iop_CmpNE64,
   16551                                             binop(Iop_And64,
   16552                                                   getIReg(rs),
   16553                                                   mkU64(0x8000000000000000ULL)),
   16554                                             mkU64(0x0)),
   16555                                       imm);
   16556          } else {
   16557             putIReg(31, mkU32(guest_PC_curr_instr + 8));
   16558             lastn = dis_branch_likely(binop(Iop_CmpNE32, binop(Iop_And32,
   16559                                       getIReg(rs), mkU32(0x80000000)),
   16560                                       mkU32(0x0)), imm);
   16561          }
   16562          break;
   16563 
   16564       case 0x08:  /* TGEI */
   16565          DIP("tgei r%u, %u %u", rs, imm, trap_code);
   16566          if (mode64) {
   16567             stmt (IRStmt_Exit (unop (Iop_Not1,
   16568                                      binop (Iop_CmpLT64S,
   16569                                             getIReg (rs),
   16570                                             mkU64 (extend_s_16to64 (imm)))),
   16571                              Ijk_SigTRAP,
   16572                              IRConst_U64(guest_PC_curr_instr + 4),
   16573                              OFFB_PC));
   16574          } else {
   16575             stmt (IRStmt_Exit (unop (Iop_Not1,
   16576                                      binop (Iop_CmpLT32S,
   16577                                      getIReg (rs),
   16578                                      mkU32 (extend_s_16to32 (imm)))),
   16579                              Ijk_SigTRAP,
   16580                              IRConst_U32(guest_PC_curr_instr + 4),
   16581                              OFFB_PC));
   16582          }
   16583          break;
   16584 
   16585       case 0x09: {  /* TGEIU */
   16586          DIP("tgeiu r%u, %u %u", rs, imm, trap_code);
   16587          if (mode64) {
   16588             stmt (IRStmt_Exit (unop (Iop_Not1,
   16589                                      binop (Iop_CmpLT64U,
   16590                                             getIReg (rs),
   16591                                             mkU64 (extend_s_16to64 (imm)))),
   16592                              Ijk_SigTRAP,
   16593                              IRConst_U64(guest_PC_curr_instr + 4),
   16594                              OFFB_PC));
   16595          } else {
   16596             stmt (IRStmt_Exit (unop (Iop_Not1,
   16597                                      binop (Iop_CmpLT32U,
   16598                                             getIReg (rs),
   16599                                             mkU32 (extend_s_16to32 (imm)))),
   16600                                Ijk_SigTRAP,
   16601                                IRConst_U32(guest_PC_curr_instr + 4),
   16602                                OFFB_PC));
   16603          }
   16604          break;
   16605       }
   16606       case 0x0A: {  /* TLTI */
   16607          DIP("tlti r%u, %u %u", rs, imm, trap_code);
   16608          if (mode64) {
   16609             stmt (IRStmt_Exit (binop (Iop_CmpLT64S, getIReg (rs),
   16610                                       mkU64 (extend_s_16to64 (imm))),
   16611                              Ijk_SigTRAP,
   16612                              IRConst_U64(guest_PC_curr_instr + 4),
   16613                              OFFB_PC));
   16614          } else {
   16615             stmt (IRStmt_Exit (binop (Iop_CmpLT32S, getIReg (rs),
   16616                                       mkU32 (extend_s_16to32 (imm))),
   16617                                Ijk_SigTRAP,
   16618                                IRConst_U32(guest_PC_curr_instr + 4),
   16619                                OFFB_PC));
   16620          }
   16621          break;
   16622       }
   16623       case 0x0B: {  /* TLTIU */
   16624          DIP("tltiu r%u, %u %u", rs, imm, trap_code);
   16625          if (mode64) {
   16626             stmt (IRStmt_Exit (binop (Iop_CmpLT64U, getIReg (rs),
   16627                                       mkU64 (extend_s_16to64 (imm))),
   16628                              Ijk_SigTRAP,
   16629                              IRConst_U64(guest_PC_curr_instr + 4),
   16630                              OFFB_PC));
   16631          } else {
   16632             stmt (IRStmt_Exit (binop (Iop_CmpLT32U, getIReg (rs),
   16633                                       mkU32 (extend_s_16to32 (imm))),
   16634                                Ijk_SigTRAP,
   16635                                IRConst_U32(guest_PC_curr_instr + 4),
   16636                                OFFB_PC));
   16637          }
   16638          break;
   16639       }
   16640       case 0x0C: {  /* TEQI */
   16641           DIP("teqi r%u, %u %u", rs, imm, trap_code);
   16642          if (mode64) {
   16643             stmt (IRStmt_Exit (binop (Iop_CmpEQ64, getIReg (rs),
   16644                                       mkU64 (extend_s_16to64 (imm))),
   16645                                Ijk_SigTRAP,
   16646                                IRConst_U64(guest_PC_curr_instr + 4),
   16647                                OFFB_PC));
   16648          } else {
   16649             stmt (IRStmt_Exit (binop (Iop_CmpEQ32, getIReg (rs),
   16650                                       mkU32 (extend_s_16to32 (imm))),
   16651                                Ijk_SigTRAP,
   16652                                IRConst_U32(guest_PC_curr_instr + 4),
   16653                                OFFB_PC));
   16654          }
   16655          break;
   16656       }
   16657       case 0x0E: {  /* TNEI */
   16658          DIP("tnei r%u, %u %u", rs, imm, trap_code);
   16659          if (mode64) {
   16660             stmt (IRStmt_Exit (binop (Iop_CmpNE64, getIReg (rs),
   16661                                       mkU64 (extend_s_16to64 (imm))),
   16662                                Ijk_SigTRAP,
   16663                                IRConst_U64(guest_PC_curr_instr + 4),
   16664                                OFFB_PC));
   16665          } else {
   16666             stmt (IRStmt_Exit (binop (Iop_CmpNE32, getIReg (rs),
   16667                                       mkU32 (extend_s_16to32 (imm))),
   16668                                Ijk_SigTRAP,
   16669                                IRConst_U32(guest_PC_curr_instr + 4),
   16670                                OFFB_PC));
   16671          }
   16672          break;
   16673       }
   16674       case 0x1C: {  /* BPOSGE32 */
   16675          DIP("bposge32 %u", imm);
   16676          vassert(!mode64);
   16677          t0 = newTemp(Ity_I32);
   16678          /* Get pos field from DSPControl register. */
   16679          assign(t0, binop(Iop_And32, getDSPControl(), mkU32(0x3f)));
   16680          dis_branch(False, unop(Iop_Not1, binop(Iop_CmpLT32U, mkexpr(t0),
   16681                                 mkU32(32))), imm, &bstmt);
   16682       }
   16683       case 0x1F:
   16684          /* SYNCI */
   16685          /* Just ignore it */
   16686          break;
   16687 
   16688       default:
   16689          goto decode_failure;
   16690       }
   16691       break;
   16692 
   16693    case 0x04:
   16694       DIP("beq r%u, r%u, %u", rs, rt, imm);
   16695       if (mode64)
   16696          dis_branch(False, binop(Iop_CmpEQ64, getIReg(rs), getIReg(rt)),
   16697                                  imm, &bstmt);
   16698       else
   16699          dis_branch(False, binop(Iop_CmpEQ32, getIReg(rs), getIReg(rt)),
   16700                                  imm, &bstmt);
   16701       break;
   16702 
   16703    case 0x14:
   16704       DIP("beql r%u, r%u, %u", rs, rt, imm);
   16705       lastn = dis_branch_likely(binop(mode64 ? Iop_CmpNE64 : Iop_CmpNE32,
   16706                                 getIReg(rs), getIReg(rt)), imm);
   16707       break;
   16708 
   16709    case 0x05:
   16710       DIP("bne r%u, r%u, %u", rs, rt, imm);
   16711       if (mode64)
   16712          dis_branch(False, binop(Iop_CmpNE64, getIReg(rs), getIReg(rt)),
   16713                                  imm, &bstmt);
   16714       else
   16715          dis_branch(False, binop(Iop_CmpNE32, getIReg(rs), getIReg(rt)),
   16716                                  imm, &bstmt);
   16717       break;
   16718 
   16719    case 0x15:
   16720       DIP("bnel r%u, r%u, %u", rs, rt, imm);
   16721       lastn = dis_branch_likely(binop(mode64 ? Iop_CmpEQ64 : Iop_CmpEQ32,
   16722                                       getIReg(rs), getIReg(rt)), imm);
   16723       break;
   16724 
   16725    case 0x07:  /* BGTZ */
   16726       DIP("bgtz r%u, %u", rs, imm);
   16727       if (mode64)
   16728          dis_branch(False, unop(Iop_Not1, binop(Iop_CmpLE64S, getIReg(rs),
   16729                                 mkU64(0x00))), imm, &bstmt);
   16730       else
   16731          dis_branch(False, unop(Iop_Not1, binop(Iop_CmpLE32S, getIReg(rs),
   16732                                 mkU32(0x00))), imm, &bstmt);
   16733       break;
   16734 
   16735    case 0x17:  /* BGTZL */
   16736       DIP("bgtzl r%u, %u", rs, imm);
   16737       if (mode64)
   16738          lastn = dis_branch_likely(binop(Iop_CmpLE64S, getIReg(rs),
   16739                                          mkU64(0x00)), imm);
   16740       else
   16741          lastn = dis_branch_likely(binop(Iop_CmpLE32S, getIReg(rs),
   16742                                          mkU32(0x00)), imm);
   16743       break;
   16744 
   16745    case 0x06:  /* BLEZ */
   16746       DIP("blez r%u, %u", rs, imm);
   16747       if (mode64)
   16748          dis_branch(False, binop(Iop_CmpLE64S, getIReg(rs), mkU64(0x0)),
   16749                                 imm, &bstmt);
   16750       else
   16751          dis_branch(False,binop(Iop_CmpLE32S, getIReg(rs), mkU32(0x0)), imm,
   16752                                 &bstmt);
   16753       break;
   16754 
   16755    case 0x16:  /* BLEZL */
   16756       DIP("blezl r%u, %u", rs, imm);
   16757       lastn = dis_branch_likely(unop(Iop_Not1, (binop(mode64 ? Iop_CmpLE64S :
   16758                                      Iop_CmpLE32S, getIReg(rs), mode64 ?
   16759                                      mkU64(0x0) : mkU32(0x0)))), imm);
   16760       break;
   16761 
   16762    case 0x08: {  /* ADDI */
   16763       DIP("addi r%u, r%u, %u", rt, rs, imm);
   16764       IRTemp tmpRs32 = newTemp(Ity_I32);
   16765       assign(tmpRs32, mkNarrowTo32(ty, getIReg(rs)));
   16766 
   16767       t0 = newTemp(Ity_I32);
   16768       t1 = newTemp(Ity_I32);
   16769       t2 = newTemp(Ity_I32);
   16770       t3 = newTemp(Ity_I32);
   16771       t4 = newTemp(Ity_I32);
   16772       /* dst = src0 + sign(imm)
   16773          if(sign(src0 ) != sign(imm ))
   16774          goto no overflow;
   16775          if(sign(dst) == sign(src0 ))
   16776          goto no overflow;
   16777          we have overflow! */
   16778 
   16779       assign(t0, binop(Iop_Add32, mkexpr(tmpRs32),
   16780                        mkU32(extend_s_16to32(imm))));
   16781       assign(t1, binop(Iop_Xor32, mkexpr(tmpRs32),
   16782                        mkU32(extend_s_16to32(imm))));
   16783       assign(t2, unop(Iop_1Sto32, binop(Iop_CmpEQ32, binop(Iop_And32,
   16784                       mkexpr(t1), mkU32(0x80000000)), mkU32(0x80000000))));
   16785 
   16786       assign(t3, binop(Iop_Xor32, mkexpr(t0), mkexpr(tmpRs32)));
   16787       assign(t4, unop(Iop_1Sto32, binop(Iop_CmpNE32, binop(Iop_And32,
   16788                       mkexpr(t3), mkU32(0x80000000)), mkU32(0x80000000))));
   16789 
   16790       stmt(IRStmt_Exit(binop(Iop_CmpEQ32, binop(Iop_Or32, mkexpr(t2),
   16791                              mkexpr(t4)), mkU32(0)), Ijk_SigFPE_IntOvf,
   16792                        mode64 ? IRConst_U64(guest_PC_curr_instr + 4) :
   16793                                 IRConst_U32(guest_PC_curr_instr + 4),
   16794                        OFFB_PC));
   16795 
   16796       putIReg(rt,  mkWidenFrom32(ty, mkexpr(t0), True));
   16797       break;
   16798    }
   16799    case 0x09:  /* ADDIU */
   16800       DIP("addiu r%u, r%u, %u", rt, rs, imm);
   16801       if (mode64) {
   16802          putIReg(rt, mkWidenFrom32(ty, binop(Iop_Add32,
   16803                      mkNarrowTo32(ty, getIReg(rs)),mkU32(extend_s_16to32(imm))),
   16804                      True));
   16805       } else
   16806          putIReg(rt, binop(Iop_Add32, getIReg(rs),mkU32(extend_s_16to32(imm))));
   16807       break;
   16808 
   16809    case 0x0C:  /* ANDI */
   16810       DIP("andi r%u, r%u, %u", rt, rs, imm);
   16811       if (mode64) {
   16812          ALUI_PATTERN64(Iop_And64);
   16813       } else {
   16814          ALUI_PATTERN(Iop_And32);
   16815       }
   16816       break;
   16817 
   16818    case 0x0E:  /* XORI */
   16819       DIP("xori r%u, r%u, %u", rt, rs, imm);
   16820       if (mode64) {
   16821          ALUI_PATTERN64(Iop_Xor64);
   16822       } else {
   16823          ALUI_PATTERN(Iop_Xor32);
   16824       }
   16825       break;
   16826 
   16827    case 0x0D:  /* ORI */
   16828       DIP("ori r%u, r%u, %u", rt, rs, imm);
   16829       if (mode64) {
   16830          ALUI_PATTERN64(Iop_Or64);
   16831       } else {
   16832          ALUI_PATTERN(Iop_Or32);
   16833       }
   16834       break;
   16835 
   16836    case 0x0A:  /* SLTI */
   16837       DIP("slti r%u, r%u, %u", rt, rs, imm);
   16838       if (mode64)
   16839          putIReg(rt, unop(Iop_1Uto64, binop(Iop_CmpLT64S, getIReg(rs),
   16840                                             mkU64(extend_s_16to64(imm)))));
   16841       else
   16842          putIReg(rt, unop(Iop_1Uto32, binop(Iop_CmpLT32S, getIReg(rs),
   16843                                             mkU32(extend_s_16to32(imm)))));
   16844       break;
   16845 
   16846    case 0x0B:  /* SLTIU */
   16847       DIP("sltiu r%u, r%u, %u", rt, rs, imm);
   16848       if (mode64)
   16849          putIReg(rt, unop(Iop_1Uto64, binop(Iop_CmpLT64U, getIReg(rs),
   16850                                             mkU64(extend_s_16to64(imm)))));
   16851       else
   16852          putIReg(rt, unop(Iop_1Uto32, binop(Iop_CmpLT32U, getIReg(rs),
   16853                                             mkU32(extend_s_16to32(imm)))));
   16854       break;
   16855 
   16856    case 0x18: {  /* Doubleword Add Immidiate - DADD; MIPS64 */
   16857       DIP("daddi r%u, r%u, %u", rt, rs, imm);
   16858       IRTemp tmpRs64 = newTemp(Ity_I64);
   16859       assign(tmpRs64, getIReg(rs));
   16860 
   16861       t0 = newTemp(Ity_I64);
   16862       t1 = newTemp(Ity_I64);
   16863       t2 = newTemp(Ity_I64);
   16864       t3 = newTemp(Ity_I64);
   16865       t4 = newTemp(Ity_I64);
   16866       /* dst = src0 + sign(imm)
   16867          if(sign(src0 ) != sign(imm ))
   16868          goto no overflow;
   16869          if(sign(dst) == sign(src0 ))
   16870          goto no overflow;
   16871          we have overflow! */
   16872 
   16873       assign(t0, binop(Iop_Add64, mkexpr(tmpRs64),
   16874                        mkU64(extend_s_16to64(imm))));
   16875       assign(t1, binop(Iop_Xor64, mkexpr(tmpRs64),
   16876                        mkU64(extend_s_16to64(imm))));
   16877       assign(t2, unop(Iop_1Sto64, binop(Iop_CmpEQ64, binop(Iop_And64,
   16878                       mkexpr(t1), mkU64(0x8000000000000000ULL)),
   16879                                         mkU64(0x8000000000000000ULL))));
   16880 
   16881       assign(t3, binop(Iop_Xor64, mkexpr(t0), mkexpr(tmpRs64)));
   16882       assign(t4, unop(Iop_1Sto64, binop(Iop_CmpNE64, binop(Iop_And64,
   16883                       mkexpr(t3), mkU64(0x8000000000000000ULL)),
   16884                                         mkU64(0x8000000000000000ULL))));
   16885 
   16886       stmt(IRStmt_Exit(binop(Iop_CmpEQ64, binop(Iop_Or64, mkexpr(t2),
   16887                              mkexpr(t4)), mkU64(0)), Ijk_SigFPE_IntOvf,
   16888                        IRConst_U64(guest_PC_curr_instr + 4),
   16889                        OFFB_PC));
   16890 
   16891       putIReg(rt,  mkexpr(t0));
   16892       break;
   16893    }
   16894 
   16895    case 0x19:  /* Doubleword Add Immidiate Unsigned - DADDIU; MIPS64 */
   16896       DIP("daddiu r%u, r%u, %u", rt, rs, imm);
   16897       putIReg(rt, binop(Iop_Add64, getIReg(rs), mkU64(extend_s_16to64(imm))));
   16898       break;
   16899 
   16900    case 0x1A: {
   16901       /* Load Doubleword Left - LDL; MIPS64 */
   16902       vassert(mode64);
   16903       DIP("ldl r%u, %u(r%u)", rt, imm, rs);
   16904       /* t1 = addr */
   16905 #if defined (_MIPSEL)
   16906       t1 = newTemp(Ity_I64);
   16907       assign(t1, binop(Iop_Add64, getIReg(rs), mkU64(extend_s_16to64(imm))));
   16908 #elif defined (_MIPSEB)
   16909       t1 = newTemp(Ity_I64);
   16910       assign(t1, binop(Iop_Xor64, mkU64(0x7), binop(Iop_Add64, getIReg(rs),
   16911                                   mkU64(extend_s_16to64(imm)))));
   16912 #endif
   16913       /* t2 = word addr */
   16914       /* t4 = addr mod 8 */
   16915       LWX_SWX_PATTERN64_1;
   16916 
   16917       /* t3 = word content - shifted */
   16918       t3 = newTemp(Ity_I64);
   16919       assign(t3, binop(Iop_Shl64, load(Ity_I64, mkexpr(t2)),
   16920                  narrowTo(Ity_I8, binop(Iop_Shl64, binop(Iop_Sub64, mkU64(0x07),
   16921                  mkexpr(t4)), mkU8(3)))));
   16922 
   16923       /* rt content  - adjusted */
   16924       t5 = newTemp(Ity_I64);
   16925       t6 = newTemp(Ity_I64);
   16926       t7 = newTemp(Ity_I64);
   16927 
   16928       assign(t5, binop(Iop_Mul64, mkexpr(t4), mkU64(0x8)));
   16929 
   16930       assign(t6, binop(Iop_Shr64, mkU64(0x00FFFFFFFFFFFFFFULL),
   16931                        narrowTo(Ity_I8, mkexpr(t5))));
   16932 
   16933       assign(t7, binop(Iop_And64, getIReg(rt), mkexpr(t6)));
   16934 
   16935       putIReg(rt, binop(Iop_Or64, mkexpr(t7), mkexpr(t3)));
   16936       break;
   16937    }
   16938 
   16939    case 0x1B: {
   16940       /* Load Doubleword Right - LDR; MIPS64 */
   16941       vassert(mode64);
   16942       DIP("ldr r%u,%u(r%u)", rt, imm, rs);
   16943       /* t1 = addr */
   16944 #if defined (_MIPSEL)
   16945       t1 = newTemp(Ity_I64);
   16946       assign(t1, binop(Iop_Add64, getIReg(rs), mkU64(extend_s_16to64(imm))));
   16947 #elif defined (_MIPSEB)
   16948       t1 = newTemp(Ity_I64);
   16949       assign(t1, binop(Iop_Xor64, mkU64(0x7), binop(Iop_Add64, getIReg(rs),
   16950                                   mkU64(extend_s_16to64(imm)))));
   16951 #endif
   16952       /* t2 = word addr */
   16953       /* t4 = addr mod 8 */
   16954       LWX_SWX_PATTERN64_1;
   16955 
   16956       /* t3 = word content - shifted */
   16957       t3 = newTemp(Ity_I64);
   16958       assign(t3, binop(Iop_Shr64, load(Ity_I64, mkexpr(t2)),
   16959                  narrowTo(Ity_I8, binop(Iop_Shl64, mkexpr(t4), mkU8(3)))));
   16960 
   16961       /* rt content  - adjusted */
   16962       t5 = newTemp(Ity_I64);
   16963       assign(t5, binop(Iop_And64, getIReg(rt), unop(Iop_Not64,
   16964                  binop(Iop_Shr64, mkU64(0xFFFFFFFFFFFFFFFFULL),
   16965                  narrowTo(Ity_I8, binop(Iop_Shl64, mkexpr(t4), mkU8(0x3)))))));
   16966 
   16967       putIReg(rt, binop(Iop_Or64, mkexpr(t5), mkexpr(t3)));
   16968       break;
   16969    }
   16970 
   16971    case 0x27:  /* Load Word unsigned - LWU; MIPS64 */
   16972       DIP("lwu r%u,%u(r%u)", rt, imm, rs);
   16973       LOAD_STORE_PATTERN;
   16974 
   16975       putIReg(rt, mkWidenFrom32(ty, load(Ity_I32, mkexpr(t1)), False));
   16976       break;
   16977 
   16978    case 0x30:  /* LL */
   16979       DIP("ll r%u, %u(r%u)", rt, imm, rs);
   16980       LOAD_STORE_PATTERN;
   16981       if (abiinfo->guest__use_fallback_LLSC) {
   16982          t2 = newTemp(ty);
   16983          assign(t2, mkWidenFrom32(ty, load(Ity_I32, mkexpr(t1)), True));
   16984          putLLaddr(mkexpr(t1));
   16985          putLLdata(mkexpr(t2));
   16986          putIReg(rt, mkexpr(t2));
   16987       } else {
   16988          t2 = newTemp(Ity_I32);
   16989          stmt(IRStmt_LLSC(MIPS_IEND, t2, mkexpr(t1), NULL));
   16990          putIReg(rt, mkWidenFrom32(ty, mkexpr(t2), True));
   16991       }
   16992       break;
   16993 
   16994    case 0x34:  /* Load Linked Doubleword - LLD; MIPS64 */
   16995       DIP("lld r%u, %u(r%u)", rt, imm, rs);
   16996       if (mode64) {
   16997          LOAD_STORE_PATTERN;
   16998          t2 = newTemp(Ity_I64);
   16999          if (abiinfo->guest__use_fallback_LLSC) {
   17000             assign(t2, load(Ity_I64, mkexpr(t1)));
   17001             putLLaddr(mkexpr(t1));
   17002             putLLdata(mkexpr(t2));
   17003          } else {
   17004             stmt(IRStmt_LLSC(MIPS_IEND, t2, mkexpr(t1), NULL));
   17005          }
   17006          putIReg(rt, mkexpr(t2));
   17007       } else {
   17008          ILLEGAL_INSTRUCTON;
   17009       }
   17010       break;
   17011 
   17012    case 0x38:  /* SC */
   17013       DIP("sc r%u, %u(r%u)", rt, imm, rs);
   17014       t2 = newTemp(Ity_I1);
   17015       LOAD_STORE_PATTERN;
   17016       if (abiinfo->guest__use_fallback_LLSC) {
   17017          t3 = newTemp(Ity_I32);
   17018          assign(t2, binop(mode64 ? Iop_CmpNE64 : Iop_CmpNE32,
   17019                           mkexpr(t1), getLLaddr()));
   17020          assign(t3, mkNarrowTo32(ty, getIReg(rt)));
   17021          putLLaddr(LLADDR_INVALID);
   17022          putIReg(rt, getIReg(0));
   17023 
   17024          mips_next_insn_if(mkexpr(t2));
   17025 
   17026          t4 = newTemp(Ity_I32);
   17027          t5 = newTemp(Ity_I32);
   17028 
   17029          assign(t5, mkNarrowTo32(ty, getLLdata()));
   17030 
   17031          stmt(IRStmt_CAS(mkIRCAS(IRTemp_INVALID, t4, /* old_mem */
   17032               MIPS_IEND, mkexpr(t1),                 /* addr */
   17033               NULL, mkexpr(t5),                      /* expected value */
   17034               NULL, mkexpr(t3)                       /* new value */)));
   17035 
   17036          putIReg(rt, unop(mode64 ? Iop_1Uto64 : Iop_1Uto32,
   17037                           binop(Iop_CmpEQ32, mkexpr(t4), mkexpr(t5))));
   17038       } else {
   17039          stmt(IRStmt_LLSC(MIPS_IEND, t2, mkexpr(t1),
   17040                           mkNarrowTo32(ty, getIReg(rt))));
   17041          putIReg(rt, unop(mode64 ? Iop_1Uto64 : Iop_1Uto32, mkexpr(t2)));
   17042       }
   17043       break;
   17044 
   17045    case 0x3C:  /* Store Conditional Doubleword - SCD; MIPS64 */
   17046       DIP("scd r%u, %u(r%u)", rt, imm, rs);
   17047       if (mode64) {
   17048          t2 = newTemp(Ity_I1);
   17049          LOAD_STORE_PATTERN;
   17050          if (abiinfo->guest__use_fallback_LLSC) {
   17051             t3 = newTemp(Ity_I64);
   17052             assign(t2, binop(Iop_CmpNE64, mkexpr(t1), getLLaddr()));
   17053             assign(t3, getIReg(rt));
   17054             putLLaddr(LLADDR_INVALID);
   17055             putIReg(rt, getIReg(0));
   17056 
   17057             mips_next_insn_if(mkexpr(t2));
   17058 
   17059             t4 = newTemp(Ity_I64);
   17060             t5 = newTemp(Ity_I64);
   17061 
   17062             assign(t5, getLLdata());
   17063 
   17064             stmt(IRStmt_CAS(mkIRCAS(IRTemp_INVALID, t4, /* old_mem */
   17065                  MIPS_IEND, mkexpr(t1),                 /* addr */
   17066                  NULL, mkexpr(t5),                      /* expected value */
   17067                  NULL, mkexpr(t3)                       /* new value */)));
   17068 
   17069             putIReg(rt, unop(Iop_1Uto64,
   17070                              binop(Iop_CmpEQ64, mkexpr(t4), mkexpr(t5))));
   17071          } else {
   17072             stmt(IRStmt_LLSC(MIPS_IEND, t2, mkexpr(t1), getIReg(rt)));
   17073             putIReg(rt, unop(Iop_1Uto64, mkexpr(t2)));
   17074          }
   17075       } else {
   17076          ILLEGAL_INSTRUCTON;
   17077       }
   17078       break;
   17079 
   17080    case 0x37:  /* Load Doubleword - LD; MIPS64 */
   17081       DIP("ld r%u, %u(r%u)", rt, imm, rs);
   17082       LOAD_STORE_PATTERN;
   17083       putIReg(rt, load(Ity_I64, mkexpr(t1)));
   17084       break;
   17085 
   17086    case 0x3F:  /* Store Doubleword - SD; MIPS64 */
   17087       DIP("sd r%u, %u(r%u)", rt, imm, rs);
   17088       LOAD_STORE_PATTERN;
   17089       store(mkexpr(t1), getIReg(rt));
   17090       break;
   17091 
   17092    case 0x32:  /* Branch on Bit Clear - BBIT0; Cavium OCTEON */
   17093       /* Cavium Specific instructions. */
   17094       if (VEX_MIPS_COMP_ID(archinfo->hwcaps) == VEX_PRID_COMP_CAVIUM) {
   17095          DIP("bbit0 r%u, 0x%x, %x", rs, rt, imm);
   17096          t0 = newTemp(Ity_I32);
   17097          t1 = newTemp(Ity_I32);
   17098          assign(t0, mkU32(0x1));
   17099          assign(t1, binop(Iop_Shl32, mkexpr(t0), mkU8(rt)));
   17100          dis_branch(False, binop(Iop_CmpEQ32,
   17101                                  binop(Iop_And32,
   17102                                        mkexpr(t1),
   17103                                        mkNarrowTo32(ty, getIReg(rs))),
   17104                                  mkU32(0x0)),
   17105                     imm, &bstmt);
   17106          break;
   17107       } else {
   17108          goto decode_failure;
   17109       }
   17110 
   17111    case 0x36:  /* Branch on Bit Clear Plus 32 - BBIT032; Cavium OCTEON */
   17112       /* Cavium Specific instructions. */
   17113       if (VEX_MIPS_COMP_ID(archinfo->hwcaps) == VEX_PRID_COMP_CAVIUM) {
   17114          DIP("bbit032 r%u, 0x%x, %x", rs, rt, imm);
   17115          t0 = newTemp(Ity_I64);
   17116          t1 = newTemp(Ity_I8);  /* Shift. */
   17117          t2 = newTemp(Ity_I64);
   17118          assign(t0, mkU64(0x1));
   17119          assign(t1, binop(Iop_Add8, mkU8(rt), mkU8(32)));
   17120          assign(t2, binop(Iop_Shl64, mkexpr(t0), mkexpr(t1)));
   17121          dis_branch(False, binop(Iop_CmpEQ64,
   17122                                  binop(Iop_And64,
   17123                                        mkexpr(t2),
   17124                                        getIReg(rs)),
   17125                                  mkU64(0x0)),
   17126                     imm, &bstmt);
   17127          break;
   17128       } else {
   17129          goto decode_failure;
   17130       }
   17131 
   17132    case 0x3A:  /* Branch on Bit Set - BBIT1; Cavium OCTEON */
   17133       /* Cavium Specific instructions. */
   17134       if (VEX_MIPS_COMP_ID(archinfo->hwcaps) == VEX_PRID_COMP_CAVIUM) {
   17135          DIP("bbit1 r%u, 0x%x, %x", rs, rt, imm);
   17136          t0 = newTemp(Ity_I32);
   17137          t1 = newTemp(Ity_I32);
   17138          assign(t0, mkU32(0x1));
   17139          assign(t1, binop(Iop_Shl32, mkexpr(t0), mkU8(rt)));
   17140          dis_branch(False, binop(Iop_CmpNE32,
   17141                                  binop(Iop_And32,
   17142                                        mkexpr(t1),
   17143                                        mkNarrowTo32(ty, getIReg(rs))),
   17144                                  mkU32(0x0)),
   17145                     imm, &bstmt);
   17146          break;
   17147       } else {
   17148          goto decode_failure;
   17149       }
   17150 
   17151    case 0x3E:  /* Branch on Bit Set Plus 32 - BBIT132; Cavium OCTEON */
   17152       /* Cavium Specific instructions. */
   17153       if (VEX_MIPS_COMP_ID(archinfo->hwcaps) == VEX_PRID_COMP_CAVIUM) {
   17154          DIP("bbit132 r%u, 0x%x, %x", rs, rt, imm);
   17155          t0 = newTemp(Ity_I64);
   17156          t1 = newTemp(Ity_I8);  /* Shift. */
   17157          t2 = newTemp(Ity_I64);
   17158          assign(t0, mkU64(0x1));
   17159          assign(t1, binop(Iop_Add8, mkU8(rt), mkU8(32)));
   17160          assign(t2, binop(Iop_Shl64, mkexpr(t0), mkexpr(t1)));
   17161          dis_branch(False, binop(Iop_CmpNE64,
   17162                                  binop(Iop_And64,
   17163                                        mkexpr(t2),
   17164                                        getIReg(rs)),
   17165                                  mkU64(0x0)),
   17166                     imm, &bstmt);
   17167          break;
   17168       } else {
   17169          goto decode_failure;
   17170       }
   17171 
   17172    default:
   17173       goto decode_failure;
   17174 
   17175    decode_failure_dsp:
   17176       vex_printf("Error occured while trying to decode MIPS32 DSP "
   17177                  "instruction.\nYour platform probably doesn't support "
   17178                  "MIPS32 DSP ASE.\n");
   17179    decode_failure:
   17180       /* All decode failures end up here. */
   17181       if (sigill_diag)
   17182          vex_printf("vex mips->IR: unhandled instruction bytes: "
   17183                     "0x%x 0x%x 0x%x 0x%x\n",
   17184                     (UInt) getIByte(delta_start + 0),
   17185                     (UInt) getIByte(delta_start + 1),
   17186                     (UInt) getIByte(delta_start + 2),
   17187                     (UInt) getIByte(delta_start + 3));
   17188 
   17189       /* Tell the dispatcher that this insn cannot be decoded, and so has
   17190          not been executed, and (is currently) the next to be executed.
   17191          EIP should be up-to-date since it made so at the start bnezof each
   17192          insn, but nevertheless be paranoid and update it again right
   17193          now. */
   17194       if (mode64) {
   17195          stmt(IRStmt_Put(offsetof(VexGuestMIPS64State, guest_PC),
   17196               mkU64(guest_PC_curr_instr)));
   17197          jmp_lit64(&dres, Ijk_NoDecode, guest_PC_curr_instr);
   17198       } else {
   17199          stmt(IRStmt_Put(offsetof(VexGuestMIPS32State, guest_PC),
   17200               mkU32(guest_PC_curr_instr)));
   17201          jmp_lit32(&dres, Ijk_NoDecode, guest_PC_curr_instr);
   17202       }
   17203       dres.whatNext = Dis_StopHere;
   17204       dres.len = 0;
   17205       return dres;
   17206    }  /* switch (opc) for the main (primary) opcode switch. */
   17207 
   17208    /* All MIPS insn have 4 bytes */
   17209 
   17210    if (delay_slot_branch) {
   17211       delay_slot_branch = False;
   17212       stmt(bstmt);
   17213       bstmt = NULL;
   17214       if (mode64)
   17215          putPC(mkU64(guest_PC_curr_instr + 4));
   17216       else
   17217          putPC(mkU32(guest_PC_curr_instr + 4));
   17218       dres.jk_StopHere = is_Branch_or_Jump_and_Link(guest_code + delta - 4) ?
   17219                          Ijk_Call : Ijk_Boring;
   17220    }
   17221 
   17222    if (likely_delay_slot) {
   17223       dres.jk_StopHere = Ijk_Boring;
   17224       dres.whatNext = Dis_StopHere;
   17225       putPC(lastn);
   17226       lastn = NULL;
   17227    }
   17228    if (delay_slot_jump) {
   17229       putPC(lastn);
   17230       lastn = NULL;
   17231       dres.jk_StopHere = is_Branch_or_Jump_and_Link(guest_code + delta - 4) ?
   17232                          Ijk_Call : Ijk_Boring;
   17233    }
   17234 
   17235  decode_success:
   17236    /* All decode successes end up here. */
   17237    switch (dres.whatNext) {
   17238       case Dis_Continue:
   17239          if (mode64)
   17240             putPC(mkU64(guest_PC_curr_instr + 4));
   17241          else
   17242             putPC(mkU32(guest_PC_curr_instr + 4));
   17243          break;
   17244       case Dis_ResteerU:
   17245       case Dis_ResteerC:
   17246          if (mode64)
   17247             putPC(mkU64(dres.continueAt));
   17248          else
   17249             putPC(mkU32(dres.continueAt));
   17250          break;
   17251       case Dis_StopHere:
   17252          break;
   17253       default:
   17254          vassert(0);
   17255          break;
   17256    }
   17257 
   17258    /* On MIPS we need to check if the last instruction in block is branch or
   17259       jump. */
   17260    if (((vex_control.guest_max_insns - 1) == (delta + 4) / 4)
   17261        &&  (dres.whatNext != Dis_StopHere))
   17262       if (branch_or_jump(guest_code + delta + 4)) {
   17263          dres.whatNext = Dis_StopHere;
   17264          dres.jk_StopHere = Ijk_Boring;
   17265          if (mode64)
   17266             putPC(mkU64(guest_PC_curr_instr + 4));
   17267          else
   17268             putPC(mkU32(guest_PC_curr_instr + 4));
   17269       }
   17270    dres.len = 4;
   17271 
   17272    DIP("\n");
   17273 
   17274    return dres;
   17275 
   17276 }
   17277 
   17278 /*------------------------------------------------------------*/
   17279 /*--- Top-level fn                                         ---*/
   17280 /*------------------------------------------------------------*/
   17281 
   17282 /* Disassemble a single instruction into IR.  The instruction
   17283    is located in host memory at &guest_code[delta]. */
   17284 DisResult disInstr_MIPS( IRSB*        irsb_IN,
   17285                          Bool         (*resteerOkFn) ( void *, Addr ),
   17286                          Bool         resteerCisOk,
   17287                          void*        callback_opaque,
   17288                          const UChar* guest_code_IN,
   17289                          Long         delta,
   17290                          Addr         guest_IP,
   17291                          VexArch      guest_arch,
   17292                          const VexArchInfo* archinfo,
   17293                          const VexAbiInfo*  abiinfo,
   17294                          VexEndness   host_endness_IN,
   17295                          Bool         sigill_diag_IN )
   17296 {
   17297    DisResult dres;
   17298    /* Set globals (see top of this file) */
   17299    vassert(guest_arch == VexArchMIPS32 || guest_arch == VexArchMIPS64);
   17300 
   17301    mode64 = guest_arch != VexArchMIPS32;
   17302    fp_mode64 = abiinfo->guest_mips_fp_mode64;
   17303 
   17304    vassert(VEX_MIPS_HOST_FP_MODE(archinfo->hwcaps) >= fp_mode64);
   17305 
   17306    guest_code = guest_code_IN;
   17307    irsb = irsb_IN;
   17308    host_endness = host_endness_IN;
   17309 #if defined(VGP_mips32_linux)
   17310    guest_PC_curr_instr = (Addr32)guest_IP;
   17311 #elif defined(VGP_mips64_linux)
   17312    guest_PC_curr_instr = (Addr64)guest_IP;
   17313 #endif
   17314 
   17315    dres = disInstr_MIPS_WRK(resteerOkFn, resteerCisOk, callback_opaque,
   17316                             delta, archinfo, abiinfo, sigill_diag_IN);
   17317 
   17318    return dres;
   17319 }
   17320 
   17321 /*--------------------------------------------------------------------*/
   17322 /*--- end                                        guest_mips_toIR.c ---*/
   17323 /*--------------------------------------------------------------------*/
   17324