Home | History | Annotate | Download | only in priv
      1 
      2 /*--------------------------------------------------------------------*/
      3 /*--- begin                                      guest_mips_toIR.c ---*/
      4 /*--------------------------------------------------------------------*/
      5 
      6 /*
      7    This file is part of Valgrind, a dynamic binary instrumentation
      8    framework.
      9 
     10    Copyright (C) 2010-2015 RT-RK
     11       mips-valgrind (at) rt-rk.com
     12 
     13    This program is free software; you can redistribute it and/or
     14    modify it under the terms of the GNU General Public License as
     15    published by the Free Software Foundation; either version 2 of the
     16    License, or (at your option) any later version.
     17 
     18    This program is distributed in the hope that it will be useful, but
     19    WITHOUT ANY WARRANTY; without even the implied warranty of
     20    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     21    General Public License for more details.
     22 
     23    You should have received a copy of the GNU General Public License
     24    along with this program; if not, write to the Free Software
     25    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
     26    02111-1307, USA.
     27 
     28    The GNU General Public License is contained in the file COPYING.
     29 */
     30 
     31 /* Translates MIPS code to IR. */
     32 
     33 #include "libvex_basictypes.h"
     34 #include "libvex_ir.h"
     35 #include "libvex.h"
     36 #include "libvex_guest_mips32.h"
     37 #include "libvex_guest_mips64.h"
     38 
     39 #include "main_util.h"
     40 #include "main_globals.h"
     41 #include "guest_generic_bb_to_IR.h"
     42 #include "guest_mips_defs.h"
     43 
     44 /*------------------------------------------------------------*/
     45 /*---                      Globals                         ---*/
     46 /*------------------------------------------------------------*/
     47 
     48 /* These are set at the start of the translation of a instruction, so
     49    that we don't have to pass them around endlessly. CONST means does
     50    not change during translation of the instruction. */
     51 
     52 /* CONST: what is the host's endianness?  This has to do with float vs
     53    double register accesses on VFP, but it's complex and not properly
     54    thought out. */
     55 static VexEndness host_endness;
     56 
     57 /* Pointer to the guest code area. */
     58 static const UChar *guest_code;
     59 
     60 /* CONST: The guest address for the instruction currently being
     61    translated. */
     62 #if defined(VGP_mips32_linux)
     63 static Addr32 guest_PC_curr_instr;
     64 #else
     65 static Addr64 guest_PC_curr_instr;
     66 #endif
     67 
     68 /* MOD: The IRSB* into which we're generating code. */
     69 static IRSB *irsb;
     70 
     71 /* Is our guest binary 32 or 64bit? Set at each call to
     72    disInstr_MIPS below. */
     73 static Bool mode64 = False;
     74 
     75 /* CPU has FPU and 32 dbl. prec. FP registers. */
     76 static Bool fp_mode64 = False;
     77 
     78 /* Define 1.0 in single and double precision. */
     79 #define ONE_SINGLE 0x3F800000
     80 #define ONE_DOUBLE 0x3FF0000000000000ULL
     81 
     82 /*------------------------------------------------------------*/
     83 /*---                  Debugging output                    ---*/
     84 /*------------------------------------------------------------*/
     85 
     86 #define DIP(format, args...)           \
     87    if (vex_traceflags & VEX_TRACE_FE)  \
     88       vex_printf(format, ## args)
     89 
     90 /*------------------------------------------------------------*/
     91 /*--- Helper bits and pieces for deconstructing the        ---*/
     92 /*--- mips insn stream.                                    ---*/
     93 /*------------------------------------------------------------*/
     94 
     95 /* ---------------- Integer registers ---------------- */
     96 
     97 static UInt integerGuestRegOffset(UInt iregNo)
     98 {
     99    /* Do we care about endianness here?  We do if sub-parts of integer
    100       registers are accessed, but I don't think that ever happens on
    101       MIPS. */
    102    UInt ret;
    103    if (!mode64)
    104       switch (iregNo) {
    105          case 0:
    106             ret = offsetof(VexGuestMIPS32State, guest_r0); break;
    107          case 1:
    108             ret = offsetof(VexGuestMIPS32State, guest_r1); break;
    109          case 2:
    110             ret = offsetof(VexGuestMIPS32State, guest_r2); break;
    111          case 3:
    112             ret = offsetof(VexGuestMIPS32State, guest_r3); break;
    113          case 4:
    114             ret = offsetof(VexGuestMIPS32State, guest_r4); break;
    115          case 5:
    116             ret = offsetof(VexGuestMIPS32State, guest_r5); break;
    117          case 6:
    118             ret = offsetof(VexGuestMIPS32State, guest_r6); break;
    119          case 7:
    120             ret = offsetof(VexGuestMIPS32State, guest_r7); break;
    121          case 8:
    122             ret = offsetof(VexGuestMIPS32State, guest_r8); break;
    123          case 9:
    124             ret = offsetof(VexGuestMIPS32State, guest_r9); break;
    125          case 10:
    126             ret = offsetof(VexGuestMIPS32State, guest_r10); break;
    127          case 11:
    128             ret = offsetof(VexGuestMIPS32State, guest_r11); break;
    129          case 12:
    130             ret = offsetof(VexGuestMIPS32State, guest_r12); break;
    131          case 13:
    132             ret = offsetof(VexGuestMIPS32State, guest_r13); break;
    133          case 14:
    134             ret = offsetof(VexGuestMIPS32State, guest_r14); break;
    135          case 15:
    136             ret = offsetof(VexGuestMIPS32State, guest_r15); break;
    137          case 16:
    138             ret = offsetof(VexGuestMIPS32State, guest_r16); break;
    139          case 17:
    140             ret = offsetof(VexGuestMIPS32State, guest_r17); break;
    141          case 18:
    142             ret = offsetof(VexGuestMIPS32State, guest_r18); break;
    143          case 19:
    144             ret = offsetof(VexGuestMIPS32State, guest_r19); break;
    145          case 20:
    146             ret = offsetof(VexGuestMIPS32State, guest_r20); break;
    147          case 21:
    148             ret = offsetof(VexGuestMIPS32State, guest_r21); break;
    149          case 22:
    150             ret = offsetof(VexGuestMIPS32State, guest_r22); break;
    151          case 23:
    152             ret = offsetof(VexGuestMIPS32State, guest_r23); break;
    153          case 24:
    154             ret = offsetof(VexGuestMIPS32State, guest_r24); break;
    155          case 25:
    156             ret = offsetof(VexGuestMIPS32State, guest_r25); break;
    157          case 26:
    158             ret = offsetof(VexGuestMIPS32State, guest_r26); break;
    159          case 27:
    160             ret = offsetof(VexGuestMIPS32State, guest_r27); break;
    161          case 28:
    162             ret = offsetof(VexGuestMIPS32State, guest_r28); break;
    163          case 29:
    164             ret = offsetof(VexGuestMIPS32State, guest_r29); break;
    165          case 30:
    166             ret = offsetof(VexGuestMIPS32State, guest_r30); break;
    167          case 31:
    168             ret = offsetof(VexGuestMIPS32State, guest_r31); break;
    169          default:
    170             vassert(0);
    171             break;
    172       }
    173    else
    174       switch (iregNo) {
    175          case 0:
    176             ret = offsetof(VexGuestMIPS64State, guest_r0); break;
    177          case 1:
    178             ret = offsetof(VexGuestMIPS64State, guest_r1); break;
    179          case 2:
    180             ret = offsetof(VexGuestMIPS64State, guest_r2); break;
    181          case 3:
    182             ret = offsetof(VexGuestMIPS64State, guest_r3); break;
    183          case 4:
    184             ret = offsetof(VexGuestMIPS64State, guest_r4); break;
    185          case 5:
    186             ret = offsetof(VexGuestMIPS64State, guest_r5); break;
    187          case 6:
    188             ret = offsetof(VexGuestMIPS64State, guest_r6); break;
    189          case 7:
    190             ret = offsetof(VexGuestMIPS64State, guest_r7); break;
    191          case 8:
    192             ret = offsetof(VexGuestMIPS64State, guest_r8); break;
    193          case 9:
    194             ret = offsetof(VexGuestMIPS64State, guest_r9); break;
    195          case 10:
    196             ret = offsetof(VexGuestMIPS64State, guest_r10); break;
    197          case 11:
    198             ret = offsetof(VexGuestMIPS64State, guest_r11); break;
    199          case 12:
    200             ret = offsetof(VexGuestMIPS64State, guest_r12); break;
    201          case 13:
    202             ret = offsetof(VexGuestMIPS64State, guest_r13); break;
    203          case 14:
    204             ret = offsetof(VexGuestMIPS64State, guest_r14); break;
    205          case 15:
    206             ret = offsetof(VexGuestMIPS64State, guest_r15); break;
    207          case 16:
    208             ret = offsetof(VexGuestMIPS64State, guest_r16); break;
    209          case 17:
    210             ret = offsetof(VexGuestMIPS64State, guest_r17); break;
    211          case 18:
    212             ret = offsetof(VexGuestMIPS64State, guest_r18); break;
    213          case 19:
    214             ret = offsetof(VexGuestMIPS64State, guest_r19); break;
    215          case 20:
    216             ret = offsetof(VexGuestMIPS64State, guest_r20); break;
    217          case 21:
    218             ret = offsetof(VexGuestMIPS64State, guest_r21); break;
    219          case 22:
    220             ret = offsetof(VexGuestMIPS64State, guest_r22); break;
    221          case 23:
    222             ret = offsetof(VexGuestMIPS64State, guest_r23); break;
    223          case 24:
    224             ret = offsetof(VexGuestMIPS64State, guest_r24); break;
    225          case 25:
    226             ret = offsetof(VexGuestMIPS64State, guest_r25); break;
    227          case 26:
    228             ret = offsetof(VexGuestMIPS64State, guest_r26); break;
    229          case 27:
    230             ret = offsetof(VexGuestMIPS64State, guest_r27); break;
    231          case 28:
    232             ret = offsetof(VexGuestMIPS64State, guest_r28); break;
    233          case 29:
    234             ret = offsetof(VexGuestMIPS64State, guest_r29); break;
    235          case 30:
    236             ret = offsetof(VexGuestMIPS64State, guest_r30); break;
    237          case 31:
    238             ret = offsetof(VexGuestMIPS64State, guest_r31); break;
    239          default:
    240             vassert(0);
    241             break;
    242       }
    243    return ret;
    244 }
    245 
    246 #if defined(VGP_mips32_linux)
    247 #define OFFB_PC     offsetof(VexGuestMIPS32State, guest_PC)
    248 #else
    249 #define OFFB_PC     offsetof(VexGuestMIPS64State, guest_PC)
    250 #endif
    251 
    252 /* ---------------- Floating point registers ---------------- */
    253 
    254 static UInt floatGuestRegOffset(UInt fregNo)
    255 {
    256    vassert(fregNo < 32);
    257    UInt ret;
    258    if (!mode64)
    259       switch (fregNo) {
    260          case 0:
    261             ret = offsetof(VexGuestMIPS32State, guest_f0); break;
    262          case 1:
    263             ret = offsetof(VexGuestMIPS32State, guest_f1); break;
    264          case 2:
    265             ret = offsetof(VexGuestMIPS32State, guest_f2); break;
    266          case 3:
    267             ret = offsetof(VexGuestMIPS32State, guest_f3); break;
    268          case 4:
    269             ret = offsetof(VexGuestMIPS32State, guest_f4); break;
    270          case 5:
    271             ret = offsetof(VexGuestMIPS32State, guest_f5); break;
    272          case 6:
    273             ret = offsetof(VexGuestMIPS32State, guest_f6); break;
    274          case 7:
    275             ret = offsetof(VexGuestMIPS32State, guest_f7); break;
    276          case 8:
    277             ret = offsetof(VexGuestMIPS32State, guest_f8); break;
    278          case 9:
    279             ret = offsetof(VexGuestMIPS32State, guest_f9); break;
    280          case 10:
    281             ret = offsetof(VexGuestMIPS32State, guest_f10); break;
    282          case 11:
    283             ret = offsetof(VexGuestMIPS32State, guest_f11); break;
    284          case 12:
    285             ret = offsetof(VexGuestMIPS32State, guest_f12); break;
    286          case 13:
    287             ret = offsetof(VexGuestMIPS32State, guest_f13); break;
    288          case 14:
    289             ret = offsetof(VexGuestMIPS32State, guest_f14); break;
    290          case 15:
    291             ret = offsetof(VexGuestMIPS32State, guest_f15); break;
    292          case 16:
    293             ret = offsetof(VexGuestMIPS32State, guest_f16); break;
    294          case 17:
    295             ret = offsetof(VexGuestMIPS32State, guest_f17); break;
    296          case 18:
    297             ret = offsetof(VexGuestMIPS32State, guest_f18); break;
    298          case 19:
    299             ret = offsetof(VexGuestMIPS32State, guest_f19); break;
    300          case 20:
    301             ret = offsetof(VexGuestMIPS32State, guest_f20); break;
    302          case 21:
    303             ret = offsetof(VexGuestMIPS32State, guest_f21); break;
    304          case 22:
    305             ret = offsetof(VexGuestMIPS32State, guest_f22); break;
    306          case 23:
    307             ret = offsetof(VexGuestMIPS32State, guest_f23); break;
    308          case 24:
    309             ret = offsetof(VexGuestMIPS32State, guest_f24); break;
    310          case 25:
    311             ret = offsetof(VexGuestMIPS32State, guest_f25); break;
    312          case 26:
    313             ret = offsetof(VexGuestMIPS32State, guest_f26); break;
    314          case 27:
    315             ret = offsetof(VexGuestMIPS32State, guest_f27); break;
    316          case 28:
    317             ret = offsetof(VexGuestMIPS32State, guest_f28); break;
    318          case 29:
    319             ret = offsetof(VexGuestMIPS32State, guest_f29); break;
    320          case 30:
    321             ret = offsetof(VexGuestMIPS32State, guest_f30); break;
    322          case 31:
    323             ret = offsetof(VexGuestMIPS32State, guest_f31); break;
    324          default:
    325             vassert(0);
    326             break;
    327       }
    328    else
    329       switch (fregNo) {
    330          case 0:
    331             ret = offsetof(VexGuestMIPS64State, guest_f0); break;
    332          case 1:
    333             ret = offsetof(VexGuestMIPS64State, guest_f1); break;
    334          case 2:
    335             ret = offsetof(VexGuestMIPS64State, guest_f2); break;
    336          case 3:
    337             ret = offsetof(VexGuestMIPS64State, guest_f3); break;
    338          case 4:
    339             ret = offsetof(VexGuestMIPS64State, guest_f4); break;
    340          case 5:
    341             ret = offsetof(VexGuestMIPS64State, guest_f5); break;
    342          case 6:
    343             ret = offsetof(VexGuestMIPS64State, guest_f6); break;
    344          case 7:
    345             ret = offsetof(VexGuestMIPS64State, guest_f7); break;
    346          case 8:
    347             ret = offsetof(VexGuestMIPS64State, guest_f8); break;
    348          case 9:
    349             ret = offsetof(VexGuestMIPS64State, guest_f9); break;
    350          case 10:
    351             ret = offsetof(VexGuestMIPS64State, guest_f10); break;
    352          case 11:
    353             ret = offsetof(VexGuestMIPS64State, guest_f11); break;
    354          case 12:
    355             ret = offsetof(VexGuestMIPS64State, guest_f12); break;
    356          case 13:
    357             ret = offsetof(VexGuestMIPS64State, guest_f13); break;
    358          case 14:
    359             ret = offsetof(VexGuestMIPS64State, guest_f14); break;
    360          case 15:
    361             ret = offsetof(VexGuestMIPS64State, guest_f15); break;
    362          case 16:
    363             ret = offsetof(VexGuestMIPS64State, guest_f16); break;
    364          case 17:
    365             ret = offsetof(VexGuestMIPS64State, guest_f17); break;
    366          case 18:
    367             ret = offsetof(VexGuestMIPS64State, guest_f18); break;
    368          case 19:
    369             ret = offsetof(VexGuestMIPS64State, guest_f19); break;
    370          case 20:
    371             ret = offsetof(VexGuestMIPS64State, guest_f20); break;
    372          case 21:
    373             ret = offsetof(VexGuestMIPS64State, guest_f21); break;
    374          case 22:
    375             ret = offsetof(VexGuestMIPS64State, guest_f22); break;
    376          case 23:
    377             ret = offsetof(VexGuestMIPS64State, guest_f23); break;
    378          case 24:
    379             ret = offsetof(VexGuestMIPS64State, guest_f24); break;
    380          case 25:
    381             ret = offsetof(VexGuestMIPS64State, guest_f25); break;
    382          case 26:
    383             ret = offsetof(VexGuestMIPS64State, guest_f26); break;
    384          case 27:
    385             ret = offsetof(VexGuestMIPS64State, guest_f27); break;
    386          case 28:
    387             ret = offsetof(VexGuestMIPS64State, guest_f28); break;
    388          case 29:
    389             ret = offsetof(VexGuestMIPS64State, guest_f29); break;
    390          case 30:
    391             ret = offsetof(VexGuestMIPS64State, guest_f30); break;
    392          case 31:
    393             ret = offsetof(VexGuestMIPS64State, guest_f31); break;
    394          default:
    395             vassert(0);
    396             break;
    397       }
    398    return ret;
    399 }
    400 
    401 /* ---------------- MIPS32 DSP ASE(r2) accumulators ---------------- */
    402 
    403 static UInt accumulatorGuestRegOffset(UInt acNo)
    404 {
    405    vassert(!mode64);
    406    vassert(acNo <= 3);
    407    UInt ret;
    408    switch (acNo) {
    409       case 0:
    410          ret = offsetof(VexGuestMIPS32State, guest_ac0); break;
    411       case 1:
    412          ret = offsetof(VexGuestMIPS32State, guest_ac1); break;
    413       case 2:
    414          ret = offsetof(VexGuestMIPS32State, guest_ac2); break;
    415       case 3:
    416          ret = offsetof(VexGuestMIPS32State, guest_ac3); break;
    417       default:
    418          vassert(0);
    419     break;
    420    }
    421    return ret;
    422 }
    423 
    424 /* Do a endian load of a 32-bit word, regardless of the endianness of the
    425    underlying host. */
    426 static inline UInt getUInt(const UChar * p)
    427 {
    428    UInt w = 0;
    429 #if defined (_MIPSEL)
    430    w = (w << 8) | p[3];
    431    w = (w << 8) | p[2];
    432    w = (w << 8) | p[1];
    433    w = (w << 8) | p[0];
    434 #elif defined (_MIPSEB)
    435    w = (w << 8) | p[0];
    436    w = (w << 8) | p[1];
    437    w = (w << 8) | p[2];
    438    w = (w << 8) | p[3];
    439 #endif
    440    return w;
    441 }
    442 
    443 #define BITS2(_b1,_b0) \
    444    (((_b1) << 1) | (_b0))
    445 
    446 #define BITS3(_b2,_b1,_b0)                      \
    447   (((_b2) << 2) | ((_b1) << 1) | (_b0))
    448 
    449 #define BITS4(_b3,_b2,_b1,_b0) \
    450    (((_b3) << 3) | ((_b2) << 2) | ((_b1) << 1) | (_b0))
    451 
    452 #define BITS5(_b4,_b3,_b2,_b1,_b0)  \
    453    (((_b4) << 4) | BITS4((_b3),(_b2),(_b1),(_b0)))
    454 
    455 #define BITS6(_b5,_b4,_b3,_b2,_b1,_b0)  \
    456    ((BITS2((_b5),(_b4)) << 4) \
    457     | BITS4((_b3),(_b2),(_b1),(_b0)))
    458 
    459 #define BITS8(_b7,_b6,_b5,_b4,_b3,_b2,_b1,_b0)  \
    460    ((BITS4((_b7),(_b6),(_b5),(_b4)) << 4) \
    461     | BITS4((_b3),(_b2),(_b1),(_b0)))
    462 
    463 #define LOAD_STORE_PATTERN \
    464    t1 = newTemp(mode64 ? Ity_I64 : Ity_I32); \
    465       if(!mode64) \
    466          assign(t1, binop(Iop_Add32, getIReg(rs), \
    467                                      mkU32(extend_s_16to32(imm)))); \
    468       else \
    469          assign(t1, binop(Iop_Add64, getIReg(rs), \
    470                                      mkU64(extend_s_16to64(imm)))); \
    471 
    472 #define LOADX_STORE_PATTERN \
    473    t1 = newTemp(mode64 ? Ity_I64 : Ity_I32); \
    474       if(!mode64) \
    475          assign(t1, binop(Iop_Add32, getIReg(regRs), getIReg(regRt))); \
    476       else \
    477          assign(t1, binop(Iop_Add64, getIReg(regRs), getIReg(regRt)));
    478 
    479 #define LWX_SWX_PATTERN64 \
    480    t2 = newTemp(Ity_I64); \
    481    assign(t2, binop(Iop_And64, mkexpr(t1), mkU64(0xFFFFFFFFFFFFFFFCULL))); \
    482    t4 = newTemp(Ity_I32); \
    483    assign(t4, mkNarrowTo32( ty, binop(Iop_And64, \
    484                                       mkexpr(t1), mkU64(0x3))));
    485 
    486 #define LWX_SWX_PATTERN64_1 \
    487    t2 = newTemp(Ity_I64); \
    488    assign(t2, binop(Iop_And64, mkexpr(t1), mkU64(0xFFFFFFFFFFFFFFF8ULL))); \
    489    t4 = newTemp(Ity_I64); \
    490    assign(t4, binop(Iop_And64, mkexpr(t1), mkU64(0x7)));
    491 
    492 #define LWX_SWX_PATTERN \
    493    t2 = newTemp(Ity_I32); \
    494    assign(t2, binop(Iop_And32, mkexpr(t1), mkU32(0xFFFFFFFC))); \
    495    t4 = newTemp(Ity_I32); \
    496    assign(t4, binop(Iop_And32, mkexpr(t1), mkU32(0x00000003)))
    497 
    498 #define SXXV_PATTERN(op) \
    499    putIReg(rd, binop(op, \
    500          getIReg(rt), \
    501             unop(Iop_32to8, \
    502                binop(Iop_And32, \
    503                   getIReg(rs), \
    504                   mkU32(0x0000001F) \
    505                ) \
    506             ) \
    507          ) \
    508       )
    509 
    510 #define SXXV_PATTERN64(op) \
    511    putIReg(rd, mkWidenFrom32(ty, binop(op, \
    512            mkNarrowTo32(ty, getIReg(rt)), \
    513              unop(Iop_32to8, \
    514                 binop(Iop_And32, \
    515                    mkNarrowTo32(ty, getIReg(rs)), \
    516                    mkU32(0x0000001F) \
    517                 ) \
    518              ) \
    519           ), True \
    520        ))
    521 
    522 #define SXX_PATTERN(op) \
    523    putIReg(rd, binop(op, getIReg(rt), mkU8(sa)));
    524 
    525 #define ALU_PATTERN(op) \
    526    putIReg(rd, binop(op, getIReg(rs), getIReg(rt)));
    527 
    528 #define ALUI_PATTERN(op) \
    529    putIReg(rt, binop(op, getIReg(rs), mkU32(imm)));
    530 
    531 #define ALUI_PATTERN64(op) \
    532    putIReg(rt, binop(op, getIReg(rs), mkU64(imm)));
    533 
    534 #define ALU_PATTERN64(op) \
    535    putIReg(rd, mkWidenFrom32(ty, binop(op, \
    536                              mkNarrowTo32(ty, getIReg(rs)), \
    537                              mkNarrowTo32(ty, getIReg(rt))), True));
    538 
    539 #define FP_CONDITIONAL_CODE \
    540    t3 = newTemp(Ity_I32);   \
    541    assign(t3, binop(Iop_And32, \
    542                  IRExpr_ITE( binop(Iop_CmpEQ32, mkU32(cc), mkU32(0)), \
    543                              binop(Iop_Shr32, getFCSR(), mkU8(23)), \
    544                              binop(Iop_Shr32, getFCSR(), mkU8(24+cc))), \
    545                  mkU32(0x1)));
    546 
    547 #define ILLEGAL_INSTRUCTON \
    548    putPC(mkU32(guest_PC_curr_instr + 4)); \
    549    dres.jk_StopHere = Ijk_SigILL; \
    550    dres.whatNext    = Dis_StopHere;
    551 
    552 /*------------------------------------------------------------*/
    553 /*---                  Field helpers                       ---*/
    554 /*------------------------------------------------------------*/
    555 
    556 static UInt get_opcode(UInt mipsins)
    557 {
    558    return (0xFC000000 & mipsins) >> 26;
    559 }
    560 
    561 static UInt get_rs(UInt mipsins)
    562 {
    563    return (0x03E00000 & mipsins) >> 21;
    564 }
    565 
    566 static UInt get_rt(UInt mipsins)
    567 {
    568    return (0x001F0000 & mipsins) >> 16;
    569 }
    570 
    571 static UInt get_imm(UInt mipsins)
    572 {
    573    return (0x0000FFFF & mipsins);
    574 }
    575 
    576 static UInt get_instr_index(UInt mipsins)
    577 {
    578    return (0x03FFFFFF & mipsins);
    579 }
    580 
    581 static UInt get_rd(UInt mipsins)
    582 {
    583    return (0x0000F800 & mipsins) >> 11;
    584 }
    585 
    586 static UInt get_sa(UInt mipsins)
    587 {
    588    return (0x000007C0 & mipsins) >> 6;
    589 }
    590 
    591 static UInt get_function(UInt mipsins)
    592 {
    593    return (0x0000003F & mipsins);
    594 }
    595 
    596 static UInt get_ft(UInt mipsins)
    597 {
    598    return (0x001F0000 & mipsins) >> 16;
    599 }
    600 
    601 static UInt get_fs(UInt mipsins)
    602 {
    603    return (0x0000F800 & mipsins) >> 11;
    604 }
    605 
    606 static UInt get_fd(UInt mipsins)
    607 {
    608    return (0x000007C0 & mipsins) >> 6;
    609 }
    610 
    611 static UInt get_mov_cc(UInt mipsins)
    612 {
    613    return (0x001C0000 & mipsins) >> 18;
    614 }
    615 
    616 static UInt get_bc1_cc(UInt mipsins)
    617 {
    618    return (0x001C0000 & mipsins) >> 18;
    619 }
    620 
    621 static UInt get_fpc_cc(UInt mipsins)
    622 {
    623    return (0x00000700 & mipsins) >> 8;
    624 }
    625 
    626 static UInt get_tf(UInt mipsins)
    627 {
    628    return (0x00010000 & mipsins) >> 16;
    629 }
    630 
    631 static UInt get_nd(UInt mipsins)
    632 {
    633    return (0x00020000 & mipsins) >> 17;
    634 }
    635 
    636 static UInt get_fmt(UInt mipsins)
    637 {
    638    return (0x03E00000 & mipsins) >> 21;
    639 }
    640 
    641 static UInt get_FC(UInt mipsins)
    642 {
    643    return (0x000000F0 & mipsins) >> 4;
    644 }
    645 
    646 static UInt get_cond(UInt mipsins)
    647 {
    648    return (0x0000000F & mipsins);
    649 }
    650 
    651 /* for break & syscall */
    652 static UInt get_code(UInt mipsins)
    653 {
    654    return (0xFFC0 & mipsins) >> 6;
    655 }
    656 
    657 static UInt get_lsb(UInt mipsins)
    658 {
    659    return (0x7C0 & mipsins) >> 6;
    660 }
    661 
    662 static UInt get_msb(UInt mipsins)
    663 {
    664    return (0x0000F800 & mipsins) >> 11;
    665 }
    666 
    667 static UInt get_rot(UInt mipsins)
    668 {
    669    return (0x00200000 & mipsins) >> 21;
    670 }
    671 
    672 static UInt get_rotv(UInt mipsins)
    673 {
    674    return (0x00000040 & mipsins) >> 6;
    675 }
    676 
    677 static UInt get_sel(UInt mipsins)
    678 {
    679    return (0x00000007 & mipsins);
    680 }
    681 
    682 /* Get acc number for all MIPS32 DSP ASE(r2) instructions that use them,
    683    except for MFHI and MFLO. */
    684 static UInt get_acNo(UInt mipsins)
    685 {
    686    return (0x00001800 & mipsins) >> 11;
    687 }
    688 
    689 /* Get accumulator number for MIPS32 DSP ASEr2 MFHI and MFLO instructions. */
    690 static UInt get_acNo_mfhilo(UInt mipsins)
    691 {
    692    return (0x00600000 & mipsins) >> 21;
    693 }
    694 
    695 /* Get mask field (helper function for wrdsp instruction). */
    696 static UInt get_wrdspMask(UInt mipsins)
    697 {
    698    return (0x001ff800 & mipsins) >> 11;
    699 }
    700 
    701 /* Get mask field (helper function for rddsp instruction). */
    702 static UInt get_rddspMask(UInt mipsins)
    703 {
    704    return (0x03ff0000 & mipsins) >> 16;
    705 }
    706 
    707 /* Get shift field (helper function for DSP ASE instructions). */
    708 static UInt get_shift(UInt mipsins)
    709 {
    710    return (0x03f00000 & mipsins) >> 20;
    711 }
    712 
    713 /* Get immediate field for DSP ASE instructions. */
    714 static UInt get_dspImm(UInt mipsins)
    715 {
    716    return (0x03ff0000 & mipsins) >> 16;
    717 }
    718 
    719 static Bool branch_or_jump(const UChar * addr)
    720 {
    721    UInt fmt;
    722    UInt cins = getUInt(addr);
    723 
    724    UInt opcode = get_opcode(cins);
    725    UInt rt = get_rt(cins);
    726    UInt function = get_function(cins);
    727 
    728    /* bgtz, blez, bne, beq, jal */
    729    if (opcode == 0x07 || opcode == 0x06 || opcode == 0x05 || opcode == 0x04
    730        || opcode == 0x03 || opcode == 0x02) {
    731       return True;
    732    }
    733 
    734    /* bgez */
    735    if (opcode == 0x01 && rt == 0x01) {
    736       return True;
    737    }
    738 
    739    /* bgezal */
    740    if (opcode == 0x01 && rt == 0x11) {
    741       return True;
    742    }
    743 
    744    /* bltzal */
    745    if (opcode == 0x01 && rt == 0x10) {
    746       return True;
    747    }
    748 
    749    /* bltz */
    750    if (opcode == 0x01 && rt == 0x00) {
    751       return True;
    752    }
    753 
    754    /* jalr */
    755    if (opcode == 0x00 && function == 0x09) {
    756       return True;
    757    }
    758 
    759    /* jr */
    760    if (opcode == 0x00 && function == 0x08) {
    761       return True;
    762    }
    763 
    764    if (opcode == 0x11) {
    765       /*bc1f & bc1t */
    766       fmt = get_fmt(cins);
    767       if (fmt == 0x08) {
    768          return True;
    769       }
    770    }
    771 
    772    /* bposge32 */
    773    if (opcode == 0x01 && rt == 0x1c) {
    774       return True;
    775    }
    776 
    777    /* Cavium Specific instructions. */
    778    if (opcode == 0x32 || opcode == 0x3A || opcode == 0x36 || opcode == 0x3E) {
    779        /* BBIT0, BBIT1, BBIT032, BBIT132 */
    780       return True;
    781    }
    782 
    783    return False;
    784 }
    785 
    786 static Bool is_Branch_or_Jump_and_Link(const UChar * addr)
    787 {
    788    UInt cins = getUInt(addr);
    789 
    790    UInt opcode = get_opcode(cins);
    791    UInt rt = get_rt(cins);
    792    UInt function = get_function(cins);
    793 
    794    /* jal */
    795    if (opcode == 0x02) {
    796       return True;
    797    }
    798 
    799    /* bgezal */
    800    if (opcode == 0x01 && rt == 0x11) {
    801       return True;
    802    }
    803 
    804    /* bltzal */
    805    if (opcode == 0x01 && rt == 0x10) {
    806       return True;
    807    }
    808 
    809    /* jalr */
    810    if (opcode == 0x00 && function == 0x09) {
    811       return True;
    812    }
    813 
    814    return False;
    815 }
    816 
    817 static Bool branch_or_link_likely(const UChar * addr)
    818 {
    819    UInt cins = getUInt(addr);
    820    UInt opcode = get_opcode(cins);
    821    UInt rt = get_rt(cins);
    822 
    823    /* bgtzl, blezl, bnel, beql */
    824    if (opcode == 0x17 || opcode == 0x16 || opcode == 0x15 || opcode == 0x14)
    825       return True;
    826 
    827    /* bgezl */
    828    if (opcode == 0x01 && rt == 0x03)
    829       return True;
    830 
    831    /* bgezall */
    832    if (opcode == 0x01 && rt == 0x13)
    833       return True;
    834 
    835    /* bltzall */
    836    if (opcode == 0x01 && rt == 0x12)
    837       return True;
    838 
    839    /* bltzl */
    840    if (opcode == 0x01 && rt == 0x02)
    841       return True;
    842 
    843    return False;
    844 }
    845 
    846 /*------------------------------------------------------------*/
    847 /*--- Helper bits and pieces for creating IR fragments.    ---*/
    848 /*------------------------------------------------------------*/
    849 
    850 static IRExpr *mkU8(UInt i)
    851 {
    852    vassert(i < 256);
    853    return IRExpr_Const(IRConst_U8((UChar) i));
    854 }
    855 
    856 /* Create an expression node for a 16-bit integer constant. */
    857 static IRExpr *mkU16(UInt i)
    858 {
    859    return IRExpr_Const(IRConst_U16(i));
    860 }
    861 
    862 /* Create an expression node for a 32-bit integer constant. */
    863 static IRExpr *mkU32(UInt i)
    864 {
    865    return IRExpr_Const(IRConst_U32(i));
    866 }
    867 
    868 /* Create an expression node for a 64-bit integer constant. */
    869 static IRExpr *mkU64(ULong i)
    870 {
    871    return IRExpr_Const(IRConst_U64(i));
    872 }
    873 
    874 static IRExpr *mkexpr(IRTemp tmp)
    875 {
    876    return IRExpr_RdTmp(tmp);
    877 }
    878 
    879 static IRExpr *unop(IROp op, IRExpr * a)
    880 {
    881    return IRExpr_Unop(op, a);
    882 }
    883 
    884 static IRExpr *binop(IROp op, IRExpr * a1, IRExpr * a2)
    885 {
    886    return IRExpr_Binop(op, a1, a2);
    887 }
    888 
    889 static IRExpr *triop(IROp op, IRExpr * a1, IRExpr * a2, IRExpr * a3)
    890 {
    891    return IRExpr_Triop(op, a1, a2, a3);
    892 }
    893 
    894 static IRExpr *qop ( IROp op, IRExpr * a1, IRExpr * a2, IRExpr * a3,
    895                      IRExpr * a4 )
    896 {
    897    return IRExpr_Qop(op, a1, a2, a3, a4);
    898 }
    899 
    900 static IRExpr *load(IRType ty, IRExpr * addr)
    901 {
    902    IRExpr *load1 = NULL;
    903 #if defined (_MIPSEL)
    904    load1 = IRExpr_Load(Iend_LE, ty, addr);
    905 #elif defined (_MIPSEB)
    906    load1 = IRExpr_Load(Iend_BE, ty, addr);
    907 #endif
    908    return load1;
    909 }
    910 
    911 /* Add a statement to the list held by "irsb". */
    912 static void stmt(IRStmt * st)
    913 {
    914    addStmtToIRSB(irsb, st);
    915 }
    916 
    917 static void assign(IRTemp dst, IRExpr * e)
    918 {
    919    stmt(IRStmt_WrTmp(dst, e));
    920 }
    921 
    922 static void store(IRExpr * addr, IRExpr * data)
    923 {
    924 #if defined (_MIPSEL)
    925    stmt(IRStmt_Store(Iend_LE, addr, data));
    926 #elif defined (_MIPSEB)
    927    stmt(IRStmt_Store(Iend_BE, addr, data));
    928 #endif
    929 }
    930 
    931 /* Generate a new temporary of the given type. */
    932 static IRTemp newTemp(IRType ty)
    933 {
    934    vassert(isPlausibleIRType(ty));
    935    return newIRTemp(irsb->tyenv, ty);
    936 }
    937 
    938 /* Generate an expression for SRC rotated right by ROT. */
    939 static IRExpr *genROR32(IRExpr * src, Int rot)
    940 {
    941    vassert(rot >= 0 && rot < 32);
    942    if (rot == 0)
    943       return src;
    944    return binop(Iop_Or32, binop(Iop_Shl32, src, mkU8(32 - rot)),
    945                           binop(Iop_Shr32, src, mkU8(rot)));
    946 }
    947 
    948 static IRExpr *genRORV32(IRExpr * src, IRExpr * rs)
    949 {
    950    IRTemp t0 = newTemp(Ity_I8);
    951    IRTemp t1 = newTemp(Ity_I8);
    952 
    953    assign(t0, unop(Iop_32to8, binop(Iop_And32, rs, mkU32(0x0000001F))));
    954    assign(t1, binop(Iop_Sub8, mkU8(32), mkexpr(t0)));
    955    return binop(Iop_Or32, binop(Iop_Shl32, src, mkexpr(t1)),
    956                           binop(Iop_Shr32, src, mkexpr(t0)));
    957 }
    958 
    959 static UShort extend_s_10to16(UInt x)
    960 {
    961    return (UShort) ((((Int) x) << 22) >> 22);
    962 }
    963 
    964 static ULong extend_s_10to32(UInt x)
    965 {
    966    return (ULong)((((Long) x) << 22) >> 22);
    967 }
    968 
    969 static ULong extend_s_10to64(UInt x)
    970 {
    971    return (ULong)((((Long) x) << 54) >> 54);
    972 }
    973 
    974 static UInt extend_s_16to32(UInt x)
    975 {
    976    return (UInt) ((((Int) x) << 16) >> 16);
    977 }
    978 
    979 static UInt extend_s_18to32(UInt x)
    980 {
    981    return (UInt) ((((Int) x) << 14) >> 14);
    982 }
    983 
    984 static ULong extend_s_16to64 ( UInt x )
    985 {
    986    return (ULong) ((((Long) x) << 48) >> 48);
    987 }
    988 
    989 static ULong extend_s_18to64 ( UInt x )
    990 {
    991    return (ULong) ((((Long) x) << 46) >> 46);
    992 }
    993 
    994 static ULong extend_s_32to64 ( UInt x )
    995 {
    996    return (ULong) ((((Long) x) << 32) >> 32);
    997 }
    998 
    999 static void jmp_lit32 ( /*MOD*/ DisResult* dres, IRJumpKind kind, Addr32 d32 )
   1000 {
   1001    vassert(dres->whatNext    == Dis_Continue);
   1002    vassert(dres->len         == 0);
   1003    vassert(dres->continueAt  == 0);
   1004    vassert(dres->jk_StopHere == Ijk_INVALID);
   1005    dres->whatNext    = Dis_StopHere;
   1006    dres->jk_StopHere = kind;
   1007    stmt( IRStmt_Put( OFFB_PC, mkU32(d32) ) );
   1008 }
   1009 
   1010 static void jmp_lit64 ( /*MOD*/ DisResult* dres, IRJumpKind kind, Addr64 d64 )
   1011 {
   1012    vassert(dres->whatNext    == Dis_Continue);
   1013    vassert(dres->len         == 0);
   1014    vassert(dres->continueAt  == 0);
   1015    vassert(dres->jk_StopHere == Ijk_INVALID);
   1016    dres->whatNext    = Dis_StopHere;
   1017    dres->jk_StopHere = kind;
   1018    stmt(IRStmt_Put(OFFB_PC, mkU64(d64)));
   1019 }
   1020 
   1021 /* Get value from accumulator (helper function for MIPS32 DSP ASE instructions).
   1022    This function should be called before any other operation if widening
   1023    multiplications are used. */
   1024 static IRExpr *getAcc(UInt acNo)
   1025 {
   1026    vassert(!mode64);
   1027    vassert(acNo <= 3);
   1028    return IRExpr_Get(accumulatorGuestRegOffset(acNo), Ity_I64);
   1029 }
   1030 
   1031 /* Get value from DSPControl register (helper function for MIPS32 DSP ASE
   1032    instructions). */
   1033 static IRExpr *getDSPControl(void)
   1034 {
   1035    vassert(!mode64);
   1036    return IRExpr_Get(offsetof(VexGuestMIPS32State, guest_DSPControl), Ity_I32);
   1037 }
   1038 
   1039 /* Put value to DSPControl register. Expression e is written to DSPControl as
   1040    is. If only certain bits of DSPControl need to be changed, it should be done
   1041    before calling putDSPControl(). It could be done by reading DSPControl and
   1042    ORing it with appropriate mask. */
   1043 static void putDSPControl(IRExpr * e)
   1044 {
   1045    vassert(!mode64);
   1046    stmt(IRStmt_Put(offsetof(VexGuestMIPS32State, guest_DSPControl), e));
   1047 }
   1048 
   1049 /* Fetch a byte from the guest insn stream. */
   1050 static UChar getIByte(Int delta)
   1051 {
   1052    return guest_code[delta];
   1053 }
   1054 
   1055 static IRExpr *getIReg(UInt iregNo)
   1056 {
   1057    if (0 == iregNo) {
   1058       return mode64 ? mkU64(0x0) : mkU32(0x0);
   1059    } else {
   1060       IRType ty = mode64 ? Ity_I64 : Ity_I32;
   1061       vassert(iregNo < 32);
   1062       return IRExpr_Get(integerGuestRegOffset(iregNo), ty);
   1063    }
   1064 }
   1065 
   1066 static IRExpr *getHI(void)
   1067 {
   1068    if (mode64)
   1069       return IRExpr_Get(offsetof(VexGuestMIPS64State, guest_HI), Ity_I64);
   1070    else
   1071       return IRExpr_Get(offsetof(VexGuestMIPS32State, guest_HI), Ity_I32);
   1072 }
   1073 
   1074 static IRExpr *getLO(void)
   1075 {
   1076    if (mode64)
   1077       return IRExpr_Get(offsetof(VexGuestMIPS64State, guest_LO), Ity_I64);
   1078    else
   1079       return IRExpr_Get(offsetof(VexGuestMIPS32State, guest_LO), Ity_I32);
   1080 }
   1081 
   1082 static IRExpr *getFCSR(void)
   1083 {
   1084    if (mode64)
   1085       return IRExpr_Get(offsetof(VexGuestMIPS64State, guest_FCSR), Ity_I32);
   1086    else
   1087       return IRExpr_Get(offsetof(VexGuestMIPS32State, guest_FCSR), Ity_I32);
   1088 }
   1089 
   1090 /* Get byte from register reg, byte pos from 0 to 3 (or 7 for MIPS64) . */
   1091 static IRExpr *getByteFromReg(UInt reg, UInt byte_pos)
   1092 {
   1093   UInt pos = byte_pos * 8;
   1094   if (mode64)
   1095       return unop(Iop_64to8, binop(Iop_And64,
   1096                                    binop(Iop_Shr64, getIReg(reg), mkU8(pos)),
   1097                                    mkU64(0xFF)));
   1098    else
   1099       return unop(Iop_32to8, binop(Iop_And32,
   1100                                    binop(Iop_Shr32, getIReg(reg), mkU8(pos)),
   1101                                    mkU32(0xFF)));
   1102 }
   1103 
   1104 static void putFCSR(IRExpr * e)
   1105 {
   1106    if (mode64)
   1107       stmt(IRStmt_Put(offsetof(VexGuestMIPS64State, guest_FCSR), e));
   1108    else
   1109       stmt(IRStmt_Put(offsetof(VexGuestMIPS32State, guest_FCSR), e));
   1110 }
   1111 
   1112 /* fs   - fpu source register number.
   1113    inst - fpu instruction that needs to be executed.
   1114    sz32 - size of source register.
   1115    opN  - number of operads:
   1116           1 - unary operation.
   1117           2 - binary operation. */
   1118 static void calculateFCSR(UInt fs, UInt ft, UInt inst, Bool sz32, UInt opN)
   1119 {
   1120    IRDirty *d;
   1121    IRTemp fcsr = newTemp(Ity_I32);
   1122    /* IRExpr_BBPTR() => Need to pass pointer to guest state to helper. */
   1123    if (fp_mode64)
   1124       d = unsafeIRDirty_1_N(fcsr, 0,
   1125                             "mips_dirtyhelper_calculate_FCSR_fp64",
   1126                             &mips_dirtyhelper_calculate_FCSR_fp64,
   1127                             mkIRExprVec_4(IRExpr_BBPTR(),
   1128                                           mkU32(fs),
   1129                                           mkU32(ft),
   1130                                           mkU32(inst)));
   1131    else
   1132       d = unsafeIRDirty_1_N(fcsr, 0,
   1133                             "mips_dirtyhelper_calculate_FCSR_fp32",
   1134                             &mips_dirtyhelper_calculate_FCSR_fp32,
   1135                             mkIRExprVec_4(IRExpr_BBPTR(),
   1136                                           mkU32(fs),
   1137                                           mkU32(ft),
   1138                                           mkU32(inst)));
   1139 
   1140    if (opN == 1) {  /* Unary operation. */
   1141       /* Declare we're reading guest state. */
   1142       if (sz32 || fp_mode64)
   1143          d->nFxState = 2;
   1144       else
   1145          d->nFxState = 3;
   1146       vex_bzero(&d->fxState, sizeof(d->fxState));
   1147 
   1148       d->fxState[0].fx     = Ifx_Read;  /* read */
   1149       if (mode64)
   1150          d->fxState[0].offset = offsetof(VexGuestMIPS64State, guest_FCSR);
   1151       else
   1152          d->fxState[0].offset = offsetof(VexGuestMIPS32State, guest_FCSR);
   1153       d->fxState[0].size   = sizeof(UInt);
   1154       d->fxState[1].fx     = Ifx_Read;  /* read */
   1155       d->fxState[1].offset = floatGuestRegOffset(fs);
   1156       d->fxState[1].size   = sizeof(ULong);
   1157 
   1158       if (!(sz32 || fp_mode64)) {
   1159          d->fxState[2].fx     = Ifx_Read;  /* read */
   1160          d->fxState[2].offset = floatGuestRegOffset(fs+1);
   1161          d->fxState[2].size   = sizeof(ULong);
   1162       }
   1163    } else if (opN == 2) {  /* Binary operation. */
   1164       /* Declare we're reading guest state. */
   1165       if (sz32 || fp_mode64)
   1166          d->nFxState = 3;
   1167       else
   1168          d->nFxState = 5;
   1169       vex_bzero(&d->fxState, sizeof(d->fxState));
   1170 
   1171       d->fxState[0].fx     = Ifx_Read;  /* read */
   1172       if (mode64)
   1173          d->fxState[0].offset = offsetof(VexGuestMIPS64State, guest_FCSR);
   1174       else
   1175          d->fxState[0].offset = offsetof(VexGuestMIPS32State, guest_FCSR);
   1176       d->fxState[0].size   = sizeof(UInt);
   1177       d->fxState[1].fx     = Ifx_Read;  /* read */
   1178       d->fxState[1].offset = floatGuestRegOffset(fs);
   1179       d->fxState[1].size   = sizeof(ULong);
   1180       d->fxState[2].fx     = Ifx_Read;  /* read */
   1181       d->fxState[2].offset = floatGuestRegOffset(ft);
   1182       d->fxState[2].size   = sizeof(ULong);
   1183 
   1184       if (!(sz32 || fp_mode64)) {
   1185          d->fxState[3].fx     = Ifx_Read;  /* read */
   1186          d->fxState[3].offset = floatGuestRegOffset(fs+1);
   1187          d->fxState[3].size   = sizeof(ULong);
   1188          d->fxState[4].fx     = Ifx_Read;  /* read */
   1189          d->fxState[4].offset = floatGuestRegOffset(ft+1);
   1190          d->fxState[4].size   = sizeof(ULong);
   1191       }
   1192    }
   1193 
   1194    stmt(IRStmt_Dirty(d));
   1195 
   1196    putFCSR(mkexpr(fcsr));
   1197 }
   1198 
   1199 static IRExpr *getULR(void)
   1200 {
   1201    if (mode64)
   1202       return IRExpr_Get(offsetof(VexGuestMIPS64State, guest_ULR), Ity_I64);
   1203    else
   1204       return IRExpr_Get(offsetof(VexGuestMIPS32State, guest_ULR), Ity_I32);
   1205 }
   1206 
   1207 static void putIReg(UInt archreg, IRExpr * e)
   1208 {
   1209    IRType ty = mode64 ? Ity_I64 : Ity_I32;
   1210    vassert(archreg < 32);
   1211    vassert(typeOfIRExpr(irsb->tyenv, e) == ty);
   1212    if (archreg != 0)
   1213       stmt(IRStmt_Put(integerGuestRegOffset(archreg), e));
   1214 }
   1215 
   1216 static IRExpr *mkNarrowTo32(IRType ty, IRExpr * src)
   1217 {
   1218    vassert(ty == Ity_I32 || ty == Ity_I64);
   1219    return ty == Ity_I64 ? unop(Iop_64to32, src) : src;
   1220 }
   1221 
   1222 static void putLO(IRExpr * e)
   1223 {
   1224    if (mode64) {
   1225       stmt(IRStmt_Put(offsetof(VexGuestMIPS64State, guest_LO), e));
   1226    } else {
   1227       stmt(IRStmt_Put(offsetof(VexGuestMIPS32State, guest_LO), e));
   1228    /* Add value to lower 32 bits of ac0 to maintain compatibility between
   1229       regular MIPS32 instruction set and MIPS DSP ASE. Keep higher 32bits
   1230       unchanged. */
   1231       IRTemp t_lo = newTemp(Ity_I32);
   1232       IRTemp t_hi = newTemp(Ity_I32);
   1233       assign(t_lo, e);
   1234       assign(t_hi, unop(Iop_64HIto32, getAcc(0)));
   1235       stmt(IRStmt_Put(accumulatorGuestRegOffset(0),
   1236            binop(Iop_32HLto64, mkexpr(t_hi), mkexpr(t_lo))));
   1237    }
   1238 }
   1239 
   1240 static void putHI(IRExpr * e)
   1241 {
   1242    if (mode64) {
   1243       stmt(IRStmt_Put(offsetof(VexGuestMIPS64State, guest_HI), e));
   1244    } else {
   1245       stmt(IRStmt_Put(offsetof(VexGuestMIPS32State, guest_HI), e));
   1246    /* Add value to higher 32 bits of ac0 to maintain compatibility between
   1247       regular MIPS32 instruction set and MIPS DSP ASE. Keep lower 32bits
   1248       unchanged. */
   1249       IRTemp t_lo = newTemp(Ity_I32);
   1250       IRTemp t_hi = newTemp(Ity_I32);
   1251       assign(t_hi, e);
   1252       assign(t_lo, unop(Iop_64to32, getAcc(0)));
   1253       stmt(IRStmt_Put(accumulatorGuestRegOffset(0),
   1254            binop(Iop_32HLto64, mkexpr(t_hi), mkexpr(t_lo))));
   1255    }
   1256 }
   1257 
   1258 /* Put value to accumulator(helper function for MIPS32 DSP ASE instructions). */
   1259 static void putAcc(UInt acNo, IRExpr * e)
   1260 {
   1261    vassert(!mode64);
   1262    vassert(acNo <= 3);
   1263    vassert(typeOfIRExpr(irsb->tyenv, e) == Ity_I64);
   1264    stmt(IRStmt_Put(accumulatorGuestRegOffset(acNo), e));
   1265 /* If acNo = 0, split value to HI and LO regs in order to maintain compatibility
   1266    between MIPS32 and MIPS DSP ASE insn sets. */
   1267    if (0 == acNo) {
   1268      putLO(unop(Iop_64to32, e));
   1269      putHI(unop(Iop_64HIto32, e));
   1270    }
   1271 }
   1272 
   1273 static IRExpr *mkNarrowTo8 ( IRType ty, IRExpr * src )
   1274 {
   1275    vassert(ty == Ity_I32 || ty == Ity_I64);
   1276    return ty == Ity_I64 ? unop(Iop_64to8, src) : unop(Iop_32to8, src);
   1277 }
   1278 
   1279 static void putPC(IRExpr * e)
   1280 {
   1281    stmt(IRStmt_Put(OFFB_PC, e));
   1282 }
   1283 
   1284 static IRExpr *mkWidenFrom32(IRType ty, IRExpr * src, Bool sined)
   1285 {
   1286    vassert(ty == Ity_I32 || ty == Ity_I64);
   1287    if (ty == Ity_I32)
   1288       return src;
   1289    return (sined) ? unop(Iop_32Sto64, src) : unop(Iop_32Uto64, src);
   1290 }
   1291 
   1292 /* Narrow 8/16/32 bit int expr to 8/16/32.  Clearly only some
   1293    of these combinations make sense. */
   1294 static IRExpr *narrowTo(IRType dst_ty, IRExpr * e)
   1295 {
   1296    IRType src_ty = typeOfIRExpr(irsb->tyenv, e);
   1297    if (src_ty == dst_ty)
   1298       return e;
   1299    if (src_ty == Ity_I32 && dst_ty == Ity_I16)
   1300       return unop(Iop_32to16, e);
   1301    if (src_ty == Ity_I32 && dst_ty == Ity_I8)
   1302       return unop(Iop_32to8, e);
   1303    if (src_ty == Ity_I64 && dst_ty == Ity_I8) {
   1304       vassert(mode64);
   1305       return unop(Iop_64to8, e);
   1306    }
   1307    if (src_ty == Ity_I64 && dst_ty == Ity_I16) {
   1308       vassert(mode64);
   1309       return unop(Iop_64to16, e);
   1310    }
   1311    vpanic("narrowTo(mips)");
   1312    return 0;
   1313 }
   1314 
   1315 static IRExpr *getLoFromF64(IRType ty, IRExpr * src)
   1316 {
   1317    vassert(ty == Ity_F32 || ty == Ity_F64);
   1318    if (ty == Ity_F64) {
   1319       IRTemp t0, t1;
   1320       t0 = newTemp(Ity_I64);
   1321       t1 = newTemp(Ity_I32);
   1322       assign(t0, unop(Iop_ReinterpF64asI64, src));
   1323       assign(t1, unop(Iop_64to32, mkexpr(t0)));
   1324       return unop(Iop_ReinterpI32asF32, mkexpr(t1));
   1325    } else
   1326       return src;
   1327 }
   1328 
   1329 static IRExpr *mkWidenFromF32(IRType ty, IRExpr * src)
   1330 {
   1331    vassert(ty == Ity_F32 || ty == Ity_F64);
   1332    if (ty == Ity_F64) {
   1333       IRTemp t0 = newTemp(Ity_I32);
   1334       IRTemp t1 = newTemp(Ity_I64);
   1335       assign(t0, unop(Iop_ReinterpF32asI32, src));
   1336       assign(t1, binop(Iop_32HLto64, mkU32(0x0), mkexpr(t0)));
   1337       return unop(Iop_ReinterpI64asF64, mkexpr(t1));
   1338    } else
   1339       return src;
   1340 }
   1341 
   1342 static IRExpr *dis_branch_likely(IRExpr * guard, UInt imm)
   1343 {
   1344    ULong branch_offset;
   1345    IRTemp t0;
   1346 
   1347    /* PC = PC + (SignExtend(signed_immed_24) << 2)
   1348       An 18-bit signed offset (the 16-bit offset field shifted left 2 bits)
   1349       is added to the address of the instruction following
   1350       the branch (not the branch itself), in the branch delay slot, to form
   1351       a PC-relative effective target address. */
   1352    if (mode64)
   1353       branch_offset = extend_s_18to64(imm << 2);
   1354    else
   1355       branch_offset = extend_s_18to32(imm << 2);
   1356 
   1357    t0 = newTemp(Ity_I1);
   1358    assign(t0, guard);
   1359 
   1360    if (mode64)
   1361       stmt(IRStmt_Exit(mkexpr(t0), Ijk_Boring,
   1362                        IRConst_U64(guest_PC_curr_instr + 8), OFFB_PC));
   1363    else
   1364       stmt(IRStmt_Exit(mkexpr(t0), Ijk_Boring,
   1365                        IRConst_U32(guest_PC_curr_instr + 8), OFFB_PC));
   1366 
   1367    irsb->jumpkind = Ijk_Boring;
   1368 
   1369    if (mode64)
   1370       return mkU64(guest_PC_curr_instr + 4 + branch_offset);
   1371    else
   1372       return mkU32(guest_PC_curr_instr + 4 + branch_offset);
   1373 }
   1374 
   1375 static void dis_branch(Bool link, IRExpr * guard, UInt imm, IRStmt ** set)
   1376 {
   1377    ULong branch_offset;
   1378    IRTemp t0;
   1379 
   1380    if (link) {  /* LR (GPR31) = addr of the 2nd instr after branch instr */
   1381       if (mode64)
   1382          putIReg(31, mkU64(guest_PC_curr_instr + 8));
   1383       else
   1384          putIReg(31, mkU32(guest_PC_curr_instr + 8));
   1385    }
   1386 
   1387    /* PC = PC + (SignExtend(signed_immed_24) << 2)
   1388       An 18-bit signed offset (the 16-bit offset field shifted left 2 bits)
   1389       is added to the address of the instruction following
   1390       the branch (not the branch itself), in the branch delay slot, to form
   1391       a PC-relative effective target address. */
   1392 
   1393    if (mode64)
   1394       branch_offset = extend_s_18to64(imm << 2);
   1395    else
   1396       branch_offset = extend_s_18to32(imm << 2);
   1397 
   1398    t0 = newTemp(Ity_I1);
   1399    assign(t0, guard);
   1400    if (mode64)
   1401       *set = IRStmt_Exit(mkexpr(t0), link ? Ijk_Call : Ijk_Boring,
   1402                          IRConst_U64(guest_PC_curr_instr + 4 + branch_offset),
   1403                          OFFB_PC);
   1404    else
   1405       *set = IRStmt_Exit(mkexpr(t0), link ? Ijk_Call : Ijk_Boring,
   1406                          IRConst_U32(guest_PC_curr_instr + 4 +
   1407                                      (UInt) branch_offset), OFFB_PC);
   1408 }
   1409 
   1410 static IRExpr *getFReg(UInt fregNo)
   1411 {
   1412    vassert(fregNo < 32);
   1413    IRType ty = fp_mode64 ? Ity_F64 : Ity_F32;
   1414    return IRExpr_Get(floatGuestRegOffset(fregNo), ty);
   1415 }
   1416 
   1417 static IRExpr *getDReg(UInt dregNo)
   1418 {
   1419    vassert(dregNo < 32);
   1420    if (fp_mode64) {
   1421       return IRExpr_Get(floatGuestRegOffset(dregNo), Ity_F64);
   1422    } else {
   1423       /* Read a floating point register pair and combine their contents into a
   1424          64-bit value */
   1425       IRTemp t0 = newTemp(Ity_F32);
   1426       IRTemp t1 = newTemp(Ity_F32);
   1427       IRTemp t2 = newTemp(Ity_F64);
   1428       IRTemp t3 = newTemp(Ity_I32);
   1429       IRTemp t4 = newTemp(Ity_I32);
   1430       IRTemp t5 = newTemp(Ity_I64);
   1431 
   1432       assign(t0, getFReg(dregNo));
   1433       assign(t1, getFReg(dregNo + 1));
   1434 
   1435       assign(t3, unop(Iop_ReinterpF32asI32, mkexpr(t0)));
   1436       assign(t4, unop(Iop_ReinterpF32asI32, mkexpr(t1)));
   1437       assign(t5, binop(Iop_32HLto64, mkexpr(t4), mkexpr(t3)));
   1438       assign(t2, unop(Iop_ReinterpI64asF64, mkexpr(t5)));
   1439 
   1440       return mkexpr(t2);
   1441    }
   1442 }
   1443 
   1444 static void putFReg(UInt dregNo, IRExpr * e)
   1445 {
   1446    vassert(dregNo < 32);
   1447    IRType ty = fp_mode64 ? Ity_F64 : Ity_F32;
   1448    vassert(typeOfIRExpr(irsb->tyenv, e) == ty);
   1449    stmt(IRStmt_Put(floatGuestRegOffset(dregNo), e));
   1450 }
   1451 
   1452 static void putDReg(UInt dregNo, IRExpr * e)
   1453 {
   1454    if (fp_mode64) {
   1455       vassert(dregNo < 32);
   1456       IRType ty = Ity_F64;
   1457       vassert(typeOfIRExpr(irsb->tyenv, e) == ty);
   1458       stmt(IRStmt_Put(floatGuestRegOffset(dregNo), e));
   1459    } else {
   1460       vassert(dregNo < 32);
   1461       vassert(typeOfIRExpr(irsb->tyenv, e) == Ity_F64);
   1462       IRTemp t1 = newTemp(Ity_F64);
   1463       IRTemp t4 = newTemp(Ity_I32);
   1464       IRTemp t5 = newTemp(Ity_I32);
   1465       IRTemp t6 = newTemp(Ity_I64);
   1466       assign(t1, e);
   1467       assign(t6, unop(Iop_ReinterpF64asI64, mkexpr(t1)));
   1468       assign(t4, unop(Iop_64HIto32, mkexpr(t6)));  /* hi */
   1469       assign(t5, unop(Iop_64to32, mkexpr(t6)));    /* lo */
   1470       putFReg(dregNo, unop(Iop_ReinterpI32asF32, mkexpr(t5)));
   1471       putFReg(dregNo + 1, unop(Iop_ReinterpI32asF32, mkexpr(t4)));
   1472    }
   1473 }
   1474 
   1475 static void setFPUCondCode(IRExpr * e, UInt cc)
   1476 {
   1477    if (cc == 0) {
   1478       putFCSR(binop(Iop_And32, getFCSR(), mkU32(0xFF7FFFFF)));
   1479       putFCSR(binop(Iop_Or32, getFCSR(), binop(Iop_Shl32, e, mkU8(23))));
   1480    } else {
   1481       putFCSR(binop(Iop_And32, getFCSR(), unop(Iop_Not32,
   1482                                binop(Iop_Shl32, mkU32(0x01000000), mkU8(cc)))));
   1483       putFCSR(binop(Iop_Or32, getFCSR(), binop(Iop_Shl32, e, mkU8(24 + cc))));
   1484    }
   1485 }
   1486 
   1487 static IRExpr* get_IR_roundingmode ( void )
   1488 {
   1489 /*
   1490    rounding mode | MIPS | IR
   1491    ------------------------
   1492    to nearest    | 00  | 00
   1493    to zero       | 01  | 11
   1494    to +infinity  | 10  | 10
   1495    to -infinity  | 11  | 01
   1496 */
   1497    IRTemp rm_MIPS = newTemp(Ity_I32);
   1498    /* Last two bits in FCSR are rounding mode. */
   1499 
   1500    if (mode64)
   1501       assign(rm_MIPS, binop(Iop_And32, IRExpr_Get(offsetof(VexGuestMIPS64State,
   1502                                        guest_FCSR), Ity_I32), mkU32(3)));
   1503    else
   1504       assign(rm_MIPS, binop(Iop_And32, IRExpr_Get(offsetof(VexGuestMIPS32State,
   1505                                        guest_FCSR), Ity_I32), mkU32(3)));
   1506 
   1507    /* rm_IR = XOR( rm_MIPS32, (rm_MIPS32 << 1) & 2) */
   1508 
   1509    return binop(Iop_Xor32, mkexpr(rm_MIPS), binop(Iop_And32,
   1510                 binop(Iop_Shl32, mkexpr(rm_MIPS), mkU8(1)), mkU32(2)));
   1511 }
   1512 
   1513 /* sz, ULong -> IRExpr */
   1514 static IRExpr *mkSzImm ( IRType ty, ULong imm64 )
   1515 {
   1516    vassert(ty == Ity_I32 || ty == Ity_I64);
   1517    return ty == Ity_I64 ? mkU64(imm64) : mkU32((UInt) imm64);
   1518 }
   1519 
   1520 static IRConst *mkSzConst ( IRType ty, ULong imm64 )
   1521 {
   1522    vassert(ty == Ity_I32 || ty == Ity_I64);
   1523    return (ty == Ity_I64 ? IRConst_U64(imm64) : IRConst_U32((UInt) imm64));
   1524 }
   1525 
   1526 /* Make sure we get valid 32 and 64bit addresses */
   1527 static Addr64 mkSzAddr ( IRType ty, Addr64 addr )
   1528 {
   1529    vassert(ty == Ity_I32 || ty == Ity_I64);
   1530    return (ty == Ity_I64 ? (Addr64) addr :
   1531                            (Addr64) extend_s_32to64(toUInt(addr)));
   1532 }
   1533 
   1534 /* Shift and Rotate instructions for MIPS64 */
   1535 static Bool dis_instr_shrt ( UInt theInstr )
   1536 {
   1537    UInt opc2 = get_function(theInstr);
   1538    UChar regRs = get_rs(theInstr);
   1539    UChar regRt = get_rt(theInstr);
   1540    UChar regRd = get_rd(theInstr);
   1541    UChar uImmsa = get_sa(theInstr);
   1542    Long sImmsa = extend_s_16to64(uImmsa);
   1543    IRType ty = mode64 ? Ity_I64 : Ity_I32;
   1544    IRTemp tmp = newTemp(ty);
   1545    IRTemp tmpOr = newTemp(ty);
   1546    IRTemp tmpRt = newTemp(ty);
   1547    IRTemp tmpRs = newTemp(ty);
   1548    IRTemp tmpRd = newTemp(ty);
   1549 
   1550    assign(tmpRs, getIReg(regRs));
   1551    assign(tmpRt, getIReg(regRt));
   1552 
   1553    switch (opc2) {
   1554       case 0x3A:
   1555          if ((regRs & 0x01) == 0) {
   1556             /* Doubleword Shift Right Logical - DSRL; MIPS64 */
   1557             DIP("dsrl r%u, r%u, %lld", regRd, regRt, sImmsa);
   1558             assign(tmpRd, binop(Iop_Shr64, mkexpr(tmpRt), mkU8(uImmsa)));
   1559             putIReg(regRd, mkexpr(tmpRd));
   1560          } else if ((regRs & 0x01) == 1) {
   1561             /* Doubleword Rotate Right - DROTR; MIPS64r2 */
   1562             vassert(mode64);
   1563             DIP("drotr r%u, r%u, %lld", regRd, regRt, sImmsa);
   1564             IRTemp tmpL = newTemp(ty);
   1565             IRTemp tmpR = newTemp(ty);
   1566             assign(tmpR, binop(Iop_Shr64, mkexpr(tmpRt), mkU8(uImmsa)));
   1567             assign(tmp, binop(Iop_Shl64, mkexpr(tmpRt), mkU8(63 - uImmsa)));
   1568             assign(tmpL, binop(Iop_Shl64, mkexpr(tmp), mkU8(1)));
   1569             assign(tmpRd, binop(Iop_Or64, mkexpr(tmpL), mkexpr(tmpR)));
   1570             putIReg(regRd, mkexpr(tmpRd));
   1571          } else
   1572             return False;
   1573          break;
   1574 
   1575       case 0x3E:
   1576          if ((regRs & 0x01) == 0) {
   1577             /* Doubleword Shift Right Logical Plus 32 - DSRL32; MIPS64 */
   1578             DIP("dsrl32 r%u, r%u, %lld", regRd, regRt, sImmsa + 32);
   1579             assign(tmpRd, binop(Iop_Shr64, mkexpr(tmpRt), mkU8(uImmsa + 32)));
   1580             putIReg(regRd, mkexpr(tmpRd));
   1581          } else if ((regRs & 0x01) == 1) {
   1582             /* Doubleword Rotate Right Plus 32 - DROTR32; MIPS64r2 */
   1583             DIP("drotr32 r%u, r%u, %lld", regRd, regRt, sImmsa);
   1584             vassert(mode64);
   1585             IRTemp tmpL = newTemp(ty);
   1586             IRTemp tmpR = newTemp(ty);
   1587             /* (tmpRt >> sa) | (tmpRt << (64 - sa)) */
   1588             assign(tmpR, binop(Iop_Shr64, mkexpr(tmpRt), mkU8(uImmsa + 32)));
   1589             assign(tmp, binop(Iop_Shl64, mkexpr(tmpRt),
   1590                               mkU8(63 - (uImmsa + 32))));
   1591             assign(tmpL, binop(Iop_Shl64, mkexpr(tmp), mkU8(1)));
   1592             assign(tmpRd, binop(Iop_Or64, mkexpr(tmpL), mkexpr(tmpR)));
   1593             putIReg(regRd, mkexpr(tmpRd));
   1594          } else
   1595             return False;
   1596          break;
   1597 
   1598       case 0x16:
   1599          if ((uImmsa & 0x01) == 0) {
   1600             /* Doubleword Shift Right Logical Variable - DSRLV; MIPS64 */
   1601             DIP("dsrlv r%u, r%u, r%u", regRd, regRt, regRs);
   1602             IRTemp tmpRs8 = newTemp(Ity_I8);
   1603             /* s = tmpRs[5..0] */
   1604             assign(tmp, binop(Iop_And64, mkexpr(tmpRs), mkU64(63)));
   1605             assign(tmpRs8, mkNarrowTo8(ty, mkexpr(tmp)));
   1606             assign(tmpRd, binop(Iop_Shr64, mkexpr(tmpRt), mkexpr(tmpRs8)));
   1607             putIReg(regRd, mkexpr(tmpRd));
   1608          } else if ((uImmsa & 0x01) == 1) {
   1609             /* Doubleword Rotate Right Variable - DROTRV; MIPS64r2 */
   1610             DIP("drotrv r%u, r%u, r%u", regRd, regRt, regRs);
   1611             IRTemp tmpL = newTemp(ty);
   1612             IRTemp tmpR = newTemp(ty);
   1613             IRTemp tmpRs8 = newTemp(Ity_I8);
   1614             IRTemp tmpLs8 = newTemp(Ity_I8);
   1615             IRTemp tmp64 = newTemp(ty);
   1616             /* s = tmpRs[5...0]
   1617                m = 64 - s
   1618                (tmpRt << s) | (tmpRt >> m) */
   1619 
   1620             assign(tmp64, binop(Iop_And64, mkexpr(tmpRs), mkSzImm(ty, 63)));
   1621             assign(tmp, binop(Iop_Sub64, mkU64(63), mkexpr(tmp64)));
   1622 
   1623             assign(tmpLs8, mkNarrowTo8(ty, mkexpr(tmp)));
   1624             assign(tmpRs8, mkNarrowTo8(ty, mkexpr(tmp64)));
   1625 
   1626             assign(tmpR, binop(Iop_Shr64, mkexpr(tmpRt), mkexpr(tmpRs8)));
   1627             assign(tmpL, binop(Iop_Shl64, mkexpr(tmpRt), mkexpr(tmpLs8)));
   1628             assign(tmpRd, binop(Iop_Shl64, mkexpr(tmpL), mkU8(1)));
   1629             assign(tmpOr, binop(Iop_Or64, mkexpr(tmpRd), mkexpr(tmpR)));
   1630 
   1631             putIReg(regRd, mkexpr(tmpOr));
   1632          } else
   1633             return False;
   1634          break;
   1635 
   1636       case 0x38:  /* Doubleword Shift Left Logical - DSLL; MIPS64 */
   1637          DIP("dsll r%u, r%u, %lld", regRd, regRt, sImmsa);
   1638          vassert(mode64);
   1639          assign(tmpRd, binop(Iop_Shl64, mkexpr(tmpRt), mkU8(uImmsa)));
   1640          putIReg(regRd, mkexpr(tmpRd));
   1641          break;
   1642 
   1643       case 0x3C:  /* Doubleword Shift Left Logical Plus 32 - DSLL32; MIPS64 */
   1644          DIP("dsll32 r%u, r%u, %lld", regRd, regRt, sImmsa);
   1645          assign(tmpRd, binop(Iop_Shl64, mkexpr(tmpRt), mkU8(uImmsa + 32)));
   1646          putIReg(regRd, mkexpr(tmpRd));
   1647          break;
   1648 
   1649       case 0x14: {  /* Doubleword Shift Left Logical Variable - DSLLV; MIPS64 */
   1650          DIP("dsllv r%u, r%u, r%u", regRd, regRt, regRs);
   1651          IRTemp tmpRs8 = newTemp(Ity_I8);
   1652 
   1653          assign(tmp, binop(Iop_And64, mkexpr(tmpRs), mkSzImm(ty, 63)));
   1654          assign(tmpRs8, mkNarrowTo8(ty, mkexpr(tmp)));
   1655          assign(tmpRd, binop(Iop_Shl64, mkexpr(tmpRt), mkexpr(tmpRs8)));
   1656          putIReg(regRd, mkexpr(tmpRd));
   1657          break;
   1658       }
   1659 
   1660       case 0x3B:  /* Doubleword Shift Right Arithmetic - DSRA; MIPS64 */
   1661          DIP("dsra r%u, r%u, %lld", regRd, regRt, sImmsa);
   1662          assign(tmpRd, binop(Iop_Sar64, mkexpr(tmpRt), mkU8(uImmsa)));
   1663          putIReg(regRd, mkexpr(tmpRd));
   1664          break;
   1665 
   1666       case 0x3F:  /* Doubleword Shift Right Arithmetic Plus 32 - DSRA32;
   1667                      MIPS64 */
   1668          DIP("dsra32 r%u, r%u, %lld", regRd, regRt, sImmsa);
   1669          assign(tmpRd, binop(Iop_Sar64, mkexpr(tmpRt), mkU8(uImmsa + 32)));
   1670          putIReg(regRd, mkexpr(tmpRd));
   1671          break;
   1672 
   1673       case 0x17: {  /* Doubleword Shift Right Arithmetic Variable - DSRAV;
   1674                        MIPS64 */
   1675          DIP("dsrav r%u, r%u, r%u", regRd, regRt, regRs);
   1676          IRTemp tmpRs8 = newTemp(Ity_I8);
   1677          assign(tmp, binop(Iop_And64, mkexpr(tmpRs), mkSzImm(ty, 63)));
   1678          assign(tmpRs8, mkNarrowTo8(ty, mkexpr(tmp)));
   1679          assign(tmpRd, binop(Iop_Sar64, mkexpr(tmpRt), mkexpr(tmpRs8)));
   1680          putIReg(regRd, mkexpr(tmpRd));
   1681          break;
   1682 
   1683       }
   1684 
   1685       default:
   1686          return False;
   1687 
   1688    }
   1689    return True;
   1690 }
   1691 
   1692 static IROp mkSzOp ( IRType ty, IROp op8 )
   1693 {
   1694    Int adj;
   1695    vassert(ty == Ity_I8 || ty == Ity_I16 || ty == Ity_I32 || ty == Ity_I64);
   1696    vassert(op8 == Iop_Add8 || op8 == Iop_Sub8 || op8 == Iop_Mul8
   1697            || op8 == Iop_Or8 || op8 == Iop_And8 || op8 == Iop_Xor8
   1698            || op8 == Iop_Shl8 || op8 == Iop_Shr8 || op8 == Iop_Sar8
   1699            || op8 == Iop_CmpEQ8 || op8 == Iop_CmpNE8 || op8 == Iop_Not8);
   1700    adj = ty == Ity_I8 ? 0 : (ty == Ity_I16 ? 1 : (ty == Ity_I32 ? 2 : 3));
   1701    return adj + op8;
   1702 }
   1703 
   1704 /*********************************************************/
   1705 /*---             Floating Point Compare              ---*/
   1706 /*********************************************************/
   1707 /* Function that returns a string that represent mips cond
   1708    mnemonic for the input code. */
   1709 static const HChar* showCondCode(UInt code) {
   1710    const HChar* ret;
   1711    switch (code) {
   1712       case 0: ret = "f"; break;
   1713       case 1: ret = "un"; break;
   1714       case 2: ret = "eq"; break;
   1715       case 3: ret = "ueq"; break;
   1716       case 4: ret = "olt"; break;
   1717       case 5: ret = "ult"; break;
   1718       case 6: ret = "ole"; break;
   1719       case 7: ret = "ule"; break;
   1720       case 8: ret = "sf"; break;
   1721       case 9: ret = "ngle"; break;
   1722       case 10: ret = "seq"; break;
   1723       case 11: ret = "ngl"; break;
   1724       case 12: ret = "lt"; break;
   1725       case 13: ret = "nge"; break;
   1726       case 14: ret = "le"; break;
   1727       case 15: ret = "ngt"; break;
   1728       default: vpanic("showCondCode"); break;
   1729    }
   1730    return ret;
   1731 }
   1732 
   1733 static Bool dis_instr_CCondFmt ( UInt cins )
   1734 {
   1735    IRTemp t0, t1, t2, t3, tmp5, tmp6;
   1736    IRTemp ccIR = newTemp(Ity_I32);
   1737    IRTemp ccMIPS = newTemp(Ity_I32);
   1738    UInt FC = get_FC(cins);
   1739    UInt fmt = get_fmt(cins);
   1740    UInt fs = get_fs(cins);
   1741    UInt ft = get_ft(cins);
   1742    UInt cond = get_cond(cins);
   1743 
   1744    if (FC == 0x3) {  /* C.cond.fmt */
   1745       UInt fpc_cc = get_fpc_cc(cins);
   1746       switch (fmt) {
   1747          case 0x10: {  /* C.cond.S */
   1748             DIP("c.%s.s %u, f%u, f%u", showCondCode(cond), fpc_cc, fs, ft);
   1749             if (fp_mode64) {
   1750                t0 = newTemp(Ity_I32);
   1751                t1 = newTemp(Ity_I32);
   1752                t2 = newTemp(Ity_I32);
   1753                t3 = newTemp(Ity_I32);
   1754 
   1755                tmp5 = newTemp(Ity_F64);
   1756                tmp6 = newTemp(Ity_F64);
   1757 
   1758                assign(tmp5, unop(Iop_F32toF64, getLoFromF64(Ity_F64,
   1759                                  getFReg(fs))));
   1760                assign(tmp6, unop(Iop_F32toF64, getLoFromF64(Ity_F64,
   1761                                  getFReg(ft))));
   1762 
   1763                assign(ccIR, binop(Iop_CmpF64, mkexpr(tmp5), mkexpr(tmp6)));
   1764                putHI(mkWidenFrom32(mode64 ? Ity_I64: Ity_I32,
   1765                                    mkexpr(ccIR), True));
   1766                /* Map compare result from IR to MIPS
   1767                   FP cmp result | MIPS | IR
   1768                   --------------------------
   1769                   UN            | 0x1 | 0x45
   1770                   EQ            | 0x2 | 0x40
   1771                   GT            | 0x4 | 0x00
   1772                   LT            | 0x8 | 0x01
   1773                 */
   1774 
   1775                /* ccMIPS = Shl(1, (~(ccIR>>5) & 2) | ((ccIR ^ (ccIR>>6)) & 1) */
   1776                assign(ccMIPS, binop(Iop_Shl32, mkU32(1), unop(Iop_32to8,
   1777                               binop(Iop_Or32, binop(Iop_And32, unop(Iop_Not32,
   1778                               binop(Iop_Shr32, mkexpr(ccIR),mkU8(5))),mkU32(2)),
   1779                               binop(Iop_And32, binop(Iop_Xor32, mkexpr(ccIR),
   1780                               binop(Iop_Shr32, mkexpr(ccIR), mkU8(6))),
   1781                               mkU32(1))))));
   1782                putLO(mkWidenFrom32(mode64 ? Ity_I64: Ity_I32,
   1783                                    mkexpr(ccMIPS), True));
   1784 
   1785                /* UN */
   1786                assign(t0, binop(Iop_And32, mkexpr(ccMIPS), mkU32(0x1)));
   1787                /* EQ */
   1788                assign(t1, binop(Iop_And32, binop(Iop_Shr32, mkexpr(ccMIPS),
   1789                                                  mkU8(0x1)), mkU32(0x1)));
   1790                /* NGT */
   1791                assign(t2, binop(Iop_And32, unop(Iop_Not32, binop(Iop_Shr32,
   1792                                  mkexpr(ccMIPS), mkU8(0x2))),mkU32(0x1)));
   1793                /* LT */
   1794                assign(t3, binop(Iop_And32, binop(Iop_Shr32, mkexpr(ccMIPS),
   1795                                                  mkU8(0x3)), mkU32(0x1)));
   1796                switch (cond) {
   1797                   case 0x0:
   1798                      setFPUCondCode(mkU32(0), fpc_cc);
   1799                      break;
   1800                   case 0x1:
   1801                      setFPUCondCode(mkexpr(t0), fpc_cc);
   1802                      break;
   1803                   case 0x2:
   1804                      setFPUCondCode(mkexpr(t1), fpc_cc);
   1805                      break;
   1806                   case 0x3:
   1807                      setFPUCondCode(binop(Iop_Or32, mkexpr(t0), mkexpr(t1)),
   1808                                           fpc_cc);
   1809                      break;
   1810                   case 0x4:
   1811                      setFPUCondCode(mkexpr(t3), fpc_cc);
   1812                      break;
   1813                   case 0x5:
   1814                      setFPUCondCode(binop(Iop_Or32, mkexpr(t0), mkexpr(t3)),
   1815                                           fpc_cc);
   1816                      break;
   1817                   case 0x6:
   1818                      setFPUCondCode(binop(Iop_Or32, mkexpr(t3), mkexpr(t1)),
   1819                                           fpc_cc);
   1820                      break;
   1821                   case 0x7:
   1822                      setFPUCondCode(mkexpr(t2), fpc_cc);
   1823                      break;
   1824                   case 0x8:
   1825                      setFPUCondCode(mkU32(0), fpc_cc);
   1826                      break;
   1827                   case 0x9:
   1828                      setFPUCondCode(mkexpr(t0), fpc_cc);
   1829                      break;
   1830                   case 0xA:
   1831                      setFPUCondCode(mkexpr(t1), fpc_cc);
   1832                      break;
   1833                   case 0xB:
   1834                      setFPUCondCode(binop(Iop_Or32, mkexpr(t0), mkexpr(t1)),
   1835                                           fpc_cc);
   1836                      break;
   1837                   case 0xC:
   1838                      setFPUCondCode(mkexpr(t3), fpc_cc);
   1839                      break;
   1840                   case 0xD:
   1841                      setFPUCondCode(binop(Iop_Or32, mkexpr(t0), mkexpr(t3)),
   1842                                           fpc_cc);
   1843                      break;
   1844                   case 0xE:
   1845                      setFPUCondCode(binop(Iop_Or32, mkexpr(t3), mkexpr(t1)),
   1846                                           fpc_cc);
   1847                      break;
   1848                   case 0xF:
   1849                      setFPUCondCode(mkexpr(t2), fpc_cc);
   1850                      break;
   1851 
   1852                   default:
   1853                      return False;
   1854                }
   1855 
   1856             } else {
   1857                t0 = newTemp(Ity_I32);
   1858                t1 = newTemp(Ity_I32);
   1859                t2 = newTemp(Ity_I32);
   1860                t3 = newTemp(Ity_I32);
   1861 
   1862                assign(ccIR, binop(Iop_CmpF64, unop(Iop_F32toF64, getFReg(fs)),
   1863                                   unop(Iop_F32toF64, getFReg(ft))));
   1864                /* Map compare result from IR to MIPS
   1865                   FP cmp result | MIPS | IR
   1866                   --------------------------
   1867                   UN            | 0x1 | 0x45
   1868                   EQ            | 0x2 | 0x40
   1869                   GT            | 0x4 | 0x00
   1870                   LT            | 0x8 | 0x01
   1871                 */
   1872 
   1873                /* ccMIPS = Shl(1, (~(ccIR>>5) & 2) | ((ccIR ^ (ccIR>>6)) & 1) */
   1874                assign(ccMIPS, binop(Iop_Shl32, mkU32(1), unop(Iop_32to8,
   1875                               binop(Iop_Or32, binop(Iop_And32, unop(Iop_Not32,
   1876                               binop(Iop_Shr32, mkexpr(ccIR), mkU8(5))),
   1877                                     mkU32(2)), binop(Iop_And32,
   1878                               binop(Iop_Xor32, mkexpr(ccIR),
   1879                               binop(Iop_Shr32, mkexpr(ccIR), mkU8(6))),
   1880                               mkU32(1))))));
   1881                /* UN */
   1882                assign(t0, binop(Iop_And32, mkexpr(ccMIPS), mkU32(0x1)));
   1883                /* EQ */
   1884                assign(t1, binop(Iop_And32, binop(Iop_Shr32, mkexpr(ccMIPS),
   1885                       mkU8(0x1)), mkU32(0x1)));
   1886                /* NGT */
   1887                assign(t2, binop(Iop_And32, unop(Iop_Not32, binop(Iop_Shr32,
   1888                       mkexpr(ccMIPS), mkU8(0x2))), mkU32(0x1)));
   1889                /* LT */
   1890                assign(t3, binop(Iop_And32, binop(Iop_Shr32, mkexpr(ccMIPS),
   1891                       mkU8(0x3)), mkU32(0x1)));
   1892 
   1893                switch (cond) {
   1894                   case 0x0:
   1895                      setFPUCondCode(mkU32(0), fpc_cc);
   1896                      break;
   1897                   case 0x1:
   1898                      setFPUCondCode(mkexpr(t0), fpc_cc);
   1899                      break;
   1900                   case 0x2:
   1901                      setFPUCondCode(mkexpr(t1), fpc_cc);
   1902                      break;
   1903                   case 0x3:
   1904                      setFPUCondCode(binop(Iop_Or32, mkexpr(t0), mkexpr(t1)),
   1905                                           fpc_cc);
   1906                      break;
   1907                   case 0x4:
   1908                      setFPUCondCode(mkexpr(t3), fpc_cc);
   1909                      break;
   1910                   case 0x5:
   1911                      setFPUCondCode(binop(Iop_Or32, mkexpr(t0), mkexpr(t3)),
   1912                                           fpc_cc);
   1913                      break;
   1914                   case 0x6:
   1915                      setFPUCondCode(binop(Iop_Or32, mkexpr(t3), mkexpr(t1)),
   1916                                           fpc_cc);
   1917                      break;
   1918                   case 0x7:
   1919                      setFPUCondCode(mkexpr(t2), fpc_cc);
   1920                      break;
   1921                   case 0x8:
   1922                      setFPUCondCode(mkU32(0), fpc_cc);
   1923                      break;
   1924                   case 0x9:
   1925                      setFPUCondCode(mkexpr(t0), fpc_cc);
   1926                      break;
   1927                   case 0xA:
   1928                      setFPUCondCode(mkexpr(t1), fpc_cc);
   1929                      break;
   1930                   case 0xB:
   1931                      setFPUCondCode(binop(Iop_Or32, mkexpr(t0), mkexpr(t1)),
   1932                                           fpc_cc);
   1933                      break;
   1934                   case 0xC:
   1935                      setFPUCondCode(mkexpr(t3), fpc_cc);
   1936                      break;
   1937                   case 0xD:
   1938                      setFPUCondCode(binop(Iop_Or32, mkexpr(t0), mkexpr(t3)),
   1939                                           fpc_cc);
   1940                      break;
   1941                   case 0xE:
   1942                      setFPUCondCode(binop(Iop_Or32, mkexpr(t3), mkexpr(t1)),
   1943                                           fpc_cc);
   1944                      break;
   1945                   case 0xF:
   1946                      setFPUCondCode(mkexpr(t2), fpc_cc);
   1947                      break;
   1948 
   1949                   default:
   1950                      return False;
   1951                }
   1952             }
   1953          }
   1954             break;
   1955 
   1956          case 0x11: {  /* C.cond.D */
   1957             DIP("c.%s.d %u, f%u, f%u", showCondCode(cond), fpc_cc, fs, ft);
   1958             t0 = newTemp(Ity_I32);
   1959             t1 = newTemp(Ity_I32);
   1960             t2 = newTemp(Ity_I32);
   1961             t3 = newTemp(Ity_I32);
   1962             assign(ccIR, binop(Iop_CmpF64, getDReg(fs), getDReg(ft)));
   1963             /* Map compare result from IR to MIPS
   1964                FP cmp result | MIPS | IR
   1965                --------------------------
   1966                UN            | 0x1 | 0x45
   1967                EQ            | 0x2 | 0x40
   1968                GT            | 0x4 | 0x00
   1969                LT            | 0x8 | 0x01
   1970              */
   1971 
   1972             /* ccMIPS = Shl(1, (~(ccIR>>5) & 2) | ((ccIR ^ (ccIR>>6)) & 1) */
   1973             assign(ccMIPS, binop(Iop_Shl32, mkU32(1), unop(Iop_32to8,
   1974                            binop(Iop_Or32, binop(Iop_And32, unop(Iop_Not32,
   1975                            binop(Iop_Shr32, mkexpr(ccIR), mkU8(5))), mkU32(2)),
   1976                            binop(Iop_And32, binop(Iop_Xor32, mkexpr(ccIR),
   1977                            binop(Iop_Shr32, mkexpr(ccIR), mkU8(6))),
   1978                            mkU32(1))))));
   1979 
   1980             /* UN */
   1981             assign(t0, binop(Iop_And32, mkexpr(ccMIPS), mkU32(0x1)));
   1982             /* EQ */
   1983             assign(t1, binop(Iop_And32, binop(Iop_Shr32, mkexpr(ccMIPS),
   1984                    mkU8(0x1)), mkU32(0x1)));
   1985             /* NGT */
   1986             assign(t2, binop(Iop_And32, unop(Iop_Not32, binop(Iop_Shr32,
   1987                    mkexpr(ccMIPS), mkU8(0x2))), mkU32(0x1)));
   1988             /* LT */
   1989             assign(t3, binop(Iop_And32, binop(Iop_Shr32, mkexpr(ccMIPS),
   1990                    mkU8(0x3)), mkU32(0x1)));
   1991 
   1992             switch (cond) {
   1993                case 0x0:
   1994                   setFPUCondCode(mkU32(0), fpc_cc);
   1995                   break;
   1996                case 0x1:
   1997                   setFPUCondCode(mkexpr(t0), fpc_cc);
   1998                   break;
   1999                case 0x2:
   2000                   setFPUCondCode(mkexpr(t1), fpc_cc);
   2001                   break;
   2002                case 0x3:
   2003                   setFPUCondCode(binop(Iop_Or32, mkexpr(t0), mkexpr(t1)),
   2004                                        fpc_cc);
   2005                   break;
   2006                case 0x4:
   2007                   setFPUCondCode(mkexpr(t3), fpc_cc);
   2008                   break;
   2009                case 0x5:
   2010                   setFPUCondCode(binop(Iop_Or32, mkexpr(t0), mkexpr(t3)),
   2011                                        fpc_cc);
   2012                   break;
   2013                case 0x6:
   2014                   setFPUCondCode(binop(Iop_Or32, mkexpr(t3), mkexpr(t1)),
   2015                                        fpc_cc);
   2016                   break;
   2017                case 0x7:
   2018                   setFPUCondCode(mkexpr(t2), fpc_cc);
   2019                   break;
   2020                case 0x8:
   2021                   setFPUCondCode(mkU32(0), fpc_cc);
   2022                   break;
   2023                case 0x9:
   2024                   setFPUCondCode(mkexpr(t0), fpc_cc);
   2025                   break;
   2026                case 0xA:
   2027                   setFPUCondCode(mkexpr(t1), fpc_cc);
   2028                   break;
   2029                case 0xB:
   2030                   setFPUCondCode(binop(Iop_Or32, mkexpr(t0), mkexpr(t1)),
   2031                                        fpc_cc);
   2032                   break;
   2033                case 0xC:
   2034                   setFPUCondCode(mkexpr(t3), fpc_cc);
   2035                   break;
   2036                case 0xD:
   2037                   setFPUCondCode(binop(Iop_Or32, mkexpr(t0), mkexpr(t3)),
   2038                                        fpc_cc);
   2039                   break;
   2040                case 0xE:
   2041                   setFPUCondCode(binop(Iop_Or32, mkexpr(t3), mkexpr(t1)),
   2042                                        fpc_cc);
   2043                   break;
   2044                case 0xF:
   2045                   setFPUCondCode(mkexpr(t2), fpc_cc);
   2046                   break;
   2047                default:
   2048                   return False;
   2049             }
   2050          }
   2051          break;
   2052 
   2053          default:
   2054             return False;
   2055       }
   2056    } else {
   2057       return False;
   2058    }
   2059 
   2060    return True;
   2061 }
   2062 
   2063 /*********************************************************/
   2064 /*---        Branch Instructions for mips64           ---*/
   2065 /*********************************************************/
   2066 static Bool dis_instr_branch ( UInt theInstr, DisResult * dres,
   2067                                Bool(*resteerOkFn) (void *, Addr),
   2068                                void *callback_opaque, IRStmt ** set )
   2069 {
   2070    UInt jmpKind = 0;
   2071    UChar opc1 = get_opcode(theInstr);
   2072    UChar regRs = get_rs(theInstr);
   2073    UChar regRt = get_rt(theInstr);
   2074    UInt offset = get_imm(theInstr);
   2075    Long sOffset = extend_s_16to64(offset);
   2076    IRType ty = mode64 ? Ity_I64 : Ity_I32;
   2077    IROp opSlt = mode64 ? Iop_CmpLT64S : Iop_CmpLT32S;
   2078 
   2079    IRTemp tmp = newTemp(ty);
   2080    IRTemp tmpRs = newTemp(ty);
   2081    IRTemp tmpRt = newTemp(ty);
   2082    IRTemp tmpLt = newTemp(ty);
   2083    IRTemp tmpReg0 = newTemp(ty);
   2084 
   2085    UChar regLnk = 31;   /* reg 31 is link reg in MIPS */
   2086    Addr64 addrTgt = 0;
   2087    Addr64 cia = guest_PC_curr_instr;
   2088 
   2089    IRExpr *eConst0 = mkSzImm(ty, (UInt) 0);
   2090    IRExpr *eNia = mkSzImm(ty, cia + 8);
   2091    IRExpr *eCond = NULL;
   2092 
   2093    assign(tmpRs, getIReg(regRs));
   2094    assign(tmpRt, getIReg(regRt));
   2095    assign(tmpReg0, getIReg(0));
   2096 
   2097    eCond = binop(mkSzOp(ty, Iop_CmpNE8), mkexpr(tmpReg0), mkexpr(tmpReg0));
   2098 
   2099    switch (opc1) {
   2100       case 0x01:
   2101          switch (regRt) {
   2102             case 0x00: {  /* BLTZ rs, offset */
   2103                addrTgt = mkSzAddr(ty, cia + 4 + (sOffset << 2));
   2104                IRTemp tmpLtRes = newTemp(Ity_I1);
   2105 
   2106                assign(tmp, eConst0);
   2107                assign(tmpLtRes, binop(opSlt, mkexpr(tmpRs), mkexpr(tmp)));
   2108                assign(tmpLt, mode64 ? unop(Iop_1Uto64, mkexpr(tmpLtRes)) :
   2109                       unop(Iop_1Uto32, mkexpr(tmpLtRes)));
   2110 
   2111                eCond = binop(mkSzOp(ty, Iop_CmpNE8), mkexpr(tmpLt),
   2112                              mkexpr(tmpReg0));
   2113 
   2114                jmpKind = Ijk_Boring;
   2115                break;
   2116             }
   2117 
   2118             case 0x01: {  /* BGEZ rs, offset */
   2119                IRTemp tmpLtRes = newTemp(Ity_I1);
   2120                addrTgt = mkSzAddr(ty, cia + 4 + (sOffset << 2));
   2121 
   2122                assign(tmp, eConst0);
   2123                assign(tmpLtRes, binop(opSlt, mkexpr(tmpRs), mkexpr(tmp)));
   2124                assign(tmpLt, mode64 ? unop(Iop_1Uto64, mkexpr(tmpLtRes)) :
   2125                                       unop(Iop_1Uto32, mkexpr(tmpLtRes)));
   2126                eCond = binop(mkSzOp(ty, Iop_CmpEQ8), mkexpr(tmpLt),
   2127                                     mkexpr(tmpReg0));
   2128 
   2129                jmpKind = Ijk_Boring;
   2130                break;
   2131             }
   2132 
   2133             case 0x11: {  /* BGEZAL rs, offset */
   2134                addrTgt = mkSzAddr(ty, cia + 4 + (sOffset << 2));
   2135                putIReg(regLnk, eNia);
   2136                IRTemp tmpLtRes = newTemp(Ity_I1);
   2137 
   2138                assign(tmpLtRes, binop(opSlt, mkexpr(tmpRs), eConst0));
   2139                assign(tmpLt, mode64 ? unop(Iop_1Uto64, mkexpr(tmpLtRes)) :
   2140                                       unop(Iop_1Uto32, mkexpr(tmpLtRes)));
   2141 
   2142                eCond = binop(mkSzOp(ty, Iop_CmpEQ8), mkexpr(tmpLt),
   2143                                     mkexpr(tmpReg0));
   2144 
   2145                jmpKind = Ijk_Call;
   2146                break;
   2147             }
   2148 
   2149             case 0x10: {  /* BLTZAL rs, offset */
   2150                IRTemp tmpLtRes = newTemp(Ity_I1);
   2151                IRTemp tmpRes = newTemp(ty);
   2152 
   2153                addrTgt = mkSzAddr(ty, cia + 4 + (sOffset << 2));
   2154                putIReg(regLnk, eNia);
   2155 
   2156                assign(tmp, eConst0);
   2157                assign(tmpLtRes, binop(opSlt, mkexpr(tmpRs), mkexpr(tmp)));
   2158                assign(tmpRes, mode64 ? unop(Iop_1Uto64,
   2159                       mkexpr(tmpLtRes)) : unop(Iop_1Uto32, mkexpr(tmpLtRes)));
   2160                eCond = binop(mkSzOp(ty, Iop_CmpNE8), mkexpr(tmpRes),
   2161                                                      mkexpr(tmpReg0));
   2162 
   2163                jmpKind = Ijk_Call;
   2164                break;
   2165             }
   2166 
   2167          }
   2168          break;
   2169       default:
   2170          return False;
   2171       }
   2172    *set = IRStmt_Exit(eCond, jmpKind, mkSzConst(ty, addrTgt), OFFB_PC);
   2173    return True;
   2174 }
   2175 
   2176 /*********************************************************/
   2177 /*---         Cavium Specific Instructions            ---*/
   2178 /*********************************************************/
   2179 
   2180 /* Convenience function to yield to thread scheduler */
   2181 static void jump_back(IRExpr *condition)
   2182 {
   2183    stmt( IRStmt_Exit(condition,
   2184                      Ijk_Yield,
   2185                      IRConst_U64( guest_PC_curr_instr ),
   2186                      OFFB_PC) );
   2187 }
   2188 
   2189 /* Based on s390_irgen_load_and_add32. */
   2190 static void mips_irgen_load_and_add32(IRTemp op1addr, IRTemp new_val,
   2191                                       UChar rd, Bool putIntoRd)
   2192 {
   2193    IRCAS *cas;
   2194    IRTemp old_mem = newTemp(Ity_I32);
   2195    IRTemp expd    = newTemp(Ity_I32);
   2196 
   2197    assign(expd, load(Ity_I32, mkexpr(op1addr)));
   2198 
   2199    cas = mkIRCAS(IRTemp_INVALID, old_mem,
   2200                  Iend_LE, mkexpr(op1addr),
   2201                  NULL, mkexpr(expd), /* expected value */
   2202                  NULL, mkexpr(new_val)  /* new value */);
   2203    stmt(IRStmt_CAS(cas));
   2204 
   2205    /* If old_mem contains the expected value, then the CAS succeeded.
   2206       Otherwise, it did not */
   2207    jump_back(binop(Iop_CmpNE32, mkexpr(old_mem), mkexpr(expd)));
   2208    if (putIntoRd)
   2209       putIReg(rd, mkWidenFrom32(Ity_I64, mkexpr(old_mem), True));
   2210 }
   2211 
   2212 /* Based on s390_irgen_load_and_add64. */
   2213 static void mips_irgen_load_and_add64(IRTemp op1addr, IRTemp new_val,
   2214                                       UChar rd, Bool putIntoRd)
   2215 {
   2216    IRCAS *cas;
   2217    IRTemp old_mem = newTemp(Ity_I64);
   2218    IRTemp expd    = newTemp(Ity_I64);
   2219 
   2220    assign(expd, load(Ity_I64, mkexpr(op1addr)));
   2221 
   2222    cas = mkIRCAS(IRTemp_INVALID, old_mem,
   2223                  Iend_LE, mkexpr(op1addr),
   2224                  NULL, mkexpr(expd), /* expected value */
   2225                  NULL, mkexpr(new_val)  /* new value */);
   2226    stmt(IRStmt_CAS(cas));
   2227 
   2228    /* If old_mem contains the expected value, then the CAS succeeded.
   2229       Otherwise, it did not */
   2230    jump_back(binop(Iop_CmpNE64, mkexpr(old_mem), mkexpr(expd)));
   2231    if (putIntoRd)
   2232       putIReg(rd, mkexpr(old_mem));
   2233 }
   2234 
   2235 static Bool dis_instr_CVM ( UInt theInstr )
   2236 {
   2237    UChar  opc2     = get_function(theInstr);
   2238    UChar  opc1     = get_opcode(theInstr);
   2239    UChar  regRs    = get_rs(theInstr);
   2240    UChar  regRt    = get_rt(theInstr);
   2241    UChar  regRd    = get_rd(theInstr);
   2242    /* MIPS trap instructions extract code from theInstr[15:6].
   2243       Cavium OCTEON instructions SNEI, SEQI extract immediate operands
   2244       from the same bit field [15:6]. */
   2245    UInt   imm      = get_code(theInstr);
   2246    UChar  lenM1    = get_msb(theInstr);
   2247    UChar  p        = get_lsb(theInstr);
   2248    IRType ty       = mode64? Ity_I64 : Ity_I32;
   2249    IRTemp tmp      = newTemp(ty);
   2250    IRTemp tmpRs    = newTemp(ty);
   2251    IRTemp tmpRt    = newTemp(ty);
   2252    IRTemp t1       = newTemp(ty);
   2253    UInt size;
   2254    assign(tmpRs, getIReg(regRs));
   2255 
   2256    switch(opc1) {
   2257       case 0x1C: {
   2258          switch(opc2) {
   2259             case 0x03: {  /* DMUL rd, rs, rt */
   2260                DIP("dmul r%u, r%u, r%u", regRd, regRs, regRt);
   2261                IRTemp t0 = newTemp(Ity_I128);
   2262                assign(t0, binop(Iop_MullU64, getIReg(regRs), getIReg(regRt)));
   2263                putIReg(regRd, unop(Iop_128to64, mkexpr(t0)));
   2264                break;
   2265             }
   2266 
   2267             case 0x18: {  /* Store Atomic Add Word - SAA; Cavium OCTEON */
   2268                DIP("saa r%u, (r%u)", regRt, regRs);
   2269                IRTemp addr = newTemp(Ity_I64);
   2270                IRTemp new  = newTemp(Ity_I32);
   2271                assign (addr, getIReg(regRs));
   2272                assign(new, binop(Iop_Add32,
   2273                                  load(Ity_I32, mkexpr(addr)),
   2274                                  mkNarrowTo32(ty, getIReg(regRt))));
   2275                mips_irgen_load_and_add32(addr, new, 0, False);
   2276                break;
   2277             }
   2278 
   2279             /* Store Atomic Add Doubleword - SAAD; Cavium OCTEON */
   2280             case 0x19: {
   2281                DIP( "saad r%u, (r%u)", regRt, regRs);
   2282                IRTemp addr = newTemp(Ity_I64);
   2283                IRTemp new  = newTemp(Ity_I64);
   2284                assign (addr, getIReg(regRs));
   2285                assign(new, binop(Iop_Add64,
   2286                                  load(Ity_I64, mkexpr(addr)),
   2287                                  getIReg(regRt)));
   2288                mips_irgen_load_and_add64(addr, new, 0, False);
   2289                break;
   2290             }
   2291 
   2292             /* LAI, LAID, LAD, LADD, LAS, LASD,
   2293                LAC, LACD, LAA, LAAD, LAW, LAWD */
   2294             case 0x1f: {
   2295                UInt opc3 = get_sa(theInstr);
   2296                IRTemp addr = newTemp(Ity_I64);
   2297                switch (opc3) {
   2298                   /* Load Atomic Increment Word - LAI; Cavium OCTEON2 */
   2299                   case 0x02: {
   2300                      DIP("lai r%u,(r%u)\n", regRd, regRs);
   2301                      IRTemp new  = newTemp(Ity_I32);
   2302                      assign(addr, getIReg(regRs));
   2303                      assign(new, binop(Iop_Add32,
   2304                                        load(Ity_I32, mkexpr(addr)),
   2305                                        mkU32(1)));
   2306                      mips_irgen_load_and_add32(addr, new, regRd, True);
   2307                      break;
   2308                   }
   2309                   /* Load Atomic Increment Doubleword - LAID; Cavium OCTEON2 */
   2310                   case 0x03: {
   2311                      DIP("laid r%u,(r%u)\n", regRd, regRs);
   2312                      IRTemp new  = newTemp(Ity_I64);
   2313                      assign(addr, getIReg(regRs));
   2314                      assign(new, binop(Iop_Add64,
   2315                                        load(Ity_I64, mkexpr(addr)),
   2316                                        mkU64(1)));
   2317                      mips_irgen_load_and_add64(addr, new, regRd, True);
   2318                      break;
   2319                   }
   2320                   /* Load Atomic Decrement Word - LAD; Cavium OCTEON2 */
   2321                   case 0x06: {
   2322                      DIP("lad r%u,(r%u)\n", regRd, regRs);
   2323                      IRTemp new  = newTemp(Ity_I32);
   2324                      assign(addr, getIReg(regRs));
   2325                      assign(new, binop(Iop_Sub32,
   2326                                        load(Ity_I32, mkexpr(addr)),
   2327                                        mkU32(1)));
   2328                      mips_irgen_load_and_add32(addr, new, regRd, True);
   2329                      break;
   2330                   }
   2331                   /* Load Atomic Decrement Doubleword - LADD; Cavium OCTEON2 */
   2332                   case 0x07: {
   2333                      DIP("ladd r%u,(r%u)\n", regRd, regRs);
   2334                      IRTemp new  = newTemp(Ity_I64);
   2335                      assign (addr, getIReg(regRs));
   2336                      assign(new, binop(Iop_Sub64,
   2337                                        load(Ity_I64, mkexpr(addr)),
   2338                                        mkU64(1)));
   2339                      mips_irgen_load_and_add64(addr, new, regRd, True);
   2340                      break;
   2341                   }
   2342                   /* Load Atomic Set Word - LAS; Cavium OCTEON2 */
   2343                   case 0x0a: {
   2344                      DIP("las r%u,(r%u)\n", regRd, regRs);
   2345                      IRTemp new  = newTemp(Ity_I32);
   2346                      assign(addr, getIReg(regRs));
   2347                      assign(new, mkU32(0xffffffff));
   2348                      mips_irgen_load_and_add32(addr, new, regRd, True);
   2349                      break;
   2350                   }
   2351                   /* Load Atomic Set Doubleword - LASD; Cavium OCTEON2 */
   2352                   case 0x0b: {
   2353                      DIP("lasd r%u,(r%u)\n", regRd, regRs);
   2354                      IRTemp new  = newTemp(Ity_I64);
   2355                      assign (addr, getIReg(regRs));
   2356                      assign(new, mkU64(0xffffffffffffffffULL));
   2357                      mips_irgen_load_and_add64(addr, new, regRd, True);
   2358                      break;
   2359                   }
   2360                   /* Load Atomic Clear Word - LAC; Cavium OCTEON2 */
   2361                   case 0x0e: {
   2362                      DIP("lac r%u,(r%u)\n", regRd, regRs);
   2363                      IRTemp new  = newTemp(Ity_I32);
   2364                      assign (addr, getIReg(regRs));
   2365                      assign(new, mkU32(0));
   2366                      mips_irgen_load_and_add32(addr, new, regRd, True);
   2367                      break;
   2368                   }
   2369                   /* Load Atomic Clear Doubleword - LACD; Cavium OCTEON2 */
   2370                   case 0x0f: {
   2371                      DIP("lacd r%u,(r%u)\n", regRd, regRs);
   2372                      IRTemp new  = newTemp(Ity_I64);
   2373                      assign(addr, getIReg(regRs));
   2374                      assign(new, mkU64(0));
   2375                      mips_irgen_load_and_add64(addr, new, regRd, True);
   2376                      break;
   2377                   }
   2378                   /* Load Atomic Add Word - LAA; Cavium OCTEON2 */
   2379                   case 0x12: {
   2380                      DIP("laa r%u,(r%u),r%u\n", regRd, regRs, regRt);
   2381                      IRTemp new  = newTemp(Ity_I32);
   2382                      assign(addr, getIReg(regRs));
   2383                      assign(new, binop(Iop_Add32,
   2384                                        load(Ity_I32, mkexpr(addr)),
   2385                                        mkNarrowTo32(ty, getIReg(regRt))));
   2386                      mips_irgen_load_and_add32(addr, new, regRd, True);
   2387                      break;
   2388                   }
   2389                   /* Load Atomic Add Doubleword - LAAD; Cavium OCTEON2 */
   2390                   case 0x13: {
   2391                      DIP("laad r%u,(r%u),r%u\n", regRd, regRs, regRt);
   2392                      IRTemp new  = newTemp(Ity_I64);
   2393                      assign (addr, getIReg(regRs));
   2394                      assign(new, binop(Iop_Add64,
   2395                                        load(Ity_I64, mkexpr(addr)),
   2396                                        getIReg(regRt)));
   2397                      mips_irgen_load_and_add64(addr, new, regRd, True);
   2398                      break;
   2399                   }
   2400                   /* Load Atomic Swap Word - LAW; Cavium OCTEON2 */
   2401                   case 0x16: {
   2402                      DIP("law r%u,(r%u)\n", regRd, regRs);
   2403                      IRTemp new  = newTemp(Ity_I32);
   2404                      assign(addr, getIReg(regRs));
   2405                      assign(new, mkNarrowTo32(ty, getIReg(regRt)));
   2406                      mips_irgen_load_and_add32(addr, new, regRd, True);
   2407                      break;
   2408                   }
   2409                   /* Load Atomic Swap Doubleword - LAWD; Cavium OCTEON2 */
   2410                   case 0x17: {
   2411                      DIP("lawd r%u,(r%u)\n", regRd, regRs);
   2412                      IRTemp new  = newTemp(Ity_I64);
   2413                      assign(addr, getIReg(regRs));
   2414                      assign(new, getIReg(regRt));
   2415                      mips_irgen_load_and_add64(addr, new, regRd, True);
   2416                      break;
   2417                   }
   2418                   default:
   2419                      vex_printf("Unknown laxx instruction, opc3=0x%x\n", opc3);
   2420                      vex_printf("Instruction=0x%08x\n", theInstr);
   2421                      return False;
   2422                }
   2423                break;
   2424             }
   2425 
   2426             /* Unsigned Byte Add - BADDU rd, rs, rt; Cavium OCTEON */
   2427             case 0x28: {
   2428                DIP("BADDU r%u, r%u, r%u", regRs, regRt, regRd);
   2429                IRTemp t0 = newTemp(Ity_I8);
   2430 
   2431                assign(t0, binop(Iop_Add8,
   2432                                 mkNarrowTo8(ty, getIReg(regRs)),
   2433                                 mkNarrowTo8(ty, getIReg(regRt))));
   2434 
   2435                if (mode64)
   2436                   putIReg(regRd, binop(mkSzOp(ty, Iop_And8),
   2437                                        unop(Iop_8Uto64, mkexpr(t0)),
   2438                                        mkSzImm(ty, 0xFF)));
   2439                else
   2440                   putIReg(regRd, binop(mkSzOp(ty, Iop_And8),
   2441                                        unop(Iop_8Uto32, mkexpr(t0)),
   2442                                        mkSzImm(ty, 0xFF)));
   2443                break;
   2444             }
   2445 
   2446             case 0x2c: {  /* Count Ones in a Word - POP; Cavium OCTEON */
   2447                int i, shift[5];
   2448                IRTemp mask[5];
   2449                IRTemp old = newTemp(ty);
   2450                IRTemp nyu = IRTemp_INVALID;
   2451                assign(old, getIReg(regRs));
   2452                DIP("pop r%u, r%u", regRd, regRs);
   2453 
   2454                for (i = 0; i < 5; i++) {
   2455                   mask[i] = newTemp(ty);
   2456                   shift[i] = 1 << i;
   2457                }
   2458                if(mode64) {
   2459                   assign(mask[0], mkU64(0x0000000055555555));
   2460                   assign(mask[1], mkU64(0x0000000033333333));
   2461                   assign(mask[2], mkU64(0x000000000F0F0F0F));
   2462                   assign(mask[3], mkU64(0x0000000000FF00FF));
   2463                   assign(mask[4], mkU64(0x000000000000FFFF));
   2464 
   2465                   for (i = 0; i < 5; i++) {
   2466                      nyu = newTemp(ty);
   2467                      assign(nyu,
   2468                             binop(Iop_Add64,
   2469                                   binop(Iop_And64,
   2470                                         mkexpr(old), mkexpr(mask[i])),
   2471                                   binop(Iop_And64,
   2472                                         binop(Iop_Shr64,
   2473                                               mkexpr(old), mkU8(shift[i])),
   2474                                         mkexpr(mask[i]))));
   2475                      old = nyu;
   2476                   }
   2477                } else {
   2478                   assign(mask[0], mkU32(0x55555555));
   2479                   assign(mask[1], mkU32(0x33333333));
   2480                   assign(mask[2], mkU32(0x0F0F0F0F));
   2481                   assign(mask[3], mkU32(0x00FF00FF));
   2482                   assign(mask[4], mkU32(0x0000FFFF));
   2483                   assign(old, getIReg(regRs));
   2484 
   2485                   for (i = 0; i < 5; i++) {
   2486                      nyu = newTemp(ty);
   2487                      assign(nyu,
   2488                             binop(Iop_Add32,
   2489                                   binop(Iop_And32,
   2490                                         mkexpr(old), mkexpr(mask[i])),
   2491                                   binop(Iop_And32,
   2492                                         binop(Iop_Shr32,
   2493                                               mkexpr(old), mkU8(shift[i])),
   2494                                         mkexpr(mask[i]))));
   2495                      old = nyu;
   2496                   }
   2497                }
   2498                putIReg(regRd, mkexpr(nyu));
   2499                break;
   2500             }
   2501 
   2502             /* Count Ones in a Doubleword - DPOP; Cavium OCTEON */
   2503             case 0x2d: {
   2504                int i, shift[6];
   2505                IRTemp mask[6];
   2506                IRTemp old = newTemp(ty);
   2507                IRTemp nyu = IRTemp_INVALID;
   2508                DIP("dpop r%u, r%u", regRd, regRs);
   2509 
   2510                for (i = 0; i < 6; i++) {
   2511                   mask[i] = newTemp(ty);
   2512                   shift[i] = 1 << i;
   2513                }
   2514                vassert(mode64); /*Caution! Only for Mode 64*/
   2515                assign(mask[0], mkU64(0x5555555555555555ULL));
   2516                assign(mask[1], mkU64(0x3333333333333333ULL));
   2517                assign(mask[2], mkU64(0x0F0F0F0F0F0F0F0FULL));
   2518                assign(mask[3], mkU64(0x00FF00FF00FF00FFULL));
   2519                assign(mask[4], mkU64(0x0000FFFF0000FFFFULL));
   2520                assign(mask[5], mkU64(0x00000000FFFFFFFFULL));
   2521                assign(old, getIReg(regRs));
   2522                for (i = 0; i < 6; i++) {
   2523                   nyu = newTemp(Ity_I64);
   2524                   assign(nyu,
   2525                          binop(Iop_Add64,
   2526                                binop(Iop_And64,
   2527                                      mkexpr(old), mkexpr(mask[i])),
   2528                                binop(Iop_And64,
   2529                                      binop(Iop_Shr64,
   2530                                            mkexpr(old), mkU8(shift[i])),
   2531                                      mkexpr(mask[i]))));
   2532                   old = nyu;
   2533                }
   2534                putIReg(regRd, mkexpr(nyu));
   2535                break;
   2536             }
   2537 
   2538             case 0x32:  /* 5. CINS rd, rs, p, lenm1 */
   2539                DIP("cins r%u, r%u, %u, %u\n", regRt, regRs, p, lenM1);
   2540                assign ( tmp  , binop(Iop_Shl64, mkexpr(tmpRs),
   2541                                      mkU8(64-( lenM1+1 ))));
   2542                assign ( tmpRt, binop(Iop_Shr64, mkexpr( tmp ),
   2543                                      mkU8(64-(p+lenM1+1))));
   2544                putIReg( regRt, mkexpr(tmpRt));
   2545                break;
   2546 
   2547             case 0x33:  /* 6. CINS32 rd, rs, p+32, lenm1 */
   2548                DIP("cins32 r%u, r%u, %d, %d\n", regRt, regRs, p+32, lenM1);
   2549                assign ( tmp  , binop(Iop_Shl64, mkexpr(tmpRs),
   2550                                      mkU8(64-( lenM1+1 ))));
   2551                assign ( tmpRt, binop(Iop_Shr64, mkexpr( tmp ),
   2552                                      mkU8(32-(p+lenM1+1))));
   2553                putIReg( regRt, mkexpr(tmpRt));
   2554                break;
   2555 
   2556             case 0x3A:  /* 3. EXTS rt, rs, p len */
   2557                DIP("exts r%u, r%u, %d, %d\n", regRt, regRs, p, lenM1);
   2558                size = lenM1 + 1;  /* lenm1+1 */
   2559                UChar lsAmt = 64 - (p + size);  /* p+lenm1+1 */
   2560                UChar rsAmt = 64 - size;  /* lenm1+1 */
   2561                tmp = newTemp(Ity_I64);
   2562                assign(tmp, binop(Iop_Shl64, mkexpr(tmpRs), mkU8(lsAmt)));
   2563                putIReg(regRt, binop(Iop_Sar64, mkexpr(tmp), mkU8(rsAmt)));
   2564                break;
   2565 
   2566             case 0x3B:  /* 4. EXTS32 rt, rs, p len */
   2567                DIP("exts32 r%u, r%u, %d, %d\n", regRt, regRs, p, lenM1);
   2568                assign ( tmp  , binop(Iop_Shl64, mkexpr(tmpRs),
   2569                                      mkU8(32-(p+lenM1+1))));
   2570                assign ( tmpRt, binop(Iop_Sar64, mkexpr(tmp),
   2571                                      mkU8(64-(lenM1+1))) );
   2572                putIReg( regRt, mkexpr(tmpRt));
   2573                break;
   2574 
   2575             case 0x2B:  /* 20. SNE rd, rs, rt */
   2576                DIP("sne r%u, r%u, r%u", regRd,regRs, regRt);
   2577                if (mode64)
   2578                   putIReg(regRd, unop(Iop_1Uto64, binop(Iop_CmpNE64,
   2579                                                         getIReg(regRs),
   2580                                                         getIReg(regRt))));
   2581                else
   2582                   putIReg(regRd,unop(Iop_1Uto32, binop(Iop_CmpNE32,
   2583                                                        getIReg(regRs),
   2584                                                        getIReg(regRt))));
   2585                break;
   2586 
   2587             case 0x2A:  /* Set Equals - SEQ; Cavium OCTEON */
   2588                DIP("seq r%u, r%u, %d", regRd, regRs, regRt);
   2589                if (mode64)
   2590                   putIReg(regRd, unop(Iop_1Uto64,
   2591                                       binop(Iop_CmpEQ64, getIReg(regRs),
   2592                                             getIReg(regRt))));
   2593                else
   2594                   putIReg(regRd, unop(Iop_1Uto32,
   2595                                       binop(Iop_CmpEQ32, getIReg(regRs),
   2596                                             getIReg(regRt))));
   2597                break;
   2598 
   2599             case 0x2E:  /* Set Equals Immediate - SEQI; Cavium OCTEON */
   2600                DIP("seqi r%u, r%u, %u", regRt, regRs, imm);
   2601                if (mode64)
   2602                   putIReg(regRt, unop(Iop_1Uto64,
   2603                                       binop(Iop_CmpEQ64, getIReg(regRs),
   2604                                             mkU64(extend_s_10to64(imm)))));
   2605                else
   2606                   putIReg(regRt, unop(Iop_1Uto32,
   2607                                       binop(Iop_CmpEQ32, getIReg(regRs),
   2608                                             mkU32(extend_s_10to32(imm)))));
   2609                break;
   2610 
   2611             case 0x2F:  /* Set Not Equals Immediate - SNEI; Cavium OCTEON */
   2612                DIP("snei r%u, r%u, %u", regRt, regRs, imm);
   2613                if (mode64)
   2614                   putIReg(regRt, unop(Iop_1Uto64,
   2615                                    binop(Iop_CmpNE64,
   2616                                          getIReg(regRs),
   2617                                          mkU64(extend_s_10to64(imm)))));
   2618                else
   2619                   putIReg(regRt, unop(Iop_1Uto32,
   2620                                    binop(Iop_CmpNE32,
   2621                                          getIReg(regRs),
   2622                                          mkU32(extend_s_10to32(imm)))));
   2623                break;
   2624 
   2625             default:
   2626                return False;
   2627          }
   2628          break;
   2629       } /* opc1 0x1C ends here*/
   2630       case 0x1F: {
   2631          switch(opc2) {
   2632             case 0x0A: {  // lx - Load indexed instructions
   2633                switch (get_sa(theInstr)) {
   2634                   case 0x00: {  // LWX rd, index(base)
   2635                      DIP("lwx r%u, r%u(r%u)", regRd, regRt, regRs);
   2636                      LOADX_STORE_PATTERN;
   2637                      putIReg(regRd, mkWidenFrom32(ty, load(Ity_I32, mkexpr(t1)),
   2638                                                   True));
   2639                      break;
   2640                   }
   2641                   case 0x04:  // LHX rd, index(base)
   2642                      DIP("lhx r%u, r%u(r%u)", regRd, regRt, regRs);
   2643                      LOADX_STORE_PATTERN;
   2644                      if (mode64)
   2645                         putIReg(regRd, unop(Iop_16Sto64, load(Ity_I16,
   2646                                                               mkexpr(t1))));
   2647                      else
   2648                         putIReg(regRd, unop(Iop_16Sto32, load(Ity_I16,
   2649                                                               mkexpr(t1))));
   2650                      break;
   2651                   case 0x08: {  // LDX rd, index(base)
   2652                      DIP("ldx r%u, r%u(r%u)", regRd, regRt, regRs);
   2653                      vassert(mode64); /* Currently Implemented only for n64 */
   2654                      LOADX_STORE_PATTERN;
   2655                      putIReg(regRd, load(Ity_I64, mkexpr(t1)));
   2656                      break;
   2657                   }
   2658                   case 0x06: {  // LBUX rd, index(base)
   2659                      DIP("lbux r%u, r%u(r%u)", regRd, regRt, regRs);
   2660                      LOADX_STORE_PATTERN;
   2661                      if (mode64)
   2662                         putIReg(regRd, unop(Iop_8Uto64, load(Ity_I8,
   2663                                                              mkexpr(t1))));
   2664                      else
   2665                         putIReg(regRd, unop(Iop_8Uto32, load(Ity_I8,
   2666                                                              mkexpr(t1))));
   2667                      break;
   2668                   }
   2669                   case 0x10: {  // LWUX rd, index(base) (Cavium OCTEON)
   2670                      DIP("lwux r%u, r%u(r%u)", regRd, regRt, regRs);
   2671                      LOADX_STORE_PATTERN; /* same for both 32 and 64 modes*/
   2672                      putIReg(regRd, mkWidenFrom32(ty, load(Ity_I32, mkexpr(t1)),
   2673                                                   False));
   2674                      break;
   2675                   }
   2676                   case 0x14: {  // LHUX rd, index(base) (Cavium OCTEON)
   2677                      DIP("lhux r%u, r%u(r%u)", regRd, regRt, regRs);
   2678                      LOADX_STORE_PATTERN;
   2679                      if (mode64)
   2680                         putIReg(regRd,
   2681                                 unop(Iop_16Uto64, load(Ity_I16, mkexpr(t1))));
   2682                      else
   2683                         putIReg(regRd,
   2684                                 unop(Iop_16Uto32, load(Ity_I16, mkexpr(t1))));
   2685                      break;
   2686                   }
   2687                   case 0x16: {  // LBX rd, index(base) (Cavium OCTEON)
   2688                      DIP("lbx r%u, r%u(r%u)", regRd, regRs, regRt);
   2689                      LOADX_STORE_PATTERN;
   2690                      if (mode64)
   2691                         putIReg(regRd,
   2692                                 unop(Iop_8Sto64, load(Ity_I8, mkexpr(t1))));
   2693                      else
   2694                         putIReg(regRd,
   2695                                 unop(Iop_8Sto32, load(Ity_I8, mkexpr(t1))));
   2696                      break;
   2697                   }
   2698                   default:
   2699                      vex_printf("\nUnhandled LX instruction opc3 = %x\n",
   2700                                 get_sa(theInstr));
   2701                      return False;
   2702                }
   2703                break;
   2704             }
   2705          } /* opc1 = 0x1F & opc2 = 0xA (LX) ends here*/
   2706          break;
   2707       } /* opc1 = 0x1F ends here*/
   2708       default:
   2709          return False;
   2710    } /* main opc1 switch ends here */
   2711    return True;
   2712 }
   2713 
   2714 /*------------------------------------------------------------*/
   2715 /*---       Disassemble a single DSP ASE instruction       ---*/
   2716 /*------------------------------------------------------------*/
   2717 
   2718 static UInt disDSPInstr_MIPS_WRK ( UInt cins )
   2719 {
   2720    IRTemp t0, t1 = 0, t2, t3, t4, t5, t6, t7, t8, t9, t10, t11, t12, t13, t14,
   2721           t15, t16, t17;
   2722    UInt opcode, rs, rt, rd, sa, function, ac, ac_mfhilo, rddsp_mask,
   2723         wrdsp_mask, dsp_imm, shift;
   2724 
   2725    opcode = get_opcode(cins);
   2726    rs = get_rs(cins);
   2727    rt = get_rt(cins);
   2728    rd = get_rd(cins);
   2729    sa = get_sa(cins);
   2730    function = get_function(cins);
   2731    ac = get_acNo(cins);
   2732    ac_mfhilo = get_acNo_mfhilo(cins);
   2733    rddsp_mask = get_rddspMask(cins);
   2734    wrdsp_mask = get_wrdspMask(cins);
   2735    dsp_imm = get_dspImm(cins);
   2736    shift = get_shift(cins);
   2737 
   2738    switch (opcode) {
   2739       case 0x00: {  /* Special */
   2740          switch (function) {
   2741             case 0x10: {  /* MFHI */
   2742                DIP("mfhi ac%u r%u", ac_mfhilo, rd);
   2743                putIReg(rd, unop(Iop_64HIto32, getAcc(ac_mfhilo)));
   2744                break;
   2745             }
   2746 
   2747             case 0x11: {  /* MTHI */
   2748                DIP("mthi ac%u r%u", ac, rs);
   2749                t1 = newTemp(Ity_I32);
   2750                assign(t1, unop(Iop_64to32, getAcc(ac)));
   2751                putAcc(ac, binop(Iop_32HLto64, getIReg(rs), mkexpr(t1)));
   2752                break;
   2753             }
   2754 
   2755             case 0x12: {  /* MFLO */
   2756                DIP("mflo ac%u r%u", ac_mfhilo, rd);
   2757                putIReg(rd, unop(Iop_64to32, getAcc(ac_mfhilo)));
   2758                break;
   2759             }
   2760 
   2761             case 0x13: {  /* MTLO */
   2762                DIP("mtlo ac%u r%u", ac, rs);
   2763                t1 = newTemp(Ity_I32);
   2764                assign(t1, unop(Iop_64HIto32, getAcc(ac)));
   2765                putAcc(ac, binop(Iop_32HLto64, mkexpr(t1), getIReg(rs)));
   2766                break;
   2767             }
   2768 
   2769             case 0x18: {  /* MULT */
   2770                DIP("mult ac%u r%u, r%u", ac, rs, rt);
   2771                t1 = newTemp(Ity_I64);
   2772                assign(t1, binop(Iop_MullS32, mkNarrowTo32(Ity_I32, getIReg(rs)),
   2773                                 mkNarrowTo32(Ity_I32, getIReg(rt))));
   2774                putAcc(ac, mkexpr(t1));
   2775                break;
   2776             }
   2777 
   2778             case 0x19: {  /* MULTU */
   2779                DIP("multu ac%u r%u, r%u", ac, rs, rt);
   2780                t1 = newTemp(Ity_I64);
   2781                assign(t1, binop(Iop_MullU32, mkNarrowTo32(Ity_I32, getIReg(rs)),
   2782                                              mkNarrowTo32(Ity_I32,
   2783                                                           getIReg(rt))));
   2784                putAcc(ac, mkexpr(t1));
   2785             break;
   2786             }
   2787          }
   2788          break;
   2789       }
   2790       case 0x1C: {  /* Special2 */
   2791          switch (function) {
   2792             case 0x00: {  /* MADD */
   2793                DIP("madd ac%u, r%u, r%u", ac, rs, rt);
   2794                t1 = newTemp(Ity_I64);
   2795                t2 = newTemp(Ity_I64);
   2796                t3 = newTemp(Ity_I64);
   2797 
   2798                assign(t1, getAcc(ac));
   2799                assign(t2, binop(Iop_MullS32, getIReg(rs), getIReg(rt)));
   2800                assign(t3, binop(Iop_Add64, mkexpr(t1), mkexpr(t2)));
   2801 
   2802                putAcc(ac, mkexpr(t3));
   2803                break;
   2804             }
   2805             case 0x01: {  /* MADDU */
   2806                DIP("maddu ac%u r%u, r%u", ac, rs, rt);
   2807                t1 = newTemp(Ity_I64);
   2808                t2 = newTemp(Ity_I64);
   2809                t3 = newTemp(Ity_I64);
   2810 
   2811                assign(t1, getAcc(ac));
   2812                assign(t2, binop(Iop_MullU32, getIReg(rs), getIReg(rt)));
   2813                assign(t3, binop(Iop_Add64, mkexpr(t2), mkexpr(t1)));
   2814 
   2815                putAcc(ac, mkexpr(t3));
   2816                break;
   2817             }
   2818             case 0x04: {  /* MSUB */
   2819                DIP("msub ac%u r%u, r%u", ac, rs, rt);
   2820                t1 = newTemp(Ity_I64);
   2821                t2 = newTemp(Ity_I64);
   2822                t3 = newTemp(Ity_I64);
   2823 
   2824                assign(t1, getAcc(ac));
   2825                assign(t2, binop(Iop_MullS32, getIReg(rs), getIReg(rt)));
   2826                assign(t3, binop(Iop_Sub64, mkexpr(t1), mkexpr(t2)));
   2827 
   2828                putAcc(ac, mkexpr(t3));
   2829                break;
   2830             }
   2831             case 0x05: {  /* MSUBU */
   2832                DIP("msubu ac%u r%u, r%u", ac, rs, rt);
   2833                t1 = newTemp(Ity_I64);
   2834                t2 = newTemp(Ity_I64);
   2835                t3 = newTemp(Ity_I64);
   2836 
   2837                assign(t1, getAcc(ac));
   2838                assign(t2, binop(Iop_MullU32, getIReg(rs), getIReg(rt)));
   2839                assign(t3, binop(Iop_Sub64, mkexpr(t1), mkexpr(t2)));
   2840 
   2841                putAcc(ac, mkexpr(t3));
   2842                break;
   2843             }
   2844          }
   2845          break;
   2846       }
   2847       case 0x1F: {  /* Special3 */
   2848          switch (function) {
   2849             case 0x12: {  /* ABSQ_S.PH */
   2850                switch (sa) {
   2851                   case 0x1: {  /* ABSQ_S.QB */
   2852                      DIP("absq_s.qb r%u, r%u", rd, rt);
   2853                      vassert(!mode64);
   2854                      t0 = newTemp(Ity_I8);
   2855                      t1 = newTemp(Ity_I1);
   2856                      t2 = newTemp(Ity_I1);
   2857                      t3 = newTemp(Ity_I8);
   2858                      t4 = newTemp(Ity_I8);
   2859                      t5 = newTemp(Ity_I1);
   2860                      t6 = newTemp(Ity_I1);
   2861                      t7 = newTemp(Ity_I8);
   2862                      t8 = newTemp(Ity_I8);
   2863                      t9 = newTemp(Ity_I1);
   2864                      t10 = newTemp(Ity_I1);
   2865                      t11 = newTemp(Ity_I8);
   2866                      t12 = newTemp(Ity_I8);
   2867                      t13 = newTemp(Ity_I1);
   2868                      t14 = newTemp(Ity_I1);
   2869                      t15 = newTemp(Ity_I8);
   2870                      t16 = newTemp(Ity_I32);
   2871                      t17 = newTemp(Ity_I32);
   2872 
   2873                      /* Absolute value of the rightmost byte (bits 7-0). */
   2874                      /* t0 - rightmost byte. */
   2875                      assign(t0, unop(Iop_16to8, unop(Iop_32to16, getIReg(rt))));
   2876                      /* t1 holds 1 if t0 is equal to 0x80, or 0 otherwise. */
   2877                      assign(t1, binop(Iop_CmpEQ32,
   2878                                       unop(Iop_8Uto32, mkexpr(t0)),
   2879                                       mkU32(0x00000080)));
   2880                      /* t2 holds 1 if value in t0 is negative, 0 otherwise. */
   2881                      assign(t2, unop(Iop_32to1,
   2882                                      binop(Iop_Shr32,
   2883                                            binop(Iop_And32,
   2884                                                  getIReg(rt),
   2885                                                  mkU32(0x00000080)),
   2886                                            mkU8(0x7))));
   2887                      /* t3 holds abs(t0). */
   2888                      assign(t3, IRExpr_ITE(mkexpr(t1),
   2889                                            mkU8(0x7F),
   2890                                            IRExpr_ITE(mkexpr(t2),
   2891                                                       binop(Iop_Add8,
   2892                                                             unop(Iop_Not8,
   2893                                                                  mkexpr(t0)),
   2894                                                             mkU8(0x1)),
   2895                                                       mkexpr(t0))));
   2896 
   2897                      /* Absolute value of bits 15-8. */
   2898                      /* t4 - input byte. */
   2899                      assign(t4,
   2900                             unop(Iop_16HIto8, unop(Iop_32to16, getIReg(rt))));
   2901                      /* t5 holds 1 if t4 is equal to 0x80, or 0 otherwise. */
   2902                      assign(t5, binop(Iop_CmpEQ32,
   2903                                       unop(Iop_8Uto32, mkexpr(t4)),
   2904                                       mkU32(0x00000080)));
   2905                      /* t6 holds 1 if value in t4 is negative, 0 otherwise. */
   2906                      assign(t6, unop(Iop_32to1,
   2907                                      binop(Iop_Shr32,
   2908                                            binop(Iop_And32,
   2909                                                  getIReg(rt),
   2910                                                  mkU32(0x00008000)),
   2911                                            mkU8(15))));
   2912                      /* t3 holds abs(t4). */
   2913                      assign(t7, IRExpr_ITE(mkexpr(t5),
   2914                                            mkU8(0x7F),
   2915                                            IRExpr_ITE(mkexpr(t6),
   2916                                                       binop(Iop_Add8,
   2917                                                             unop(Iop_Not8,
   2918                                                                  mkexpr(t4)),
   2919                                                             mkU8(0x1)),
   2920                                                       mkexpr(t4))));
   2921 
   2922                      /* Absolute value of bits 23-15. */
   2923                      /* t8 - input byte. */
   2924                      assign(t8,
   2925                             unop(Iop_16to8, unop(Iop_32HIto16, getIReg(rt))));
   2926                      /* t9 holds 1 if t8 is equal to 0x80, or 0 otherwise. */
   2927                      assign(t9, binop(Iop_CmpEQ32,
   2928                                       unop(Iop_8Uto32, mkexpr(t8)),
   2929                                       mkU32(0x00000080)));
   2930                      /* t6 holds 1 if value in t8 is negative, 0 otherwise. */
   2931                      assign(t10, unop(Iop_32to1,
   2932                                       binop(Iop_Shr32,
   2933                                             binop(Iop_And32,
   2934                                                   getIReg(rt),
   2935                                                   mkU32(0x00800000)),
   2936                                             mkU8(23))));
   2937                      /* t3 holds abs(t8). */
   2938                      assign(t11, IRExpr_ITE(mkexpr(t9),
   2939                                             mkU8(0x7F),
   2940                                             IRExpr_ITE(mkexpr(t10),
   2941                                                        binop(Iop_Add8,
   2942                                                              unop(Iop_Not8,
   2943                                                                   mkexpr(t8)),
   2944                                                              mkU8(0x1)),
   2945                                                        mkexpr(t8))));
   2946 
   2947                      /* Absolute value of bits 31-24. */
   2948                      /* t12 - input byte. */
   2949                      assign(t12,
   2950                             unop(Iop_16HIto8, unop(Iop_32HIto16, getIReg(rt))));
   2951                      /* t13 holds 1 if t12 is equal to 0x80, or 0 otherwise. */
   2952                      assign(t13, binop(Iop_CmpEQ32,
   2953                                        unop(Iop_8Uto32, mkexpr(t12)),
   2954                                        mkU32(0x00000080)));
   2955                      /* t14 holds 1 if value in t12 is negative, 0 otherwise. */
   2956                      assign(t14, unop(Iop_32to1,
   2957                                       binop(Iop_Shr32,
   2958                                             binop(Iop_And32,
   2959                                                   getIReg(rt),
   2960                                                   mkU32(0x80000000)),
   2961                                             mkU8(31))));
   2962                      /* t15 holds abs(t12). */
   2963                      assign(t15, IRExpr_ITE(mkexpr(t13),
   2964                                             mkU8(0x7F),
   2965                                             IRExpr_ITE(mkexpr(t14),
   2966                                                        binop(Iop_Add8,
   2967                                                              unop(Iop_Not8,
   2968                                                                   mkexpr(t12)),
   2969                                                              mkU8(0x1)),
   2970                                                        mkexpr(t12))));
   2971 
   2972                      /* t16 holds !0 if any of input bytes is 0x80 or 0
   2973                         otherwise. */
   2974                      assign(t16,
   2975                             binop(Iop_Or32,
   2976                                   binop(Iop_Or32,
   2977                                         binop(Iop_Or32,
   2978                                               unop(Iop_1Sto32, mkexpr(t13)),
   2979                                               unop(Iop_1Sto32, mkexpr(t9))),
   2980                                         unop(Iop_1Sto32, mkexpr(t5))),
   2981                                   unop(Iop_1Sto32, mkexpr(t1))));
   2982 
   2983                      putDSPControl(IRExpr_ITE(binop(Iop_CmpEQ32,
   2984                                                     mkexpr(t16),
   2985                                                     mkU32(0x0)),
   2986                                               getDSPControl(),
   2987                                               binop(Iop_Or32,
   2988                                                     getDSPControl(),
   2989                                                     mkU32(0x00100000))));
   2990 
   2991                      /* t17 = t15|t11|t7|t3 */
   2992                      assign(t17,
   2993                             binop(Iop_16HLto32,
   2994                                   binop(Iop_8HLto16, mkexpr(t15), mkexpr(t11)),
   2995                                   binop(Iop_8HLto16, mkexpr(t7), mkexpr(t3))));
   2996 
   2997                      putIReg(rd, mkexpr(t17));
   2998                      break;
   2999                   }
   3000                   case 0x2: {  /* REPL.QB */
   3001                      DIP("repl.qb r%u, %u", rd, dsp_imm);
   3002                      vassert(!mode64);
   3003 
   3004                      putIReg(rd, mkU32((dsp_imm << 24) | (dsp_imm << 16) |
   3005                                        (dsp_imm << 8) | (dsp_imm)));
   3006                      break;
   3007                   }
   3008                   case 0x3: {  /* REPLV.QB */
   3009                      DIP("replv.qb r%u, r%u", rd, rt);
   3010                      vassert(!mode64);
   3011                      t0 = newTemp(Ity_I8);
   3012 
   3013                      assign(t0, unop(Iop_32to8,
   3014                                 binop(Iop_And32, getIReg(rt), mkU32(0xff))));
   3015                      putIReg(rd,
   3016                              binop(Iop_16HLto32,
   3017                                    binop(Iop_8HLto16, mkexpr(t0), mkexpr(t0)),
   3018                                    binop(Iop_8HLto16, mkexpr(t0), mkexpr(t0))));
   3019                      break;
   3020                   }
   3021                   case 0x4: {  /* PRECEQU.PH.QBL */
   3022                      DIP("precequ.ph.qbl r%u, r%u", rd, rt);
   3023                      vassert(!mode64);
   3024 
   3025                      putIReg(rd, binop(Iop_Or32,
   3026                                        binop(Iop_Shr32,
   3027                                              binop(Iop_And32,
   3028                                                    getIReg(rt),
   3029                                                    mkU32(0xff000000)),
   3030                                              mkU8(1)),
   3031                                        binop(Iop_Shr32,
   3032                                              binop(Iop_And32,
   3033                                                    getIReg(rt),
   3034                                                    mkU32(0x00ff0000)),
   3035                                              mkU8(9))));
   3036                      break;
   3037                   }
   3038                   case 0x5: {  /* PRECEQU.PH.QBR */
   3039                      DIP("precequ.ph.qbr r%u, r%u", rd, rt);
   3040                      vassert(!mode64);
   3041 
   3042                      putIReg(rd, binop(Iop_Or32,
   3043                                        binop(Iop_Shl32,
   3044                                              binop(Iop_And32,
   3045                                                    getIReg(rt),
   3046                                                    mkU32(0x0000ff00)),
   3047                                              mkU8(15)),
   3048                                        binop(Iop_Shl32,
   3049                                              binop(Iop_And32,
   3050                                                    getIReg(rt),
   3051                                                    mkU32(0x000000ff)),
   3052                                              mkU8(7))));
   3053                      break;
   3054                   }
   3055                   case 0x6: {  /* PRECEQU.PH.QBLA */
   3056                      DIP("precequ.ph.qbla r%u, r%u", rd, rt);
   3057                      vassert(!mode64);
   3058 
   3059                      putIReg(rd, binop(Iop_Or32,
   3060                                        binop(Iop_Shr32,
   3061                                              binop(Iop_And32,
   3062                                                    getIReg(rt),
   3063                                                    mkU32(0xff000000)),
   3064                                              mkU8(1)),
   3065                                        binop(Iop_Shr32,
   3066                                              binop(Iop_And32,
   3067                                                    getIReg(rt),
   3068                                                    mkU32(0x0000ff00)),
   3069                                              mkU8(1))));
   3070                      break;
   3071                   }
   3072                   case 0x7: {  /* PRECEQU.PH.QBRA */
   3073                      DIP("precequ.ph.qbra r%u, r%u", rd, rt);
   3074                      vassert(!mode64);
   3075 
   3076                      putIReg(rd, binop(Iop_Or32,
   3077                                        binop(Iop_Shl32,
   3078                                              binop(Iop_And32,
   3079                                                    getIReg(rt),
   3080                                                    mkU32(0x00ff0000)),
   3081                                              mkU8(7)),
   3082                                        binop(Iop_Shl32,
   3083                                              binop(Iop_And32,
   3084                                                    getIReg(rt),
   3085                                                    mkU32(0x000000ff)),
   3086                                              mkU8(7))));
   3087                      break;
   3088                   }
   3089                   case 0x9: {  /* ABSQ_S.PH */
   3090                      DIP("absq_s.ph r%u, r%u", rd, rt);
   3091                      vassert(!mode64);
   3092                      t0 = newTemp(Ity_I16);
   3093                      t1 = newTemp(Ity_I1);
   3094                      t2 = newTemp(Ity_I1);
   3095                      t3 = newTemp(Ity_I16);
   3096                      t4 = newTemp(Ity_I16);
   3097                      t5 = newTemp(Ity_I1);
   3098                      t6 = newTemp(Ity_I1);
   3099                      t7 = newTemp(Ity_I16);
   3100                      t8 = newTemp(Ity_I32);
   3101                      t9 = newTemp(Ity_I32);
   3102 
   3103                      /* t0 holds lower 16 bits of value in rt. */
   3104                      assign(t0, unop(Iop_32to16, getIReg(rt)));
   3105                      /* t1 holds 1 if t0 is equal to 0x8000. */
   3106                      assign(t1, binop(Iop_CmpEQ32,
   3107                                       unop(Iop_16Uto32, mkexpr(t0)),
   3108                                       mkU32(0x00008000)));
   3109                      /* t2 holds 1 if value in t0 is negative, 0 otherwise. */
   3110                      assign(t2, unop(Iop_32to1,
   3111                                      binop(Iop_Shr32,
   3112                                            binop(Iop_And32,
   3113                                                  getIReg(rt),
   3114                                                  mkU32(0x00008000)),
   3115                                            mkU8(15))));
   3116                      /* t3 holds abs(t0). */
   3117                      assign(t3, IRExpr_ITE(mkexpr(t1),
   3118                                            mkU16(0x7FFF),
   3119                                            IRExpr_ITE(mkexpr(t2),
   3120                                                       binop(Iop_Add16,
   3121                                                             unop(Iop_Not16,
   3122                                                                  mkexpr(t0)),
   3123                                                             mkU16(0x1)),
   3124                                                       mkexpr(t0))));
   3125 
   3126                      /* t4 holds lower 16 bits of value in rt. */
   3127                      assign(t4, unop(Iop_32HIto16, getIReg(rt)));
   3128                      /* t5 holds 1 if t4 is equal to 0x8000. */
   3129                      assign(t5, binop(Iop_CmpEQ32,
   3130                                       unop(Iop_16Uto32, mkexpr(t4)),
   3131                                       mkU32(0x00008000)));
   3132                      /* t6 holds 1 if value in t4 is negative, 0 otherwise. */
   3133                      assign(t6, unop(Iop_32to1,
   3134                                      binop(Iop_Shr32,
   3135                                            binop(Iop_And32,
   3136                                                  getIReg(rt),
   3137                                                  mkU32(0x80000000)),
   3138                                            mkU8(31))));
   3139                      /* t7 holds abs(t4). */
   3140                      assign(t7, IRExpr_ITE(mkexpr(t5),
   3141                                            mkU16(0x7FFF),
   3142                                            IRExpr_ITE(mkexpr(t6),
   3143                                                       binop(Iop_Add16,
   3144                                                             unop(Iop_Not16,
   3145                                                                  mkexpr(t4)),
   3146                                                             mkU16(0x1)),
   3147                                                       mkexpr(t4))));
   3148                      /* If any of the two input halfwords is equal 0x8000,
   3149                         set bit 20 in DSPControl register. */
   3150                      assign(t8, binop(Iop_Or32,
   3151                                       unop(Iop_1Sto32, mkexpr(t5)),
   3152                                       unop(Iop_1Sto32, mkexpr(t1))));
   3153 
   3154                      putDSPControl(IRExpr_ITE(binop(Iop_CmpEQ32,
   3155                                                     mkexpr(t8),
   3156                                                     mkU32(0x0)),
   3157                                               getDSPControl(),
   3158                                               binop(Iop_Or32,
   3159                                                     getDSPControl(),
   3160                                                     mkU32(0x00100000))));
   3161 
   3162                      /* t9 = t7|t3 */
   3163                      assign(t9, binop(Iop_16HLto32, mkexpr(t7), mkexpr(t3)));
   3164 
   3165                      putIReg(rd, mkexpr(t9));
   3166                      break;
   3167                   }
   3168                   case 0xA: {  /* REPL.PH */
   3169                      DIP("repl.ph r%u, %u", rd, dsp_imm);
   3170                      vassert(!mode64);
   3171                      UShort immediate = extend_s_10to16(dsp_imm);
   3172 
   3173                      putIReg(rd, mkU32(immediate << 16 | immediate));
   3174                      break;
   3175                   }
   3176                   case 0xB: {  /* REPLV.PH */
   3177                      DIP("replv.ph r%u, r%u", rd, rt);
   3178                      vassert(!mode64);
   3179 
   3180                      putIReg(rd, binop(Iop_16HLto32,
   3181                                        unop(Iop_32to16, getIReg(rt)),
   3182                                        unop(Iop_32to16, getIReg(rt))));
   3183                      break;
   3184                   }
   3185                   case 0xC: {  /* PRECEQ.W.PHL */
   3186                      DIP("preceq.w.phl r%u, r%u", rd, rt);
   3187                      vassert(!mode64);
   3188                      putIReg(rd, binop(Iop_And32,
   3189                                        getIReg(rt),
   3190                                        mkU32(0xffff0000)));
   3191                      break;
   3192                   }
   3193                   case 0xD: {  /* PRECEQ.W.PHR */
   3194                      DIP("preceq.w.phr r%u, r%u", rd, rt);
   3195                      vassert(!mode64);
   3196                      putIReg(rd, binop(Iop_16HLto32,
   3197                                        unop(Iop_32to16, getIReg(rt)),
   3198                                        mkU16(0x0)));
   3199                      break;
   3200                   }
   3201                   case 0x11: {  /* ABSQ_S.W */
   3202                      DIP("absq_s.w r%u, r%u", rd, rt);
   3203                      vassert(!mode64);
   3204                      t0 = newTemp(Ity_I1);
   3205                      t1 = newTemp(Ity_I1);
   3206                      t2 = newTemp(Ity_I32);
   3207 
   3208                      assign(t0,
   3209                             binop(Iop_CmpEQ32, getIReg(rt), mkU32(0x80000000)));
   3210 
   3211                      putDSPControl(IRExpr_ITE(mkexpr(t0),
   3212                                               binop(Iop_Or32,
   3213                                                     getDSPControl(),
   3214                                                     mkU32(0x00100000)),
   3215                                               getDSPControl()));
   3216 
   3217                      assign(t1, binop(Iop_CmpLT32S, getIReg(rt), mkU32(0x0)));
   3218 
   3219                      assign(t2, IRExpr_ITE(mkexpr(t0),
   3220                                            mkU32(0x7FFFFFFF),
   3221                                            IRExpr_ITE(mkexpr(t1),
   3222                                                       binop(Iop_Add32,
   3223                                                             unop(Iop_Not32,
   3224                                                                  getIReg(rt)),
   3225                                                             mkU32(0x1)),
   3226                                                       getIReg(rt))));
   3227                      putIReg(rd, mkexpr(t2));
   3228                      break;
   3229                   }
   3230                   case 0x1B: {  /* BITREV */
   3231                      DIP("bitrev r%u, r%u", rd, rt);
   3232                      vassert(!mode64);
   3233                      /* 32bit reversal as seen on Bit Twiddling Hacks site
   3234                         http://graphics.stanford.edu/~seander/bithacks.html
   3235                         section ReverseParallel */
   3236                      t1 = newTemp(Ity_I32);
   3237                      t2 = newTemp(Ity_I32);
   3238                      t3 = newTemp(Ity_I32);
   3239                      t4 = newTemp(Ity_I32);
   3240                      t5 = newTemp(Ity_I32);
   3241 
   3242                      assign(t1, binop(Iop_Or32,
   3243                                       binop(Iop_Shr32,
   3244                                             binop(Iop_And32,
   3245                                                   getIReg(rt),
   3246                                                   mkU32(0xaaaaaaaa)),
   3247                                             mkU8(0x1)),
   3248                                       binop(Iop_Shl32,
   3249                                             binop(Iop_And32,
   3250                                                   getIReg(rt),
   3251                                                   mkU32(0x55555555)),
   3252                                             mkU8(0x1))));
   3253                      assign(t2, binop(Iop_Or32,
   3254                                       binop(Iop_Shr32,
   3255                                             binop(Iop_And32,
   3256                                                   mkexpr(t1),
   3257                                                   mkU32(0xcccccccc)),
   3258                                             mkU8(0x2)),
   3259                                       binop(Iop_Shl32,
   3260                                             binop(Iop_And32,
   3261                                                   mkexpr(t1),
   3262                                                   mkU32(0x33333333)),
   3263                                             mkU8(0x2))));
   3264                      assign(t3, binop(Iop_Or32,
   3265                                       binop(Iop_Shr32,
   3266                                             binop(Iop_And32,
   3267                                                   mkexpr(t2),
   3268                                                   mkU32(0xf0f0f0f0)),
   3269                                             mkU8(0x4)),
   3270                                       binop(Iop_Shl32,
   3271                                             binop(Iop_And32,
   3272                                                   mkexpr(t2),
   3273                                                   mkU32(0x0f0f0f0f)),
   3274                                             mkU8(0x4))));
   3275                      assign(t4, binop(Iop_Or32,
   3276                                       binop(Iop_Shr32,
   3277                                             binop(Iop_And32,
   3278                                                   mkexpr(t3),
   3279                                                   mkU32(0xff00ff00)),
   3280                                             mkU8(0x8)),
   3281                                       binop(Iop_Shl32,
   3282                                             binop(Iop_And32,
   3283                                                   mkexpr(t3),
   3284                                                   mkU32(0x00ff00ff)),
   3285                                             mkU8(0x8))));
   3286                      assign(t5, binop(Iop_Or32,
   3287                                       binop(Iop_Shr32,
   3288                                             mkexpr(t4),
   3289                                             mkU8(0x10)),
   3290                                       binop(Iop_Shl32,
   3291                                             mkexpr(t4),
   3292                                             mkU8(0x10))));
   3293                      putIReg(rd, binop(Iop_Shr32,
   3294                                        mkexpr(t5),
   3295                                        mkU8(16)));
   3296                      break;
   3297                   }
   3298                   case 0x1C: {  /* PRECEU.PH.QBL */
   3299                      DIP("preceu.ph.qbl r%u, r%u", rd, rt);
   3300                      vassert(!mode64);
   3301 
   3302                      putIReg(rd, binop(Iop_Or32,
   3303                                        binop(Iop_Shr32,
   3304                                              binop(Iop_And32,
   3305                                                    getIReg(rt),
   3306                                                    mkU32(0xff000000)),
   3307                                              mkU8(8)),
   3308                                        binop(Iop_Shr32,
   3309                                              binop(Iop_And32,
   3310                                                    getIReg(rt),
   3311                                                    mkU32(0x00ff0000)),
   3312                                              mkU8(16))));
   3313                      break;
   3314                   }
   3315                   case 0x1E: {  /* PRECEU.PH.QBLA */
   3316                      DIP("preceu.ph.qbla r%u, r%u", rd, rt);
   3317                      vassert(!mode64);
   3318 
   3319                      putIReg(rd, binop(Iop_Or32,
   3320                                        binop(Iop_Shr32,
   3321                                              binop(Iop_And32,
   3322                                                    getIReg(rt),
   3323                                                    mkU32(0xff000000)),
   3324                                              mkU8(8)),
   3325                                        binop(Iop_Shr32,
   3326                                              binop(Iop_And32,
   3327                                                    getIReg(rt),
   3328                                                    mkU32(0x0000ff00)),
   3329                                              mkU8(8))));
   3330                      break;
   3331                   }
   3332                   case 0x1D: {  /* PRECEU.PH.QBR */
   3333                      DIP("preceu.ph.qbr r%u, r%u", rd, rt);
   3334                      vassert(!mode64);
   3335 
   3336                      putIReg(rd, binop(Iop_Or32,
   3337                                        binop(Iop_Shl32,
   3338                                              binop(Iop_And32,
   3339                                                    getIReg(rt),
   3340                                                    mkU32(0x0000ff00)),
   3341                                              mkU8(8)),
   3342                                        binop(Iop_And32,
   3343                                              getIReg(rt),
   3344                                              mkU32(0x000000ff))));
   3345                      break;
   3346                   }
   3347                   case 0x1F: {  /* PRECEU.PH.QBRA */
   3348                      DIP("preceu.ph.qbra r%u, r%u", rd, rt);
   3349                      vassert(!mode64);
   3350 
   3351                      putIReg(rd, binop(Iop_Or32,
   3352                                        binop(Iop_And32,
   3353                                              getIReg(rt),
   3354                                              mkU32(0x00ff0000)),
   3355                                        binop(Iop_And32,
   3356                                              getIReg(rt),
   3357                                              mkU32(0x000000ff))));
   3358                      break;
   3359                   }
   3360                   default:
   3361                      return -1;
   3362                }
   3363                break;  /* end of ABSQ_S.PH */
   3364             }
   3365             case 0x38: {  /* EXTR.W */
   3366                switch(sa) {
   3367                   case 0x0: {  /* EXTR.W */
   3368                      DIP("extr.w r%u, ac%u, %u", rt, ac, rs);
   3369                      vassert(!mode64);
   3370                      t0 = newTemp(Ity_I64);
   3371                      t1 = newTemp(Ity_I64);
   3372                      t2 = newTemp(Ity_I32);
   3373                      t3 = newTemp(Ity_I1);
   3374                      t4 = newTemp(Ity_I1);
   3375                      t5 = newTemp(Ity_I1);
   3376                      t6 = newTemp(Ity_I1);
   3377                      t7 = newTemp(Ity_I32);
   3378                      t8 = newTemp(Ity_I64);
   3379                      t9 = newTemp(Ity_I64);
   3380                      t10 = newTemp(Ity_I1);
   3381                      t11 = newTemp(Ity_I1);
   3382                      t12 = newTemp(Ity_I1);
   3383                      t13 = newTemp(Ity_I1);
   3384                      t14 = newTemp(Ity_I32);
   3385 
   3386                      assign(t0, getAcc(ac));
   3387                      if (0 == rs) {
   3388                         assign(t1, mkexpr(t0));
   3389                      } else {
   3390                         assign(t1, binop(Iop_Sar64, mkexpr(t0), mkU8(rs)));
   3391                      }
   3392                      /* Check if bits 63..31 of the result in t1 aren't 0. */
   3393                      assign(t3, binop(Iop_CmpNE32,
   3394                                       unop(Iop_64HIto32,
   3395                                            mkexpr(t1)),
   3396                                       mkU32(0)));
   3397                      assign(t4, binop(Iop_CmpNE32,
   3398                                       binop(Iop_And32,
   3399                                             unop(Iop_64to32,
   3400                                                  mkexpr(t1)),
   3401                                             mkU32(0x80000000)),
   3402                                       mkU32(0)));
   3403                      /* Check if bits 63..31 of the result in t1 aren't
   3404                         0x1ffffffff. */
   3405                      assign(t5, binop(Iop_CmpNE32,
   3406                                       unop(Iop_64HIto32,
   3407                                            mkexpr(t1)),
   3408                                       mkU32(0xffffffff)));
   3409                      assign(t6, binop(Iop_CmpNE32,
   3410                                       binop(Iop_And32,
   3411                                             unop(Iop_64to32,
   3412                                                  mkexpr(t1)),
   3413                                             mkU32(0x80000000)),
   3414                                       mkU32(0x80000000)));
   3415                      /* If bits 63..31 aren't 0 nor 0x1ffffffff, set DSP
   3416                         control register. */
   3417                      assign(t7, binop(Iop_And32,
   3418                                       binop(Iop_Or32,
   3419                                             unop(Iop_1Sto32, mkexpr(t3)),
   3420                                             unop(Iop_1Sto32, mkexpr(t4))),
   3421                                       binop(Iop_Or32,
   3422                                             unop(Iop_1Sto32, mkexpr(t5)),
   3423                                             unop(Iop_1Sto32, mkexpr(t6)))));
   3424                      putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32,
   3425                                                     mkexpr(t7),
   3426                                                     mkU32(0)),
   3427                                               binop(Iop_Or32,
   3428                                                     getDSPControl(),
   3429                                                     mkU32(0x00800000)),
   3430                                               getDSPControl()));
   3431 
   3432                      /* If the last discarded bit is 1, there would be carry
   3433                         when rounding, otherwise there wouldn't. We use that
   3434                         fact and just add the value of the last discarded bit
   3435                         to the least sifgnificant bit of the shifted value
   3436                         from acc. */
   3437                      if (0 == rs) {
   3438                         assign(t8, mkU64(0x0ULL));
   3439                      } else {
   3440                         assign(t8, binop(Iop_And64,
   3441                                          binop(Iop_Shr64,
   3442                                                mkexpr(t0),
   3443                                                mkU8(rs-1)),
   3444                                          mkU64(0x1ULL)));
   3445                      }
   3446                      assign(t9, binop(Iop_Add64, mkexpr(t1), mkexpr(t8)));
   3447 
   3448                      /* Repeat previous steps for the rounded value. */
   3449                      assign(t10, binop(Iop_CmpNE32,
   3450                                       unop(Iop_64HIto32,
   3451                                            mkexpr(t9)),
   3452                                       mkU32(0)));
   3453                      assign(t11, binop(Iop_CmpNE32,
   3454                                       binop(Iop_And32,
   3455                                             unop(Iop_64to32,
   3456                                                  mkexpr(t9)),
   3457                                             mkU32(0x80000000)),
   3458                                       mkU32(0)));
   3459 
   3460                      assign(t12, binop(Iop_CmpNE32,
   3461                                       unop(Iop_64HIto32,
   3462                                            mkexpr(t9)),
   3463                                       mkU32(0xffffffff)));
   3464                      assign(t13, binop(Iop_CmpNE32,
   3465                                       binop(Iop_And32,
   3466                                             unop(Iop_64to32,
   3467                                                  mkexpr(t9)),
   3468                                             mkU32(0x80000000)),
   3469                                       mkU32(0x80000000)));
   3470 
   3471                      assign(t14, binop(Iop_And32,
   3472                                       binop(Iop_Or32,
   3473                                             unop(Iop_1Sto32, mkexpr(t10)),
   3474                                             unop(Iop_1Sto32, mkexpr(t11))),
   3475                                       binop(Iop_Or32,
   3476                                             unop(Iop_1Sto32, mkexpr(t12)),
   3477                                             unop(Iop_1Sto32, mkexpr(t13)))));
   3478                      putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32,
   3479                                                     mkexpr(t14),
   3480                                                     mkU32(0)),
   3481                                               binop(Iop_Or32,
   3482                                                     getDSPControl(),
   3483                                                     mkU32(0x00800000)),
   3484                                               getDSPControl()));
   3485                      if (0 == rs) {
   3486                         putIReg(rt, unop(Iop_64to32, mkexpr(t0)));
   3487                      } else {
   3488                         putIReg(rt, unop(Iop_64to32, mkexpr(t1)));
   3489                      }
   3490                      break;
   3491                   }
   3492                   case 0x1: {  /* EXTRV.W */
   3493                      DIP("extrv.w r%u, ac%u, r%u", rt, ac, rs);
   3494                      vassert(!mode64);
   3495                      t0 = newTemp(Ity_I64);
   3496                      t1 = newTemp(Ity_I64);
   3497                      t2 = newTemp(Ity_I32);
   3498                      t3 = newTemp(Ity_I1);
   3499                      t4 = newTemp(Ity_I1);
   3500                      t5 = newTemp(Ity_I1);
   3501                      t6 = newTemp(Ity_I1);
   3502                      t7 = newTemp(Ity_I32);
   3503                      t8 = newTemp(Ity_I64);
   3504                      t9 = newTemp(Ity_I64);
   3505                      t10 = newTemp(Ity_I1);
   3506                      t11 = newTemp(Ity_I1);
   3507                      t12 = newTemp(Ity_I1);
   3508                      t13 = newTemp(Ity_I1);
   3509                      t14 = newTemp(Ity_I32);
   3510                      t15 = newTemp(Ity_I8);
   3511 
   3512                      assign(t15, unop(Iop_32to8,
   3513                                       binop(Iop_And32,
   3514                                             getIReg(rs),
   3515                                             mkU32(0x1f))));
   3516                      assign(t0, getAcc(ac));
   3517                      assign(t1, binop(Iop_Sar64, mkexpr(t0), mkexpr(t15)));
   3518                      putIReg(rt, IRExpr_ITE(binop(Iop_CmpEQ32,
   3519                                                         unop(Iop_8Uto32,
   3520                                                              mkexpr(t15)),
   3521                                                         mkU32(0)),
   3522                                                   unop(Iop_64to32, mkexpr(t0)),
   3523                                                   unop(Iop_64to32, mkexpr(t1))));
   3524 
   3525                      /* Check if bits 63..31 of the result in t1 aren't 0. */
   3526                      assign(t3, binop(Iop_CmpNE32,
   3527                                       unop(Iop_64HIto32,
   3528                                            mkexpr(t1)),
   3529                                       mkU32(0)));
   3530                      assign(t4, binop(Iop_CmpNE32,
   3531                                       binop(Iop_And32,
   3532                                             unop(Iop_64to32,
   3533                                                  mkexpr(t1)),
   3534                                             mkU32(0x80000000)),
   3535                                       mkU32(0)));
   3536                      /* Check if bits 63..31 of the result in t1 aren't
   3537                         0x1ffffffff. */
   3538                      assign(t5, binop(Iop_CmpNE32,
   3539                                       unop(Iop_64HIto32,
   3540                                            mkexpr(t1)),
   3541                                       mkU32(0xffffffff)));
   3542                      assign(t6, binop(Iop_CmpNE32,
   3543                                       binop(Iop_And32,
   3544                                             unop(Iop_64to32,
   3545                                                  mkexpr(t1)),
   3546                                             mkU32(0x80000000)),
   3547                                       mkU32(0x80000000)));
   3548                      /* If bits 63..31 aren't 0 nor 0x1ffffffff, set DSP
   3549                         control register. */
   3550                      assign(t7, binop(Iop_And32,
   3551                                       binop(Iop_Or32,
   3552                                             unop(Iop_1Sto32, mkexpr(t3)),
   3553                                             unop(Iop_1Sto32, mkexpr(t4))),
   3554                                       binop(Iop_Or32,
   3555                                             unop(Iop_1Sto32, mkexpr(t5)),
   3556                                             unop(Iop_1Sto32, mkexpr(t6)))));
   3557                      putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32,
   3558                                                     mkexpr(t7),
   3559                                                     mkU32(0)),
   3560                                               binop(Iop_Or32,
   3561                                                     getDSPControl(),
   3562                                                     mkU32(0x00800000)),
   3563                                               getDSPControl()));
   3564 
   3565                      /* If the last discarded bit is 1, there would be carry
   3566                         when rounding, otherwise there wouldn't. We use that
   3567                         fact and just add the value of the last discarded bit
   3568                         to the least sifgnificant bit of the shifted value
   3569                         from acc. */
   3570                      assign(t8,
   3571                             IRExpr_ITE(binop(Iop_CmpEQ32,
   3572                                              unop(Iop_8Uto32,
   3573                                                   mkexpr(t15)),
   3574                                              mkU32(0)),
   3575                                        mkU64(0x0ULL),
   3576                                        binop(Iop_And64,
   3577                                              binop(Iop_Shr64,
   3578                                                    mkexpr(t0),
   3579                                                    unop(Iop_32to8,
   3580                                                         binop(Iop_Sub32,
   3581                                                               unop(Iop_8Uto32,
   3582                                                                    mkexpr(t15)),
   3583                                                                    mkU32(1)))),
   3584                                              mkU64(0x1ULL))));
   3585 
   3586                      assign(t9, binop(Iop_Add64, mkexpr(t1), mkexpr(t8)));
   3587 
   3588                      /* Repeat previous steps for the rounded value. */
   3589                      assign(t10, binop(Iop_CmpNE32,
   3590                                       unop(Iop_64HIto32,
   3591                                            mkexpr(t9)),
   3592                                       mkU32(0)));
   3593                      assign(t11, binop(Iop_CmpNE32,
   3594                                       binop(Iop_And32,
   3595                                             unop(Iop_64to32,
   3596                                                  mkexpr(t9)),
   3597                                             mkU32(0x80000000)),
   3598                                       mkU32(0)));
   3599 
   3600                      assign(t12, binop(Iop_CmpNE32,
   3601                                       unop(Iop_64HIto32,
   3602                                            mkexpr(t9)),
   3603                                       mkU32(0xffffffff)));
   3604                      assign(t13, binop(Iop_CmpNE32,
   3605                                       binop(Iop_And32,
   3606                                             unop(Iop_64to32,
   3607                                                  mkexpr(t9)),
   3608                                             mkU32(0x80000000)),
   3609                                       mkU32(0x80000000)));
   3610 
   3611                      assign(t14, binop(Iop_And32,
   3612                                       binop(Iop_Or32,
   3613                                             unop(Iop_1Sto32, mkexpr(t10)),
   3614                                             unop(Iop_1Sto32, mkexpr(t11))),
   3615                                       binop(Iop_Or32,
   3616                                             unop(Iop_1Sto32, mkexpr(t12)),
   3617                                             unop(Iop_1Sto32, mkexpr(t13)))));
   3618                      putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32,
   3619                                                     mkexpr(t14),
   3620                                                     mkU32(0)),
   3621                                               binop(Iop_Or32,
   3622                                                     getDSPControl(),
   3623                                                     mkU32(0x00800000)),
   3624                                               getDSPControl()));
   3625                      break;
   3626                   }
   3627                   case 0x2: {  /* EXTP */
   3628                      DIP("extp r%u, ac%u, %u", rt, ac, rs);
   3629                      vassert(!mode64);
   3630                      t0 = newTemp(Ity_I64);
   3631                      t1 = newTemp(Ity_I32);
   3632                      t2 = newTemp(Ity_I1);
   3633                      t3 = newTemp(Ity_I1);
   3634                      t4 = newTemp(Ity_I8);
   3635                      t5 = newTemp(Ity_I64);
   3636                      t6 = newTemp(Ity_I64);
   3637                      t7 = newTemp(Ity_I32);
   3638 
   3639                      assign(t0, getAcc(ac));
   3640                      /* Extract pos field of DSPControl register. */
   3641                      assign(t1, binop(Iop_And32, getDSPControl(), mkU32(0x3f)));
   3642 
   3643                      /* Check if (pos - size) >= 0 [size <= pos]
   3644                         if (pos < size)
   3645                            put 1 to EFI field of DSPControl register
   3646                         else
   3647                            extract bits from acc and put 0 to EFI field of
   3648                            DSPCtrl */
   3649                      assign(t2, binop(Iop_CmpLT32U, mkexpr(t1), mkU32(rs)));
   3650 
   3651                      putDSPControl(IRExpr_ITE(mkexpr(t2),
   3652                                               binop(Iop_Or32,
   3653                                                     binop(Iop_And32,
   3654                                                           getDSPControl(),
   3655                                                           mkU32(0xffffbfff)),
   3656                                                     mkU32(0x4000)),
   3657                                               binop(Iop_And32,
   3658                                                     getDSPControl(),
   3659                                                     mkU32(0xffffbfff))));
   3660 
   3661                      /* If pos <= 31, shift right the value from the acc
   3662                         (pos-size) times and take (size+1) bits from the least
   3663                         significant positions. Otherwise, shift left the value
   3664                         (63-pos) times, take (size+1) bits from the most
   3665                         significant positions and shift right (31-size) times.*/
   3666                      assign(t3, binop(Iop_CmpLE32U, mkexpr(t1), mkU32(31)));
   3667 
   3668                      assign(t4,
   3669                            IRExpr_ITE(mkexpr(t3),
   3670                                       unop(Iop_32to8,
   3671                                            binop(Iop_Sub32,
   3672                                                  mkexpr(t1), mkU32(rs))),
   3673                                       unop(Iop_32to8,
   3674                                            binop(Iop_Sub32,
   3675                                                  mkU32(63), mkexpr(t1)))));
   3676 
   3677                      assign(t5, IRExpr_ITE(mkexpr(t3),
   3678                                            binop(Iop_Shr64,
   3679                                                  mkexpr(t0), mkexpr(t4)),
   3680                                            binop(Iop_Shl64,
   3681                                                  mkexpr(t0), mkexpr(t4))));
   3682 
   3683                      /* t6 holds a mask for bit extraction */
   3684                      assign(t6,
   3685                             IRExpr_ITE(mkexpr(t3),
   3686                                        unop(Iop_Not64,
   3687                                             binop(Iop_Shl64,
   3688                                                   mkU64(0xffffffffffffffffULL),
   3689                                                   mkU8(rs+1))),
   3690                                        unop(Iop_Not64,
   3691                                             binop(Iop_Shr64,
   3692                                                   mkU64(0xffffffffffffffffULL),
   3693                                                   mkU8(rs+1)))));
   3694 
   3695                      assign(t7, IRExpr_ITE(mkexpr(t3),
   3696                                            unop(Iop_64to32,
   3697                                                 binop(Iop_And64,
   3698                                                       mkexpr(t5),
   3699                                                       mkexpr(t6))),
   3700                                            binop(Iop_Shr32,
   3701                                                  unop(Iop_64HIto32,
   3702                                                       binop(Iop_And64,
   3703                                                             mkexpr(t5),
   3704                                                             mkexpr(t6))),
   3705                                                  mkU8(31-rs))));
   3706 
   3707                      putIReg(rt, mkexpr(t7));
   3708                      break;
   3709                   }
   3710                   case 0x3: {  /* EXTPV */
   3711                      DIP("extpv r%u, ac%u, r%u", rt, ac, rs);
   3712                      vassert(!mode64);
   3713                      t0 = newTemp(Ity_I64);
   3714                      t1 = newTemp(Ity_I32);
   3715                      t2 = newTemp(Ity_I1);
   3716                      t3 = newTemp(Ity_I1);
   3717                      t4 = newTemp(Ity_I8);
   3718                      t5 = newTemp(Ity_I64);
   3719                      t6 = newTemp(Ity_I64);
   3720                      t7 = newTemp(Ity_I32);
   3721                      t8 = newTemp(Ity_I32);
   3722 
   3723                      assign(t8, binop(Iop_And32, getIReg(rs), mkU32(0x1f)));
   3724                      assign(t0, getAcc(ac));
   3725                      /* Extract pos field of DSPControl register. */
   3726                      assign(t1, binop(Iop_And32, getDSPControl(), mkU32(0x3f)));
   3727 
   3728                      /* Check if (pos - size) >= 0 [size <= pos]
   3729                         if (pos < size)
   3730                            put 1 to EFI field of DSPControl register
   3731                         else
   3732                            extract bits from acc and put 0 to EFI field of
   3733                            DSPCtrl */
   3734                      assign(t2, binop(Iop_CmpLT32U, mkexpr(t1), mkexpr(t8)));
   3735 
   3736                      putDSPControl(IRExpr_ITE(mkexpr(t2),
   3737                                               binop(Iop_Or32,
   3738                                                     binop(Iop_And32,
   3739                                                           getDSPControl(),
   3740                                                           mkU32(0xffffbfff)),
   3741                                                     mkU32(0x4000)),
   3742                                               binop(Iop_And32,
   3743                                                     getDSPControl(),
   3744                                                     mkU32(0xffffbfff))));
   3745 
   3746                      /* If pos <= 31, shift right the value from the acc
   3747                         (pos-size) times and take (size+1) bits from the least
   3748                         significant positions. Otherwise, shift left the value
   3749                         (63-pos) times, take (size+1) bits from the most
   3750                         significant positions and shift right (31-size)
   3751                         times. */
   3752                      assign(t3, binop(Iop_CmpLE32U, mkexpr(t1), mkU32(31)));
   3753 
   3754                      assign(t4,
   3755                            IRExpr_ITE(mkexpr(t3),
   3756                                       unop(Iop_32to8,
   3757                                            binop(Iop_Sub32,
   3758                                                  mkexpr(t1), mkexpr(t8))),
   3759                                       unop(Iop_32to8,
   3760                                            binop(Iop_Sub32,
   3761                                                  mkU32(63), mkexpr(t1)))));
   3762 
   3763                      assign(t5, IRExpr_ITE(mkexpr(t3),
   3764                                            binop(Iop_Shr64,
   3765                                                  mkexpr(t0), mkexpr(t4)),
   3766                                            binop(Iop_Shl64,
   3767                                                  mkexpr(t0), mkexpr(t4))));
   3768 
   3769                      /* t6 holds a mask for bit extraction. */
   3770                      assign(t6,
   3771                             IRExpr_ITE(mkexpr(t3),
   3772                                        unop(Iop_Not64,
   3773                                             binop(Iop_Shl64,
   3774                                                   mkU64(0xffffffffffffffffULL),
   3775                                                   unop(Iop_32to8,
   3776                                                        binop(Iop_Add32,
   3777                                                              mkexpr(t8),
   3778                                                              mkU32(1))))),
   3779                                        unop(Iop_Not64,
   3780                                             binop(Iop_Shr64,
   3781                                                   mkU64(0xffffffffffffffffULL),
   3782                                                   unop(Iop_32to8,
   3783                                                        binop(Iop_Add32,
   3784                                                              mkexpr(t8),
   3785                                                              mkU32(1)))))));
   3786 
   3787                      assign(t7, IRExpr_ITE(mkexpr(t3),
   3788                                            unop(Iop_64to32,
   3789                                                 binop(Iop_And64,
   3790                                                       mkexpr(t5),
   3791                                                       mkexpr(t6))),
   3792                                            binop(Iop_Shr32,
   3793                                                  unop(Iop_64HIto32,
   3794                                                       binop(Iop_And64,
   3795                                                             mkexpr(t5),
   3796                                                             mkexpr(t6))),
   3797                                                  unop(Iop_32to8,
   3798                                                       binop(Iop_Sub32,
   3799                                                             mkU32(31),
   3800                                                             mkexpr(t8))))));
   3801 
   3802                      putIReg(rt, mkexpr(t7));
   3803                      break;
   3804                   }
   3805                   case 0x4: {  /* EXTR_R.W */
   3806                      DIP("extr_r.w r%u, ac%u, %u", rt, ac, rs);
   3807                      vassert(!mode64);
   3808                      t0 = newTemp(Ity_I64);
   3809                      t1 = newTemp(Ity_I64);
   3810                      t2 = newTemp(Ity_I32);
   3811                      t3 = newTemp(Ity_I1);
   3812                      t4 = newTemp(Ity_I1);
   3813                      t5 = newTemp(Ity_I1);
   3814                      t6 = newTemp(Ity_I1);
   3815                      t7 = newTemp(Ity_I32);
   3816                      t8 = newTemp(Ity_I64);
   3817                      t9 = newTemp(Ity_I64);
   3818                      t10 = newTemp(Ity_I1);
   3819                      t11 = newTemp(Ity_I1);
   3820                      t12 = newTemp(Ity_I1);
   3821                      t13 = newTemp(Ity_I1);
   3822                      t14 = newTemp(Ity_I32);
   3823                      t15 = newTemp(Ity_I64);
   3824                      t16 = newTemp(Ity_I1);
   3825 
   3826                      assign(t0, getAcc(ac));
   3827                      assign(t16, binop(Iop_CmpEQ32,
   3828                                        mkU32(rs),
   3829                                        mkU32(0)));
   3830                      assign(t1, IRExpr_ITE(mkexpr(t16),
   3831                                            mkexpr(t0),
   3832                                            binop(Iop_Sar64,
   3833                                                  mkexpr(t0),
   3834                                                  mkU8(rs))));
   3835                      /* If the last discarded bit is 1, there would be carry
   3836                         when rounding, otherwise there wouldn't. We use that
   3837                         fact and just add the value of the last discarded bit
   3838                         to the least significant bit of the shifted value
   3839                         from acc. */
   3840                      assign(t15, binop(Iop_Shr64,
   3841                                        mkexpr(t0),
   3842                                        unop(Iop_32to8,
   3843                                             binop(Iop_Sub32,
   3844                                                   binop(Iop_And32,
   3845                                                         mkU32(rs),
   3846                                                         mkU32(0x1f)),
   3847                                                   mkU32(1)))));
   3848 
   3849                      assign(t8,
   3850                             IRExpr_ITE(mkexpr(t16),
   3851                                        mkU64(0x0ULL),
   3852                                        binop(Iop_And64,
   3853                                              mkexpr(t15),
   3854                                              mkU64(0x0000000000000001ULL))));
   3855                      assign(t9, binop(Iop_Add64, mkexpr(t1), mkexpr(t8)));
   3856                      putIReg(rt, unop(Iop_64to32, mkexpr(t9)));
   3857 
   3858                      /* Check if bits 63..31 of the result in t1 aren't 0. */
   3859                      assign(t3, binop(Iop_CmpNE32,
   3860                                       unop(Iop_64HIto32,
   3861                                            mkexpr(t1)),
   3862                                       mkU32(0)));
   3863                      assign(t4, binop(Iop_CmpNE32,
   3864                                       binop(Iop_And32,
   3865                                             unop(Iop_64to32,
   3866                                                  mkexpr(t1)),
   3867                                             mkU32(0x80000000)),
   3868                                       mkU32(0)));
   3869 
   3870                      /* Check if bits 63..31 of the result in t1 aren't
   3871                         0x1ffffffff. */
   3872                      assign(t5, binop(Iop_CmpNE32,
   3873                                       unop(Iop_64HIto32,
   3874                                            mkexpr(t1)),
   3875                                       mkU32(0xffffffff)));
   3876                      assign(t6, binop(Iop_CmpNE32,
   3877                                       binop(Iop_And32,
   3878                                             unop(Iop_64to32,
   3879                                                  mkexpr(t1)),
   3880                                             mkU32(0x80000000)),
   3881                                       mkU32(0x80000000)));
   3882                      /* If bits 63..31 aren't 0 nor 0x1ffffffff, set DSP
   3883                         control register. */
   3884                      assign(t7, binop(Iop_And32,
   3885                                       binop(Iop_Or32,
   3886                                             unop(Iop_1Sto32, mkexpr(t3)),
   3887                                             unop(Iop_1Sto32, mkexpr(t4))),
   3888                                       binop(Iop_Or32,
   3889                                             unop(Iop_1Sto32, mkexpr(t5)),
   3890                                             unop(Iop_1Sto32, mkexpr(t6)))));
   3891                      putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32,
   3892                                                     mkexpr(t7),
   3893                                                     mkU32(0)),
   3894                                               binop(Iop_Or32,
   3895                                                     getDSPControl(),
   3896                                                     mkU32(0x00800000)),
   3897                                               getDSPControl()));
   3898 
   3899                      /* Repeat previous steps for the rounded value. */
   3900                      assign(t10, binop(Iop_CmpNE32,
   3901                                       unop(Iop_64HIto32,
   3902                                            mkexpr(t9)),
   3903                                       mkU32(0)));
   3904                      assign(t11, binop(Iop_CmpNE32,
   3905                                       binop(Iop_And32,
   3906                                             unop(Iop_64to32,
   3907                                                  mkexpr(t9)),
   3908                                             mkU32(0x80000000)),
   3909                                       mkU32(0)));
   3910 
   3911                      assign(t12, binop(Iop_CmpNE32,
   3912                                       unop(Iop_64HIto32,
   3913                                            mkexpr(t9)),
   3914                                       mkU32(0xffffffff)));
   3915                      assign(t13, binop(Iop_CmpNE32,
   3916                                       binop(Iop_And32,
   3917                                             unop(Iop_64to32,
   3918                                                  mkexpr(t9)),
   3919                                             mkU32(0x80000000)),
   3920                                       mkU32(0x80000000)));
   3921 
   3922                      assign(t14, binop(Iop_And32,
   3923                                       binop(Iop_Or32,
   3924                                             unop(Iop_1Sto32, mkexpr(t10)),
   3925                                             unop(Iop_1Sto32, mkexpr(t11))),
   3926                                       binop(Iop_Or32,
   3927                                             unop(Iop_1Sto32, mkexpr(t12)),
   3928                                             unop(Iop_1Sto32, mkexpr(t13)))));
   3929                      putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32,
   3930                                                     mkexpr(t14),
   3931                                                     mkU32(0)),
   3932                                               binop(Iop_Or32,
   3933                                                     getDSPControl(),
   3934                                                     mkU32(0x00800000)),
   3935                                               getDSPControl()));
   3936                      break;
   3937                   }
   3938                   case 0x5: {  /* EXTRV_R.W */
   3939                      DIP("extrv_r.w r%u, ac%u, r%u", rt, ac, rs);
   3940                      vassert(!mode64);
   3941                      t0 = newTemp(Ity_I64);
   3942                      t1 = newTemp(Ity_I64);
   3943                      t2 = newTemp(Ity_I32);
   3944                      t3 = newTemp(Ity_I1);
   3945                      t4 = newTemp(Ity_I1);
   3946                      t5 = newTemp(Ity_I1);
   3947                      t6 = newTemp(Ity_I1);
   3948                      t7 = newTemp(Ity_I32);
   3949                      t8 = newTemp(Ity_I64);
   3950                      t9 = newTemp(Ity_I64);
   3951                      t10 = newTemp(Ity_I1);
   3952                      t11 = newTemp(Ity_I1);
   3953                      t12 = newTemp(Ity_I1);
   3954                      t13 = newTemp(Ity_I1);
   3955                      t14 = newTemp(Ity_I32);
   3956                      t15 = newTemp(Ity_I8);
   3957 
   3958                      assign(t15, unop(Iop_32to8,
   3959                                       binop(Iop_And32,
   3960                                             getIReg(rs),
   3961                                             mkU32(0x1f))));
   3962                      assign(t0, getAcc(ac));
   3963                      assign(t1, binop(Iop_Sar64, mkexpr(t0), mkexpr(t15)));
   3964 
   3965                      /* Check if bits 63..31 of the result in t1 aren't 0. */
   3966                      assign(t3, binop(Iop_CmpNE32,
   3967                                       unop(Iop_64HIto32,
   3968                                            mkexpr(t1)),
   3969                                       mkU32(0)));
   3970                      assign(t4, binop(Iop_CmpNE32,
   3971                                       binop(Iop_And32,
   3972                                             unop(Iop_64to32,
   3973                                                  mkexpr(t1)),
   3974                                             mkU32(0x80000000)),
   3975                                       mkU32(0)));
   3976                      /* Check if bits 63..31 of the result in t1 aren't
   3977                         0x1ffffffff. */
   3978                      assign(t5, binop(Iop_CmpNE32,
   3979                                       unop(Iop_64HIto32,
   3980                                            mkexpr(t1)),
   3981                                       mkU32(0xffffffff)));
   3982                      assign(t6, binop(Iop_CmpNE32,
   3983                                       binop(Iop_And32,
   3984                                             unop(Iop_64to32,
   3985                                                  mkexpr(t1)),
   3986                                             mkU32(0x80000000)),
   3987                                       mkU32(0x80000000)));
   3988                      /* If bits 63..31 aren't 0 nor 0x1ffffffff, set DSP
   3989                         control register. */
   3990                      assign(t7, binop(Iop_And32,
   3991                                       binop(Iop_Or32,
   3992                                             unop(Iop_1Sto32, mkexpr(t3)),
   3993                                             unop(Iop_1Sto32, mkexpr(t4))),
   3994                                       binop(Iop_Or32,
   3995                                             unop(Iop_1Sto32, mkexpr(t5)),
   3996                                             unop(Iop_1Sto32, mkexpr(t6)))));
   3997                      putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32,
   3998                                                     mkexpr(t7),
   3999                                                     mkU32(0)),
   4000                                               binop(Iop_Or32,
   4001                                                     getDSPControl(),
   4002                                                     mkU32(0x00800000)),
   4003                                               getDSPControl()));
   4004 
   4005                      /* If the last discarded bit is 1, there would be carry
   4006                         when rounding, otherwise there wouldn't. We use that
   4007                         fact and just add the value of the last discarded bit
   4008                         to the least sifgnificant bit of the shifted value
   4009                         from acc. */
   4010                      assign(t8,
   4011                             IRExpr_ITE(binop(Iop_CmpEQ32,
   4012                                              unop(Iop_8Uto32,
   4013                                                   mkexpr(t15)),
   4014                                              mkU32(0)),
   4015                                        mkU64(0x0ULL),
   4016                                        binop(Iop_And64,
   4017                                              binop(Iop_Shr64,
   4018                                                    mkexpr(t0),
   4019                                                    unop(Iop_32to8,
   4020                                                         binop(Iop_Sub32,
   4021                                                               unop(Iop_8Uto32,
   4022                                                                    mkexpr(t15)),
   4023                                                                    mkU32(1)))),
   4024                                              mkU64(0x1ULL))));
   4025 
   4026                      assign(t9, binop(Iop_Add64, mkexpr(t1), mkexpr(t8)));
   4027                      /* Put rounded value in destination register. */
   4028                      putIReg(rt, unop(Iop_64to32, mkexpr(t9)));
   4029 
   4030                      /* Repeat previous steps for the rounded value. */
   4031                      assign(t10, binop(Iop_CmpNE32,
   4032                                       unop(Iop_64HIto32,
   4033                                            mkexpr(t9)),
   4034                                       mkU32(0)));
   4035                      assign(t11, binop(Iop_CmpNE32,
   4036                                       binop(Iop_And32,
   4037                                             unop(Iop_64to32,
   4038                                                  mkexpr(t9)),
   4039                                             mkU32(0x80000000)),
   4040                                       mkU32(0)));
   4041 
   4042                      assign(t12, binop(Iop_CmpNE32,
   4043                                       unop(Iop_64HIto32,
   4044                                            mkexpr(t9)),
   4045                                       mkU32(0xffffffff)));
   4046                      assign(t13, binop(Iop_CmpNE32,
   4047                                       binop(Iop_And32,
   4048                                             unop(Iop_64to32,
   4049                                                  mkexpr(t9)),
   4050                                             mkU32(0x80000000)),
   4051                                       mkU32(0x80000000)));
   4052 
   4053                      assign(t14, binop(Iop_And32,
   4054                                       binop(Iop_Or32,
   4055                                             unop(Iop_1Sto32, mkexpr(t10)),
   4056                                             unop(Iop_1Sto32, mkexpr(t11))),
   4057                                       binop(Iop_Or32,
   4058                                             unop(Iop_1Sto32, mkexpr(t12)),
   4059                                             unop(Iop_1Sto32, mkexpr(t13)))));
   4060                      putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32,
   4061                                                     mkexpr(t14),
   4062                                                     mkU32(0)),
   4063                                               binop(Iop_Or32,
   4064                                                     getDSPControl(),
   4065                                                     mkU32(0x00800000)),
   4066                                               getDSPControl()));
   4067                      break;
   4068                   }
   4069                   case 0x6: {  /* EXTR_RS.W */
   4070                      DIP("extr_rs.w r%u, ac%u, %u", rt, ac, rs);
   4071                      vassert(!mode64);
   4072                      t0 = newTemp(Ity_I64);
   4073                      t1 = newTemp(Ity_I64);
   4074                      t2 = newTemp(Ity_I32);
   4075                      t3 = newTemp(Ity_I1);
   4076                      t4 = newTemp(Ity_I1);
   4077                      t5 = newTemp(Ity_I1);
   4078                      t6 = newTemp(Ity_I1);
   4079                      t7 = newTemp(Ity_I32);
   4080                      t8 = newTemp(Ity_I64);
   4081                      t9 = newTemp(Ity_I64);
   4082                      t10 = newTemp(Ity_I1);
   4083                      t11 = newTemp(Ity_I1);
   4084                      t12 = newTemp(Ity_I1);
   4085                      t13 = newTemp(Ity_I1);
   4086                      t14 = newTemp(Ity_I32);
   4087                      t16 = newTemp(Ity_I32);
   4088 
   4089                      assign(t0, getAcc(ac));
   4090                      if (0 == rs) {
   4091                         assign(t1, mkexpr(t0));
   4092                      } else {
   4093                         assign(t1, binop(Iop_Sar64, mkexpr(t0), mkU8(rs)));
   4094                      }
   4095 
   4096                      /* Check if bits 63..31 of the result in t1 aren't 0. */
   4097                      assign(t3, binop(Iop_CmpNE32,
   4098                                       unop(Iop_64HIto32,
   4099                                            mkexpr(t1)),
   4100                                       mkU32(0)));
   4101                      assign(t4, binop(Iop_CmpNE32,
   4102                                       binop(Iop_And32,
   4103                                             unop(Iop_64to32,
   4104                                                  mkexpr(t1)),
   4105                                             mkU32(0x80000000)),
   4106                                       mkU32(0)));
   4107                      /* Check if bits 63..31 of the result in t1 aren't
   4108                         0x1ffffffff. */
   4109                      assign(t5, binop(Iop_CmpNE32,
   4110                                       unop(Iop_64HIto32,
   4111                                            mkexpr(t1)),
   4112                                       mkU32(0xffffffff)));
   4113                      assign(t6, binop(Iop_CmpNE32,
   4114                                       binop(Iop_And32,
   4115                                             unop(Iop_64to32,
   4116                                                  mkexpr(t1)),
   4117                                             mkU32(0x80000000)),
   4118                                       mkU32(0x80000000)));
   4119                      /* If bits 63..31 aren't 0 nor 0x1ffffffff, set DSP
   4120                         control register. */
   4121                      assign(t7, binop(Iop_And32,
   4122                                       binop(Iop_Or32,
   4123                                             unop(Iop_1Sto32, mkexpr(t3)),
   4124                                             unop(Iop_1Sto32, mkexpr(t4))),
   4125                                       binop(Iop_Or32,
   4126                                             unop(Iop_1Sto32, mkexpr(t5)),
   4127                                             unop(Iop_1Sto32, mkexpr(t6)))));
   4128                      putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32,
   4129                                                     mkexpr(t7),
   4130                                                     mkU32(0)),
   4131                                               binop(Iop_Or32,
   4132                                                     getDSPControl(),
   4133                                                     mkU32(0x00800000)),
   4134                                               getDSPControl()));
   4135 
   4136                      /* If the last discarded bit is 1, there would be carry
   4137                         when rounding, otherwise there wouldn't. We use that
   4138                         fact and just add the value of the last discarded bit
   4139                         to the least sifgnificant bit of the shifted value
   4140                         from acc. */
   4141                      if (0 == rs) {
   4142                         assign(t8, mkU64(0x0ULL));
   4143                      } else {
   4144                         assign(t8, binop(Iop_And64,
   4145                                          binop(Iop_Shr64,
   4146                                                mkexpr(t0),
   4147                                                mkU8(rs-1)),
   4148                                          mkU64(0x1ULL)));
   4149                      }
   4150 
   4151                      assign(t9, binop(Iop_Add64, mkexpr(t1), mkexpr(t8)));
   4152 
   4153                      /* Repeat previous steps for the rounded value. */
   4154                      assign(t10, binop(Iop_CmpNE32,
   4155                                       unop(Iop_64HIto32,
   4156                                            mkexpr(t9)),
   4157                                       mkU32(0)));
   4158                      assign(t11, binop(Iop_CmpNE32,
   4159                                       binop(Iop_And32,
   4160                                             unop(Iop_64to32,
   4161                                                  mkexpr(t9)),
   4162                                             mkU32(0x80000000)),
   4163                                       mkU32(0)));
   4164 
   4165                      assign(t12, binop(Iop_CmpNE32,
   4166                                       unop(Iop_64HIto32,
   4167                                            mkexpr(t9)),
   4168                                       mkU32(0xffffffff)));
   4169                      assign(t13, binop(Iop_CmpNE32,
   4170                                       binop(Iop_And32,
   4171                                             unop(Iop_64to32,
   4172                                                  mkexpr(t9)),
   4173                                             mkU32(0x80000000)),
   4174                                       mkU32(0x80000000)));
   4175 
   4176                      assign(t14, binop(Iop_And32,
   4177                                       binop(Iop_Or32,
   4178                                             unop(Iop_1Sto32, mkexpr(t10)),
   4179                                             unop(Iop_1Sto32, mkexpr(t11))),
   4180                                       binop(Iop_Or32,
   4181                                             unop(Iop_1Sto32, mkexpr(t12)),
   4182                                             unop(Iop_1Sto32, mkexpr(t13)))));
   4183                      putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32,
   4184                                                     mkexpr(t14),
   4185                                                     mkU32(0)),
   4186                                               binop(Iop_Or32,
   4187                                                     getDSPControl(),
   4188                                                     mkU32(0x00800000)),
   4189                                               getDSPControl()));
   4190 
   4191                      assign(t16, binop(Iop_And32,
   4192                                        unop(Iop_64HIto32,
   4193                                             mkexpr(t9)),
   4194                                        mkU32(0x80000000)));
   4195                      putIReg(rt, IRExpr_ITE(binop(Iop_CmpNE32,
   4196                                                   mkexpr(t14),
   4197                                                   mkU32(0)),
   4198                                             IRExpr_ITE(binop(Iop_CmpEQ32,
   4199                                                              mkexpr(t16),
   4200                                                              mkU32(0)),
   4201                                                        mkU32(0x7fffffff),
   4202                                                        mkU32(0x80000000)),
   4203                                             unop(Iop_64to32, mkexpr(t9))));
   4204                      break;
   4205                   }
   4206                   case 0x7: {  /* EXTRV_RS.W */
   4207                      DIP("extrv_rs.w r%u, ac%u, r%u", rt, ac, rs);
   4208                      vassert(!mode64);
   4209                      t0 = newTemp(Ity_I64);
   4210                      t1 = newTemp(Ity_I64);
   4211                      t2 = newTemp(Ity_I32);
   4212                      t3 = newTemp(Ity_I1);
   4213                      t4 = newTemp(Ity_I1);
   4214                      t5 = newTemp(Ity_I1);
   4215                      t6 = newTemp(Ity_I1);
   4216                      t7 = newTemp(Ity_I32);
   4217                      t8 = newTemp(Ity_I64);
   4218                      t9 = newTemp(Ity_I64);
   4219                      t10 = newTemp(Ity_I1);
   4220                      t11 = newTemp(Ity_I1);
   4221                      t12 = newTemp(Ity_I1);
   4222                      t13 = newTemp(Ity_I1);
   4223                      t14 = newTemp(Ity_I32);
   4224                      t15 = newTemp(Ity_I32);
   4225                      t16 = newTemp(Ity_I32);
   4226                      t17 = newTemp(Ity_I1);
   4227 
   4228                      assign(t15, binop(Iop_And32,
   4229                                        getIReg(rs),
   4230                                        mkU32(0x1f)));
   4231                      assign(t17, binop(Iop_CmpEQ32,
   4232                                        mkexpr(t15),
   4233                                        mkU32(0)));
   4234                      assign(t0, getAcc(ac));
   4235                      assign(t1, IRExpr_ITE(mkexpr(t17),
   4236                                            mkexpr(t0),
   4237                                            binop(Iop_Sar64,
   4238                                                  mkexpr(t0),
   4239                                                  unop(Iop_32to8,
   4240                                                       mkexpr(t15)))));
   4241 
   4242                      /* Check if bits 63..31 of the result in t1 aren't 0. */
   4243                      assign(t3, binop(Iop_CmpNE32,
   4244                                       unop(Iop_64HIto32,
   4245                                            mkexpr(t1)),
   4246                                       mkU32(0)));
   4247                      assign(t4, binop(Iop_CmpNE32,
   4248                                       binop(Iop_And32,
   4249                                             unop(Iop_64to32,
   4250                                                  mkexpr(t1)),
   4251                                             mkU32(0x80000000)),
   4252                                       mkU32(0)));
   4253                      /* Check if bits 63..31 of the result in t1 aren't
   4254                         0x1ffffffff. */
   4255                      assign(t5, binop(Iop_CmpNE32,
   4256                                       unop(Iop_64HIto32,
   4257                                            mkexpr(t1)),
   4258                                       mkU32(0xffffffff)));
   4259                      assign(t6, binop(Iop_CmpNE32,
   4260                                       binop(Iop_And32,
   4261                                             unop(Iop_64to32,
   4262                                                  mkexpr(t1)),
   4263                                             mkU32(0x80000000)),
   4264                                       mkU32(0x80000000)));
   4265                      /* If bits 63..31 aren't 0 nor 0x1ffffffff, set DSP
   4266                         control register. */
   4267                      assign(t7, binop(Iop_And32,
   4268                                       binop(Iop_Or32,
   4269                                             unop(Iop_1Sto32, mkexpr(t3)),
   4270                                             unop(Iop_1Sto32, mkexpr(t4))),
   4271                                       binop(Iop_Or32,
   4272                                             unop(Iop_1Sto32, mkexpr(t5)),
   4273                                             unop(Iop_1Sto32, mkexpr(t6)))));
   4274                      putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32,
   4275                                                     mkexpr(t7),
   4276                                                     mkU32(0)),
   4277                                               binop(Iop_Or32,
   4278                                                     getDSPControl(),
   4279                                                     mkU32(0x00800000)),
   4280                                               getDSPControl()));
   4281 
   4282                      /* If the last discarded bit is 1, there would be carry
   4283                         when rounding, otherwise there wouldn't. We use that
   4284                         fact and just add the value of the last discarded bit
   4285                         to the least sifgnificant bit of the shifted value
   4286                         from acc. */
   4287                      assign(t8,
   4288                             IRExpr_ITE(mkexpr(t17),
   4289                                        mkU64(0x0ULL),
   4290                                        binop(Iop_And64,
   4291                                              binop(Iop_Shr64,
   4292                                                    mkexpr(t0),
   4293                                                    unop(Iop_32to8,
   4294                                                         binop(Iop_Sub32,
   4295                                                               mkexpr(t15),
   4296                                                               mkU32(1)))),
   4297                                              mkU64(0x1ULL))));
   4298 
   4299                      assign(t9, binop(Iop_Add64, mkexpr(t1), mkexpr(t8)));
   4300 
   4301                      /* Repeat previous steps for the rounded value. */
   4302                      assign(t10, binop(Iop_CmpNE32,
   4303                                       unop(Iop_64HIto32,
   4304                                            mkexpr(t9)),
   4305                                       mkU32(0)));
   4306                      assign(t11, binop(Iop_CmpNE32,
   4307                                       binop(Iop_And32,
   4308                                             unop(Iop_64to32,
   4309                                                  mkexpr(t9)),
   4310                                             mkU32(0x80000000)),
   4311                                       mkU32(0)));
   4312 
   4313                      assign(t12, binop(Iop_CmpNE32,
   4314                                       unop(Iop_64HIto32,
   4315                                            mkexpr(t9)),
   4316                                       mkU32(0xffffffff)));
   4317                      assign(t13, binop(Iop_CmpNE32,
   4318                                       binop(Iop_And32,
   4319                                             unop(Iop_64to32,
   4320                                                  mkexpr(t9)),
   4321                                             mkU32(0x80000000)),
   4322                                       mkU32(0x80000000)));
   4323 
   4324                      assign(t14, binop(Iop_And32,
   4325                                       binop(Iop_Or32,
   4326                                             unop(Iop_1Sto32, mkexpr(t10)),
   4327                                             unop(Iop_1Sto32, mkexpr(t11))),
   4328                                       binop(Iop_Or32,
   4329                                             unop(Iop_1Sto32, mkexpr(t12)),
   4330                                             unop(Iop_1Sto32, mkexpr(t13)))));
   4331                      putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32,
   4332                                                     mkexpr(t14),
   4333                                                     mkU32(0)),
   4334                                               binop(Iop_Or32,
   4335                                                     getDSPControl(),
   4336                                                     mkU32(0x00800000)),
   4337                                               getDSPControl()));
   4338 
   4339                      assign(t16, binop(Iop_And32,
   4340                                        unop(Iop_64HIto32,
   4341                                             mkexpr(t9)),
   4342                                        mkU32(0x80000000)));
   4343                      putIReg(rt, IRExpr_ITE(binop(Iop_CmpNE32,
   4344                                                   mkexpr(t14),
   4345                                                   mkU32(0)),
   4346                                             IRExpr_ITE(binop(Iop_CmpEQ32,
   4347                                                              mkexpr(t16),
   4348                                                              mkU32(0)),
   4349                                                        mkU32(0x7fffffff),
   4350                                                        mkU32(0x80000000)),
   4351                                             unop(Iop_64to32, mkexpr(t9))));
   4352                      break;
   4353                   }
   4354                   case 0xA: {  /* EXTPDP */
   4355                      DIP("extpdp r%u, ac%u, %u", rt, ac, rs);
   4356                      vassert(!mode64);
   4357                      t0 = newTemp(Ity_I64);
   4358                      t1 = newTemp(Ity_I32);
   4359                      t2 = newTemp(Ity_I1);
   4360                      t3 = newTemp(Ity_I1);
   4361                      t4 = newTemp(Ity_I8);
   4362                      t5 = newTemp(Ity_I64);
   4363                      t6 = newTemp(Ity_I64);
   4364                      t7 = newTemp(Ity_I32);
   4365                      t8 = newTemp(Ity_I32);
   4366 
   4367                      assign(t0, getAcc(ac));
   4368                      /* Extract pos field of DSPControl register. */
   4369                      assign(t1, binop(Iop_And32, getDSPControl(), mkU32(0x3f)));
   4370 
   4371                      /* Check if (pos - size) >= 0 [size <= pos]
   4372                         if (pos < size)
   4373                            put 1 to EFI field of DSPControl register
   4374                         else
   4375                            extract bits from acc and put 0 to EFI field of
   4376                            DSPCtrl */
   4377                      assign(t2, binop(Iop_CmpLT32U, mkexpr(t1), mkU32(rs)));
   4378 
   4379                      assign(t8, binop(Iop_Or32,
   4380                                       binop(Iop_And32,
   4381                                             getDSPControl(),
   4382                                             mkU32(0xffffbfc0)),
   4383                                       binop(Iop_And32,
   4384                                             binop(Iop_Sub32,
   4385                                                   binop(Iop_And32,
   4386                                                         getDSPControl(),
   4387                                                         mkU32(0x3f)),
   4388                                                   mkU32(rs+1)),
   4389                                             mkU32(0x3f))));
   4390                      putDSPControl(IRExpr_ITE(mkexpr(t2),
   4391                                               binop(Iop_Or32,
   4392                                                      binop(Iop_And32,
   4393                                                            getDSPControl(),
   4394                                                            mkU32(0xffffbfff)),
   4395                                                      mkU32(0x4000)),
   4396                                               mkexpr(t8)));
   4397 
   4398                      /* If pos <= 31, shift right the value from the acc
   4399                         (pos-size) times and take (size+1) bits from the least
   4400                         significant positions. Otherwise, shift left the value
   4401                         (63-pos) times, take (size+1) bits from the most
   4402                         significant positions and shift right (31-size) times.
   4403                      */
   4404                      assign(t3, binop(Iop_CmpLE32U, mkexpr(t1), mkU32(31)));
   4405 
   4406                      assign(t4,
   4407                             IRExpr_ITE(mkexpr(t3),
   4408                                        unop(Iop_32to8,
   4409                                             binop(Iop_Sub32,
   4410                                                   mkexpr(t1), mkU32(rs))),
   4411                                        unop(Iop_32to8,
   4412                                             binop(Iop_Sub32,
   4413                                                   mkU32(63), mkexpr(t1)))));
   4414 
   4415                      assign(t5, IRExpr_ITE(mkexpr(t3),
   4416                                            binop(Iop_Shr64,
   4417                                                  mkexpr(t0), mkexpr(t4)),
   4418                                            binop(Iop_Shl64,
   4419                                                  mkexpr(t0), mkexpr(t4))));
   4420 
   4421                      /* t6 holds a mask for bit extraction. */
   4422                      assign(t6,
   4423                             IRExpr_ITE(mkexpr(t3),
   4424                                        unop(Iop_Not64,
   4425                                             binop(Iop_Shl64,
   4426                                                   mkU64(0xffffffffffffffffULL),
   4427                                                   mkU8(rs+1))),
   4428                                        unop(Iop_Not64,
   4429                                             binop(Iop_Shr64,
   4430                                                   mkU64(0xffffffffffffffffULL),
   4431                                                   mkU8(rs+1)))));
   4432 
   4433                      assign(t7, IRExpr_ITE(mkexpr(t3),
   4434                                            unop(Iop_64to32,
   4435                                                 binop(Iop_And64,
   4436                                                       mkexpr(t5),
   4437                                                       mkexpr(t6))),
   4438                                            binop(Iop_Shr32,
   4439                                                  unop(Iop_64HIto32,
   4440                                                       binop(Iop_And64,
   4441                                                             mkexpr(t5),
   4442                                                             mkexpr(t6))),
   4443                                                  mkU8(31-rs))));
   4444 
   4445                      putIReg(rt, mkexpr(t7));
   4446                      break;
   4447                   }
   4448                   case 0xB: {  /* EXTPDPV */
   4449                      DIP("extpdpv r%u, ac%u, r%u", rt, ac, rs);
   4450                      vassert(!mode64);
   4451                      t0 = newTemp(Ity_I64);
   4452                      t1 = newTemp(Ity_I32);
   4453                      t2 = newTemp(Ity_I1);
   4454                      t3 = newTemp(Ity_I1);
   4455                      t4 = newTemp(Ity_I8);
   4456                      t5 = newTemp(Ity_I64);
   4457                      t6 = newTemp(Ity_I64);
   4458                      t7 = newTemp(Ity_I32);
   4459                      t8 = newTemp(Ity_I32);
   4460                      t9 = newTemp(Ity_I32);
   4461 
   4462                      assign(t8, binop(Iop_And32, getIReg(rs), mkU32(0x1f)));
   4463                      assign(t0, getAcc(ac));
   4464                      /* Extract pos field of DSPControl register. */
   4465                      assign(t1, binop(Iop_And32, getDSPControl(), mkU32(0x3f)));
   4466 
   4467                      /* Check if (pos - size) >= 0 [size <= pos]
   4468                         if (pos < size)
   4469                            put 1 to EFI field of DSPControl register
   4470                         else
   4471                            extract bits from acc and put 0 to EFI field of
   4472                            DSPCtrl */
   4473                      assign(t2, binop(Iop_CmpLT32U, mkexpr(t1), mkexpr(t8)));
   4474 
   4475                      assign(t9, binop(Iop_Or32,
   4476                                       binop(Iop_And32,
   4477                                             getDSPControl(),
   4478                                             mkU32(0xffffbfc0)),
   4479                                       binop(Iop_And32,
   4480                                             binop(Iop_Sub32,
   4481                                                   binop(Iop_And32,
   4482                                                         getDSPControl(),
   4483                                                         mkU32(0x3f)),
   4484                                                   binop(Iop_Add32,
   4485                                                         mkexpr(t8),
   4486                                                         mkU32(0x1))),
   4487                                             mkU32(0x3f))));
   4488                      putDSPControl(IRExpr_ITE(mkexpr(t2),
   4489                                               binop(Iop_Or32,
   4490                                                     binop(Iop_And32,
   4491                                                           getDSPControl(),
   4492                                                           mkU32(0xffffbfff)),
   4493                                                     mkU32(0x4000)),
   4494                                               mkexpr(t9)));
   4495 
   4496                      /* If pos <= 31, shift right the value from the acc
   4497                         (pos-size) times and take (size+1) bits from the least
   4498                         significant positions. Otherwise, shift left the value
   4499                         (63-pos) times, take (size+1) bits from the most
   4500                         significant positions and shift right (31-size) times.
   4501                      */
   4502                      assign(t3, binop(Iop_CmpLE32U, mkexpr(t1), mkU32(31)));
   4503 
   4504                      assign(t4,
   4505                             IRExpr_ITE(mkexpr(t3),
   4506                                       unop(Iop_32to8,
   4507                                            binop(Iop_Sub32,
   4508                                                  mkexpr(t1), mkexpr(t8))),
   4509                                       unop(Iop_32to8,
   4510                                            binop(Iop_Sub32,
   4511                                                  mkU32(63), mkexpr(t1)))));
   4512 
   4513                      assign(t5, IRExpr_ITE(mkexpr(t3),
   4514                                            binop(Iop_Shr64,
   4515                                                  mkexpr(t0), mkexpr(t4)),
   4516                                            binop(Iop_Shl64,
   4517                                                  mkexpr(t0), mkexpr(t4))));
   4518 
   4519                      /* t6 holds a mask for bit extraction. */
   4520                      assign(t6,
   4521                             IRExpr_ITE(mkexpr(t3),
   4522                                        unop(Iop_Not64,
   4523                                             binop(Iop_Shl64,
   4524                                                   mkU64(0xffffffffffffffffULL),
   4525                                                   unop(Iop_32to8,
   4526                                                        binop(Iop_Add32,
   4527                                                              mkexpr(t8),
   4528                                                              mkU32(1))))),
   4529                                        unop(Iop_Not64,
   4530                                             binop(Iop_Shr64,
   4531                                                   mkU64(0xffffffffffffffffULL),
   4532                                                   unop(Iop_32to8,
   4533                                                        binop(Iop_Add32,
   4534                                                              mkexpr(t8),
   4535                                                              mkU32(1)))))));
   4536 
   4537                      assign(t7, IRExpr_ITE(mkexpr(t3),
   4538                                            unop(Iop_64to32,
   4539                                                 binop(Iop_And64,
   4540                                                       mkexpr(t5),
   4541                                                       mkexpr(t6))),
   4542                                            binop(Iop_Shr32,
   4543                                                  unop(Iop_64HIto32,
   4544                                                       binop(Iop_And64,
   4545                                                             mkexpr(t5),
   4546                                                             mkexpr(t6))),
   4547                                                  unop(Iop_32to8,
   4548                                                       binop(Iop_Sub32,
   4549                                                             mkU32(31),
   4550                                                             mkexpr(t8))))));
   4551 
   4552                      putIReg(rt, mkexpr(t7));
   4553                      break;
   4554                   }
   4555                   case 0xE: {  /* EXTR_S.H */
   4556                      DIP("extr_s.h r%u, ac%u, %u", rt, ac, rs);
   4557                      vassert(!mode64);
   4558                      t0 = newTemp(Ity_I64);
   4559                      t1 = newTemp(Ity_I64);
   4560                      t2 = newTemp(Ity_I32);
   4561                      t3 = newTemp(Ity_I64);
   4562                      t4 = newTemp(Ity_I32);
   4563                      t5 = newTemp(Ity_I32);
   4564                      t6 = newTemp(Ity_I64);
   4565                      t7 = newTemp(Ity_I32);
   4566                      t9 = newTemp(Ity_I32);
   4567 
   4568                      assign(t0, getAcc(ac));
   4569 
   4570                      assign(t1, binop(Iop_Sar64, mkexpr(t0), mkU8(rs)));
   4571 
   4572                      assign(t2, binop(Iop_Or32,
   4573                                       getDSPControl(), mkU32(0x00800000)));
   4574 
   4575                      assign(t9, binop(Iop_And32,
   4576                                       unop(Iop_64to32,
   4577                                            mkexpr(t1)),
   4578                                       mkU32(0x80000000)));
   4579                      putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32,
   4580                                                     mkexpr(t9),
   4581                                                     binop(Iop_And32,
   4582                                                           unop(Iop_64HIto32,
   4583                                                                mkexpr(t0)),
   4584                                                           mkU32(0x80000000))),
   4585                                               mkexpr(t2),
   4586                                               getDSPControl()));
   4587 
   4588                      /* Check if t1 > 0x7fff ((t1 - 0x7fff) > 0)
   4589                         1. subtract 0x7fff from t1
   4590                         2. if the resulting number is positive (sign bit = 0)
   4591                            and any of the other bits is 1, the value is > 0. */
   4592                      assign(t3, binop(Iop_Sub64,
   4593                                       mkexpr(t1),
   4594                                       mkU64(0x0000000000007fffULL)));
   4595                      assign(t4, binop(Iop_And32,
   4596                                        binop(Iop_Or32,
   4597                                             unop(Iop_1Sto32,
   4598                                                  binop(Iop_CmpNE32,
   4599                                                        mkU32(0),
   4600                                                        binop(Iop_And32,
   4601                                                              unop(Iop_64HIto32,
   4602                                                                   mkexpr(t3)),
   4603                                                              mkU32(0x7fffffff)))),
   4604                                             unop(Iop_1Sto32,
   4605                                                  binop(Iop_CmpNE32,
   4606                                                        mkU32(0),
   4607                                                        unop(Iop_64to32,
   4608                                                             mkexpr(t3))))),
   4609                                        unop(Iop_1Sto32,
   4610                                             binop(Iop_CmpEQ32,
   4611                                                   binop(Iop_And32,
   4612                                                         unop(Iop_64HIto32,
   4613                                                                   mkexpr(t3)),
   4614                                                              mkU32(0x80000000)),
   4615                                                   mkU32(0)))));
   4616                      putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32,
   4617                                                     mkU32(0),
   4618                                                     mkexpr(t4)),
   4619                                               binop(Iop_Or32,
   4620                                                     getDSPControl(),
   4621                                                     mkU32(0x00800000)),
   4622                                               getDSPControl()));
   4623                      /* Check if t1<0xffffffffffff8000 (0xffffffffffff8000-t1)>0
   4624                         1. subtract t1 from 0xffffffffffff8000
   4625                         2. if the resulting number is positive (sign bit = 0)
   4626                             and any of the other bits is 1, the value is > 0 */
   4627                      assign(t6, binop(Iop_Sub64,
   4628                                        mkU64(0xffffffffffff8000ULL),
   4629                                        mkexpr(t1)));
   4630                      assign(t7, binop(Iop_And32,
   4631                                       binop(Iop_Or32,
   4632                                             unop(Iop_1Sto32,
   4633                                                  binop(Iop_CmpNE32,
   4634                                                        mkU32(0),
   4635                                                        binop(Iop_And32,
   4636                                                              unop(Iop_64HIto32,
   4637                                                                   mkexpr(t6)),
   4638                                                              mkU32(0x7fffffff)))),
   4639                                             unop(Iop_1Sto32,
   4640                                                  binop(Iop_CmpNE32,
   4641                                                        mkU32(0),
   4642                                                        unop(Iop_64to32,
   4643                                                             mkexpr(t6))))),
   4644                                       unop(Iop_1Sto32,
   4645                                             binop(Iop_CmpEQ32,
   4646                                                   binop(Iop_And32,
   4647                                                         unop(Iop_64HIto32,
   4648                                                                   mkexpr(t6)),
   4649                                                              mkU32(0x80000000)),
   4650                                                   mkU32(0)))));
   4651                      putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32,
   4652                                                     mkU32(0),
   4653                                                     mkexpr(t7)),
   4654                                               binop(Iop_Or32,
   4655                                                     getDSPControl(),
   4656                                                     mkU32(0x00800000)),
   4657                                               getDSPControl()));
   4658                      putIReg(rt, IRExpr_ITE(binop(Iop_CmpNE32,
   4659                                                     mkU32(0),
   4660                                                     mkexpr(t4)),
   4661                                             mkU32(0x00007fff),
   4662                                             IRExpr_ITE(binop(Iop_CmpNE32,
   4663                                                              mkU32(0),
   4664                                                              mkexpr(t7)),
   4665                                                        mkU32(0xffff8000),
   4666                                                        unop(Iop_64to32,
   4667                                                             mkexpr(t1)))));
   4668                      break;
   4669                   }
   4670                   case 0xF: {  /* EXTRV_S.H */
   4671                      DIP("extrv_s.h r%u, ac%u, %u", rt, ac, rs);
   4672                      vassert(!mode64);
   4673                      t0 = newTemp(Ity_I64);
   4674                      t1 = newTemp(Ity_I64);
   4675                      t2 = newTemp(Ity_I32);
   4676                      t3 = newTemp(Ity_I64);
   4677                      t4 = newTemp(Ity_I32);
   4678                      t5 = newTemp(Ity_I32);
   4679                      t6 = newTemp(Ity_I64);
   4680                      t7 = newTemp(Ity_I32);
   4681                      t9 = newTemp(Ity_I32);
   4682 
   4683                      assign(t0, getAcc(ac));
   4684 
   4685                      assign(t1, binop(Iop_Sar64,
   4686                                       mkexpr(t0),
   4687                                       unop(Iop_32to8,
   4688                                            binop(Iop_And32,
   4689                                                  getIReg(rs),
   4690                                                  mkU32(0x1f)))));
   4691 
   4692                      assign(t2, binop(Iop_Or32,
   4693                                       getDSPControl(), mkU32(0x00800000)));
   4694 
   4695                      assign(t9, binop(Iop_And32,
   4696                                       unop(Iop_64to32,
   4697                                            mkexpr(t1)),
   4698                                       mkU32(0x80000000)));
   4699                      putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32,
   4700                                                     mkexpr(t9),
   4701                                                     binop(Iop_And32,
   4702                                                           unop(Iop_64HIto32,
   4703                                                                mkexpr(t0)),
   4704                                                           mkU32(0x80000000))),
   4705                                               mkexpr(t2),
   4706                                               getDSPControl()));
   4707 
   4708                      /* Check if t1 > 0x7fff ((t1 - 0x7fff) > 0)
   4709                         1. subtract 0x7fff from t1
   4710                         2. if the resulting number is positive (sign bit = 0)
   4711                            and any of the other bits is 1, the value is > 0. */
   4712                      assign(t3, binop(Iop_Sub64,
   4713                                       mkexpr(t1),
   4714                                       mkU64(0x0000000000007fffULL)));
   4715                      assign(t4, binop(Iop_And32,
   4716                                        binop(Iop_Or32,
   4717                                             unop(Iop_1Sto32,
   4718                                                  binop(Iop_CmpNE32,
   4719                                                        mkU32(0),
   4720                                                        binop(Iop_And32,
   4721                                                              unop(Iop_64HIto32,
   4722                                                                   mkexpr(t3)),
   4723                                                              mkU32(0x7fffffff)))),
   4724                                             unop(Iop_1Sto32,
   4725                                                  binop(Iop_CmpNE32,
   4726                                                        mkU32(0),
   4727                                                        unop(Iop_64to32,
   4728                                                             mkexpr(t3))))),
   4729                                        unop(Iop_1Sto32,
   4730                                             binop(Iop_CmpEQ32,
   4731                                                   binop(Iop_And32,
   4732                                                         unop(Iop_64HIto32,
   4733                                                                   mkexpr(t3)),
   4734                                                              mkU32(0x80000000)),
   4735                                                   mkU32(0)))));
   4736                      putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32,
   4737                                                     mkU32(0),
   4738                                                     mkexpr(t4)),
   4739                                               binop(Iop_Or32,
   4740                                                     getDSPControl(),
   4741                                                     mkU32(0x00800000)),
   4742                                               getDSPControl()));
   4743                      /* Check if t1<0xffffffffffff8000 (0xffffffffffff8000-t1)>0
   4744                         1. subtract t1 from 0xffffffffffff8000
   4745                         2. if the resulting number is positive (sign bit = 0)
   4746                             and any of the other bits is 1, the value is > 0 */
   4747                      assign(t6, binop(Iop_Sub64,
   4748                                        mkU64(0xffffffffffff8000ULL),
   4749                                        mkexpr(t1)));
   4750                      assign(t7, binop(Iop_And32,
   4751                                       binop(Iop_Or32,
   4752                                             unop(Iop_1Sto32,
   4753                                                  binop(Iop_CmpNE32,
   4754                                                        mkU32(0),
   4755                                                        binop(Iop_And32,
   4756                                                              unop(Iop_64HIto32,
   4757                                                                   mkexpr(t6)),
   4758                                                              mkU32(0x7fffffff)))),
   4759                                             unop(Iop_1Sto32,
   4760                                                  binop(Iop_CmpNE32,
   4761                                                        mkU32(0),
   4762                                                        unop(Iop_64to32,
   4763                                                             mkexpr(t6))))),
   4764                                       unop(Iop_1Sto32,
   4765                                             binop(Iop_CmpEQ32,
   4766                                                   binop(Iop_And32,
   4767                                                         unop(Iop_64HIto32,
   4768                                                                   mkexpr(t6)),
   4769                                                              mkU32(0x80000000)),
   4770                                                   mkU32(0)))));
   4771                      putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32,
   4772                                                     mkU32(0),
   4773                                                     mkexpr(t7)),
   4774                                               binop(Iop_Or32,
   4775                                                     getDSPControl(),
   4776                                                     mkU32(0x00800000)),
   4777                                               getDSPControl()));
   4778                      putIReg(rt, IRExpr_ITE(binop(Iop_CmpNE32,
   4779                                                     mkU32(0),
   4780                                                     mkexpr(t4)),
   4781                                             mkU32(0x00007fff),
   4782                                             IRExpr_ITE(binop(Iop_CmpNE32,
   4783                                                              mkU32(0),
   4784                                                              mkexpr(t7)),
   4785                                                        mkU32(0xffff8000),
   4786                                                        unop(Iop_64to32,
   4787                                                             mkexpr(t1)))));
   4788                      break;
   4789                   }
   4790                   case 0x12: {  /* RDDSP*/
   4791                      DIP("rddsp r%u, mask 0x%x", rd, rddsp_mask);
   4792                      vassert(!mode64);
   4793 
   4794                      putIReg(rd, mkU32(0x0));
   4795 
   4796                      if ((rddsp_mask & 0x1) == 0x1) {
   4797                         /* Read pos field (bits 5-0) of DSPControl register. */
   4798                         putIReg(rd, binop(Iop_Or32,
   4799                                           getIReg(rd),
   4800                                           binop(Iop_And32,
   4801                                                 getDSPControl(),
   4802                                                 mkU32(0x0000003F))));
   4803                      }
   4804 
   4805                      if ((rddsp_mask & 0x2) == 0x2) {
   4806                         /* Read scount field (bits 12-7) of DSPControl
   4807                            register. */
   4808                         putIReg(rd, binop(Iop_Or32,
   4809                                           getIReg(rd),
   4810                                           binop(Iop_And32,
   4811                                                 getDSPControl(),
   4812                                                 mkU32(0x00001F80))));
   4813                      }
   4814 
   4815                      if ((rddsp_mask & 0x4) == 0x4) {
   4816                         /* Read C field (bit 13) of DSPControl register. */
   4817                         putIReg(rd, binop(Iop_Or32,
   4818                                           getIReg(rd),
   4819                                           binop(Iop_And32,
   4820                                                 getDSPControl(),
   4821                                                 mkU32(0x00002000))));
   4822                      }
   4823 
   4824                      if ((rddsp_mask & 0x8) == 0x8) {
   4825                         /* Read outflag field (bit s 23-16) of DSPControl
   4826                            register. */
   4827                         putIReg(rd, binop(Iop_Or32,
   4828                                           getIReg(rd),
   4829                                           binop(Iop_And32,
   4830                                                 getDSPControl(),
   4831                                                 mkU32(0x00FF0000))));
   4832                      }
   4833 
   4834                      if ((rddsp_mask & 0x10) == 0x10) {
   4835                         /* Read ccond field (bits 31-24) of DSPControl
   4836                            register. */
   4837                         putIReg(rd, binop(Iop_Or32,
   4838                                           getIReg(rd),
   4839                                           binop(Iop_And32,
   4840                                                 getDSPControl(),
   4841                                                 mkU32(0xFF000000))));
   4842                      }
   4843 
   4844                      if ((rddsp_mask & 0x20) == 0x20) {
   4845                         /* Read EFI field (bit 14) of DSPControl register. */
   4846                         putIReg(rd, binop(Iop_Or32,
   4847                                           getIReg(rd),
   4848                                           binop(Iop_And32,
   4849                                                 getDSPControl(),
   4850                                                 mkU32(0x00004000))));
   4851                      }
   4852 
   4853                      if ((rddsp_mask & 0x3f) == 0x3f) {
   4854                         /* Read all fields of DSPControl register. */
   4855                         putIReg(rd, getDSPControl());
   4856                      }
   4857                      break;
   4858                   }
   4859                   case 0x13: {  /* WRDSP */
   4860                      DIP("wrdsp r%u, mask 0x%x", rs, wrdsp_mask);
   4861                      vassert(!mode64);
   4862 
   4863                      if ((wrdsp_mask & 0x3f) == 0x3f) {
   4864                         /* If mips64 put all fields of rs, except bit 15 and bit
   4865                            6, to DSPControl register, otherwise put all except
   4866                            bits 15, 6 and bits 31..28. */
   4867                         putDSPControl(mode64 ?
   4868                                       binop(Iop_And32,
   4869                                             getIReg(rs),
   4870                                             mkU32(0xffff7fbf)) :
   4871                                       binop(Iop_And32,
   4872                                             getIReg(rs),
   4873                                             mkU32(0x0fff7fbf)));
   4874                      } else {
   4875                         if ((wrdsp_mask & 0x1) == 0x1) {
   4876                            /* Put bits 5-0 of rs to DSPControl register pos
   4877                               field. */
   4878                            putDSPControl(binop(Iop_Or32,
   4879                                                binop(Iop_And32,
   4880                                                      getDSPControl(),
   4881                                                      mkU32(0xFFFF7F40)),
   4882                                                binop(Iop_And32,
   4883                                                      getIReg(rs),
   4884                                                      mkU32(0x0000003F))));
   4885                         }
   4886 
   4887                         if ((wrdsp_mask & 0x2) == 0x2) {
   4888                            /* Put bits 12-7 of rs to DSPControl scount field. */
   4889                            putDSPControl(binop(Iop_Or32,
   4890                                                binop(Iop_And32,
   4891                                                      getDSPControl(),
   4892                                                      mkU32(0xFFFFE03F)),
   4893                                                binop(Iop_And32,
   4894                                                      getIReg(rs),
   4895                                                      mkU32(0x00001F80))));
   4896                         }
   4897 
   4898                         if ((wrdsp_mask & 0x4) == 0x4) {
   4899                            /* Put bit 13 of rs to DSPControl register C
   4900                               field. */
   4901                            putDSPControl(binop(Iop_Or32,
   4902                                                binop(Iop_And32,
   4903                                                      getDSPControl(),
   4904                                                      mkU32(0xFFFF5FBF)),
   4905                                                binop(Iop_And32,
   4906                                                      getIReg(rs),
   4907                                                      mkU32(0x00002000))));
   4908                         }
   4909 
   4910                         if ((wrdsp_mask & 0x8) == 0x8) {
   4911                            /* Put bits 23-16 of rs to DSPControl reg outflag
   4912                               field. */
   4913                            putDSPControl(binop(Iop_Or32,
   4914                                                binop(Iop_And32,
   4915                                                      getDSPControl(),
   4916                                                      mkU32(0xFF007FBF)),
   4917                                                binop(Iop_And32,
   4918                                                      getIReg(rs),
   4919                                                      mkU32(0x00FF0000))));
   4920                         }
   4921 
   4922                         if ((wrdsp_mask & 0x10) == 0x10) {
   4923                            /* Put bits 31-24 of rs to DSPControl reg ccond
   4924                               field. */
   4925                            putDSPControl(binop(Iop_Or32,
   4926                                                binop(Iop_And32,
   4927                                                      getDSPControl(),
   4928                                                      mkU32(0x00FF7FBF)),
   4929                                                binop(Iop_And32,
   4930                                                      getIReg(rs),
   4931                                                      mode64 ? mkU32(0xFF000000)
   4932                                                             : mkU32(0x0F000000))
   4933                                                )
   4934                                         );
   4935                         }
   4936 
   4937                         if ((wrdsp_mask & 0x20) == 0x20) {
   4938                            /* Put bit 14 of rs to DSPControl register EFI
   4939                               field. */
   4940                            putDSPControl(binop(Iop_Or32,
   4941                                                binop(Iop_And32,
   4942                                                      getDSPControl(),
   4943                                                      mkU32(0xFFFF3FBF)),
   4944                                                binop(Iop_And32,
   4945                                                      getIReg(rs),
   4946                                                      mkU32(0x00004000))));
   4947                         }
   4948                      }
   4949                      break;
   4950                   }
   4951                   case 0x1A: {  /* SHILO */
   4952                      DIP("shilo ac%u, %u", ac, shift);
   4953                      vassert(!mode64);
   4954                      t0 = newTemp(Ity_I64);
   4955                      t1 = newTemp(Ity_I64);
   4956 
   4957                      assign(t0, getAcc(ac));
   4958 
   4959                      putAcc(ac, mkexpr(t0));
   4960 
   4961                      if (0x20 == (shift & 0x3f)) {
   4962                         putAcc(ac, binop(Iop_32HLto64,
   4963                                          unop(Iop_64to32, mkexpr(t0)),
   4964                                          mkU32(0x0)));
   4965                      } else if (0x20 == (shift & 0x20)) {
   4966                         assign(t1, binop(Iop_Shl64,
   4967                                          mkexpr(t0),
   4968                                          unop(Iop_32to8,
   4969                                               binop(Iop_Add32,
   4970                                                     unop(Iop_Not32,
   4971                                                          mkU32(shift)),
   4972                                                     mkU32(0x1)))));
   4973 
   4974                         putAcc(ac, mkexpr(t1));
   4975                      } else {
   4976                         assign(t1, binop(Iop_Shr64, mkexpr(t0), mkU8(shift)));
   4977 
   4978                         putAcc(ac, mkexpr(t1));
   4979                      }
   4980                      break;
   4981                   }
   4982                   case 0x1B: {  /* SHILOV */
   4983                      DIP("shilov ac%u, r%u", ac, rs);
   4984                      vassert(!mode64);
   4985                      t0 = newTemp(Ity_I64);
   4986                      t1 = newTemp(Ity_I32);
   4987                      t2 = newTemp(Ity_I1);
   4988                      t3 = newTemp(Ity_I64);
   4989                      t4 = newTemp(Ity_I64);
   4990 
   4991                      assign(t0, getAcc(ac));
   4992                      assign(t1, binop(Iop_And32, getIReg(rs), mkU32(0x3f)));
   4993                      assign(t2, binop(Iop_CmpEQ32, mkexpr(t1), mkU32(0x20)));
   4994                      assign(t3, binop(Iop_Shl64,
   4995                                       mkexpr(t0),
   4996                                       unop(Iop_32to8,
   4997                                            binop(Iop_Add32,
   4998                                                  unop(Iop_Not32,
   4999                                                       mkexpr(t1)),
   5000                                                  mkU32(0x1)))));
   5001                      assign(t4, binop(Iop_Shr64,
   5002                                       mkexpr(t0),
   5003                                       unop(Iop_32to8,
   5004                                            mkexpr(t1))));
   5005 
   5006                      putAcc(ac,
   5007                             IRExpr_ITE(mkexpr(t2),
   5008                                        binop(Iop_32HLto64,
   5009                                              unop(Iop_64to32, mkexpr(t0)),
   5010                                              mkU32(0x0)),
   5011                                        IRExpr_ITE(binop(Iop_CmpEQ32,
   5012                                                         binop(Iop_And32,
   5013                                                               mkexpr(t1),
   5014                                                               mkU32(0x20)),
   5015                                                         mkU32(0x20)),
   5016                                                   mkexpr(t3),
   5017                                                   mkexpr(t4))));
   5018                      break;
   5019                   }
   5020                   case 0x1F: {  /* MTHLIP */
   5021                      DIP("mthlip r%u, ac%u", rs, ac);
   5022                      vassert(!mode64);
   5023                      t0 = newTemp(Ity_I64);
   5024                      t1 = newTemp(Ity_I32);
   5025                      t2 = newTemp(Ity_I32);
   5026                      t3 = newTemp(Ity_I1);
   5027 
   5028                      assign(t0, getAcc(ac));
   5029                      putAcc(ac, binop(Iop_32HLto64,
   5030                                       unop(Iop_64to32, mkexpr(t0)),
   5031                                       getIReg(rs)));
   5032                      assign(t1, binop(Iop_And32, getDSPControl(), mkU32(0x3f)));
   5033                      putDSPControl(IRExpr_ITE(binop(Iop_CmpLE32U,
   5034                                                     mkU32(32),
   5035                                                     mkexpr(t1)),
   5036                                               binop(Iop_Or32,
   5037                                                     binop(Iop_Sub32,
   5038                                                           mkexpr(t1),
   5039                                                           mkU32(32)),
   5040                                                    binop(Iop_And32,
   5041                                                          getDSPControl(),
   5042                                                          mkU32(0xffffffc0))),
   5043                                               binop(Iop_Or32,
   5044                                                     binop(Iop_Add32,
   5045                                                           mkexpr(t1),
   5046                                                           mkU32(32)),
   5047                                                     binop(Iop_And32,
   5048                                                           getDSPControl(),
   5049                                                           mkU32(0xffffffc0)))));
   5050                      break;
   5051                   }
   5052                   default:
   5053                      return -1;
   5054                }
   5055                break;  /* end of EXTR.W */
   5056             }
   5057             case 0xA: {  /* LX */
   5058                switch(sa) {
   5059                   case 0x0: {  /* LWX */
   5060                      DIP("lwx r%u, r%u(r%u)", rd, rt, rs);
   5061                      vassert(!mode64);
   5062                      t0 = newTemp(Ity_I32);
   5063 
   5064                      assign(t0, binop(Iop_Add32, getIReg(rt), getIReg(rs)));
   5065 
   5066                      putIReg(rd, load(Ity_I32, mkexpr(t0)));
   5067                      break;
   5068                   }
   5069                   case 0x4: {  /* LHX */
   5070                      DIP("lhx r%u, r%u(r%u)", rd, rt, rs);
   5071                      vassert(!mode64);
   5072                      t0 = newTemp(Ity_I32);
   5073 
   5074                      assign(t0, binop(Iop_Add32, getIReg(rt), getIReg(rs)));
   5075 
   5076                      putIReg(rd, unop(Iop_16Sto32, load(Ity_I16, mkexpr(t0))));
   5077                      break;
   5078                   }
   5079                   case 0x6: {  /* LBUX */
   5080                      DIP("lbux r%u, r%u(r%u)", rd, rt, rs);
   5081                      vassert(!mode64);
   5082                      t0 = newTemp(Ity_I32);
   5083 
   5084                      assign(t0, binop(Iop_Add32, getIReg(rt), getIReg(rs)));
   5085 
   5086                      putIReg(rd, unop(Iop_8Uto32, load(Ity_I8, mkexpr(t0))));
   5087                      break;
   5088                   }
   5089                   default:
   5090                      return -1;
   5091                }
   5092                break;  /* end of LX */
   5093             }
   5094             case 0xC: {  /* INSV */
   5095                switch(sa) {
   5096                   case 0x0: {  /* INSV */
   5097                      DIP("insv r%u, r%u", rt, rs);
   5098                      vassert(!mode64);
   5099 
   5100                      t0 = newTemp(Ity_I32);
   5101                      t1 = newTemp(Ity_I32);
   5102                      t2 = newTemp(Ity_I8);
   5103                      t3 = newTemp(Ity_I8);
   5104                      t4 = newTemp(Ity_I32);
   5105                      t5 = newTemp(Ity_I1);
   5106                      t6 = newTemp(Ity_I32);
   5107                      t7 = newTemp(Ity_I32);
   5108                      t8 = newTemp(Ity_I32);
   5109                      t9 = newTemp(Ity_I32);
   5110 
   5111                      /* t0 <- pos field of DSPControl register. */
   5112                      assign(t0, binop(Iop_And32, getDSPControl(), mkU32(0x3f)));
   5113                      /* t1 <- scount field of DSPControl register. */
   5114                      assign(t1, binop(Iop_Shr32,
   5115                                       binop(Iop_And32,
   5116                                             getDSPControl(),
   5117                                             mkU32(0x1f80)),
   5118                                       mkU8(7)));
   5119 
   5120                      assign(t2, unop(Iop_32to8,
   5121                                      binop(Iop_Add32,
   5122                                            mkexpr(t1),
   5123                                            mkexpr(t0))));
   5124 
   5125                      /* 32-(pos+size) most significant bits of rt. */
   5126                      assign(t6, binop(Iop_Shl32,
   5127                                       binop(Iop_Shr32,
   5128                                             getIReg(rt),
   5129                                             mkexpr(t2)),
   5130                                       mkexpr(t2)));
   5131 
   5132                      assign(t3, unop(Iop_32to8,
   5133                                      binop(Iop_Sub32,
   5134                                            mkU32(32),
   5135                                            mkexpr(t0))));
   5136                      /* Pos least significant bits of rt. */
   5137                      assign(t7, binop(Iop_Shr32,
   5138                                       binop(Iop_Shl32,
   5139                                             getIReg(rt),
   5140                                             mkexpr(t3)),
   5141                                       mkexpr(t3)));
   5142 
   5143                      /* Size least significant bits of rs,
   5144                         shifted to appropriate position. */
   5145                      assign(t8, binop(Iop_Shl32,
   5146                                       binop(Iop_And32,
   5147                                             getIReg(rs),
   5148                                             unop(Iop_Not32,
   5149                                                  binop(Iop_Shl32,
   5150                                                        mkU32(0xffffffff),
   5151                                                        unop(Iop_32to8,
   5152                                                             mkexpr(t1))))),
   5153                                       unop(Iop_32to8,
   5154                                            mkexpr(t0))));
   5155 
   5156                      putIReg(rt, IRExpr_ITE(binop(Iop_CmpEQ32,
   5157                                                   mkexpr(t0),
   5158                                                   mkU32(0)),
   5159                                             IRExpr_ITE(binop(Iop_CmpEQ32,
   5160                                                              mkexpr(t1),
   5161                                                              mkU32(32)),
   5162                                                        getIReg(rs),
   5163                                                        binop(Iop_Or32,
   5164                                                              mkexpr(t6),
   5165                                                              mkexpr(t8))),
   5166                                             IRExpr_ITE(binop(Iop_CmpEQ32,
   5167                                                              unop(Iop_8Uto32,
   5168                                                                   mkexpr(t2)),
   5169                                                              mkU32(32)),
   5170                                                        binop(Iop_Or32,
   5171                                                              mkexpr(t7),
   5172                                                              mkexpr(t8)),
   5173                                                        binop(Iop_Or32,
   5174                                                              binop(Iop_Or32,
   5175                                                                    mkexpr(t6),
   5176                                                                    mkexpr(t7)),
   5177                                                              mkexpr(t8)))));
   5178                      break;
   5179                   }
   5180                   default:
   5181                      return -1;
   5182                }
   5183                break;  /* enf of INSV */
   5184             }
   5185             case 0x10: {  /* ADDU.QB */
   5186                switch(sa) {
   5187                   case 0x00: {  /* ADDU.QB */
   5188                      DIP("addu.qb r%u, r%u, r%u", rd, rs, rt);
   5189                      vassert(!mode64);
   5190                      t0 = newTemp(Ity_I32);
   5191                      t1 = newTemp(Ity_I1);
   5192                      t2 = newTemp(Ity_I32);
   5193                      t3 = newTemp(Ity_I1);
   5194                      t4 = newTemp(Ity_I32);
   5195                      t5 = newTemp(Ity_I1);
   5196                      t6 = newTemp(Ity_I32);
   5197                      t7 = newTemp(Ity_I1);
   5198                      t8 = newTemp(Ity_I32);
   5199 
   5200                      /* Add rightmost bytes of rs and rt. */
   5201                      assign(t0,
   5202                             binop(Iop_Add32,
   5203                                   unop(Iop_8Uto32,
   5204                                        unop(Iop_16to8,
   5205                                             unop(Iop_32to16, getIReg(rs)))),
   5206                                   unop(Iop_8Uto32,
   5207                                        unop(Iop_16to8,
   5208                                             unop(Iop_32to16, getIReg(rt))))));
   5209                      /* t1 will be 1 if there is overflow, 0 otherwise. */
   5210                      assign(t1, binop(Iop_CmpEQ32,
   5211                                       binop(Iop_And32,
   5212                                             mkexpr(t0),
   5213                                             mkU32(0x00000100)),
   5214                                       mkU32(0x00000100)));
   5215 
   5216                      /* Add bits 15-8 of rs and rt. */
   5217                      assign(t2,
   5218                             binop(Iop_Add32,
   5219                                   unop(Iop_8Uto32,
   5220                                        unop(Iop_16HIto8,
   5221                                             unop(Iop_32to16, getIReg(rs)))),
   5222                                   unop(Iop_8Uto32,
   5223                                        unop(Iop_16HIto8,
   5224                                             unop(Iop_32to16, getIReg(rt))))));
   5225                      /* t3 will be 1 if there is overflow, 0 otherwise. */
   5226                      assign(t3, binop(Iop_CmpEQ32,
   5227                                       binop(Iop_And32,
   5228                                             mkexpr(t2),
   5229                                             mkU32(0x00000100)),
   5230                                       mkU32(0x00000100)));
   5231 
   5232                      /* Add bits 15-8 of rs and rt. */
   5233                      assign(t4,
   5234                             binop(Iop_Add32,
   5235                                   unop(Iop_8Uto32,
   5236                                        unop(Iop_16to8,
   5237                                             unop(Iop_32HIto16, getIReg(rs)))),
   5238                                   unop(Iop_8Uto32,
   5239                                        unop(Iop_16to8,
   5240                                             unop(Iop_32HIto16, getIReg(rt))))));
   5241                      /* t5 will be 1 if there is overflow, 0 otherwise. */
   5242                      assign(t5, binop(Iop_CmpEQ32,
   5243                                       binop(Iop_And32,
   5244                                             mkexpr(t4),
   5245                                             mkU32(0x00000100)),
   5246                                       mkU32(0x00000100)));
   5247 
   5248                      /* Add bits 15-8 of rs and rt. */
   5249                      assign(t6,
   5250                             binop(Iop_Add32,
   5251                                   unop(Iop_8Uto32,
   5252                                        unop(Iop_16HIto8,
   5253                                             unop(Iop_32HIto16, getIReg(rs)))),
   5254                                   unop(Iop_8Uto32,
   5255                                        unop(Iop_16HIto8,
   5256                                             unop(Iop_32HIto16, getIReg(rt))))));
   5257                      /* t7 will be 1 if there is overflow, 0 otherwise. */
   5258                      assign(t7, binop(Iop_CmpEQ32,
   5259                                       binop(Iop_And32,
   5260                                             mkexpr(t6),
   5261                                             mkU32(0x00000100)),
   5262                                       mkU32(0x00000100)));
   5263 
   5264                      assign(t8,
   5265                             binop(Iop_Or32,
   5266                                   binop(Iop_Or32,
   5267                                         binop(Iop_Or32,
   5268                                               unop(Iop_1Sto32, mkexpr(t7)),
   5269                                               unop(Iop_1Sto32,  mkexpr(t5))),
   5270                                         unop(Iop_1Sto32, mkexpr(t3))),
   5271                                   unop(Iop_1Sto32, mkexpr(t1))));
   5272 
   5273                      putDSPControl(IRExpr_ITE(binop(Iop_CmpEQ32,
   5274                                                     mkexpr(t8),
   5275                                                     mkU32(0x0)),
   5276                                               getDSPControl(),
   5277                                               binop(Iop_Or32,
   5278                                                     getDSPControl(),
   5279                                                     mkU32(0x00100000))));
   5280 
   5281                      putIReg(rd, binop(Iop_16HLto32,
   5282                                        binop(Iop_8HLto16,
   5283                                              unop(Iop_32to8, mkexpr(t6)),
   5284                                              unop(Iop_32to8, mkexpr(t4))),
   5285                                        binop(Iop_8HLto16,
   5286                                              unop(Iop_32to8, mkexpr(t2)),
   5287                                              unop(Iop_32to8, mkexpr(t0)))));
   5288                      break;
   5289                   }
   5290                   case 0x1: {  /* SUBU.QB */
   5291                      DIP("subu.qb r%u, r%u, r%u", rd, rs, rt);
   5292                      vassert(!mode64);
   5293                      t0 = newTemp(Ity_I32);
   5294                      t1 = newTemp(Ity_I1);
   5295                      t2 = newTemp(Ity_I32);
   5296                      t3 = newTemp(Ity_I1);
   5297                      t4 = newTemp(Ity_I32);
   5298                      t5 = newTemp(Ity_I1);
   5299                      t6 = newTemp(Ity_I32);
   5300                      t7 = newTemp(Ity_I1);
   5301                      t8 = newTemp(Ity_I32);
   5302 
   5303                      /* Subtract rightmost bytes of rs and rt. */
   5304                      assign(t0,
   5305                             binop(Iop_Sub32,
   5306                                   unop(Iop_8Uto32,
   5307                                        unop(Iop_16to8,
   5308                                             unop(Iop_32to16, getIReg(rs)))),
   5309                                   unop(Iop_8Uto32,
   5310                                        unop(Iop_16to8,
   5311                                             unop(Iop_32to16, getIReg(rt))))));
   5312                      /* t1 will be 1 if there is overflow, 0 otherwise. */
   5313                      assign(t1, binop(Iop_CmpEQ32,
   5314                                       binop(Iop_And32,
   5315                                             mkexpr(t0),
   5316                                             mkU32(0x00000100)),
   5317                                       mkU32(0x00000100)));
   5318 
   5319                      /* Subtract bits 15-8 of rs and rt. */
   5320                      assign(t2,
   5321                             binop(Iop_Sub32,
   5322                                   unop(Iop_8Uto32,
   5323                                        unop(Iop_16HIto8,
   5324                                             unop(Iop_32to16, getIReg(rs)))),
   5325                                   unop(Iop_8Uto32,
   5326                                        unop(Iop_16HIto8,
   5327                                             unop(Iop_32to16, getIReg(rt))))));
   5328                      /* t3 will be 1 if there is overflow, 0 otherwise. */
   5329                      assign(t3, binop(Iop_CmpEQ32,
   5330                                       binop(Iop_And32,
   5331                                             mkexpr(t2),
   5332                                             mkU32(0x00000100)),
   5333                                       mkU32(0x00000100)));
   5334 
   5335                      /* Subtract bits 15-8 of rs and rt. */
   5336                      assign(t4,
   5337                             binop(Iop_Sub32,
   5338                                   unop(Iop_8Uto32,
   5339                                        unop(Iop_16to8,
   5340                                             unop(Iop_32HIto16, getIReg(rs)))),
   5341                                   unop(Iop_8Uto32,
   5342                                        unop(Iop_16to8,
   5343                                             unop(Iop_32HIto16, getIReg(rt))))));
   5344                      /* t5 will be 1 if there is overflow, 0 otherwise. */
   5345                      assign(t5, binop(Iop_CmpEQ32,
   5346                                       binop(Iop_And32,
   5347                                             mkexpr(t4),
   5348                                             mkU32(0x00000100)),
   5349                                       mkU32(0x00000100)));
   5350 
   5351                      /* Subtract bits 15-8 of rs and rt. */
   5352                      assign(t6,
   5353                             binop(Iop_Sub32,
   5354                                   unop(Iop_8Uto32,
   5355                                        unop(Iop_16HIto8,
   5356                                             unop(Iop_32HIto16, getIReg(rs)))),
   5357                                   unop(Iop_8Uto32,
   5358                                        unop(Iop_16HIto8,
   5359                                             unop(Iop_32HIto16, getIReg(rt))))));
   5360                      /* t7 will be 1 if there is overflow, 0 otherwise. */
   5361                      assign(t7, binop(Iop_CmpEQ32,
   5362                                       binop(Iop_And32,
   5363                                             mkexpr(t6),
   5364                                             mkU32(0x00000100)),
   5365                                       mkU32(0x00000100)));
   5366 
   5367                      assign(t8, binop(Iop_Or32,
   5368                                       binop(Iop_Or32,
   5369                                             binop(Iop_Or32,
   5370                                                   unop(Iop_1Sto32, mkexpr(t7)),
   5371                                                   unop(Iop_1Sto32, mkexpr(t5))),
   5372                                             unop(Iop_1Sto32, mkexpr(t3))),
   5373                                       unop(Iop_1Sto32, mkexpr(t1))));
   5374 
   5375                      putDSPControl(IRExpr_ITE(binop(Iop_CmpEQ32,
   5376                                                      mkexpr(t8),
   5377                                                      mkU32(0x0)),
   5378                                               getDSPControl(),
   5379                                               binop(Iop_Or32,
   5380                                                     getDSPControl(),
   5381                                                     mkU32(0x00100000))));
   5382 
   5383                      putIReg(rd, binop(Iop_16HLto32,
   5384                                        binop(Iop_8HLto16,
   5385                                              unop(Iop_32to8, mkexpr(t6)),
   5386                                              unop(Iop_32to8, mkexpr(t4))),
   5387                                        binop(Iop_8HLto16,
   5388                                              unop(Iop_32to8, mkexpr(t2)),
   5389                                              unop(Iop_32to8, mkexpr(t0)))));
   5390                      break;
   5391                   }
   5392                   case 0x04: {  /* ADDU_S.QB */
   5393                      DIP("addu_s.qb r%u, r%u, r%u", rd, rs, rt);
   5394                      vassert(!mode64);
   5395                      t0 = newTemp(Ity_I32);
   5396                      t1 = newTemp(Ity_I1);
   5397                      t2 = newTemp(Ity_I8);
   5398                      t3 = newTemp(Ity_I32);
   5399                      t4 = newTemp(Ity_I1);
   5400                      t5 = newTemp(Ity_I8);
   5401                      t6 = newTemp(Ity_I32);
   5402                      t7 = newTemp(Ity_I1);
   5403                      t8 = newTemp(Ity_I8);
   5404                      t9 = newTemp(Ity_I32);
   5405                      t10 = newTemp(Ity_I1);
   5406                      t11 = newTemp(Ity_I8);
   5407                      t12 = newTemp(Ity_I32);
   5408 
   5409                      /* Add rightmost bytes of rs and rt. */
   5410                      assign(t0,
   5411                             binop(Iop_Add32,
   5412                                   unop(Iop_8Uto32,
   5413                                        unop(Iop_16to8,
   5414                                             unop(Iop_32to16, getIReg(rs)))),
   5415                                   unop(Iop_8Uto32,
   5416                                        unop(Iop_16to8,
   5417                                             unop(Iop_32to16, getIReg(rt))))));
   5418                      /* t1 will be 1 if there is overflow, 0 otherwise. */
   5419                      assign(t1, binop(Iop_CmpEQ32,
   5420                                       binop(Iop_And32,
   5421                                             mkexpr(t0),
   5422                                             mkU32(0x00000100)),
   5423                                       mkU32(0x00000100)));
   5424                      /* Saturate if necessary. */
   5425                      assign(t2, IRExpr_ITE(mkexpr(t1),
   5426                                            mkU8(0xff),
   5427                                            unop(Iop_32to8, mkexpr(t0))));
   5428 
   5429                      /* Add bits 15-8 of rs and rt. */
   5430                      assign(t3,
   5431                             binop(Iop_Add32,
   5432                                   unop(Iop_8Uto32,
   5433                                        unop(Iop_16HIto8,
   5434                                             unop(Iop_32to16, getIReg(rs)))),
   5435                                   unop(Iop_8Uto32,
   5436                                        unop(Iop_16HIto8,
   5437                                             unop(Iop_32to16, getIReg(rt))))));
   5438                      /* t4 will be 1 if there is overflow, 0 otherwise. */
   5439                      assign(t4, binop(Iop_CmpEQ32,
   5440                                       binop(Iop_And32,
   5441                                             mkexpr(t3),
   5442                                             mkU32(0x00000100)),
   5443                                       mkU32(0x00000100)));
   5444                      /* Saturate if necessary. */
   5445                      assign(t5, IRExpr_ITE(mkexpr(t4),
   5446                                            mkU8(0xff),
   5447                                            unop(Iop_32to8, mkexpr(t3))));
   5448 
   5449                      /* Add bits 15-8 of rs and rt. */
   5450                      assign(t6,
   5451                             binop(Iop_Add32,
   5452                                   unop(Iop_8Uto32,
   5453                                        unop(Iop_16to8,
   5454                                             unop(Iop_32HIto16, getIReg(rs)))),
   5455                                   unop(Iop_8Uto32,
   5456                                        unop(Iop_16to8,
   5457                                             unop(Iop_32HIto16, getIReg(rt))))));
   5458                      /* t7 will be 1 if there is overflow, 0 otherwise. */
   5459                      assign(t7, binop(Iop_CmpEQ32,
   5460                                       binop(Iop_And32,
   5461                                             mkexpr(t6),
   5462                                             mkU32(0x00000100)),
   5463                                       mkU32(0x00000100)));
   5464                      /* Saturate if necessary. */
   5465                      assign(t8, IRExpr_ITE(mkexpr(t7),
   5466                                            mkU8(0xff),
   5467                                            unop(Iop_32to8, mkexpr(t6))));
   5468 
   5469                      /* Add bits 15-8 of rs and rt. */
   5470                      assign(t9,
   5471                             binop(Iop_Add32,
   5472                                   unop(Iop_8Uto32,
   5473                                        unop(Iop_16HIto8,
   5474                                             unop(Iop_32HIto16, getIReg(rs)))),
   5475                                   unop(Iop_8Uto32,
   5476                                        unop(Iop_16HIto8,
   5477                                             unop(Iop_32HIto16, getIReg(rt))))));
   5478                      /* t10 will be 1 if there is overflow, 0 otherwise. */
   5479                      assign(t10, binop(Iop_CmpEQ32,
   5480                                        binop(Iop_And32,
   5481                                              mkexpr(t9),
   5482                                              mkU32(0x00000100)),
   5483                                        mkU32(0x00000100)));
   5484                      /* Saturate if necessary. */
   5485                      assign(t11, IRExpr_ITE(mkexpr(t10),
   5486                                             mkU8(0xff),
   5487                                             unop(Iop_32to8, mkexpr(t9))));
   5488 
   5489                      assign(t12,
   5490                             binop(Iop_Or32,
   5491                                   binop(Iop_Or32,
   5492                                         binop(Iop_Or32,
   5493                                               unop(Iop_1Sto32, mkexpr(t10)),
   5494                                               unop(Iop_1Sto32, mkexpr(t7))),
   5495                                         unop(Iop_1Sto32, mkexpr(t4))),
   5496                                   unop(Iop_1Sto32, mkexpr(t1))));
   5497 
   5498                      putDSPControl(IRExpr_ITE(binop(Iop_CmpEQ32,
   5499                                                     mkexpr(t12),
   5500                                                     mkU32(0x0)),
   5501                                               getDSPControl(),
   5502                                               binop(Iop_Or32,
   5503                                                     getDSPControl(),
   5504                                                     mkU32(0x00100000))));
   5505 
   5506                      putIReg(rd,
   5507                              binop(Iop_16HLto32,
   5508                                    binop(Iop_8HLto16, mkexpr(t11), mkexpr(t8)),
   5509                                    binop(Iop_8HLto16, mkexpr(t5), mkexpr(t2))));
   5510                      break;
   5511                   }
   5512                   case 0x05: {  /* SUBU_S.QB */
   5513                      DIP("subu_s.qb r%u, r%u, r%u", rd, rs, rt);
   5514                      vassert(!mode64);
   5515                      t1 = newTemp(Ity_I32);
   5516                      t2 = newTemp(Ity_I1);
   5517                      t3 = newTemp(Ity_I1);
   5518                      t4 = newTemp(Ity_I1);
   5519                      t5 = newTemp(Ity_I1);
   5520                      t6 = newTemp(Ity_I32);
   5521                      t7 = newTemp(Ity_I32);
   5522                      t8 = newTemp(Ity_I32);
   5523                      t9 = newTemp(Ity_I32);
   5524 
   5525                      /* Use C function to easily calculate the result
   5526                         and write it in the register more conveniently
   5527                         Underflow is checked using step by step subtraction. */
   5528                      assign(t1, binop(Iop_QSub8Ux4, getIReg(rs), getIReg(rt)));
   5529 
   5530                      /* Subtract each byte of rs and rt. */
   5531                      assign(t6,
   5532                             binop(Iop_Sub32,
   5533                                   unop(Iop_8Uto32,
   5534                                        unop(Iop_16to8,
   5535                                             unop(Iop_32to16, getIReg(rs)))),
   5536                                   unop(Iop_8Uto32,
   5537                                        unop(Iop_16to8,
   5538                                             unop(Iop_32to16, getIReg(rt))))));
   5539                      assign(t7,
   5540                             binop(Iop_Sub32,
   5541                                   unop(Iop_8Uto32,
   5542                                        unop(Iop_16HIto8,
   5543                                             unop(Iop_32to16, getIReg(rs)))),
   5544                                   unop(Iop_8Uto32,
   5545                                        unop(Iop_16HIto8,
   5546                                             unop(Iop_32to16, getIReg(rt))))));
   5547                      assign(t8,
   5548                             binop(Iop_Sub32,
   5549                                   unop(Iop_8Uto32,
   5550                                        unop(Iop_16to8,
   5551                                             unop(Iop_32HIto16, getIReg(rs)))),
   5552                                   unop(Iop_8Uto32,
   5553                                        unop(Iop_16to8,
   5554                                             unop(Iop_32HIto16, getIReg(rt))))));
   5555                      assign(t9,
   5556                             binop(Iop_Sub32,
   5557                                   unop(Iop_8Uto32,
   5558                                        unop(Iop_16HIto8,
   5559                                             unop(Iop_32HIto16, getIReg(rs)))),
   5560                                   unop(Iop_8Uto32,
   5561                                        unop(Iop_16HIto8,
   5562                                             unop(Iop_32HIto16, getIReg(rt))))));
   5563 
   5564                      /* Put 1 to bit 20 in DSPControl if there is underflow
   5565                         in either byte. */
   5566                      assign(t2, binop(Iop_CmpEQ32,
   5567                                       binop(Iop_And32,
   5568                                             mkexpr(t6),
   5569                                             mkU32(0x00000100)),
   5570                                       mkU32(0x00000100)));
   5571                      putDSPControl(IRExpr_ITE(mkexpr(t2),
   5572                                               binop(Iop_Or32,
   5573                                                     getDSPControl(),
   5574                                                     mkU32(0x00100000)),
   5575                                               getDSPControl()));
   5576                      assign(t3, binop(Iop_CmpEQ32,
   5577                                       binop(Iop_And32,
   5578                                             mkexpr(t7),
   5579                                             mkU32(0x00000100)),
   5580                                       mkU32(0x00000100)));
   5581                      putDSPControl(IRExpr_ITE(mkexpr(t3),
   5582                                               binop(Iop_Or32,
   5583                                                     getDSPControl(),
   5584                                                     mkU32(0x00100000)),
   5585                                               getDSPControl()));
   5586                      assign(t4, binop(Iop_CmpEQ32,
   5587                                       binop(Iop_And32,
   5588                                             mkexpr(t8),
   5589                                             mkU32(0x00000100)),
   5590                                       mkU32(0x00000100)));
   5591                      putDSPControl(IRExpr_ITE(mkexpr(t4),
   5592                                               binop(Iop_Or32,
   5593                                                     getDSPControl(),
   5594                                                     mkU32(0x00100000)),
   5595                                               getDSPControl()));
   5596                      assign(t5, binop(Iop_CmpEQ32,
   5597                                       binop(Iop_And32,
   5598                                             mkexpr(t9),
   5599                                             mkU32(0x00000100)),
   5600                                       mkU32(0x00000100)));
   5601                      putDSPControl(IRExpr_ITE(mkexpr(t5),
   5602                                               binop(Iop_Or32,
   5603                                                     getDSPControl(),
   5604                                                     mkU32(0x00100000)),
   5605                                               getDSPControl()));
   5606                      putIReg(rd, mkexpr(t1));
   5607                      break;
   5608                   }
   5609                   case 0x6: {  /* MULEU_S.PH.QBL */
   5610                      DIP("muleu_s.ph.qbl r%u, r%u, r%u", rd, rs, rt);
   5611                      vassert(!mode64);
   5612                      t0 = newTemp(Ity_I32);
   5613                      t1 = newTemp(Ity_I32);
   5614                      t2 = newTemp(Ity_I1);
   5615                      t3 = newTemp(Ity_I1);
   5616 
   5617                      assign(t0,
   5618                             unop(Iop_64to32,
   5619                                  binop(Iop_MullU32,
   5620                                        unop(Iop_8Uto32,
   5621                                             unop(Iop_16HIto8,
   5622                                                  unop(Iop_32HIto16,
   5623                                                       getIReg(rs)))),
   5624                                        unop(Iop_16Uto32,
   5625                                             unop(Iop_32HIto16, getIReg(rt))))));
   5626                      assign(t1,
   5627                             unop(Iop_64to32,
   5628                                  binop(Iop_MullU32,
   5629                                        unop(Iop_8Uto32,
   5630                                             unop(Iop_16to8,
   5631                                                  unop(Iop_32HIto16,
   5632                                                       getIReg(rs)))),
   5633                                        unop(Iop_16Uto32,
   5634                                             unop(Iop_32to16, getIReg(rt))))));
   5635 
   5636                      assign(t2, binop(Iop_CmpNE32,
   5637                                       mkU32(0x0),
   5638                                       binop(Iop_And32,
   5639                                             mkexpr(t0),
   5640                                             mkU32(0x03ff0000))));
   5641                      assign(t3, binop(Iop_CmpNE32,
   5642                                       mkU32(0x0),
   5643                                       binop(Iop_And32,
   5644                                             mkexpr(t1),
   5645                                             mkU32(0x03ff0000))));
   5646                      putDSPControl(IRExpr_ITE(mkexpr(t2),
   5647                                               binop(Iop_Or32,
   5648                                                     getDSPControl(),
   5649                                                     mkU32(0x200000)),
   5650                                               IRExpr_ITE(mkexpr(t3),
   5651                                                          binop(Iop_Or32,
   5652                                                                getDSPControl(),
   5653                                                                mkU32(0x200000)),
   5654                                                          getDSPControl())));
   5655                      putIReg(rd,
   5656                              binop(Iop_16HLto32,
   5657                                    IRExpr_ITE(mkexpr(t2),
   5658                                               mkU16(0xffff),
   5659                                               unop(Iop_32to16, mkexpr(t0))),
   5660                                    IRExpr_ITE(mkexpr(t3),
   5661                                               mkU16(0xffff),
   5662                                               unop(Iop_32to16, mkexpr(t1)))));
   5663                      break;
   5664                   }
   5665                   case 0x7: {  /* MULEU_S.PH.QBR */
   5666                      DIP("muleu_s.ph.qbr r%u, r%u, r%u", rd, rs, rt);
   5667                      vassert(!mode64);
   5668                      t0 = newTemp(Ity_I32);
   5669                      t1 = newTemp(Ity_I32);
   5670                      t2 = newTemp(Ity_I1);
   5671                      t3 = newTemp(Ity_I1);
   5672 
   5673                      assign(t0, unop(Iop_64to32,
   5674                                      binop(Iop_MullU32,
   5675                                            unop(Iop_8Uto32,
   5676                                                 unop(Iop_16HIto8,
   5677                                                      unop(Iop_32to16,
   5678                                                           getIReg(rs)))),
   5679                                            unop(Iop_16Uto32,
   5680                                                 unop(Iop_32HIto16,
   5681                                                      getIReg(rt))))));
   5682                      assign(t1, unop(Iop_64to32,
   5683                                      binop(Iop_MullU32,
   5684                                            unop(Iop_8Uto32,
   5685                                                 unop(Iop_16to8,
   5686                                                      unop(Iop_32to16,
   5687                                                           getIReg(rs)))),
   5688                                            unop(Iop_16Uto32,
   5689                                                 unop(Iop_32to16,
   5690                                                      getIReg(rt))))));
   5691 
   5692                      assign(t2, binop(Iop_CmpNE32,
   5693                                       mkU32(0x0),
   5694                                       binop(Iop_And32,
   5695                                             mkexpr(t0),
   5696                                             mkU32(0x03ff0000))));
   5697                      assign(t3, binop(Iop_CmpNE32,
   5698                                       mkU32(0x0),
   5699                                       binop(Iop_And32,
   5700                                             mkexpr(t1),
   5701                                             mkU32(0x03ff0000))));
   5702                      putDSPControl(IRExpr_ITE(mkexpr(t2),
   5703                                               binop(Iop_Or32,
   5704                                                     getDSPControl(),
   5705                                                     mkU32(0x200000)),
   5706                                               IRExpr_ITE(mkexpr(t3),
   5707                                                          binop(Iop_Or32,
   5708                                                                getDSPControl(),
   5709                                                                mkU32(0x200000)),
   5710                                                          getDSPControl())));
   5711                      putIReg(rd, binop(Iop_16HLto32,
   5712                                        IRExpr_ITE(mkexpr(t2),
   5713                                                   mkU16(0xffff),
   5714                                                   unop(Iop_32to16,
   5715                                                        mkexpr(t0))),
   5716                                        IRExpr_ITE(mkexpr(t3),
   5717                                                   mkU16(0xffff),
   5718                                                   unop(Iop_32to16,
   5719                                                        mkexpr(t1)))));
   5720                      break;
   5721                   }
   5722                   case 0x08: {  /* ADDU.PH */
   5723                      DIP("addu.ph r%u, r%u, r%u", rd, rs, rt);
   5724                      vassert(!mode64);
   5725                      t0 = newTemp(Ity_I32);
   5726                      t1 = newTemp(Ity_I1);
   5727                      t2 = newTemp(Ity_I32);
   5728                      t3 = newTemp(Ity_I1);
   5729 
   5730                      /* Add lower halves. */
   5731                      assign(t0, binop(Iop_Add32,
   5732                                       unop(Iop_16Uto32,
   5733                                            unop(Iop_32to16, getIReg(rs))),
   5734                                       unop(Iop_16Uto32,
   5735                                            unop(Iop_32to16, getIReg(rt)))));
   5736 
   5737                      /* Detect overflow. */
   5738                      assign(t1, binop(Iop_CmpLT32U,
   5739                                       unop(Iop_16Uto32,
   5740                                            unop(Iop_32to16, mkexpr(t0))),
   5741                                       unop(Iop_16Uto32,
   5742                                            unop(Iop_32to16, getIReg(rs)))));
   5743 
   5744                      putDSPControl(IRExpr_ITE(mkexpr(t1),
   5745                                               binop(Iop_Or32,
   5746                                                     getDSPControl(),
   5747                                                     mkU32(0x00100000)),
   5748                                               getDSPControl()));
   5749 
   5750                      /* Add higher halves. */
   5751                      assign(t2, binop(Iop_Add32,
   5752                                       unop(Iop_16Uto32,
   5753                                            unop(Iop_32HIto16, getIReg(rs))),
   5754                                       unop(Iop_16Uto32,
   5755                                            unop(Iop_32HIto16, getIReg(rt)))));
   5756 
   5757                      /* Detect overflow. */
   5758                      assign(t3, binop(Iop_CmpLT32U,
   5759                                       unop(Iop_16Uto32,
   5760                                            unop(Iop_32to16, mkexpr(t2))),
   5761                                       unop(Iop_16Uto32,
   5762                                            unop(Iop_32HIto16,
   5763                                                 getIReg(rs)))));
   5764 
   5765                      putDSPControl(IRExpr_ITE(mkexpr(t3),
   5766                                               binop(Iop_Or32,
   5767                                                     getDSPControl(),
   5768                                                     mkU32(0x00100000)),
   5769                                               getDSPControl()));
   5770 
   5771                      putIReg(rd, binop(Iop_16HLto32,
   5772                                        unop(Iop_32to16, mkexpr(t2)),
   5773                                        unop(Iop_32to16, mkexpr(t0))));
   5774                      break;
   5775                   }
   5776                   case 0x9: {  /* SUBU.PH */
   5777                      DIP("subu.ph r%u, r%u, r%u", rd, rs, rt);
   5778                      vassert(!mode64);
   5779                      t0 = newTemp(Ity_I32);
   5780                      t1 = newTemp(Ity_I1);
   5781                      t2 = newTemp(Ity_I32);
   5782                      t3 = newTemp(Ity_I1);
   5783 
   5784                      /* Substract lower halves. */
   5785                      assign(t0, binop(Iop_Sub32,
   5786                                       unop(Iop_16Uto32,
   5787                                            unop(Iop_32to16, getIReg(rs))),
   5788                                       unop(Iop_16Uto32,
   5789                                            unop(Iop_32to16, getIReg(rt)))));
   5790 
   5791                      /* Detect underflow. */
   5792                      assign(t1, binop(Iop_CmpNE32,
   5793                                       binop(Iop_And32,
   5794                                             mkexpr(t0),
   5795                                             mkU32(0x00010000)),
   5796                                       mkU32(0x0)));
   5797 
   5798                      putDSPControl(IRExpr_ITE(mkexpr(t1),
   5799                                               binop(Iop_Or32,
   5800                                                     getDSPControl(),
   5801                                                     mkU32(0x00100000)),
   5802                                               getDSPControl()));
   5803 
   5804                      /* Subtract higher halves. */
   5805                      assign(t2, binop(Iop_Sub32,
   5806                                       unop(Iop_16Uto32,
   5807                                            unop(Iop_32HIto16, getIReg(rs))),
   5808                                       unop(Iop_16Uto32,
   5809                                            unop(Iop_32HIto16, getIReg(rt)))));
   5810 
   5811                      /* Detect underflow. */
   5812                      assign(t3, binop(Iop_CmpNE32,
   5813                                       binop(Iop_And32,
   5814                                             mkexpr(t2),
   5815                                             mkU32(0x00010000)),
   5816                                       mkU32(0x0)));
   5817 
   5818                      putDSPControl(IRExpr_ITE(mkexpr(t3),
   5819                                               binop(Iop_Or32,
   5820                                                     getDSPControl(),
   5821                                                     mkU32(0x00100000)),
   5822                                               getDSPControl()));
   5823 
   5824                      putIReg(rd, binop(Iop_16HLto32,
   5825                                        unop(Iop_32to16, mkexpr(t2)),
   5826                                        unop(Iop_32to16, mkexpr(t0))));
   5827                      break;
   5828                   }
   5829                   case 0xA: {  /* ADDQ.PH */
   5830                      DIP("addq.ph r%u, r%u, r%u", rd, rs, rt);
   5831                      vassert(!mode64);
   5832                      t0 = newTemp(Ity_I32);
   5833                      t1 = newTemp(Ity_I1);
   5834                      t2 = newTemp(Ity_I32);
   5835                      t3 = newTemp(Ity_I1);
   5836                      t6 = newTemp(Ity_I32);
   5837                      t7 = newTemp(Ity_I32);
   5838 
   5839                      /* Add lower halves. */
   5840                      assign(t0, binop(Iop_Add32,
   5841                                       unop(Iop_16Sto32,
   5842                                            unop(Iop_32to16, getIReg(rs))),
   5843                                       unop(Iop_16Sto32,
   5844                                            unop(Iop_32to16, getIReg(rt)))));
   5845 
   5846                      /* Bit 16 of the result. */
   5847                      assign(t6, binop(Iop_And32,
   5848                                       unop(Iop_16Uto32,
   5849                                            unop(Iop_32HIto16, mkexpr(t0))),
   5850                                       mkU32(0x1)));
   5851                      /* Detect overflow. */
   5852                      assign(t1, binop(Iop_CmpNE32,
   5853                                       binop(Iop_Shr32,
   5854                                             binop(Iop_And32,
   5855                                                   mkexpr(t0),
   5856                                                   mkU32(0x8000)),
   5857                                             mkU8(15)),
   5858                                       mkexpr(t6)));
   5859 
   5860                      putDSPControl(IRExpr_ITE(mkexpr(t1),
   5861                                               binop(Iop_Or32,
   5862                                                     getDSPControl(),
   5863                                                     mkU32(0x00100000)),
   5864                                               getDSPControl()));
   5865 
   5866                      /* Add higher halves. */
   5867                      assign(t2, binop(Iop_Add32,
   5868                                       unop(Iop_16Sto32,
   5869                                            unop(Iop_32HIto16, getIReg(rs))),
   5870                                       unop(Iop_16Sto32,
   5871                                            unop(Iop_32HIto16, getIReg(rt)))));
   5872 
   5873                      /* Bit 16 of the result. */
   5874                      assign(t7, binop(Iop_And32,
   5875                                       unop(Iop_16Uto32,
   5876                                            unop(Iop_32HIto16, mkexpr(t2))),
   5877                                       mkU32(0x1)));
   5878                      /* Detect overflow. */
   5879                      assign(t3, binop(Iop_CmpNE32,
   5880                                       binop(Iop_Shr32,
   5881                                             binop(Iop_And32,
   5882                                                   mkexpr(t2),
   5883                                                   mkU32(0x00008000)),
   5884                                             mkU8(15)),
   5885                                       mkexpr(t7)));
   5886 
   5887                      putDSPControl(IRExpr_ITE(mkexpr(t3),
   5888                                               binop(Iop_Or32,
   5889                                                     getDSPControl(),
   5890                                                     mkU32(0x00100000)),
   5891                                               getDSPControl()));
   5892 
   5893                      putIReg(rd, binop(Iop_16HLto32,
   5894                                        unop(Iop_32to16, mkexpr(t2)),
   5895                                        unop(Iop_32to16, mkexpr(t0))));
   5896                      break;
   5897                   }
   5898                   case 0xB: {  /* SUBQ.PH */
   5899                      DIP("subq.ph r%u, r%u, r%u", rd, rs, rt);
   5900                      vassert(!mode64);
   5901                      t0 = newTemp(Ity_I32);
   5902                      t1 = newTemp(Ity_I1);
   5903                      t2 = newTemp(Ity_I32);
   5904                      t3 = newTemp(Ity_I1);
   5905                      t6 = newTemp(Ity_I32);
   5906                      t7 = newTemp(Ity_I32);
   5907 
   5908                      /* Subtract lower halves. */
   5909                      assign(t0, binop(Iop_Sub32,
   5910                                       unop(Iop_16Sto32,
   5911                                            unop(Iop_32to16, getIReg(rs))),
   5912                                       unop(Iop_16Sto32,
   5913                                            unop(Iop_32to16, getIReg(rt)))));
   5914 
   5915                      /* Bit 16 of the result. */
   5916                      assign(t6, binop(Iop_And32,
   5917                                       unop(Iop_16Uto32,
   5918                                            unop(Iop_32HIto16, mkexpr(t0))),
   5919                                       mkU32(0x1)));
   5920                      /* Compare the signs of input value and the result. */
   5921                      assign(t1, binop(Iop_CmpNE32,
   5922                                       binop(Iop_Shr32,
   5923                                             binop(Iop_And32,
   5924                                                   mkexpr(t0),
   5925                                                   mkU32(0x8000)),
   5926                                             mkU8(15)),
   5927                                       mkexpr(t6)));
   5928 
   5929                      putDSPControl(IRExpr_ITE(mkexpr(t1),
   5930                                               binop(Iop_Or32,
   5931                                                     getDSPControl(),
   5932                                                     mkU32(0x00100000)),
   5933                                               getDSPControl()));
   5934 
   5935                      /* Subtract higher halves. */
   5936                      assign(t2, binop(Iop_Sub32,
   5937                                       unop(Iop_16Sto32,
   5938                                            unop(Iop_32HIto16, getIReg(rs))),
   5939                                       unop(Iop_16Sto32,
   5940                                            unop(Iop_32HIto16, getIReg(rt)))));
   5941 
   5942                      /* Bit 16 of the result. */
   5943                      assign(t7, binop(Iop_And32,
   5944                                       unop(Iop_16Uto32,
   5945                                            unop(Iop_32HIto16, mkexpr(t2))),
   5946                                       mkU32(0x1)));
   5947                      /* Compare the signs of input value and the result. */
   5948                      assign(t3, binop(Iop_CmpNE32,
   5949                                       binop(Iop_Shr32,
   5950                                             binop(Iop_And32,
   5951                                                   mkexpr(t2),
   5952                                                   mkU32(0x00008000)),
   5953                                             mkU8(15)),
   5954                                       mkexpr(t7)));
   5955 
   5956                      putDSPControl(IRExpr_ITE(mkexpr(t3),
   5957                                               binop(Iop_Or32,
   5958                                                     getDSPControl(),
   5959                                                     mkU32(0x00100000)),
   5960                                               getDSPControl()));
   5961 
   5962                      putIReg(rd, binop(Iop_16HLto32,
   5963                                        unop(Iop_32to16, mkexpr(t2)),
   5964                                        unop(Iop_32to16, mkexpr(t0))));
   5965                      break;
   5966                   }
   5967                   case 0xC: {  /* ADDU_S.PH */
   5968                      DIP("addu_s.ph r%u, r%u, r%u", rd, rs, rt);
   5969                      vassert(!mode64);
   5970                      t0 = newTemp(Ity_I32);
   5971                      t1 = newTemp(Ity_I1);
   5972                      t2 = newTemp(Ity_I32);
   5973                      t3 = newTemp(Ity_I1);
   5974 
   5975                      /* Add lower halves. */
   5976                      assign(t0, binop(Iop_Add32,
   5977                                       unop(Iop_16Uto32,
   5978                                            unop(Iop_32to16, getIReg(rs))),
   5979                                       unop(Iop_16Uto32,
   5980                                            unop(Iop_32to16, getIReg(rt)))));
   5981 
   5982                      /* Detect overflow. */
   5983                      assign(t1, binop(Iop_CmpLT32U,
   5984                                       unop(Iop_16Uto32,
   5985                                            unop(Iop_32to16, mkexpr(t0))),
   5986                                       unop(Iop_16Uto32,
   5987                                            unop(Iop_32to16, getIReg(rs)))));
   5988 
   5989                      putDSPControl(IRExpr_ITE(mkexpr(t1),
   5990                                               binop(Iop_Or32,
   5991                                                     getDSPControl(),
   5992                                                     mkU32(0x00100000)),
   5993                                               getDSPControl()));
   5994 
   5995                      /* Add higher halves. */
   5996                      assign(t2, binop(Iop_Add32,
   5997                                       unop(Iop_16Uto32,
   5998                                            unop(Iop_32HIto16, getIReg(rs))),
   5999                                       unop(Iop_16Uto32,
   6000                                            unop(Iop_32HIto16, getIReg(rt)))));
   6001 
   6002                      /* Detect overflow. */
   6003                      assign(t3, binop(Iop_CmpLT32U,
   6004                                       unop(Iop_16Uto32,
   6005                                            unop(Iop_32to16, mkexpr(t2))),
   6006                                       unop(Iop_16Uto32,
   6007                                            unop(Iop_32HIto16, getIReg(rs)))));
   6008 
   6009                      putDSPControl(IRExpr_ITE(mkexpr(t3),
   6010                                               binop(Iop_Or32,
   6011                                                     getDSPControl(),
   6012                                                     mkU32(0x00100000)),
   6013                                               getDSPControl()));
   6014 
   6015                      putIReg(rd, binop(Iop_16HLto32,
   6016                                        IRExpr_ITE(mkexpr(t3),
   6017                                                   mkU16(0xffff),
   6018                                                   unop(Iop_32to16,
   6019                                                        mkexpr(t2))),
   6020                                        IRExpr_ITE(mkexpr(t1),
   6021                                                   mkU16(0xffff),
   6022                                                   unop(Iop_32to16,
   6023                                                        mkexpr(t0)))));
   6024                      break;
   6025                   }
   6026                   case 0xD: {  /* SUBU_S.PH */
   6027                      DIP("subu_s.ph r%u, r%u, r%u", rd, rs, rt);
   6028                      vassert(!mode64);
   6029                      t0 = newTemp(Ity_I32);
   6030                      t1 = newTemp(Ity_I1);
   6031                      t2 = newTemp(Ity_I32);
   6032                      t3 = newTemp(Ity_I1);
   6033 
   6034                      /* Subtract lower halves. */
   6035                      assign(t0, binop(Iop_Sub32,
   6036                                       unop(Iop_16Uto32,
   6037                                            unop(Iop_32to16, getIReg(rs))),
   6038                                       unop(Iop_16Uto32,
   6039                                            unop(Iop_32to16, getIReg(rt)))));
   6040 
   6041                      /* Detect underflow. */
   6042                      assign(t1, binop(Iop_CmpNE32,
   6043                                       binop(Iop_And32,
   6044                                             mkexpr(t0), mkU32(0x00010000)),
   6045                                       mkU32(0x0)));
   6046 
   6047                      putDSPControl(IRExpr_ITE(mkexpr(t1),
   6048                                               binop(Iop_Or32,
   6049                                                     getDSPControl(),
   6050                                                     mkU32(0x00100000)),
   6051                                               getDSPControl()));
   6052 
   6053                      /* Subtract higher halves. */
   6054                      assign(t2, binop(Iop_Sub32,
   6055                                       unop(Iop_16Uto32,
   6056                                            unop(Iop_32HIto16, getIReg(rs))),
   6057                                       unop(Iop_16Uto32,
   6058                                            unop(Iop_32HIto16, getIReg(rt)))));
   6059 
   6060                      /* Detect underflow. */
   6061                      assign(t3, binop(Iop_CmpNE32,
   6062                                       binop(Iop_And32,
   6063                                             mkexpr(t2), mkU32(0x00010000)),
   6064                                       mkU32(0x0)));
   6065 
   6066                      putDSPControl(IRExpr_ITE(mkexpr(t3),
   6067                                               binop(Iop_Or32,
   6068                                                     getDSPControl(),
   6069                                                     mkU32(0x00100000)),
   6070                                               getDSPControl()));
   6071 
   6072                      putIReg(rd,
   6073                              binop(Iop_16HLto32,
   6074                                    IRExpr_ITE(mkexpr(t3),
   6075                                               mkU16(0x0000),
   6076                                               unop(Iop_32to16, mkexpr(t2))),
   6077                                    IRExpr_ITE(mkexpr(t1),
   6078                                               mkU16(0x0000),
   6079                                               unop(Iop_32to16, mkexpr(t0)))));
   6080                      break;
   6081                   }
   6082                   case 0xE: {  /* ADDQ_S.PH */
   6083                      DIP("addq_s.ph r%u r%u, r%u", rd, rs, rt);
   6084                      vassert(!mode64);
   6085                      t0 = newTemp(Ity_I32);
   6086                      t1 = newTemp(Ity_I1);
   6087                      t2 = newTemp(Ity_I32);
   6088                      t3 = newTemp(Ity_I1);
   6089                      t4 = newTemp(Ity_I16);
   6090                      t5 = newTemp(Ity_I16);
   6091                      t6 = newTemp(Ity_I32);
   6092                      t7 = newTemp(Ity_I32);
   6093 
   6094                      /* Add lower halves. */
   6095                      assign(t0, binop(Iop_Add32,
   6096                                       unop(Iop_16Sto32,
   6097                                            unop(Iop_32to16, getIReg(rs))),
   6098                                       unop(Iop_16Sto32,
   6099                                            unop(Iop_32to16, getIReg(rt)))));
   6100 
   6101                      /* Bit 16 of the result. */
   6102                      assign(t6, binop(Iop_And32,
   6103                                       unop(Iop_16Uto32,
   6104                                            unop(Iop_32HIto16, mkexpr(t0))),
   6105                                       mkU32(0x1)));
   6106                      /* Detect overflow. */
   6107                      assign(t1, binop(Iop_CmpNE32,
   6108                                       binop(Iop_Shr32,
   6109                                             binop(Iop_And32,
   6110                                                   mkexpr(t0),
   6111                                                   mkU32(0x8000)),
   6112                                             mkU8(15)),
   6113                                       mkexpr(t6)));
   6114 
   6115                      putDSPControl(IRExpr_ITE(mkexpr(t1),
   6116                                               binop(Iop_Or32,
   6117                                                     getDSPControl(),
   6118                                                     mkU32(0x00100000)),
   6119                                               getDSPControl()));
   6120                      /* Saturate if needed. */
   6121                      assign(t4, IRExpr_ITE(mkexpr(t1),
   6122                                            IRExpr_ITE(binop(Iop_CmpEQ32,
   6123                                                             mkexpr(t6),
   6124                                                             mkU32(0x0)),
   6125                                                       mkU16(0x7fff),
   6126                                                       mkU16(0x8000)),
   6127                                            unop(Iop_32to16, mkexpr(t0))));
   6128 
   6129                      /* Add higher halves. */
   6130                      assign(t2, binop(Iop_Add32,
   6131                                       unop(Iop_16Sto32,
   6132                                            unop(Iop_32HIto16, getIReg(rs))),
   6133                                       unop(Iop_16Sto32,
   6134                                            unop(Iop_32HIto16, getIReg(rt)))));
   6135 
   6136                      /* Bit 16 of the result. */
   6137                      assign(t7, binop(Iop_And32,
   6138                                       unop(Iop_16Uto32,
   6139                                            unop(Iop_32HIto16, mkexpr(t2))),
   6140                                       mkU32(0x1)));
   6141                      /* Detect overflow. */
   6142                      assign(t3, binop(Iop_CmpNE32,
   6143                                       binop(Iop_Shr32,
   6144                                             binop(Iop_And32,
   6145                                                   mkexpr(t2),
   6146                                                   mkU32(0x00008000)),
   6147                                             mkU8(15)),
   6148                                       mkexpr(t7)));
   6149 
   6150                      putDSPControl(IRExpr_ITE(mkexpr(t3),
   6151                                               binop(Iop_Or32,
   6152                                                     getDSPControl(),
   6153                                                     mkU32(0x00100000)),
   6154                                               getDSPControl()));
   6155                      /* Saturate if needed. */
   6156                      assign(t5, IRExpr_ITE(mkexpr(t3),
   6157                                            IRExpr_ITE(binop(Iop_CmpEQ32,
   6158                                                             mkexpr(t7),
   6159                                                             mkU32(0x0)),
   6160                                                       mkU16(0x7fff),
   6161                                                       mkU16(0x8000)),
   6162                                            unop(Iop_32to16, mkexpr(t2))));
   6163 
   6164                      putIReg(rd, binop(Iop_16HLto32, mkexpr(t5), mkexpr(t4)));
   6165                      break;
   6166                   }
   6167                   case 0xF: {  /* SUBQ_S.PH */
   6168                      DIP("subq_s.ph r%u r%u, r%u", rd, rs, rt);
   6169                      vassert(!mode64);
   6170                      t0 = newTemp(Ity_I32);
   6171                      t1 = newTemp(Ity_I1);
   6172                      t2 = newTemp(Ity_I32);
   6173                      t3 = newTemp(Ity_I1);
   6174                      t4 = newTemp(Ity_I16);
   6175                      t5 = newTemp(Ity_I16);
   6176                      t6 = newTemp(Ity_I32);
   6177                      t7 = newTemp(Ity_I32);
   6178 
   6179                      /* Subtract lower halves. */
   6180                      assign(t0, binop(Iop_Sub32,
   6181                                       unop(Iop_16Sto32,
   6182                                            unop(Iop_32to16, getIReg(rs))),
   6183                                       unop(Iop_16Sto32,
   6184                                            unop(Iop_32to16, getIReg(rt)))));
   6185 
   6186                      /* Bit 16 of the result. */
   6187                      assign(t6, binop(Iop_And32,
   6188                                       unop(Iop_16Uto32,
   6189                                            unop(Iop_32HIto16, mkexpr(t0))),
   6190                                       mkU32(0x1)));
   6191                      /* Detect overflow or underflow. */
   6192                      assign(t1, binop(Iop_CmpNE32,
   6193                                       binop(Iop_Shr32,
   6194                                             binop(Iop_And32,
   6195                                                   mkexpr(t0),
   6196                                                   mkU32(0x8000)),
   6197                                             mkU8(15)),
   6198                                       mkexpr(t6)));
   6199 
   6200                      putDSPControl(IRExpr_ITE(mkexpr(t1),
   6201                                               binop(Iop_Or32,
   6202                                                     getDSPControl(),
   6203                                                     mkU32(0x00100000)),
   6204                                               getDSPControl()));
   6205                      /* Saturate if needed. */
   6206                      assign(t4, IRExpr_ITE(mkexpr(t1),
   6207                                            IRExpr_ITE(binop(Iop_CmpEQ32,
   6208                                                             mkexpr(t6),
   6209                                                             mkU32(0x0)),
   6210                                                       mkU16(0x7fff),
   6211                                                       mkU16(0x8000)),
   6212                                            unop(Iop_32to16, mkexpr(t0))));
   6213 
   6214                      /* Subtract higher halves. */
   6215                      assign(t2, binop(Iop_Sub32,
   6216                                       unop(Iop_16Sto32,
   6217                                            unop(Iop_32HIto16, getIReg(rs))),
   6218                                       unop(Iop_16Sto32,
   6219                                            unop(Iop_32HIto16, getIReg(rt)))));
   6220 
   6221                      /* Bit 16 of the result. */
   6222                      assign(t7, binop(Iop_And32,
   6223                                       unop(Iop_16Uto32,
   6224                                            unop(Iop_32HIto16, mkexpr(t2))),
   6225                                       mkU32(0x1)));
   6226                      /* Detect overflow or underflow. */
   6227                      assign(t3, binop(Iop_CmpNE32,
   6228                                       binop(Iop_Shr32,
   6229                                             binop(Iop_And32,
   6230                                                   mkexpr(t2),
   6231                                                   mkU32(0x00008000)),
   6232                                             mkU8(15)),
   6233                                       mkexpr(t7)));
   6234 
   6235                      putDSPControl(IRExpr_ITE(mkexpr(t3),
   6236                                               binop(Iop_Or32,
   6237                                                     getDSPControl(),
   6238                                                     mkU32(0x00100000)),
   6239                                               getDSPControl()));
   6240                      /* Saturate if needed. */
   6241                      assign(t5, IRExpr_ITE(mkexpr(t3),
   6242                                            IRExpr_ITE(binop(Iop_CmpEQ32,
   6243                                                             mkexpr(t7),
   6244                                                             mkU32(0x0)),
   6245                                                       mkU16(0x7fff),
   6246                                                       mkU16(0x8000)),
   6247                                            unop(Iop_32to16, mkexpr(t2))));
   6248 
   6249                      putIReg(rd, binop(Iop_16HLto32, mkexpr(t5), mkexpr(t4)));
   6250                      break;
   6251                   }
   6252                   case 0x10: {  /* ADDSC */
   6253                      DIP("addsc r%u, r%u, r%u", rd, rs, rt);
   6254                      vassert(!mode64);
   6255                      t0 = newTemp(Ity_I64);
   6256                      t1 = newTemp(Ity_I1);
   6257 
   6258                      /* The carry bit result out of the addition operation is
   6259                         written to bit 13(the c field) of the DSPControl reg. */
   6260                      assign(t0, binop(Iop_Add64,
   6261                                       unop(Iop_32Uto64, getIReg(rs)),
   6262                                       unop(Iop_32Uto64, getIReg(rt))));
   6263 
   6264                      assign(t1, binop(Iop_CmpEQ32,
   6265                                       binop(Iop_And32,
   6266                                             unop(Iop_64HIto32, mkexpr(t0)),
   6267                                             mkU32(0x1)),
   6268                                       mkU32(0x1)));
   6269                      putDSPControl(IRExpr_ITE(mkexpr(t1),
   6270                                               binop(Iop_Or32,
   6271                                                     getDSPControl(),
   6272                                                     mkU32(0x2000)),
   6273                                               binop(Iop_And32,
   6274                                                     getDSPControl(),
   6275                                                     mkU32(0xffffdfff))));
   6276 
   6277                      putIReg(rd, unop(Iop_64to32, mkexpr(t0)));
   6278                      break;
   6279                   }
   6280                   case 0x11: {  /* ADDWC */
   6281                      DIP("addwc r%u, r%u, r%u", rd, rs, rt);
   6282                      vassert(!mode64);
   6283                      t0 = newTemp(Ity_I32);
   6284                      t1 = newTemp(Ity_I64);
   6285                      t2 = newTemp(Ity_I32);
   6286                      t3 = newTemp(Ity_I32);
   6287                      t4 = newTemp(Ity_I1);
   6288 
   6289                      /* Get carry bit from DSPControl register. */
   6290                      assign(t0, binop(Iop_Shr32,
   6291                                        binop(Iop_And32,
   6292                                              getDSPControl(),
   6293                                              mkU32(0x2000)),
   6294                                        mkU8(0xd)));
   6295                      assign(t1, binop(Iop_Add64,
   6296                                       unop(Iop_32Sto64, getIReg(rs)),
   6297                                       unop(Iop_32Sto64,
   6298                                            binop(Iop_Add32,
   6299                                                  getIReg(rt),
   6300                                                  mkexpr(t0)))));
   6301 
   6302                      /* Extract bits 32 and 31. */
   6303                      assign(t2, binop(Iop_And32,
   6304                                       unop(Iop_64HIto32, mkexpr(t1)),
   6305                                       mkU32(0x1)));
   6306                      assign(t3, binop(Iop_Shr32,
   6307                                       binop(Iop_And32,
   6308                                             unop(Iop_64to32, mkexpr(t1)),
   6309                                             mkU32(0x80000000)),
   6310                                       mkU8(31)));
   6311                      assign(t4, binop(Iop_CmpNE32, mkexpr(t2), mkexpr(t3)));
   6312 
   6313                      putDSPControl(IRExpr_ITE(mkexpr(t4),
   6314                                               binop(Iop_Or32,
   6315                                                     getDSPControl(),
   6316                                                     mkU32(0x00100000)),
   6317                                               getDSPControl()));
   6318                      putIReg(rd, unop(Iop_64to32, mkexpr(t1)));
   6319                      break;
   6320                   }
   6321                   case 0x12: {  /* MODSUB */
   6322                      DIP("modsub r%u, r%u, r%u", rd, rs, rt);
   6323                      vassert(!mode64);
   6324                      t0 = newTemp(Ity_I32);
   6325                      t1 = newTemp(Ity_I32);
   6326                      t2 = newTemp(Ity_I32);
   6327 
   6328                      /* decr_7..0 */
   6329                      assign(t0,
   6330                             unop(Iop_8Uto32,
   6331                                  unop(Iop_16to8,
   6332                                       unop(Iop_32to16, getIReg(rt)))));
   6333 
   6334                      /* lastindex_15..0 */
   6335                      assign(t1,
   6336                             unop(Iop_16Uto32,
   6337                                  binop(Iop_8HLto16,
   6338                                        unop(Iop_16to8,
   6339                                             unop(Iop_32HIto16, getIReg(rt))),
   6340                                        unop(Iop_16HIto8,
   6341                                             unop(Iop_32to16, getIReg(rt))))));
   6342                      /* temp_15..0 */
   6343                      assign(t2,
   6344                             IRExpr_ITE(binop(Iop_CmpEQ32,
   6345                                              getIReg(rs),
   6346                                              mkU32(0x00000000)),
   6347                                        mkexpr(t1),
   6348                                        binop(Iop_Sub32,
   6349                                              getIReg(rs), mkexpr(t0))));
   6350                      putIReg(rd, mkexpr(t2));
   6351                      break;
   6352                   }
   6353                   case 0x14: {  /* RADDU.W.QB */
   6354                      DIP("raddu.w.qb r%u, r%u", rd, rs);
   6355                      vassert(!mode64);
   6356                      putIReg(rd, binop(Iop_Add32,
   6357                                        binop(Iop_Add32,
   6358                                              unop(Iop_8Uto32,
   6359                                                   unop(Iop_16to8,
   6360                                                        unop(Iop_32to16,
   6361                                                             getIReg(rs)))),
   6362                                              unop(Iop_8Uto32,
   6363                                                   unop(Iop_16HIto8,
   6364                                                        unop(Iop_32to16,
   6365                                                             getIReg(rs))))),
   6366                                        binop(Iop_Add32,
   6367                                              unop(Iop_8Uto32,
   6368                                                   unop(Iop_16to8,
   6369                                                        unop(Iop_32HIto16,
   6370                                                             getIReg(rs)))),
   6371                                              unop(Iop_8Uto32,
   6372                                                   unop(Iop_16HIto8,
   6373                                                        unop(Iop_32HIto16,
   6374                                                             getIReg(rs)))))));
   6375                      break;
   6376                   }
   6377                   case 0x16: {  /* ADDQ_S.W */
   6378                      DIP("addq_s.w r%u, r%u, r%u", rd, rs, rt);
   6379                      vassert(!mode64);
   6380                      t0 = newTemp(Ity_I64);
   6381                      t1 = newTemp(Ity_I1);
   6382                      t2 = newTemp(Ity_I32);
   6383                      t3 = newTemp(Ity_I32);
   6384 
   6385                      assign(t0, binop(Iop_Add64,
   6386                                       unop(Iop_32Sto64, getIReg(rs)),
   6387                                       unop(Iop_32Sto64, getIReg(rt))));
   6388 
   6389                      assign(t3, binop(Iop_And32,
   6390                                       unop(Iop_64HIto32, mkexpr(t0)),
   6391                                       mkU32(0x1)));
   6392                      assign(t1, binop(Iop_CmpNE32,
   6393                                       binop(Iop_Shr32,
   6394                                             binop(Iop_And32,
   6395                                                   unop(Iop_64to32, mkexpr(t0)),
   6396                                                   mkU32(0x80000000)),
   6397                                             mkU8(31)),
   6398                                       mkexpr(t3)));
   6399 
   6400                      putDSPControl(IRExpr_ITE(mkexpr(t1),
   6401                                               binop(Iop_Or32,
   6402                                                     getDSPControl(),
   6403                                                     mkU32(0x00100000)),
   6404                                               getDSPControl()));
   6405 
   6406                      putIReg(rd, IRExpr_ITE(mkexpr(t1),
   6407                                             IRExpr_ITE(binop(Iop_CmpEQ32,
   6408                                                              mkexpr(t3),
   6409                                                              mkU32(0x0)),
   6410                                                        mkU32(0x7fffffff),
   6411                                                        mkU32(0x80000000)),
   6412                                             unop(Iop_64to32, mkexpr(t0))));
   6413                      break;
   6414                   }
   6415                   case 0x17: {  /* SUBQ_S.W */
   6416                      DIP("subq_s.w r%u, r%u, r%u", rd, rs, rt);
   6417                      vassert(!mode64);
   6418                      t0 = newTemp(Ity_I64);
   6419                      t1 = newTemp(Ity_I1);
   6420                      t2 = newTemp(Ity_I32);
   6421                      t3 = newTemp(Ity_I32);
   6422 
   6423                      assign(t0, binop(Iop_Sub64,
   6424                                       unop(Iop_32Sto64, getIReg(rs)),
   6425                                       unop(Iop_32Sto64, getIReg(rt))));
   6426 
   6427                      assign(t3, binop(Iop_And32,
   6428                                       unop(Iop_64HIto32, mkexpr(t0)),
   6429                                       mkU32(0x1)));
   6430                      assign(t1, binop(Iop_CmpNE32,
   6431                                       binop(Iop_Shr32,
   6432                                             binop(Iop_And32,
   6433                                                   unop(Iop_64to32, mkexpr(t0)),
   6434                                                   mkU32(0x80000000)),
   6435                                             mkU8(31)),
   6436                                       mkexpr(t3)));
   6437 
   6438                      putDSPControl(IRExpr_ITE(mkexpr(t1),
   6439                                               binop(Iop_Or32,
   6440                                                     getDSPControl(),
   6441                                                     mkU32(0x00100000)),
   6442                                               getDSPControl()));
   6443 
   6444                      putIReg(rd, IRExpr_ITE(mkexpr(t1),
   6445                                             IRExpr_ITE(binop(Iop_CmpEQ32,
   6446                                                              mkexpr(t3),
   6447                                                              mkU32(0x0)),
   6448                                                        mkU32(0x7fffffff),
   6449                                                        mkU32(0x80000000)),
   6450                                             unop(Iop_64to32, mkexpr(t0))));
   6451                      break;
   6452                   }
   6453                   case 0x1C: {  /* MULEQ_S.W.PHL */
   6454                      DIP("muleq_s.w.phl r%u, r%u, r%u", rd, rs, rt);
   6455                      vassert(!mode64);
   6456                      t0 = newTemp(Ity_I32);
   6457                      t1 = newTemp(Ity_I1);
   6458                      t2 = newTemp(Ity_I1);
   6459                      t3 = newTemp(Ity_I32);
   6460 
   6461                      assign(t0,
   6462                             binop(Iop_Shl32,
   6463                                   binop(Iop_Mul32,
   6464                                         unop(Iop_16Sto32,
   6465                                              unop(Iop_32HIto16, getIReg(rt))),
   6466                                         unop(Iop_16Sto32,
   6467                                              unop(Iop_32HIto16, getIReg(rs)))),
   6468                                   mkU8(0x1)));
   6469                      assign(t1, binop(Iop_CmpEQ32,
   6470                                       binop(Iop_And32,
   6471                                             getIReg(rt),
   6472                                             mkU32(0xffff0000)),
   6473                                       mkU32(0x80000000)));
   6474                      assign(t2, binop(Iop_CmpEQ32,
   6475                                       binop(Iop_And32,
   6476                                             getIReg(rs),
   6477                                             mkU32(0xffff0000)),
   6478                                       mkU32(0x80000000)));
   6479                      assign(t3, IRExpr_ITE(mkexpr(t1),
   6480                                            IRExpr_ITE(mkexpr(t2),
   6481                                                       binop(Iop_Or32,
   6482                                                             getDSPControl(),
   6483                                                             mkU32(0x00200000)),
   6484                                                       getDSPControl()),
   6485                                            getDSPControl()));
   6486                      putDSPControl(mkexpr(t3));
   6487 
   6488                      putIReg(rd, IRExpr_ITE(mkexpr(t1),
   6489                                             IRExpr_ITE(mkexpr(t2),
   6490                                                        mkU32(0x7fffffff),
   6491                                                        mkexpr(t0)),
   6492                                             mkexpr(t0)));
   6493                      break;
   6494                   }
   6495                   case 0x1D: {  /* MULEQ_S.W.PHR */
   6496                      DIP("muleq_s.w.phr r%u, r%u, r%u", rd, rs, rt);
   6497                      vassert(!mode64);
   6498                      t0 = newTemp(Ity_I32);
   6499                      t1 = newTemp(Ity_I1);
   6500                      t2 = newTemp(Ity_I1);
   6501 
   6502                      assign(t0,
   6503                             binop(Iop_Shl32,
   6504                                   binop(Iop_Mul32,
   6505                                         unop(Iop_16Sto32,
   6506                                              unop(Iop_32to16, getIReg(rt))),
   6507                                         unop(Iop_16Sto32,
   6508                                              unop(Iop_32to16, getIReg(rs)))),
   6509                                   mkU8(0x1)));
   6510                      assign(t1, binop(Iop_CmpEQ32,
   6511                                       binop(Iop_And32,
   6512                                             getIReg(rt),
   6513                                             mkU32(0xffff)),
   6514                                       mkU32(0x8000)));
   6515                      assign(t2, binop(Iop_CmpEQ32,
   6516                                       binop(Iop_And32,
   6517                                             getIReg(rs),
   6518                                             mkU32(0xffff)),
   6519                                       mkU32(0x8000)));
   6520                      putDSPControl(IRExpr_ITE(mkexpr(t1),
   6521                                               IRExpr_ITE(mkexpr(t2),
   6522                                                          binop(Iop_Or32,
   6523                                                                getDSPControl(),
   6524                                                                mkU32(0x00200000)
   6525                                                               ),
   6526                                                          getDSPControl()),
   6527                                               getDSPControl()));
   6528                      putIReg(rd, IRExpr_ITE(mkexpr(t1),
   6529                                             IRExpr_ITE(mkexpr(t2),
   6530                                                        mkU32(0x7fffffff),
   6531                                                        mkexpr(t0)),
   6532                                             mkexpr(t0)));
   6533                      break;
   6534                   }
   6535                   case 0x1E: {  /* MULQ_S.PH */
   6536                      DIP("mulq_s.ph r%u, r%u, r%u", rd, rs, rt);
   6537                      vassert(!mode64);
   6538                      t0 = newTemp(Ity_I32);
   6539                      t1 = newTemp(Ity_I32);
   6540                      t2 = newTemp(Ity_I16);
   6541                      t3 = newTemp(Ity_I16);
   6542                      t5 = newTemp(Ity_I32);
   6543                      t6 = newTemp(Ity_I32);
   6544                      t7 = newTemp(Ity_I32);
   6545                      t8 = newTemp(Ity_I32);
   6546 
   6547                      assign(t5,
   6548                             unop(Iop_16Sto32, unop(Iop_32to16, getIReg(rs))));
   6549                      assign(t6,
   6550                             unop(Iop_16Sto32, unop(Iop_32to16, getIReg(rt))));
   6551 
   6552                      assign(t7,
   6553                             unop(Iop_16Sto32, unop(Iop_32HIto16, getIReg(rs))));
   6554                      assign(t8,
   6555                             unop(Iop_16Sto32, unop(Iop_32HIto16, getIReg(rt))));
   6556 
   6557                      assign(t0, binop(Iop_And32,
   6558                                       unop(Iop_1Sto32,
   6559                                            binop(Iop_CmpEQ32,
   6560                                                  binop(Iop_And32,
   6561                                                        mkexpr(t5),
   6562                                                        mkU32(0xffff)),
   6563                                                  mkU32(0x8000))),
   6564                                       unop(Iop_1Sto32,
   6565                                            binop(Iop_CmpEQ32,
   6566                                                  binop(Iop_And32,
   6567                                                        mkexpr(t6),
   6568                                                        mkU32(0xffff)),
   6569                                                  mkU32(0x8000)))));
   6570                      assign(t1, binop(Iop_And32,
   6571                                       unop(Iop_1Sto32,
   6572                                            binop(Iop_CmpEQ32,
   6573                                                  binop(Iop_And32,
   6574                                                        mkexpr(t7),
   6575                                                        mkU32(0xffff)),
   6576                                                  mkU32(0x8000))),
   6577                                       unop(Iop_1Sto32,
   6578                                            binop(Iop_CmpEQ32,
   6579                                                  binop(Iop_And32,
   6580                                                        mkexpr(t8),
   6581                                                        mkU32(0xffff)),
   6582                                                  mkU32(0x8000)))));
   6583 
   6584                      putDSPControl(IRExpr_ITE(binop(Iop_CmpEQ32,
   6585                                                     binop(Iop_Or32,
   6586                                                           mkexpr(t0),
   6587                                                           mkexpr(t1)),
   6588                                                     mkU32(0x0)),
   6589                                               getDSPControl(),
   6590                                               binop(Iop_Or32,
   6591                                                     getDSPControl(),
   6592                                                     mkU32(0x200000))));
   6593 
   6594                      assign(t2, unop(Iop_32HIto16,
   6595                                      binop(Iop_Shl32,
   6596                                            unop(Iop_64to32,
   6597                                                 binop(Iop_MullS32,
   6598                                                       mkexpr(t7),
   6599                                                       mkexpr(t8))),
   6600                                            mkU8(0x1))));
   6601                      assign(t3, unop(Iop_32HIto16,
   6602                                      binop(Iop_Shl32,
   6603                                            unop(Iop_64to32,
   6604                                                 binop(Iop_MullS32,
   6605                                                       mkexpr(t5),
   6606                                                       mkexpr(t6))),
   6607                                            mkU8(0x1))));
   6608                      putIReg(rd, binop(Iop_16HLto32,
   6609                                        IRExpr_ITE(binop(Iop_CmpEQ32,
   6610                                                         mkexpr(t1),
   6611                                                         mkU32(0x0)),
   6612                                                   mkexpr(t2),
   6613                                                   mkU16(0x7fff)),
   6614                                        IRExpr_ITE(binop(Iop_CmpEQ32,
   6615                                                         mkexpr(t0),
   6616                                                         mkU32(0x0)),
   6617                                                   mkexpr(t3),
   6618                                                   mkU16(0x7fff))));
   6619                      break;
   6620                   }
   6621                   case 0x1F: {  /* MULQ_RS.PH */
   6622                      DIP("mulq_rs.ph r%u, r%u, r%u", rd, rs, rt);
   6623                      vassert(!mode64);
   6624                      t0 = newTemp(Ity_I32);
   6625                      t1 = newTemp(Ity_I1);
   6626                      t2 = newTemp(Ity_I1);
   6627                      t3 = newTemp(Ity_I16);
   6628                      t4 = newTemp(Ity_I32);
   6629                      t5 = newTemp(Ity_I1);
   6630                      t6 = newTemp(Ity_I1);
   6631                      t7 = newTemp(Ity_I16);
   6632 
   6633                      /* Multiply and round lower halfwords. */
   6634                      assign(t0, binop(Iop_Add32,
   6635                                       binop(Iop_Shl32,
   6636                                             binop(Iop_Mul32,
   6637                                                   unop(Iop_16Sto32,
   6638                                                        unop(Iop_32to16,
   6639                                                             getIReg(rt))),
   6640                                                   unop(Iop_16Sto32,
   6641                                                        unop(Iop_32to16,
   6642                                                             getIReg(rs)))),
   6643                                             mkU8(0x1)),
   6644                                       mkU32(0x00008000)));
   6645                      assign(t1, binop(Iop_CmpEQ32,
   6646                                       binop(Iop_And32,
   6647                                             getIReg(rt), mkU32(0xffff)),
   6648                                       mkU32(0x8000)));
   6649                      assign(t2, binop(Iop_CmpEQ32,
   6650                                       binop(Iop_And32,
   6651                                             getIReg(rs), mkU32(0xffff)),
   6652                                       mkU32(0x8000)));
   6653                      putDSPControl(IRExpr_ITE(mkexpr(t1),
   6654                                               IRExpr_ITE(mkexpr(t2),
   6655                                                          binop(Iop_Or32,
   6656                                                                getDSPControl(),
   6657                                                                mkU32(0x00200000)
   6658                                                               ),
   6659                                                          getDSPControl()),
   6660                                               getDSPControl()));
   6661                      assign(t3, IRExpr_ITE(mkexpr(t1),
   6662                                            IRExpr_ITE(mkexpr(t2),
   6663                                                       mkU16(0x7fff),
   6664                                                       unop(Iop_32HIto16,
   6665                                                            mkexpr(t0))),
   6666                                            unop(Iop_32HIto16, mkexpr(t0))));
   6667 
   6668                      /* Multiply and round higher halfwords. */
   6669                      assign(t4, binop(Iop_Add32,
   6670                                       binop(Iop_Shl32,
   6671                                             binop(Iop_Mul32,
   6672                                                   unop(Iop_16Sto32,
   6673                                                        unop(Iop_32HIto16,
   6674                                                             getIReg(rt))),
   6675                                                   unop(Iop_16Sto32,
   6676                                                        unop(Iop_32HIto16,
   6677                                                             getIReg(rs)))),
   6678                                             mkU8(0x1)),
   6679                                       mkU32(0x00008000)));
   6680                      assign(t5, binop(Iop_CmpEQ32,
   6681                                       binop(Iop_And32,
   6682                                             getIReg(rt),
   6683                                             mkU32(0xffff0000)),
   6684                                       mkU32(0x80000000)));
   6685                      assign(t6, binop(Iop_CmpEQ32,
   6686                                       binop(Iop_And32,
   6687                                             getIReg(rs),
   6688                                             mkU32(0xffff0000)),
   6689                                       mkU32(0x80000000)));
   6690                      putDSPControl(IRExpr_ITE(mkexpr(t5),
   6691                                              IRExpr_ITE(mkexpr(t6),
   6692                                                         binop(Iop_Or32,
   6693                                                              getDSPControl(),
   6694                                                              mkU32(0x00200000)),
   6695                                                         getDSPControl()),
   6696                                              getDSPControl()));
   6697                      assign(t7, IRExpr_ITE(mkexpr(t5),
   6698                                            IRExpr_ITE(mkexpr(t6),
   6699                                                       mkU16(0x7fff),
   6700                                                       unop(Iop_32HIto16,
   6701                                                            mkexpr(t4))),
   6702                                            unop(Iop_32HIto16, mkexpr(t4))));
   6703 
   6704                      putIReg(rd, binop(Iop_16HLto32, mkexpr(t7), mkexpr(t3)));
   6705                      break;
   6706                   }
   6707                   default:
   6708                      return -1;
   6709                }
   6710                break;  /* end of ADDU.QB */
   6711             }
   6712             case 0x11: {  /* CMPU.EQ.QB */
   6713                switch(sa) {
   6714                   case 0x0: {  /* CMPU.EQ.QB */
   6715                      DIP("cmpu.eq.qb r%u, r%u", rs, rt);
   6716                      vassert(!mode64);
   6717                      t1 = newTemp(Ity_I1);
   6718                      t2 = newTemp(Ity_I1);
   6719                      t3 = newTemp(Ity_I1);
   6720                      t4 = newTemp(Ity_I1);
   6721 
   6722                      assign(t1,
   6723                             binop(Iop_CmpEQ32,
   6724                                   binop(Iop_And32, getIReg(rs), mkU32(0xff)),
   6725                                   binop(Iop_And32, getIReg(rt), mkU32(0xff))));
   6726                      putDSPControl(IRExpr_ITE(mkexpr(t1),
   6727                                               binop(Iop_Or32,
   6728                                                     getDSPControl(),
   6729                                                     mkU32(0x01000000)),
   6730                                               binop(Iop_And32,
   6731                                                     getDSPControl(),
   6732                                                     mkU32(0xfeffffff))));
   6733 
   6734                      assign(t2, binop(Iop_CmpEQ32,
   6735                                       unop(Iop_8Uto32,
   6736                                            unop(Iop_16HIto8,
   6737                                                 unop(Iop_32to16,
   6738                                                      getIReg(rs)))),
   6739                                       unop(Iop_8Uto32,
   6740                                            unop(Iop_16HIto8,
   6741                                                 unop(Iop_32to16,
   6742                                                      getIReg(rt))))));
   6743                      putDSPControl(IRExpr_ITE(mkexpr(t2),
   6744                                               binop(Iop_Or32,
   6745                                                     getDSPControl(),
   6746                                                     mkU32(0x02000000)),
   6747                                               binop(Iop_And32,
   6748                                                     getDSPControl(),
   6749                                                     mkU32(0xfdffffff))));
   6750 
   6751                      assign(t3, binop(Iop_CmpEQ32,
   6752                                       unop(Iop_8Uto32,
   6753                                            unop(Iop_16to8,
   6754                                                 unop(Iop_32HIto16,
   6755                                                      getIReg(rs)))),
   6756                                       unop(Iop_8Uto32,
   6757                                            unop(Iop_16to8,
   6758                                                 unop(Iop_32HIto16,
   6759                                                      getIReg(rt))))));
   6760                      putDSPControl(IRExpr_ITE(mkexpr(t3),
   6761                                               binop(Iop_Or32,
   6762                                                     getDSPControl(),
   6763                                                     mkU32(0x04000000)),
   6764                                               binop(Iop_And32,
   6765                                                     getDSPControl(),
   6766                                                     mkU32(0xfbffffff))));
   6767 
   6768                      assign(t4, binop(Iop_CmpEQ32,
   6769                                       unop(Iop_8Uto32,
   6770                                            unop(Iop_16HIto8,
   6771                                                 unop(Iop_32HIto16,
   6772                                                      getIReg(rs)))),
   6773                                       unop(Iop_8Uto32,
   6774                                            unop(Iop_16HIto8,
   6775                                                 unop(Iop_32HIto16,
   6776                                                      getIReg(rt))))));
   6777                      putDSPControl(IRExpr_ITE(mkexpr(t4),
   6778                                               binop(Iop_Or32,
   6779                                                     getDSPControl(),
   6780                                                     mkU32(0x08000000)),
   6781                                               binop(Iop_And32,
   6782                                                     getDSPControl(),
   6783                                                     mkU32(0xf7ffffff))));
   6784                      break;
   6785                   }
   6786                   case 0x1: {  /* CMPU.LT.QB */
   6787                      DIP("cmpu.lt.qb r%u, r%u", rs, rt);
   6788                      vassert(!mode64);
   6789                      t1 = newTemp(Ity_I1);
   6790                      t2 = newTemp(Ity_I1);
   6791                      t3 = newTemp(Ity_I1);
   6792                      t4 = newTemp(Ity_I1);
   6793 
   6794                      assign(t1, binop(Iop_CmpLT32U,
   6795                                       unop(Iop_8Uto32,
   6796                                            unop(Iop_16to8,
   6797                                                 unop(Iop_32to16,
   6798                                                      getIReg(rs)))),
   6799                                       unop(Iop_8Uto32,
   6800                                            unop(Iop_16to8,
   6801                                                 unop(Iop_32to16,
   6802                                                      getIReg(rt))))));
   6803                      putDSPControl(IRExpr_ITE(mkexpr(t1),
   6804                                               binop(Iop_Or32,
   6805                                                     getDSPControl(),
   6806                                                     mkU32(0x01000000)),
   6807                                               binop(Iop_And32,
   6808                                                     getDSPControl(),
   6809                                                     mkU32(0xfeffffff))));
   6810 
   6811                      assign(t2, binop(Iop_CmpLT32U,
   6812                                       unop(Iop_8Uto32,
   6813                                            unop(Iop_16HIto8,
   6814                                                 unop(Iop_32to16,
   6815                                                      getIReg(rs)))),
   6816                                       unop(Iop_8Uto32,
   6817                                            unop(Iop_16HIto8,
   6818                                                 unop(Iop_32to16,
   6819                                                      getIReg(rt))))));
   6820                      putDSPControl(IRExpr_ITE(mkexpr(t2),
   6821                                               binop(Iop_Or32,
   6822                                                     getDSPControl(),
   6823                                                     mkU32(0x02000000)),
   6824                                               binop(Iop_And32,
   6825                                                     getDSPControl(),
   6826                                                     mkU32(0xfdffffff))));
   6827 
   6828                      assign(t3, binop(Iop_CmpLT32U,
   6829                                       unop(Iop_8Uto32,
   6830                                            unop(Iop_16to8,
   6831                                                 unop(Iop_32HIto16,
   6832                                                      getIReg(rs)))),
   6833                                       unop(Iop_8Uto32,
   6834                                            unop(Iop_16to8,
   6835                                                 unop(Iop_32HIto16,
   6836                                                      getIReg(rt))))));
   6837                      putDSPControl(IRExpr_ITE(mkexpr(t3),
   6838                                               binop(Iop_Or32,
   6839                                                     getDSPControl(),
   6840                                                     mkU32(0x04000000)),
   6841                                               binop(Iop_And32,
   6842                                                     getDSPControl(),
   6843                                                     mkU32(0xfbffffff))));
   6844 
   6845                      assign(t4, binop(Iop_CmpLT32U,
   6846                                       unop(Iop_8Uto32,
   6847                                            unop(Iop_16HIto8,
   6848                                                 unop(Iop_32HIto16,
   6849                                                      getIReg(rs)))),
   6850                                       unop(Iop_8Uto32,
   6851                                            unop(Iop_16HIto8,
   6852                                                 unop(Iop_32HIto16,
   6853                                                      getIReg(rt))))));
   6854                      putDSPControl(IRExpr_ITE(mkexpr(t4),
   6855                                               binop(Iop_Or32,
   6856                                                     getDSPControl(),
   6857                                                     mkU32(0x08000000)),
   6858                                               binop(Iop_And32,
   6859                                                     getDSPControl(),
   6860                                                     mkU32(0xf7ffffff))));
   6861                      break;
   6862                   }
   6863                   case 0x2: {  /* CMPU.LE.QB */
   6864                      DIP("cmpu.le.qb r%u, r%u", rs, rt);
   6865                      vassert(!mode64);
   6866                      t1 = newTemp(Ity_I1);
   6867                      t2 = newTemp(Ity_I1);
   6868                      t3 = newTemp(Ity_I1);
   6869                      t4 = newTemp(Ity_I1);
   6870 
   6871                      assign(t1, binop(Iop_CmpLE32U,
   6872                                       unop(Iop_8Uto32,
   6873                                            unop(Iop_16to8,
   6874                                                 unop(Iop_32to16,
   6875                                                      getIReg(rs)))),
   6876                                       unop(Iop_8Uto32,
   6877                                            unop(Iop_16to8,
   6878                                                 unop(Iop_32to16,
   6879                                                      getIReg(rt))))));
   6880                      putDSPControl(IRExpr_ITE(mkexpr(t1),
   6881                                               binop(Iop_Or32,
   6882                                                     getDSPControl(),
   6883                                                     mkU32(0x01000000)),
   6884                                               binop(Iop_And32,
   6885                                                     getDSPControl(),
   6886                                                     mkU32(0xfeffffff))));
   6887 
   6888                      assign(t2, binop(Iop_CmpLE32U,
   6889                                       unop(Iop_8Uto32,
   6890                                            unop(Iop_16HIto8,
   6891                                                 unop(Iop_32to16,
   6892                                                      getIReg(rs)))),
   6893                                       unop(Iop_8Uto32,
   6894                                            unop(Iop_16HIto8,
   6895                                                 unop(Iop_32to16,
   6896                                                      getIReg(rt))))));
   6897                      putDSPControl(IRExpr_ITE(mkexpr(t2),
   6898                                               binop(Iop_Or32,
   6899                                                     getDSPControl(),
   6900                                                     mkU32(0x02000000)),
   6901                                               binop(Iop_And32,
   6902                                                     getDSPControl(),
   6903                                                     mkU32(0xfdffffff))));
   6904 
   6905                      assign(t3, binop(Iop_CmpLE32U,
   6906                                       unop(Iop_8Uto32,
   6907                                            unop(Iop_16to8,
   6908                                                 unop(Iop_32HIto16,
   6909                                                      getIReg(rs)))),
   6910                                       unop(Iop_8Uto32,
   6911                                            unop(Iop_16to8,
   6912                                                 unop(Iop_32HIto16,
   6913                                                      getIReg(rt))))));
   6914                      putDSPControl(IRExpr_ITE(mkexpr(t3),
   6915                                               binop(Iop_Or32,
   6916                                                     getDSPControl(),
   6917                                                     mkU32(0x04000000)),
   6918                                               binop(Iop_And32,
   6919                                                     getDSPControl(),
   6920                                                     mkU32(0xfbffffff))));
   6921 
   6922                      assign(t4, binop(Iop_CmpLE32U,
   6923                                       unop(Iop_8Uto32,
   6924                                            unop(Iop_16HIto8,
   6925                                                 unop(Iop_32HIto16,
   6926                                                      getIReg(rs)))),
   6927                                       unop(Iop_8Uto32,
   6928                                            unop(Iop_16HIto8,
   6929                                                 unop(Iop_32HIto16,
   6930                                                      getIReg(rt))))));
   6931                      putDSPControl(IRExpr_ITE(mkexpr(t4),
   6932                                               binop(Iop_Or32,
   6933                                                     getDSPControl(),
   6934                                                     mkU32(0x08000000)),
   6935                                               binop(Iop_And32,
   6936                                                     getDSPControl(),
   6937                                                     mkU32(0xf7ffffff))));
   6938                      break;
   6939                   }
   6940                   case 0x3: {  /* PICK.QB */
   6941                      DIP("pick.qb r%u, r%u, r%u", rd, rs, rt);
   6942                      vassert(!mode64);
   6943                      t0 = newTemp(Ity_I32);
   6944                      t1 = newTemp(Ity_I8);
   6945                      t2 = newTemp(Ity_I8);
   6946                      t3 = newTemp(Ity_I8);
   6947                      t4 = newTemp(Ity_I8);
   6948 
   6949                      assign(t0, getDSPControl());
   6950                      assign(t1, IRExpr_ITE(binop(Iop_CmpNE32,
   6951                                                  binop(Iop_And32,
   6952                                                        mkexpr(t0),
   6953                                                        mkU32(0x01000000)),
   6954                                                  mkU32(0x0)),
   6955                                            unop(Iop_16to8,
   6956                                                  unop(Iop_32to16,
   6957                                                       getIReg(rs))),
   6958                                            unop(Iop_16to8,
   6959                                                 unop(Iop_32to16,
   6960                                                      getIReg(rt)))));
   6961                      assign(t2, IRExpr_ITE(binop(Iop_CmpNE32,
   6962                                                  binop(Iop_And32,
   6963                                                        mkexpr(t0),
   6964                                                        mkU32(0x02000000)),
   6965                                                  mkU32(0x0)),
   6966                                            unop(Iop_16HIto8,
   6967                                                 unop(Iop_32to16, getIReg(rs))),
   6968                                            unop(Iop_16HIto8,
   6969                                                 unop(Iop_32to16,
   6970                                                      getIReg(rt)))));
   6971                      assign(t3, IRExpr_ITE(binop(Iop_CmpNE32,
   6972                                                  binop(Iop_And32,
   6973                                                        mkexpr(t0),
   6974                                                        mkU32(0x04000000)),
   6975                                                  mkU32(0x0)),
   6976                                            unop(Iop_16to8,
   6977                                                 unop(Iop_32HIto16,
   6978                                                      getIReg(rs))),
   6979                                            unop(Iop_16to8,
   6980                                                 unop(Iop_32HIto16,
   6981                                                      getIReg(rt)))));
   6982                      assign(t4, IRExpr_ITE(binop(Iop_CmpNE32,
   6983                                                  binop(Iop_And32,
   6984                                                        mkexpr(t0),
   6985                                                        mkU32(0x08000000)),
   6986                                                  mkU32(0x0)),
   6987                                            unop(Iop_16HIto8,
   6988                                                 unop(Iop_32HIto16,
   6989                                                      getIReg(rs))),
   6990                                            unop(Iop_16HIto8,
   6991                                                 unop(Iop_32HIto16,
   6992                                                      getIReg(rt)))));
   6993                      putIReg(rd,
   6994                              binop(Iop_16HLto32,
   6995                                    binop(Iop_8HLto16, mkexpr(t4), mkexpr(t3)),
   6996                                    binop(Iop_8HLto16, mkexpr(t2), mkexpr(t1))));
   6997                      break;
   6998                   }
   6999                   case 0x4: {  /* CMPGU.EQ.QB */
   7000                      DIP("cmpgu.eq.qb r%u, r%u, r%u", rd, rs, rt);
   7001                      vassert(!mode64);
   7002                      t1 = newTemp(Ity_I1);
   7003                      t2 = newTemp(Ity_I1);
   7004                      t3 = newTemp(Ity_I1);
   7005                      t4 = newTemp(Ity_I1);
   7006                      t5 = newTemp(Ity_I32);
   7007                      t6 = newTemp(Ity_I32);
   7008                      t7 = newTemp(Ity_I32);
   7009                      t8 = newTemp(Ity_I32);
   7010 
   7011                      assign(t1, binop(Iop_CmpEQ32,
   7012                                       unop(Iop_8Uto32,
   7013                                            unop(Iop_16to8,
   7014                                                 unop(Iop_32to16, getIReg(rs)))),
   7015                                       unop(Iop_8Uto32,
   7016                                            unop(Iop_16to8,
   7017                                                 unop(Iop_32to16,
   7018                                                      getIReg(rt))))));
   7019                      assign(t5, IRExpr_ITE(mkexpr(t1),
   7020                                            mkU32(0x00000001), mkU32(0)));
   7021 
   7022                      assign(t2, binop(Iop_CmpEQ32,
   7023                                       unop(Iop_8Uto32,
   7024                                            unop(Iop_16HIto8,
   7025                                                 unop(Iop_32to16, getIReg(rs)))),
   7026                                       unop(Iop_8Uto32,
   7027                                            unop(Iop_16HIto8,
   7028                                                 unop(Iop_32to16,
   7029                                                      getIReg(rt))))));
   7030                      assign(t6, IRExpr_ITE(mkexpr(t2),
   7031                                            mkU32(0x00000002), mkU32(0)));
   7032 
   7033                      assign(t3, binop(Iop_CmpEQ32,
   7034                                       unop(Iop_8Uto32,
   7035                                            unop(Iop_16to8,
   7036                                                 unop(Iop_32HIto16,
   7037                                                      getIReg(rs)))),
   7038                                       unop(Iop_8Uto32,
   7039                                            unop(Iop_16to8,
   7040                                                 unop(Iop_32HIto16,
   7041                                                      getIReg(rt))))));
   7042                      assign(t7, IRExpr_ITE(mkexpr(t3),
   7043                                            mkU32(0x00000004), mkU32(0)));
   7044 
   7045                      assign(t4, binop(Iop_CmpEQ32,
   7046                                       unop(Iop_8Uto32,
   7047                                            unop(Iop_16HIto8,
   7048                                                 unop(Iop_32HIto16,
   7049                                                      getIReg(rs)))),
   7050                                       unop(Iop_8Uto32,
   7051                                            unop(Iop_16HIto8,
   7052                                                 unop(Iop_32HIto16,
   7053                                                      getIReg(rt))))));
   7054                      assign(t8, IRExpr_ITE(mkexpr(t4),
   7055                                            mkU32(0x00000008), mkU32(0)));
   7056 
   7057                      putIReg(rd, binop(Iop_Or32,
   7058                                        binop(Iop_Or32,
   7059                                              binop(Iop_Or32,
   7060                                                    mkexpr(t5), mkexpr(t6)),
   7061                                              mkexpr(t7)),
   7062                                        mkexpr(t8)));
   7063                      break;
   7064                   }
   7065                   case 0x5: {  /* CMPGU.LT.QB */
   7066                      DIP("cmpgu.lt.qb r%u, r%u, r%u", rd, rs, rt);
   7067                      vassert(!mode64);
   7068                      t1 = newTemp(Ity_I1);
   7069                      t2 = newTemp(Ity_I1);
   7070                      t3 = newTemp(Ity_I1);
   7071                      t4 = newTemp(Ity_I1);
   7072                      t5 = newTemp(Ity_I32);
   7073                      t6 = newTemp(Ity_I32);
   7074                      t7 = newTemp(Ity_I32);
   7075                      t8 = newTemp(Ity_I32);
   7076 
   7077                      assign(t1, binop(Iop_CmpLT32U,
   7078                                       unop(Iop_8Uto32,
   7079                                            unop(Iop_16to8,
   7080                                                 unop(Iop_32to16, getIReg(rs)))),
   7081                                       unop(Iop_8Uto32,
   7082                                            unop(Iop_16to8,
   7083                                                 unop(Iop_32to16,
   7084                                                      getIReg(rt))))));
   7085                      assign(t5, IRExpr_ITE(mkexpr(t1),
   7086                                            mkU32(0x00000001), mkU32(0)));
   7087 
   7088                      assign(t2, binop(Iop_CmpLT32U,
   7089                                       unop(Iop_8Uto32,
   7090                                            unop(Iop_16HIto8,
   7091                                                 unop(Iop_32to16, getIReg(rs)))),
   7092                                       unop(Iop_8Uto32,
   7093                                            unop(Iop_16HIto8,
   7094                                                 unop(Iop_32to16,
   7095                                                      getIReg(rt))))));
   7096                      assign(t6, IRExpr_ITE(mkexpr(t2),
   7097                                            mkU32(0x00000002), mkU32(0)));
   7098 
   7099                      assign(t3, binop(Iop_CmpLT32U,
   7100                                       unop(Iop_8Uto32,
   7101                                            unop(Iop_16to8,
   7102                                                 unop(Iop_32HIto16,
   7103                                                      getIReg(rs)))),
   7104                                       unop(Iop_8Uto32,
   7105                                            unop(Iop_16to8,
   7106                                                 unop(Iop_32HIto16,
   7107                                                      getIReg(rt))))));
   7108                      assign(t7, IRExpr_ITE(mkexpr(t3),
   7109                                            mkU32(0x00000004), mkU32(0)));
   7110 
   7111                      assign(t4, binop(Iop_CmpLT32U,
   7112                                       unop(Iop_8Uto32,
   7113                                            unop(Iop_16HIto8,
   7114                                                 unop(Iop_32HIto16,
   7115                                                      getIReg(rs)))),
   7116                                       unop(Iop_8Uto32,
   7117                                            unop(Iop_16HIto8,
   7118                                                 unop(Iop_32HIto16,
   7119                                                      getIReg(rt))))));
   7120                      assign(t8, IRExpr_ITE(mkexpr(t4),
   7121                                            mkU32(0x00000008), mkU32(0)));
   7122                      putIReg(rd, binop(Iop_Or32,
   7123                                        binop(Iop_Or32,
   7124                                              binop(Iop_Or32,
   7125                                                    mkexpr(t5), mkexpr(t6)),
   7126                                              mkexpr(t7)),
   7127                                        mkexpr(t8)));
   7128                      break;
   7129                   }
   7130                   case 0x6: {  /* CMPGU.LE.QB */
   7131                      DIP("cmpgu.le.qb r%u, r%u, r%u", rd, rs, rt);
   7132                      vassert(!mode64);
   7133                      t1 = newTemp(Ity_I1);
   7134                      t2 = newTemp(Ity_I1);
   7135                      t3 = newTemp(Ity_I1);
   7136                      t4 = newTemp(Ity_I1);
   7137                      t5 = newTemp(Ity_I32);
   7138                      t6 = newTemp(Ity_I32);
   7139                      t7 = newTemp(Ity_I32);
   7140                      t8 = newTemp(Ity_I32);
   7141 
   7142                      assign(t1, binop(Iop_CmpLE32U,
   7143                                       unop(Iop_8Uto32,
   7144                                            unop(Iop_16to8,
   7145                                                 unop(Iop_32to16, getIReg(rs)))),
   7146                                       unop(Iop_8Uto32,
   7147                                            unop(Iop_16to8,
   7148                                                 unop(Iop_32to16,
   7149                                                      getIReg(rt))))));
   7150                      assign(t5, IRExpr_ITE(mkexpr(t1),
   7151                                            mkU32(0x00000001), mkU32(0)));
   7152 
   7153                      assign(t2, binop(Iop_CmpLE32U,
   7154                                       unop(Iop_8Uto32,
   7155                                            unop(Iop_16HIto8,
   7156                                                 unop(Iop_32to16, getIReg(rs)))),
   7157                                       unop(Iop_8Uto32,
   7158                                            unop(Iop_16HIto8,
   7159                                                 unop(Iop_32to16,
   7160                                                      getIReg(rt))))));
   7161                      assign(t6, IRExpr_ITE(mkexpr(t2),
   7162                                            mkU32(0x00000002), mkU32(0)));
   7163 
   7164                      assign(t3, binop(Iop_CmpLE32U,
   7165                                       unop(Iop_8Uto32,
   7166                                            unop(Iop_16to8,
   7167                                                 unop(Iop_32HIto16,
   7168                                                      getIReg(rs)))),
   7169                                       unop(Iop_8Uto32,
   7170                                            unop(Iop_16to8,
   7171                                                 unop(Iop_32HIto16,
   7172                                                      getIReg(rt))))));
   7173                      assign(t7, IRExpr_ITE(mkexpr(t3),
   7174                                            mkU32(0x00000004), mkU32(0)));
   7175 
   7176                      assign(t4, binop(Iop_CmpLE32U,
   7177                                       unop(Iop_8Uto32,
   7178                                            unop(Iop_16HIto8,
   7179                                                 unop(Iop_32HIto16,
   7180                                                      getIReg(rs)))),
   7181                                       unop(Iop_8Uto32,
   7182                                            unop(Iop_16HIto8,
   7183                                                 unop(Iop_32HIto16,
   7184                                                      getIReg(rt))))));
   7185                      assign(t8, IRExpr_ITE(mkexpr(t4),
   7186                                            mkU32(0x00000008), mkU32(0)));
   7187                      putIReg(rd, binop(Iop_Or32,
   7188                                        binop(Iop_Or32,
   7189                                              binop(Iop_Or32,
   7190                                                    mkexpr(t5), mkexpr(t6)),
   7191                                              mkexpr(t7)),
   7192                                        mkexpr(t8)));
   7193                      break;
   7194                   }
   7195                   case 0x8: {  /* CMP.EQ.PH */
   7196                      DIP("cmp.eq.ph r%u, r%u", rs, rt);
   7197                      vassert(!mode64);
   7198                      t1 = newTemp(Ity_I1);
   7199                      t2 = newTemp(Ity_I1);
   7200 
   7201                      assign(t1, binop(Iop_CmpEQ16,
   7202                                       unop(Iop_32to16, getIReg(rs)),
   7203                                       unop(Iop_32to16, getIReg(rt))));
   7204                      putDSPControl(IRExpr_ITE(mkexpr(t1),
   7205                                               binop(Iop_Or32,
   7206                                                     getDSPControl(),
   7207                                                     mkU32(0x01000000)),
   7208                                               binop(Iop_And32,
   7209                                                     getDSPControl(),
   7210                                                     mkU32(0xfeffffff))));
   7211                      assign(t2, binop(Iop_CmpEQ16,
   7212                                       unop(Iop_32HIto16, getIReg(rs)),
   7213                                       unop(Iop_32HIto16, getIReg(rt))));
   7214                      putDSPControl(IRExpr_ITE(mkexpr(t2),
   7215                                               binop(Iop_Or32,
   7216                                                     getDSPControl(),
   7217                                                     mkU32(0x02000000)),
   7218                                               binop(Iop_And32,
   7219                                                     getDSPControl(),
   7220                                                     mkU32(0xfdffffff))));
   7221                      break;
   7222                   }
   7223                   case 0x9: {  /* CMP.LT.PH */
   7224                      DIP("cmp.lt.ph r%u, r%u", rs, rt);
   7225                      vassert(!mode64);
   7226                      t1 = newTemp(Ity_I1);
   7227                      t2 = newTemp(Ity_I1);
   7228 
   7229                      assign(t1, binop(Iop_CmpLT32S,
   7230                                       unop(Iop_16Sto32,
   7231                                            unop(Iop_32to16, getIReg(rs))),
   7232                                       unop(Iop_16Sto32,
   7233                                            unop(Iop_32to16, getIReg(rt)))));
   7234                      putDSPControl(IRExpr_ITE(mkexpr(t1),
   7235                                               binop(Iop_Or32,
   7236                                                     getDSPControl(),
   7237                                                     mkU32(0x01000000)),
   7238                                               binop(Iop_And32,
   7239                                                     getDSPControl(),
   7240                                                     mkU32(0xfeffffff))));
   7241 
   7242                      assign(t2, binop(Iop_CmpLT32S,
   7243                                       unop(Iop_16Sto32,
   7244                                            unop(Iop_32HIto16, getIReg(rs))),
   7245                                       unop(Iop_16Sto32,
   7246                                            unop(Iop_32HIto16, getIReg(rt)))));
   7247                      putDSPControl(IRExpr_ITE(mkexpr(t2),
   7248                                               binop(Iop_Or32,
   7249                                                     getDSPControl(),
   7250                                                     mkU32(0x02000000)),
   7251                                               binop(Iop_And32,
   7252                                                     getDSPControl(),
   7253                                                     mkU32(0xfdffffff))));
   7254                      break;
   7255                   }
   7256                   case 0xA: {  /* CMP.LE.PH */
   7257                      DIP("cmp.le.ph r%u, r%u", rs, rt);
   7258                      vassert(!mode64);
   7259                      t1 = newTemp(Ity_I1);
   7260                      t2 = newTemp(Ity_I1);
   7261 
   7262                      assign(t1, binop(Iop_CmpLE32S,
   7263                                       unop(Iop_16Sto32,
   7264                                            unop(Iop_32to16, getIReg(rs))),
   7265                                       unop(Iop_16Sto32,
   7266                                            unop(Iop_32to16, getIReg(rt)))));
   7267                      putDSPControl(IRExpr_ITE(mkexpr(t1),
   7268                                               binop(Iop_Or32,
   7269                                                     getDSPControl(),
   7270                                                     mkU32(0x01000000)),
   7271                                               binop(Iop_And32,
   7272                                                     getDSPControl(),
   7273                                                     mkU32(0xfeffffff))));
   7274 
   7275                      assign(t2, binop(Iop_CmpLE32S,
   7276                                       unop(Iop_16Sto32,
   7277                                            unop(Iop_32HIto16, getIReg(rs))),
   7278                                       unop(Iop_16Sto32,
   7279                                            unop(Iop_32HIto16, getIReg(rt)))));
   7280                      putDSPControl(IRExpr_ITE(mkexpr(t2),
   7281                                               binop(Iop_Or32,
   7282                                                     getDSPControl(),
   7283                                                     mkU32(0x02000000)),
   7284                                               binop(Iop_And32,
   7285                                                     getDSPControl(),
   7286                                                     mkU32(0xfdffffff))));
   7287                      break;
   7288                   }
   7289                   case 0xB: {  /* PICK.PH */
   7290                      DIP("pick.qb r%u, r%u, r%u", rd, rs, rt);
   7291                      vassert(!mode64);
   7292                      t0 = newTemp(Ity_I32);
   7293                      t1 = newTemp(Ity_I16);
   7294                      t2 = newTemp(Ity_I16);
   7295 
   7296                      assign(t0, getDSPControl());
   7297 
   7298                      assign(t1, IRExpr_ITE(binop(Iop_CmpNE32,
   7299                                                  binop(Iop_And32,
   7300                                                        mkexpr(t0),
   7301                                                        mkU32(0x01000000)),
   7302                                                  mkU32(0x0)),
   7303                                            unop(Iop_32to16, getIReg(rs)),
   7304                                            unop(Iop_32to16, getIReg(rt))));
   7305 
   7306                      assign(t2, IRExpr_ITE(binop(Iop_CmpNE32,
   7307                                                  binop(Iop_And32,
   7308                                                        mkexpr(t0),
   7309                                                        mkU32(0x02000000)),
   7310                                                  mkU32(0x0)),
   7311                                            unop(Iop_32HIto16, getIReg(rs)),
   7312                                            unop(Iop_32HIto16, getIReg(rt))));
   7313 
   7314                      putIReg(rd, binop(Iop_16HLto32, mkexpr(t2), mkexpr(t1)));
   7315                      break;
   7316                   }
   7317                   case 0xC: {  /* PRECRQ.QB.PH */
   7318                      DIP("precrq.qb.ph r%u, r%u, %u", rd, rs, rt);
   7319                      vassert(!mode64);
   7320                      putIReg(rd,
   7321                              binop(Iop_16HLto32,
   7322                                    binop(Iop_8HLto16,
   7323                                          unop(Iop_16HIto8,
   7324                                               unop(Iop_32HIto16, getIReg(rs))),
   7325                                          unop(Iop_16HIto8,
   7326                                               unop(Iop_32to16, getIReg(rs)))),
   7327                                    binop(Iop_8HLto16,
   7328                                          unop(Iop_16HIto8,
   7329                                               unop(Iop_32HIto16, getIReg(rt))),
   7330                                          unop(Iop_16HIto8,
   7331                                               unop(Iop_32to16, getIReg(rt))))));
   7332                      break;
   7333                   }
   7334                   case 0xD: {  /* PRECR.QB.PH */
   7335                      DIP("precr.qb.ph r%u, r%u, r%u", rd, rs, rt);
   7336                      vassert(!mode64);
   7337 
   7338                      putIReg(rd,
   7339                              binop(Iop_16HLto32,
   7340                                    binop(Iop_8HLto16,
   7341                                          unop(Iop_16to8,
   7342                                               unop(Iop_32HIto16, getIReg(rs))),
   7343                                          unop(Iop_16to8,
   7344                                               unop(Iop_32to16, getIReg(rs)))),
   7345                                    binop(Iop_8HLto16,
   7346                                          unop(Iop_16to8,
   7347                                               unop(Iop_32HIto16, getIReg(rt))),
   7348                                          unop(Iop_16to8,
   7349                                               unop(Iop_32to16, getIReg(rt))))));
   7350                      break;
   7351                   }
   7352                   case 0xF: {  /* PRECRQU_S.QB.PH */
   7353                      DIP("precrqu_s.qb.ph r%u, r%u, %u", rd, rs, rt);
   7354                      vassert(!mode64);
   7355                      t0 = newTemp(Ity_I8);
   7356                      t1 = newTemp(Ity_I8);
   7357                      t2 = newTemp(Ity_I8);
   7358                      t3 = newTemp(Ity_I8);
   7359                      t4 = newTemp(Ity_I8);
   7360                      t5 = newTemp(Ity_I32);
   7361                      t6 = newTemp(Ity_I1);
   7362                      t7 = newTemp(Ity_I8);
   7363                      t8 = newTemp(Ity_I1);
   7364                      t9 = newTemp(Ity_I32);
   7365                      t10 = newTemp(Ity_I8);
   7366                      t11 = newTemp(Ity_I1);
   7367                      t12 = newTemp(Ity_I32);
   7368                      t13 = newTemp(Ity_I8);
   7369                      t14 = newTemp(Ity_I1);
   7370                      t15 = newTemp(Ity_I32);
   7371 
   7372                      assign(t4, IRExpr_ITE(binop(Iop_CmpLT32U,
   7373                                                  mkU32(0x7f80),
   7374                                                  binop(Iop_And32,
   7375                                                        unop(Iop_16Uto32,
   7376                                                             unop(Iop_32to16,
   7377                                                             getIReg(rs))),
   7378                                                        mkU32(0x7fff))),
   7379                                            mkU8(0xff),
   7380                                            unop(Iop_16HIto8,
   7381                                                 unop(Iop_32to16,
   7382                                                      binop(Iop_Shl32,
   7383                                                            getIReg(rs),
   7384                                                            mkU8(1))))));
   7385                      assign(t0, IRExpr_ITE(binop(Iop_CmpEQ32,
   7386                                                  binop(Iop_And32,
   7387                                                        unop(Iop_16Uto32,
   7388                                                             unop(Iop_32to16,
   7389                                                                  getIReg(rs))),
   7390                                                        mkU32(0x00008000)),
   7391                                                  mkU32(0x0)),
   7392                                            mkexpr(t4),
   7393                                            mkU8(0x0)));
   7394                      assign(t5, binop(Iop_And32,
   7395                                       unop(Iop_16Uto32,
   7396                                             unop(Iop_32to16,
   7397                                                  getIReg(rs))),
   7398                                       mkU32(0x00008000)));
   7399                      assign(t6, binop(Iop_CmpLT32U,
   7400                                       mkU32(0x7f80),
   7401                                       binop(Iop_And32,
   7402                                             unop(Iop_16Uto32,
   7403                                                  unop(Iop_32to16,
   7404                                                  getIReg(rs))),
   7405                                             mkU32(0x7fff))));
   7406                      putDSPControl(IRExpr_ITE(binop(Iop_CmpEQ32,
   7407                                                     mkexpr(t5),
   7408                                                     mkU32(0x0)),
   7409                                               IRExpr_ITE(mkexpr(t6),
   7410                                                          binop(Iop_Or32,
   7411                                                                getDSPControl(),
   7412                                                                mkU32(0x00400000)
   7413                                                               ),
   7414                                                          getDSPControl()),
   7415                                               binop(Iop_Or32,
   7416                                                     getDSPControl(),
   7417                                                     mkU32(0x00400000))));
   7418 
   7419                      assign(t7, IRExpr_ITE(binop(Iop_CmpLT32U,
   7420                                                  mkU32(0x7f80),
   7421                                                  binop(Iop_And32,
   7422                                                        unop(Iop_16Uto32,
   7423                                                             unop(Iop_32HIto16,
   7424                                                                  getIReg(rs))),
   7425                                                        mkU32(0x7fff))),
   7426                                            mkU8(0xff),
   7427                                            unop(Iop_16HIto8,
   7428                                                 unop(Iop_32HIto16,
   7429                                                      binop(Iop_Shl32,
   7430                                                            getIReg(rs),
   7431                                                            mkU8(1))))));
   7432                      assign(t1, IRExpr_ITE(binop(Iop_CmpEQ32,
   7433                                                  binop(Iop_And32,
   7434                                                        unop(Iop_16Uto32,
   7435                                                             unop(Iop_32HIto16,
   7436                                                                  getIReg(rs))),
   7437                                                        mkU32(0x00008000)),
   7438                                                  mkU32(0x0)),
   7439                                            mkexpr(t7),
   7440                                            mkU8(0x0)));
   7441                      assign(t8, binop(Iop_CmpEQ32,
   7442                                       binop(Iop_And32,
   7443                                             unop(Iop_16Uto32,
   7444                                                  unop(Iop_32HIto16,
   7445                                                       getIReg(rs))),
   7446                                             mkU32(0x00008000)),
   7447                                       mkU32(0x0)));
   7448                      assign(t9, IRExpr_ITE(binop(Iop_CmpLT32U,
   7449                                                  mkU32(0x7f80),
   7450                                                  binop(Iop_And32,
   7451                                                        unop(Iop_16Uto32,
   7452                                                             unop(Iop_32HIto16,
   7453                                                                  getIReg(rs))),
   7454                                                        mkU32(0x7fff))),
   7455                                            binop(Iop_Or32,
   7456                                                  getDSPControl(),
   7457                                                  mkU32(0x00400000)),
   7458                                            getDSPControl()));
   7459                      putDSPControl(IRExpr_ITE(mkexpr(t8),
   7460                                               mkexpr(t9),
   7461                                               binop(Iop_Or32,
   7462                                                     getDSPControl(),
   7463                                                     mkU32(0x00400000))));
   7464 
   7465                      assign(t10, IRExpr_ITE(binop(Iop_CmpLT32U,
   7466                                                   mkU32(0x7f80),
   7467                                                   binop(Iop_And32,
   7468                                                         unop(Iop_16Uto32,
   7469                                                              unop(Iop_32to16,
   7470                                                              getIReg(rt))),
   7471                                                         mkU32(0x7fff))),
   7472                                             mkU8(0xff),
   7473                                             unop(Iop_16HIto8,
   7474                                                  unop(Iop_32to16,
   7475                                                       binop(Iop_Shl32,
   7476                                                             getIReg(rt),
   7477                                                             mkU8(1))))));
   7478                      assign(t2, IRExpr_ITE(binop(Iop_CmpEQ32,
   7479                                                  binop(Iop_And32,
   7480                                                        unop(Iop_16Uto32,
   7481                                                             unop(Iop_32to16,
   7482                                                                  getIReg(rt))),
   7483                                                        mkU32(0x00008000)),
   7484                                                  mkU32(0x0)),
   7485                                            mkexpr(t10),
   7486                                            mkU8(0x0)));
   7487                      assign(t11, binop(Iop_CmpEQ32,
   7488                                        binop(Iop_And32,
   7489                                              unop(Iop_16Uto32,
   7490                                                   unop(Iop_32to16,
   7491                                                        getIReg(rt))),
   7492                                              mkU32(0x00008000)),
   7493                                        mkU32(0x0)));
   7494                      assign(t12, IRExpr_ITE(binop(Iop_CmpLT32U,
   7495                                                   mkU32(0x7f80),
   7496                                                   binop(Iop_And32,
   7497                                                         unop(Iop_16Uto32,
   7498                                                              unop(Iop_32to16,
   7499                                                              getIReg(rt))),
   7500                                                         mkU32(0x7fff))),
   7501                                             binop(Iop_Or32,
   7502                                                   getDSPControl(),
   7503                                                   mkU32(0x00400000)),
   7504                                             getDSPControl()));
   7505                      putDSPControl(IRExpr_ITE(mkexpr(t11),
   7506                                               mkexpr(t12),
   7507                                               binop(Iop_Or32,
   7508                                                     getDSPControl(),
   7509                                                     mkU32(0x00400000))));
   7510 
   7511                      assign(t13, IRExpr_ITE(binop(Iop_CmpLT32U,
   7512                                                   mkU32(0x7f80),
   7513                                                   binop(Iop_And32,
   7514                                                         unop(Iop_16Uto32,
   7515                                                              unop(Iop_32HIto16,
   7516                                                                   getIReg(rt))),
   7517                                                         mkU32(0x7fff))),
   7518                                             mkU8(0xff),
   7519                                             unop(Iop_16HIto8,
   7520                                                  unop(Iop_32HIto16,
   7521                                                       binop(Iop_Shl32,
   7522                                                             getIReg(rt),
   7523                                                             mkU8(1))))));
   7524                      assign(t3, IRExpr_ITE(binop(Iop_CmpEQ32,
   7525                                                  binop(Iop_And32,
   7526                                                        unop(Iop_16Uto32,
   7527                                                             unop(Iop_32HIto16,
   7528                                                                  getIReg(rt))),
   7529                                                        mkU32(0x00008000)),
   7530                                                  mkU32(0x0)),
   7531                                            mkexpr(t13),
   7532                                            mkU8(0x0)));
   7533                      assign(t14, binop(Iop_CmpEQ32,
   7534                                        binop(Iop_And32,
   7535                                              unop(Iop_16Uto32,
   7536                                                   unop(Iop_32HIto16,
   7537                                                        getIReg(rt))),
   7538                                              mkU32(0x00008000)),
   7539                                        mkU32(0x0)));
   7540                      assign(t15, IRExpr_ITE(binop(Iop_CmpLT32U,
   7541                                                   mkU32(0x7f80),
   7542                                                   binop(Iop_And32,
   7543                                                         unop(Iop_16Uto32,
   7544                                                              unop(Iop_32HIto16,
   7545                                                                   getIReg(rt))),
   7546                                                         mkU32(0x7fff))),
   7547                                             binop(Iop_Or32,
   7548                                                   getDSPControl(),
   7549                                                   mkU32(0x00400000)),
   7550                                             getDSPControl()));
   7551                      putDSPControl(IRExpr_ITE(mkexpr(t14),
   7552                                               mkexpr(t15),
   7553                                               binop(Iop_Or32,
   7554                                                     getDSPControl(),
   7555                                                     mkU32(0x00400000))));
   7556 
   7557                      putIReg(rd, binop(Iop_16HLto32,
   7558                                        binop(Iop_8HLto16,
   7559                                              mkexpr(t1), mkexpr(t0)),
   7560                                        binop(Iop_8HLto16,
   7561                                              mkexpr(t3), mkexpr(t2))));
   7562                      break;
   7563                   }
   7564                   case 0x14: {  /* PRECRQ.PH.W */
   7565                      DIP("precrq.ph.w r%u, r%u, %u", rd, rs, rt);
   7566                      vassert(!mode64);
   7567                      putIReg(rd, binop(Iop_16HLto32,
   7568                                        unop(Iop_32HIto16, getIReg(rs)),
   7569                                        unop(Iop_32HIto16, getIReg(rt))));
   7570                      break;
   7571                   }
   7572                   case 0x15: {  /* PRECRQ_RS.PH.W */
   7573                      DIP("precrq_rs.ph.w r%u, r%u, %u", rd, rs, rt);
   7574                      vassert(!mode64);
   7575                      t0 = newTemp(Ity_I64);
   7576                      t1 = newTemp(Ity_I1);
   7577                      t2 = newTemp(Ity_I32);
   7578                      t3 = newTemp(Ity_I64);
   7579                      t4 = newTemp(Ity_I1);
   7580                      t5 = newTemp(Ity_I32);
   7581 
   7582                      assign(t0, binop(Iop_Add64,
   7583                                       binop(Iop_32HLto64,
   7584                                             binop(Iop_Shr32,
   7585                                                   binop(Iop_And32,
   7586                                                         getIReg(rs),
   7587                                                         mkU32(0x80000000)),
   7588                                                   mkU8(31)),
   7589                                             getIReg(rs)),
   7590                                       mkU64(0x0000000000008000ULL)));
   7591                      assign(t1, binop(Iop_CmpNE32,
   7592                                       binop(Iop_And32,
   7593                                             unop(Iop_64HIto32, mkexpr(t0)),
   7594                                             mkU32(0x1)),
   7595                                       binop(Iop_And32,
   7596                                             binop(Iop_Shr32,
   7597                                                   unop(Iop_64to32, mkexpr(t0)),
   7598                                                   mkU8(31)),
   7599                                             mkU32(0x1))));
   7600                      assign(t2, IRExpr_ITE(mkexpr(t1),
   7601                                            mkU32(0x7fffffff),
   7602                                            unop(Iop_64to32, mkexpr(t0))));
   7603                      putDSPControl(IRExpr_ITE(mkexpr(t1),
   7604                                               binop(Iop_Or32,
   7605                                                     getDSPControl(),
   7606                                                     mkU32(0x400000)),
   7607                                               getDSPControl()));
   7608                      assign(t3, binop(Iop_Add64,
   7609                                       binop(Iop_32HLto64,
   7610                                             binop(Iop_Shr32,
   7611                                                   binop(Iop_And32,
   7612                                                         getIReg(rt),
   7613                                                         mkU32(0x80000000)),
   7614                                                   mkU8(31)),
   7615                                             getIReg(rt)),
   7616                                       mkU64(0x0000000000008000ULL)));
   7617                      assign(t4, binop(Iop_CmpNE32,
   7618                                       binop(Iop_And32,
   7619                                             unop(Iop_64HIto32, mkexpr(t3)),
   7620                                             mkU32(0x1)),
   7621                                       binop(Iop_And32,
   7622                                             binop(Iop_Shr32,
   7623                                                   unop(Iop_64to32, mkexpr(t3)),
   7624                                                   mkU8(31)),
   7625                                             mkU32(0x1))));
   7626                      assign(t5, IRExpr_ITE(mkexpr(t4),
   7627                                            mkU32(0x7fffffff),
   7628                                            unop(Iop_64to32, mkexpr(t3))));
   7629                      putDSPControl(IRExpr_ITE(mkexpr(t4),
   7630                                               binop(Iop_Or32,
   7631                                                     getDSPControl(),
   7632                                                     mkU32(0x400000)),
   7633                                               getDSPControl()));
   7634                      putIReg(rd, binop(Iop_16HLto32,
   7635                                        unop(Iop_32HIto16, mkexpr(t2)),
   7636                                        unop(Iop_32HIto16, mkexpr(t5))));
   7637                      break;
   7638                   }
   7639                   case 0x1E: {  /* PRECR_SRA.PH.W */
   7640                      DIP("precr_sra.ph.w r%u, r%u, %u", rt, rs, rd);
   7641                      vassert(!mode64);
   7642 
   7643                      if (0 == rd) {
   7644                         putIReg(rt, binop(Iop_16HLto32,
   7645                                           unop(Iop_32to16, getIReg(rt)),
   7646                                           unop(Iop_32to16, getIReg(rs))));
   7647                      } else {
   7648                         putIReg(rt, binop(Iop_16HLto32,
   7649                                           unop(Iop_32to16, binop(Iop_Sar32,
   7650                                                                  getIReg(rt),
   7651                                                                  mkU8(rd))),
   7652                                           unop(Iop_32to16, binop(Iop_Sar32,
   7653                                                                  getIReg(rs),
   7654                                                                  mkU8(rd)))));
   7655                      }
   7656                      break;
   7657                   }
   7658                   case 0x1F: {  /* PRECR_SRA_R.PH.W */
   7659                      DIP("precr_sra_r.ph.w r%u, r%u, %u", rt, rs, rd);
   7660                      vassert(!mode64);
   7661 
   7662                      t0 = newTemp(Ity_I32);
   7663                      t1 = newTemp(Ity_I32);
   7664 
   7665                      if (0 == rd) {
   7666                         putIReg(rt, binop(Iop_16HLto32,
   7667                                           unop(Iop_32to16, getIReg(rt)),
   7668                                           unop(Iop_32to16, getIReg(rs))));
   7669                      } else {
   7670                         assign(t0, binop(Iop_Shr32,
   7671                                          binop(Iop_Add32,
   7672                                                binop(Iop_Sar32,
   7673                                                      getIReg(rt),
   7674                                                      mkU8(rd-1)),
   7675                                                mkU32(0x1)),
   7676                                          mkU8(0x1)));
   7677                         assign(t1, binop(Iop_Shr32,
   7678                                          binop(Iop_Add32,
   7679                                                binop(Iop_Sar32,
   7680                                                      getIReg(rs),
   7681                                                      mkU8(rd-1)),
   7682                                                mkU32(0x1)),
   7683                                          mkU8(0x1)));
   7684                         putIReg(rt, binop(Iop_16HLto32,
   7685                                           unop(Iop_32to16, mkexpr(t0)),
   7686                                           unop(Iop_32to16, mkexpr(t1))));
   7687                      };
   7688                      break;
   7689                   }
   7690                   case 0xE: {  /* PACKRL.PH */
   7691                      DIP("packrl.ph r%u, r%u, r%u", rd, rs, rt);
   7692                      vassert(!mode64);
   7693 
   7694                      putIReg(rd, binop(Iop_16HLto32,
   7695                                        unop(Iop_32to16, getIReg(rs)),
   7696                                        unop(Iop_32HIto16, getIReg(rt))));
   7697                      break;
   7698                   }
   7699                   case 0x18: {  /* CMPGDU.EQ.QB */
   7700                      DIP("cmpgdu.eq.qb r%u, r%u, r%u", rd, rs, rt);
   7701                      vassert(!mode64);
   7702                      t1 = newTemp(Ity_I1);
   7703                      t2 = newTemp(Ity_I1);
   7704                      t3 = newTemp(Ity_I1);
   7705                      t4 = newTemp(Ity_I1);
   7706                      t5 = newTemp(Ity_I32);
   7707                      t6 = newTemp(Ity_I32);
   7708                      t7 = newTemp(Ity_I32);
   7709                      t8 = newTemp(Ity_I32);
   7710 
   7711                      assign(t1,
   7712                             binop(Iop_CmpEQ32,
   7713                                   unop(Iop_8Uto32,
   7714                                        unop(Iop_16to8,
   7715                                             unop(Iop_32to16, getIReg(rs)))),
   7716                                   unop(Iop_8Uto32,
   7717                                        unop(Iop_16to8,
   7718                                             unop(Iop_32to16, getIReg(rt))))));
   7719                      assign(t5, IRExpr_ITE(mkexpr(t1),
   7720                                            mkU32(0x00000001), mkU32(0)));
   7721                      putDSPControl(IRExpr_ITE(mkexpr(t1),
   7722                                               binop(Iop_Or32,
   7723                                                     getDSPControl(),
   7724                                                     mkU32(0x01000000)),
   7725                                               binop(Iop_And32,
   7726                                                     getDSPControl(),
   7727                                                     mkU32(0xfeffffff))));
   7728 
   7729                      assign(t2, binop(Iop_CmpEQ32,
   7730                                       unop(Iop_8Uto32,
   7731                                            unop(Iop_16HIto8,
   7732                                                 unop(Iop_32to16, getIReg(rs)))),
   7733                                       unop(Iop_8Uto32,
   7734                                            unop(Iop_16HIto8,
   7735                                                 unop(Iop_32to16,
   7736                                                      getIReg(rt))))));
   7737                      assign(t6, IRExpr_ITE(mkexpr(t2),
   7738                                            mkU32(0x00000002), mkU32(0)));
   7739                      putDSPControl(IRExpr_ITE(mkexpr(t2),
   7740                                               binop(Iop_Or32,
   7741                                                     getDSPControl(),
   7742                                                     mkU32(0x02000000)),
   7743                                               binop(Iop_And32,
   7744                                                     getDSPControl(),
   7745                                                     mkU32(0xfdffffff))));
   7746 
   7747                      assign(t3, binop(Iop_CmpEQ32,
   7748                                       unop(Iop_8Uto32,
   7749                                            unop(Iop_16to8,
   7750                                                 unop(Iop_32HIto16,
   7751                                                      getIReg(rs)))),
   7752                                       unop(Iop_8Uto32,
   7753                                            unop(Iop_16to8,
   7754                                                 unop(Iop_32HIto16,
   7755                                                      getIReg(rt))))));
   7756                      assign(t7, IRExpr_ITE(mkexpr(t3),
   7757                                            mkU32(0x00000004), mkU32(0)));
   7758                      putDSPControl(IRExpr_ITE(mkexpr(t3),
   7759                                               binop(Iop_Or32,
   7760                                                     getDSPControl(),
   7761                                                     mkU32(0x04000000)),
   7762                                               binop(Iop_And32,
   7763                                                     getDSPControl(),
   7764                                                     mkU32(0xfbffffff))));
   7765 
   7766                      assign(t4, binop(Iop_CmpEQ32,
   7767                                       unop(Iop_8Uto32,
   7768                                            unop(Iop_16HIto8,
   7769                                                 unop(Iop_32HIto16,
   7770                                                      getIReg(rs)))),
   7771                                       unop(Iop_8Uto32,
   7772                                            unop(Iop_16HIto8,
   7773                                                 unop(Iop_32HIto16,
   7774                                                      getIReg(rt))))));
   7775                      assign(t8, IRExpr_ITE(mkexpr(t4),
   7776                                            mkU32(0x00000008), mkU32(0)));
   7777                      putDSPControl(IRExpr_ITE(mkexpr(t4),
   7778                                               binop(Iop_Or32,
   7779                                                     getDSPControl(),
   7780                                                     mkU32(0x08000000)),
   7781                                               binop(Iop_And32,
   7782                                                     getDSPControl(),
   7783                                                     mkU32(0xf7ffffff))));
   7784 
   7785                      putIReg(rd, binop(Iop_Or32,
   7786                                        binop(Iop_Or32,
   7787                                              binop(Iop_Or32,
   7788                                                    mkexpr(t5), mkexpr(t6)),
   7789                                              mkexpr(t7)),
   7790                                        mkexpr(t8)));
   7791                      break;
   7792                   }
   7793                   case 0x19: {  /* CMPGDU.LT.QB */
   7794                      DIP("cmpgdu.lt.qb r%u, r%u, r%u", rd, rs, rt);
   7795                      vassert(!mode64);
   7796                      t1 = newTemp(Ity_I1);
   7797                      t2 = newTemp(Ity_I1);
   7798                      t3 = newTemp(Ity_I1);
   7799                      t4 = newTemp(Ity_I1);
   7800                      t5 = newTemp(Ity_I32);
   7801                      t6 = newTemp(Ity_I32);
   7802                      t7 = newTemp(Ity_I32);
   7803                      t8 = newTemp(Ity_I32);
   7804 
   7805                      assign(t1, binop(Iop_CmpLT32U,
   7806                                       unop(Iop_8Uto32,
   7807                                            unop(Iop_16to8,
   7808                                                 unop(Iop_32to16, getIReg(rs)))),
   7809                                       unop(Iop_8Uto32,
   7810                                            unop(Iop_16to8,
   7811                                                 unop(Iop_32to16,
   7812                                                      getIReg(rt))))));
   7813                      assign(t5, IRExpr_ITE(mkexpr(t1),
   7814                                            mkU32(0x00000001), mkU32(0)));
   7815                      putDSPControl(IRExpr_ITE(mkexpr(t1),
   7816                                               binop(Iop_Or32,
   7817                                                     getDSPControl(),
   7818                                                     mkU32(0x01000000)),
   7819                                               binop(Iop_And32,
   7820                                                     getDSPControl(),
   7821                                                     mkU32(0xfeffffff))));
   7822 
   7823                      assign(t2, binop(Iop_CmpLT32U,
   7824                                       unop(Iop_8Uto32,
   7825                                            unop(Iop_16HIto8,
   7826                                                 unop(Iop_32to16, getIReg(rs)))),
   7827                                       unop(Iop_8Uto32,
   7828                                            unop(Iop_16HIto8,
   7829                                                 unop(Iop_32to16,
   7830                                                      getIReg(rt))))));
   7831                      assign(t6, IRExpr_ITE(mkexpr(t2),
   7832                                            mkU32(0x00000002), mkU32(0)));
   7833                      putDSPControl(IRExpr_ITE(mkexpr(t2),
   7834                                               binop(Iop_Or32,
   7835                                                     getDSPControl(),
   7836                                                     mkU32(0x02000000)),
   7837                                               binop(Iop_And32,
   7838                                                     getDSPControl(),
   7839                                                     mkU32(0xfdffffff))));
   7840 
   7841                      assign(t3, binop(Iop_CmpLT32U,
   7842                                       unop(Iop_8Uto32,
   7843                                            unop(Iop_16to8,
   7844                                                 unop(Iop_32HIto16,
   7845                                                      getIReg(rs)))),
   7846                                       unop(Iop_8Uto32,
   7847                                            unop(Iop_16to8,
   7848                                                 unop(Iop_32HIto16,
   7849                                                      getIReg(rt))))));
   7850                      assign(t7, IRExpr_ITE(mkexpr(t3),
   7851                                            mkU32(0x00000004), mkU32(0)));
   7852                      putDSPControl(IRExpr_ITE(mkexpr(t3),
   7853                                               binop(Iop_Or32,
   7854                                                     getDSPControl(),
   7855                                                     mkU32(0x04000000)),
   7856                                               binop(Iop_And32,
   7857                                                     getDSPControl(),
   7858                                                     mkU32(0xfbffffff))));
   7859 
   7860                      assign(t4, binop(Iop_CmpLT32U,
   7861                                       unop(Iop_8Uto32,
   7862                                            unop(Iop_16HIto8,
   7863                                                 unop(Iop_32HIto16,
   7864                                                      getIReg(rs)))),
   7865                                       unop(Iop_8Uto32,
   7866                                            unop(Iop_16HIto8,
   7867                                                 unop(Iop_32HIto16,
   7868                                                      getIReg(rt))))));
   7869                      assign(t8, IRExpr_ITE(mkexpr(t4),
   7870                                            mkU32(0x00000008), mkU32(0)));
   7871                      putDSPControl(IRExpr_ITE(mkexpr(t4),
   7872                                               binop(Iop_Or32,
   7873                                                     getDSPControl(),
   7874                                                     mkU32(0x08000000)),
   7875                                               binop(Iop_And32,
   7876                                                     getDSPControl(),
   7877                                                     mkU32(0xf7ffffff))));
   7878 
   7879                      putIReg(rd, binop(Iop_Or32,
   7880                                        binop(Iop_Or32,
   7881                                              binop(Iop_Or32,
   7882                                                    mkexpr(t5), mkexpr(t6)),
   7883                                              mkexpr(t7)),
   7884                                        mkexpr(t8)));
   7885                      break;
   7886                   }
   7887                   case 0x1A: {  /* CMPGDU.LE.QB */
   7888                      DIP("cmpgdu.le.qb r%u, r%u, r%u", rd, rs, rt);
   7889                      vassert(!mode64);
   7890                      t1 = newTemp(Ity_I1);
   7891                      t2 = newTemp(Ity_I1);
   7892                      t3 = newTemp(Ity_I1);
   7893                      t4 = newTemp(Ity_I1);
   7894                      t5 = newTemp(Ity_I32);
   7895                      t6 = newTemp(Ity_I32);
   7896                      t7 = newTemp(Ity_I32);
   7897                      t8 = newTemp(Ity_I32);
   7898 
   7899                      assign(t1, binop(Iop_CmpLE32U,
   7900                                       unop(Iop_8Uto32,
   7901                                            unop(Iop_16to8,
   7902                                                 unop(Iop_32to16, getIReg(rs)))),
   7903                                       unop(Iop_8Uto32,
   7904                                            unop(Iop_16to8,
   7905                                                 unop(Iop_32to16,
   7906                                                      getIReg(rt))))));
   7907                      assign(t5, IRExpr_ITE(mkexpr(t1),
   7908                                            mkU32(0x00000001),
   7909                                            mkU32(0)));
   7910                      putDSPControl(IRExpr_ITE(mkexpr(t1),
   7911                                               binop(Iop_Or32,
   7912                                                     getDSPControl(),
   7913                                                     mkU32(0x01000000)),
   7914                                               binop(Iop_And32,
   7915                                                     getDSPControl(),
   7916                                                     mkU32(0xfeffffff))));
   7917 
   7918                      assign(t2, binop(Iop_CmpLE32U,
   7919                                       unop(Iop_8Uto32,
   7920                                            unop(Iop_16HIto8,
   7921                                                 unop(Iop_32to16, getIReg(rs)))),
   7922                                       unop(Iop_8Uto32,
   7923                                            unop(Iop_16HIto8,
   7924                                                 unop(Iop_32to16,
   7925                                                      getIReg(rt))))));
   7926                      assign(t6, IRExpr_ITE(mkexpr(t2),
   7927                                            mkU32(0x00000002), mkU32(0)));
   7928                      putDSPControl(IRExpr_ITE(mkexpr(t2),
   7929                                               binop(Iop_Or32,
   7930                                                     getDSPControl(),
   7931                                                     mkU32(0x02000000)),
   7932                                               binop(Iop_And32,
   7933                                                     getDSPControl(),
   7934                                                     mkU32(0xfdffffff))));
   7935 
   7936                      assign(t3, binop(Iop_CmpLE32U,
   7937                                       unop(Iop_8Uto32,
   7938                                            unop(Iop_16to8,
   7939                                                 unop(Iop_32HIto16,
   7940                                                      getIReg(rs)))),
   7941                                       unop(Iop_8Uto32,
   7942                                            unop(Iop_16to8,
   7943                                                 unop(Iop_32HIto16,
   7944                                                      getIReg(rt))))));
   7945                      assign(t7, IRExpr_ITE(mkexpr(t3),
   7946                                            mkU32(0x00000004), mkU32(0)));
   7947                      putDSPControl(IRExpr_ITE(mkexpr(t3),
   7948                                               binop(Iop_Or32,
   7949                                                     getDSPControl(),
   7950                                                     mkU32(0x04000000)),
   7951                                               binop(Iop_And32,
   7952                                                     getDSPControl(),
   7953                                                     mkU32(0xfbffffff))));
   7954 
   7955                      assign(t4, binop(Iop_CmpLE32U,
   7956                                       unop(Iop_8Uto32,
   7957                                            unop(Iop_16HIto8,
   7958                                                 unop(Iop_32HIto16,
   7959                                                      getIReg(rs)))),
   7960                                       unop(Iop_8Uto32,
   7961                                            unop(Iop_16HIto8,
   7962                                                 unop(Iop_32HIto16,
   7963                                                      getIReg(rt))))));
   7964                      assign(t8, IRExpr_ITE(mkexpr(t4),
   7965                                            mkU32(0x00000008), mkU32(0)));
   7966                      putDSPControl(IRExpr_ITE(mkexpr(t4),
   7967                                               binop(Iop_Or32,
   7968                                                     getDSPControl(),
   7969                                                     mkU32(0x08000000)),
   7970                                               binop(Iop_And32,
   7971                                                     getDSPControl(),
   7972                                                     mkU32(0xf7ffffff))));
   7973 
   7974                      putIReg(rd, binop(Iop_Or32,
   7975                                        binop(Iop_Or32,
   7976                                              binop(Iop_Or32,
   7977                                                    mkexpr(t5), mkexpr(t6)),
   7978                                              mkexpr(t7)),
   7979                                        mkexpr(t8)));
   7980                      break;
   7981                   }
   7982                   default:
   7983                      return -1;
   7984                }
   7985                break;  /* end of CMPU.EQ.QB */
   7986             }
   7987             case 0x13: {  /* SHLL.QB */
   7988                switch(sa) {
   7989                   case 0x0: {  /* SHLL.QB */
   7990                      DIP("shll.qb r%u, r%u, %u", rd, rt, rs);
   7991                      vassert(!mode64);
   7992                      t0 = newTemp(Ity_I32);
   7993                      t1 = newTemp(Ity_I1);
   7994                      t2 = newTemp(Ity_I1);
   7995                      t3 = newTemp(Ity_I32);
   7996                      t4 = newTemp(Ity_I1);
   7997                      t5 = newTemp(Ity_I1);
   7998                      t6 = newTemp(Ity_I32);
   7999                      t7 = newTemp(Ity_I1);
   8000                      t8 = newTemp(Ity_I1);
   8001                      t9 = newTemp(Ity_I1);
   8002                      t10 = newTemp(Ity_I1);
   8003 
   8004                      if (0 == rs) {
   8005                         putIReg(rd, getIReg(rt));
   8006                      } else {
   8007                         /* Shift bits 7..0 and 23..16. */
   8008                         assign(t0, binop(Iop_Shl32,
   8009                                          binop(Iop_And32,
   8010                                                getIReg(rt),
   8011                                                mkU32(0x00ff00ff)),
   8012                                          mkU8(rs)));
   8013                         assign(t1, binop(Iop_CmpNE32,
   8014                                         binop(Iop_And32,
   8015                                               mkexpr(t0),
   8016                                               mkU32(0xff000000)),
   8017                                         mkU32(0x00000000)));
   8018                         assign(t2, binop(Iop_CmpNE32,
   8019                                         binop(Iop_And32,
   8020                                               mkexpr(t0),
   8021                                               mkU32(0xff000000)),
   8022                                         mkU32(0xff000000)));
   8023                         assign(t7, binop(Iop_CmpNE32,
   8024                                         binop(Iop_And32,
   8025                                               mkexpr(t0),
   8026                                               mkU32(0x0000ff00)),
   8027                                         mkU32(0x00000000)));
   8028                         assign(t8, binop(Iop_CmpNE32,
   8029                                         binop(Iop_And32,
   8030                                               mkexpr(t0),
   8031                                               mkU32(0x0000ff00)),
   8032                                         mkU32(0x000ff00)));
   8033                         /* Shift bits 15..8 and 31..24. */
   8034                         assign(t3, binop(Iop_Shl32,
   8035                                          binop(Iop_Shr32,
   8036                                                binop(Iop_And32,
   8037                                                      getIReg(rt),
   8038                                                      mkU32(0xff00ff00)),
   8039                                                mkU8(8)),
   8040                                          mkU8(rs)));
   8041                         assign(t4, binop(Iop_CmpNE32,
   8042                                         binop(Iop_And32,
   8043                                               mkexpr(t3),
   8044                                               mkU32(0xff000000)),
   8045                                         mkU32(0x00000000)));
   8046                         assign(t5, binop(Iop_CmpNE32,
   8047                                         binop(Iop_And32,
   8048                                               mkexpr(t3),
   8049                                               mkU32(0xff000000)),
   8050                                         mkU32(0xff000000)));
   8051                         assign(t9, binop(Iop_CmpNE32,
   8052                                         binop(Iop_And32,
   8053                                               mkexpr(t3),
   8054                                               mkU32(0x0000ff00)),
   8055                                         mkU32(0x00000000)));
   8056                         assign(t10, binop(Iop_CmpNE32,
   8057                                         binop(Iop_And32,
   8058                                               mkexpr(t3),
   8059                                               mkU32(0x0000ff00)),
   8060                                         mkU32(0x0000ff00)));
   8061 
   8062                         assign(t6, binop(Iop_Or32,
   8063                                          binop(Iop_Or32,
   8064                                                binop(Iop_And32,
   8065                                                      unop(Iop_1Uto32,
   8066                                                           mkexpr(t1)),
   8067                                                      unop(Iop_1Uto32,
   8068                                                           mkexpr(t2))),
   8069                                                binop(Iop_And32,
   8070                                                      unop(Iop_1Uto32,
   8071                                                           mkexpr(t7)),
   8072                                                      unop(Iop_1Uto32,
   8073                                                           mkexpr(t8)))),
   8074                                          binop(Iop_Or32,
   8075                                                binop(Iop_And32,
   8076                                                      unop(Iop_1Uto32,
   8077                                                           mkexpr(t4)),
   8078                                                      unop(Iop_1Uto32,
   8079                                                           mkexpr(t5))),
   8080                                                binop(Iop_And32,
   8081                                                      unop(Iop_1Uto32,
   8082                                                           mkexpr(t9)),
   8083                                                      unop(Iop_1Uto32,
   8084                                                           mkexpr(t10))))));
   8085 
   8086                         putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32,
   8087                                                        mkexpr(t6),
   8088                                                        mkU32(0x0)),
   8089                                                  binop(Iop_Or32,
   8090                                                        getDSPControl(),
   8091                                                        mkU32(0x400000)),
   8092                                                  getDSPControl()));
   8093                         putIReg(rd, binop(Iop_Or32,
   8094                                           binop(Iop_Shl32,
   8095                                                 binop(Iop_And32,
   8096                                                       mkexpr(t3),
   8097                                                       mkU32(0x00ff00ff)),
   8098                                                 mkU8(8)),
   8099                                           binop(Iop_And32,
   8100                                                 mkexpr(t0),
   8101                                                 mkU32(0x00ff00ff))));
   8102                      }
   8103                      break;
   8104                   }
   8105                   case 0x3: {  /* SHRL.QB */
   8106                      DIP("shrl.qb r%u, r%u, %u", rd, rt, rs);
   8107                      vassert(!mode64);
   8108                      t0 = newTemp(Ity_I32);
   8109                      t1 = newTemp(Ity_I8);
   8110                      t2 = newTemp(Ity_I32);
   8111                      t3 = newTemp(Ity_I8);
   8112                      t4 = newTemp(Ity_I32);
   8113                      t5 = newTemp(Ity_I8);
   8114                      t6 = newTemp(Ity_I32);
   8115                      t7 = newTemp(Ity_I8);
   8116                      t9 = newTemp(Ity_I32);
   8117 
   8118                      assign(t9, binop(Iop_And32, getIReg(rs), mkU32(0x7)));
   8119                      assign(t0, unop(Iop_8Uto32,
   8120                                      unop(Iop_16to8,
   8121                                           unop(Iop_32to16, getIReg(rt)))));
   8122                      assign(t1, unop(Iop_32to8,
   8123                                      binop(Iop_Shr32,
   8124                                            mkexpr(t0),
   8125                                            unop(Iop_32to8, mkexpr(t9)))));
   8126 
   8127                      assign(t2, unop(Iop_8Uto32,
   8128                                      unop(Iop_16HIto8,
   8129                                           unop(Iop_32to16, getIReg(rt)))));
   8130                      assign(t3, unop(Iop_32to8,
   8131                                      binop(Iop_Shr32,
   8132                                            mkexpr(t2),
   8133                                            unop(Iop_32to8, mkexpr(t9)))));
   8134 
   8135                      assign(t4, unop(Iop_8Uto32,
   8136                                      unop(Iop_16to8,
   8137                                           unop(Iop_32HIto16, getIReg(rt)))));
   8138                      assign(t5, unop(Iop_32to8,
   8139                                      binop(Iop_Shr32,
   8140                                            mkexpr(t4),
   8141                                            unop(Iop_32to8, mkexpr(t9)))));
   8142 
   8143                      assign(t6, unop(Iop_8Uto32,
   8144                                      unop(Iop_16HIto8,
   8145                                           unop(Iop_32HIto16, getIReg(rt)))));
   8146                      assign(t7, unop(Iop_32to8,
   8147                                      binop(Iop_Shr32,
   8148                                            mkexpr(t6),
   8149                                            unop(Iop_32to8, mkexpr(t9)))));
   8150                      putIReg(rd, IRExpr_ITE(binop(Iop_CmpEQ32,
   8151                                                   mkexpr(t9),
   8152                                                   mkU32(0x0)),
   8153                                             getIReg(rt),
   8154                                             binop(Iop_16HLto32,
   8155                                                   binop(Iop_8HLto16,
   8156                                                         mkexpr(t7),
   8157                                                         mkexpr(t5)),
   8158                                                   binop(Iop_8HLto16,
   8159                                                         mkexpr(t3),
   8160                                                         mkexpr(t1)))));
   8161                      break;
   8162                   }
   8163                   case 0x2: {  /* SHLLV.QB */
   8164                      DIP("shllv.qb r%u, r%u, r%u", rd, rt, rs);
   8165                      vassert(!mode64);
   8166                      t0 = newTemp(Ity_I32);
   8167                      t1 = newTemp(Ity_I1);
   8168                      t2 = newTemp(Ity_I1);
   8169                      t3 = newTemp(Ity_I32);
   8170                      t4 = newTemp(Ity_I1);
   8171                      t5 = newTemp(Ity_I1);
   8172                      t6 = newTemp(Ity_I32);
   8173                      t7 = newTemp(Ity_I1);
   8174                      t8 = newTemp(Ity_I1);
   8175                      t9 = newTemp(Ity_I1);
   8176                      t10 = newTemp(Ity_I1);
   8177                      t11 = newTemp(Ity_I8);
   8178 
   8179                      assign(t11, unop(Iop_32to8,
   8180                                       binop(Iop_And32,
   8181                                             getIReg(rs),
   8182                                             mkU32(0x7))));
   8183                      /* Shift bits 7..0 and 23..16. */
   8184                      assign(t0, binop(Iop_Shl32,
   8185                                       binop(Iop_And32,
   8186                                             getIReg(rt),
   8187                                             mkU32(0x00ff00ff)),
   8188                                       mkexpr(t11)));
   8189                      assign(t1, binop(Iop_CmpNE32,
   8190                                      binop(Iop_And32,
   8191                                            mkexpr(t0),
   8192                                            mkU32(0xff000000)),
   8193                                      mkU32(0x00000000)));
   8194                      assign(t2, binop(Iop_CmpNE32,
   8195                                      binop(Iop_And32,
   8196                                            mkexpr(t0),
   8197                                            mkU32(0xff000000)),
   8198                                      mkU32(0xff000000)));
   8199                      assign(t7, binop(Iop_CmpNE32,
   8200                                      binop(Iop_And32,
   8201                                            mkexpr(t0),
   8202                                            mkU32(0x0000ff00)),
   8203                                      mkU32(0x00000000)));
   8204                      assign(t8, binop(Iop_CmpNE32,
   8205                                      binop(Iop_And32,
   8206                                            mkexpr(t0),
   8207                                            mkU32(0x0000ff00)),
   8208                                      mkU32(0x000ff00)));
   8209                      /* Shift bits 15..8 and 31..24. */
   8210                      assign(t3, binop(Iop_Shl32,
   8211                                       binop(Iop_Shr32,
   8212                                             binop(Iop_And32,
   8213                                                   getIReg(rt),
   8214                                                   mkU32(0xff00ff00)),
   8215                                             mkU8(8)),
   8216                                       mkexpr(t11)));
   8217                      assign(t4, binop(Iop_CmpNE32,
   8218                                      binop(Iop_And32,
   8219                                            mkexpr(t3),
   8220                                            mkU32(0xff000000)),
   8221                                      mkU32(0x00000000)));
   8222                      assign(t5, binop(Iop_CmpNE32,
   8223                                      binop(Iop_And32,
   8224                                            mkexpr(t3),
   8225                                            mkU32(0xff000000)),
   8226                                      mkU32(0xff000000)));
   8227                      assign(t9, binop(Iop_CmpNE32,
   8228                                      binop(Iop_And32,
   8229                                            mkexpr(t3),
   8230                                            mkU32(0x0000ff00)),
   8231                                      mkU32(0x00000000)));
   8232                      assign(t10, binop(Iop_CmpNE32,
   8233                                      binop(Iop_And32,
   8234                                            mkexpr(t3),
   8235                                            mkU32(0x0000ff00)),
   8236                                      mkU32(0x0000ff00)));
   8237 
   8238                      assign(t6, binop(Iop_Or32,
   8239                                       binop(Iop_Or32,
   8240                                             binop(Iop_And32,
   8241                                                   unop(Iop_1Uto32,
   8242                                                        mkexpr(t1)),
   8243                                                   unop(Iop_1Uto32,
   8244                                                        mkexpr(t2))),
   8245                                             binop(Iop_And32,
   8246                                                   unop(Iop_1Uto32,
   8247                                                        mkexpr(t7)),
   8248                                                   unop(Iop_1Uto32,
   8249                                                        mkexpr(t8)))),
   8250                                       binop(Iop_Or32,
   8251                                             binop(Iop_And32,
   8252                                                   unop(Iop_1Uto32,
   8253                                                        mkexpr(t4)),
   8254                                                   unop(Iop_1Uto32,
   8255                                                        mkexpr(t5))),
   8256                                             binop(Iop_And32,
   8257                                                   unop(Iop_1Uto32,
   8258                                                        mkexpr(t9)),
   8259                                                   unop(Iop_1Uto32,
   8260                                                        mkexpr(t10))))));
   8261 
   8262                      putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32,
   8263                                                     mkexpr(t6),
   8264                                                     mkU32(0x0)),
   8265                                               binop(Iop_Or32,
   8266                                                     getDSPControl(),
   8267                                                     mkU32(0x400000)),
   8268                                               getDSPControl()));
   8269                      putIReg(rd, IRExpr_ITE(binop(Iop_CmpEQ32,
   8270                                                   unop(Iop_8Uto32, mkexpr(t11)),
   8271                                                   mkU32(0)),
   8272                                             getIReg(rt),
   8273                                             binop(Iop_Or32,
   8274                                                   binop(Iop_Shl32,
   8275                                                         binop(Iop_And32,
   8276                                                               mkexpr(t3),
   8277                                                               mkU32(0xff00ff)),
   8278                                                         mkU8(8)),
   8279                                                   binop(Iop_And32,
   8280                                                         mkexpr(t0),
   8281                                                         mkU32(0x00ff00ff)))));
   8282                      break;
   8283                   }
   8284                   case 0x1: {  /* SHRLV.QB */
   8285                      DIP("shrlv.qb r%u, r%u, r%u", rd, rt, rs);
   8286                      vassert(!mode64);
   8287                      t0 = newTemp(Ity_I8);
   8288                      t1 = newTemp(Ity_I8);
   8289                      t2 = newTemp(Ity_I8);
   8290                      t3 = newTemp(Ity_I8);
   8291 
   8292                      assign(t0, unop(Iop_32to8,
   8293                                      binop(Iop_Shr32,
   8294                                            unop(Iop_8Uto32,
   8295                                                 unop(Iop_32to8, getIReg(rt))),
   8296                                            mkU8(rs))));
   8297                      assign(t1, unop(Iop_32to8,
   8298                                      binop(Iop_Shr32,
   8299                                            unop(Iop_8Uto32,
   8300                                                 unop(Iop_16HIto8,
   8301                                                      unop(Iop_32to16,
   8302                                                           getIReg(rt)))),
   8303                                            mkU8(rs))));
   8304                      assign(t2, unop(Iop_32to8,
   8305                                       binop(Iop_Shr32,
   8306                                             unop(Iop_8Uto32,
   8307                                                  unop(Iop_16to8,
   8308                                                       unop(Iop_32HIto16,
   8309                                                            getIReg(rt)))),
   8310                                             mkU8(rs))));
   8311                      assign(t3, unop(Iop_32to8,
   8312                                      binop(Iop_Shr32,
   8313                                            unop(Iop_8Uto32,
   8314                                                 unop(Iop_16HIto8,
   8315                                                      unop(Iop_32HIto16,
   8316                                                           getIReg(rt)))),
   8317                                            mkU8(rs))));
   8318                      putIReg(rd,
   8319                              binop(Iop_16HLto32,
   8320                                    binop(Iop_8HLto16, mkexpr(t3), mkexpr(t2)),
   8321                                    binop(Iop_8HLto16, mkexpr(t1), mkexpr(t0))));
   8322                      break;
   8323                   }
   8324                   case 0x4: {  /* SHRA.QB */
   8325                      DIP("shra.qb r%u, r%u, %u", rd, rt, rs);
   8326                      vassert(!mode64);
   8327                      t0 = newTemp(Ity_I32);
   8328                      t1 = newTemp(Ity_I32);
   8329                      t2 = newTemp(Ity_I32);
   8330                      t3 = newTemp(Ity_I32);
   8331                      t4 = newTemp(Ity_I32);
   8332                      t5 = newTemp(Ity_I32);
   8333                      t6 = newTemp(Ity_I32);
   8334                      t7 = newTemp(Ity_I32);
   8335                      t8 = newTemp(Ity_I32);
   8336                      t9 = newTemp(Ity_I32);
   8337                      t10 = newTemp(Ity_I32);
   8338                      t11 = newTemp(Ity_I32);
   8339 
   8340                      /* ========== GPR[rt]_31..24 ========== */
   8341                      assign(t1,
   8342                             unop(Iop_8Uto32,
   8343                                  unop(Iop_16HIto8,
   8344                                       unop(Iop_32HIto16, getIReg(rt)))));
   8345                      assign(t2,
   8346                             binop(Iop_Shr32, mkexpr(t1), mkU8(rs)));
   8347                      /* tempD_7..0 */
   8348                      assign(t0,
   8349                             binop(Iop_Or32,
   8350                                   mkexpr(t2),
   8351                                   binop(Iop_Shl32,
   8352                                         IRExpr_ITE(binop(Iop_CmpEQ32,
   8353                                                          binop(Iop_And32,
   8354                                                                mkexpr(t1),
   8355                                                                mkU32(0x00000080)
   8356                                                               ),
   8357                                                          mkU32(0x00000080)),
   8358                                                    mkU32(0xFFFFFFFF),
   8359                                                    mkU32(0x00000000)),
   8360                                         binop(Iop_Sub8, mkU8(0x8), mkU8(rs)))));
   8361 
   8362                      /* ========== GPR[rt]_23..16 ========== */
   8363                      assign(t4,
   8364                             unop(Iop_8Uto32,
   8365                                  unop(Iop_16to8,
   8366                                       unop(Iop_32HIto16, getIReg(rt)))));
   8367                      assign(t5, binop(Iop_Shr32, mkexpr(t4), mkU8(rs)));
   8368                      /* tempC_7..0 */
   8369                      assign(t3,
   8370                             binop(Iop_Or32,
   8371                                   mkexpr(t5),
   8372                                   binop(Iop_Shl32,
   8373                                         IRExpr_ITE(binop(Iop_CmpEQ32,
   8374                                                          binop(Iop_And32,
   8375                                                                mkexpr(t4),
   8376                                                                mkU32(0x00000080)
   8377                                                               ),
   8378                                                          mkU32(0x00000080)),
   8379                                                    mkU32(0xFFFFFFFF),
   8380                                                    mkU32(0x00000000)),
   8381                                         binop(Iop_Sub8, mkU8(0x8), mkU8(rs)))));
   8382 
   8383                      /* ========== GPR[rt]_15..8 ========== */
   8384                      assign(t7,
   8385                             unop(Iop_8Uto32,
   8386                                  unop(Iop_16HIto8,
   8387                                       unop(Iop_32to16, getIReg(rt)))));
   8388                      assign(t8, binop(Iop_Shr32, mkexpr(t7), mkU8(rs)));
   8389                      /* tempB_7..0 */
   8390                      assign(t6,
   8391                             binop(Iop_Or32,
   8392                                   mkexpr(t8),
   8393                                   binop(Iop_Shl32,
   8394                                         IRExpr_ITE(binop(Iop_CmpEQ32,
   8395                                                          binop(Iop_And32,
   8396                                                                mkexpr(t7),
   8397                                                                mkU32(0x00000080)
   8398                                                               ),
   8399                                                          mkU32(0x00000080)),
   8400                                                    mkU32(0xFFFFFFFF),
   8401                                                    mkU32(0x00000000)),
   8402                                         binop(Iop_Sub8, mkU8(0x8), mkU8(rs)))));
   8403 
   8404                      /* ========== GPR[rt]_7..0 ========== */
   8405                      assign(t10,
   8406                             unop(Iop_8Uto32,
   8407                                  unop(Iop_16to8,
   8408                                       unop(Iop_32to16, getIReg(rt)))));
   8409                      assign(t11, binop(Iop_Shr32, mkexpr(t10), mkU8(rs)));
   8410                      /* tempB_7..0 */
   8411                      assign(t9,
   8412                             binop(Iop_Or32,
   8413                                   mkexpr(t11),
   8414                                   binop(Iop_Shl32,
   8415                                         IRExpr_ITE(binop(Iop_CmpEQ32,
   8416                                                          binop(Iop_And32,
   8417                                                                mkexpr(t10),
   8418                                                                mkU32(0x00000080)
   8419                                                               ),
   8420                                                          mkU32(0x00000080)),
   8421                                                    mkU32(0xFFFFFFFF),
   8422                                                    mkU32(0x00000000)),
   8423                                         binop(Iop_Sub8, mkU8(0x8), mkU8(rs)))));
   8424 
   8425                      putIReg(rd,
   8426                              binop(Iop_16HLto32,
   8427                                    binop(Iop_8HLto16,
   8428                                          unop(Iop_32to8, mkexpr(t0)),
   8429                                          unop(Iop_32to8, mkexpr(t3))),
   8430                                    binop(Iop_8HLto16,
   8431                                          unop(Iop_32to8, mkexpr(t6)),
   8432                                          unop(Iop_32to8, mkexpr(t9)))));
   8433                      break;
   8434                   }
   8435                   case 0x5: {  /* SHRA_R.QB */
   8436                      DIP("shra_r.qb r%u, r%u, %u", rd, rt, rs);
   8437                      vassert(!mode64);
   8438                      t0 = newTemp(Ity_I32);
   8439                      t1 = newTemp(Ity_I8);
   8440                      t2 = newTemp(Ity_I32);
   8441                      t3 = newTemp(Ity_I8);
   8442                      t4 = newTemp(Ity_I32);
   8443                      t5 = newTemp(Ity_I8);
   8444                      t6 = newTemp(Ity_I32);
   8445                      t7 = newTemp(Ity_I8);
   8446 
   8447                      if (0 == rs) {
   8448                         putIReg(rd, getIReg(rt));
   8449                      } else {
   8450                         assign(t0, unop(Iop_8Sto32,
   8451                                         unop(Iop_16to8,
   8452                                              unop(Iop_32to16, getIReg(rt)))));
   8453                         assign(t1, unop(Iop_32to8,
   8454                                         binop(Iop_Sar32,
   8455                                               binop(Iop_Add32,
   8456                                                     mkexpr(t0),
   8457                                                     binop(Iop_Shl32,
   8458                                                           mkU32(0x1),
   8459                                                           mkU8(rs-1))),
   8460                                               mkU8(rs))));
   8461 
   8462                         assign(t2, unop(Iop_8Sto32,
   8463                                         unop(Iop_16HIto8,
   8464                                              unop(Iop_32to16, getIReg(rt)))));
   8465                         assign(t3, unop(Iop_32to8,
   8466                                         binop(Iop_Sar32,
   8467                                               binop(Iop_Add32,
   8468                                                     mkexpr(t2),
   8469                                                     binop(Iop_Shl32,
   8470                                                           mkU32(0x1),
   8471                                                           mkU8(rs-1))),
   8472                                               mkU8(rs))));
   8473 
   8474                         assign(t4, unop(Iop_8Sto32,
   8475                                         unop(Iop_16to8,
   8476                                              unop(Iop_32HIto16, getIReg(rt)))));
   8477                         assign(t5, unop(Iop_32to8,
   8478                                         binop(Iop_Sar32,
   8479                                               binop(Iop_Add32,
   8480                                                     mkexpr(t4),
   8481                                                     binop(Iop_Shl32,
   8482                                                           mkU32(0x1),
   8483                                                           mkU8(rs-1))),
   8484                                               mkU8(rs))));
   8485 
   8486                         assign(t6, unop(Iop_8Sto32,
   8487                                         unop(Iop_16HIto8,
   8488                                              unop(Iop_32HIto16, getIReg(rt)))));
   8489                         assign(t7, unop(Iop_32to8,
   8490                                         binop(Iop_Sar32,
   8491                                               binop(Iop_Add32,
   8492                                                     mkexpr(t6),
   8493                                                     binop(Iop_Shl32,
   8494                                                           mkU32(0x1),
   8495                                                           mkU8(rs-1))),
   8496                                               mkU8(rs))));
   8497                         putIReg(rd, binop(Iop_16HLto32,
   8498                                          binop(Iop_8HLto16,
   8499                                                mkexpr(t7), mkexpr(t5)),
   8500                                          binop(Iop_8HLto16,
   8501                                                mkexpr(t3), mkexpr(t1))));
   8502                      }
   8503                      break;
   8504                   }
   8505                   case 0x6: {  /* SHRAV.QB */
   8506                      DIP("shrav.qb r%u, r%u, %u", rd, rt, rs);
   8507                      vassert(!mode64);
   8508 
   8509                      t0 = newTemp(Ity_I32);
   8510                      t1 = newTemp(Ity_I32);
   8511                      t2 = newTemp(Ity_I32);
   8512 
   8513                      t3 = newTemp(Ity_I32);
   8514                      t4 = newTemp(Ity_I32);
   8515                      t5 = newTemp(Ity_I32);
   8516 
   8517                      t6 = newTemp(Ity_I32);
   8518                      t7 = newTemp(Ity_I32);
   8519                      t8 = newTemp(Ity_I32);
   8520 
   8521                      t9 = newTemp(Ity_I32);
   8522                      t10 = newTemp(Ity_I32);
   8523                      t11 = newTemp(Ity_I32);
   8524 
   8525                      /* ========== GPR[rt]_31..24 ========== */
   8526                      assign(t1,
   8527                             unop(Iop_8Uto32,
   8528                                  unop(Iop_16HIto8,
   8529                                       unop(Iop_32HIto16, getIReg(rt)))));
   8530                      assign(t2,
   8531                             binop(Iop_Shr32,
   8532                                   mkexpr(t1),
   8533                                   unop(Iop_32to8, binop(Iop_And32,
   8534                                                         getIReg(rs),
   8535                                                         mkU32(0x7)))));
   8536                      /* tempD_7..0 */
   8537                      assign(t0,
   8538                             binop(Iop_Or32,
   8539                                   mkexpr(t2),
   8540                                   binop(Iop_Shl32,
   8541                                         IRExpr_ITE(binop(Iop_CmpEQ32,
   8542                                                          binop(Iop_And32,
   8543                                                                mkexpr(t1),
   8544                                                                mkU32(0x00000080)
   8545                                                               ),
   8546                                                          mkU32(0x00000080)),
   8547                                                    mkU32(0xFFFFFFFF),
   8548                                                    mkU32(0x00000000)),
   8549                                         binop(Iop_Sub8,
   8550                                               mkU8(0x8),
   8551                                               unop(Iop_32to8, binop(Iop_And32,
   8552                                                                     getIReg(rs),
   8553                                                                     mkU32(0x7)))
   8554                                               ))));
   8555 
   8556                      /* ========== GPR[rt]_23..16 ========== */
   8557                      assign(t4,
   8558                             unop(Iop_8Uto32,
   8559                                  unop(Iop_16to8,
   8560                                       unop(Iop_32HIto16, getIReg(rt)))));
   8561                      assign(t5,
   8562                             binop(Iop_Shr32,
   8563                                   mkexpr(t4),
   8564                                   unop(Iop_32to8, binop(Iop_And32,
   8565                                                         getIReg(rs),
   8566                                                         mkU32(0x7)))));
   8567                      /* tempC_7..0 */
   8568                      assign(t3,
   8569                             binop(Iop_Or32,
   8570                                   mkexpr(t5),
   8571                                   binop(Iop_Shl32,
   8572                                         IRExpr_ITE(binop(Iop_CmpEQ32,
   8573                                                          binop(Iop_And32,
   8574                                                                mkexpr(t4),
   8575                                                                mkU32(0x00000080)
   8576                                                               ),
   8577                                                          mkU32(0x00000080)),
   8578                                                    mkU32(0xFFFFFFFF),
   8579                                                    mkU32(0x00000000)),
   8580                                         binop(Iop_Sub8,
   8581                                               mkU8(0x8),
   8582                                               unop(Iop_32to8, binop(Iop_And32,
   8583                                                                     getIReg(rs),
   8584                                                                     mkU32(0x7)))
   8585                                               ))));
   8586 
   8587                      /* ========== GPR[rt]_15..8 ========== */
   8588                      assign(t7,
   8589                             unop(Iop_8Uto32,
   8590                                  unop(Iop_16HIto8,
   8591                                       unop(Iop_32to16, getIReg(rt)))));
   8592                      assign(t8,
   8593                             binop(Iop_Shr32,
   8594                                   mkexpr(t7),
   8595                                   unop(Iop_32to8, binop(Iop_And32,
   8596                                                         getIReg(rs),
   8597                                                         mkU32(0x7)))));
   8598                      /* tempB_7..0 */
   8599                      assign(t6,
   8600                             binop(Iop_Or32,
   8601                                   mkexpr(t8),
   8602                                   binop(Iop_Shl32,
   8603                                         IRExpr_ITE(binop(Iop_CmpEQ32,
   8604                                                          binop(Iop_And32,
   8605                                                                mkexpr(t7),
   8606                                                                mkU32(0x00000080)
   8607                                                               ),
   8608                                                          mkU32(0x00000080)),
   8609                                                    mkU32(0xFFFFFFFF),
   8610                                                    mkU32(0x00000000)),
   8611                                         binop(Iop_Sub8,
   8612                                               mkU8(0x8),
   8613                                               unop(Iop_32to8, binop(Iop_And32,
   8614                                                                     getIReg(rs),
   8615                                                                     mkU32(0x7)))
   8616                                               ))));
   8617 
   8618                      /* ========== GPR[rt]_7..0 ========== */
   8619                      assign(t10,
   8620                             unop(Iop_8Uto32,
   8621                                  unop(Iop_16to8,
   8622                                       unop(Iop_32to16, getIReg(rt)))));
   8623                      assign(t11,
   8624                             binop(Iop_Shr32,
   8625                                   mkexpr(t10),
   8626                                   unop(Iop_32to8, binop(Iop_And32,
   8627                                                         getIReg(rs),
   8628                                                         mkU32(0x7)))));
   8629                      /* tempB_7..0 */
   8630                      assign(t9,
   8631                             binop(Iop_Or32,
   8632                                   mkexpr(t11),
   8633                                   binop(Iop_Shl32,
   8634                                         IRExpr_ITE(binop(Iop_CmpEQ32,
   8635                                                          binop(Iop_And32,
   8636                                                                mkexpr(t10),
   8637                                                                mkU32(0x00000080)
   8638                                                               ),
   8639                                                          mkU32(0x00000080)),
   8640                                                    mkU32(0xFFFFFFFF),
   8641                                                    mkU32(0x00000000)),
   8642                                         binop(Iop_Sub8,
   8643                                               mkU8(0x8),
   8644                                               unop(Iop_32to8, binop(Iop_And32,
   8645                                                                     getIReg(rs),
   8646                                                                     mkU32(0x7)))
   8647                                               ))));
   8648 
   8649                      putIReg(rd,
   8650                              binop(Iop_16HLto32,
   8651                                    binop(Iop_8HLto16,
   8652                                          unop(Iop_32to8,
   8653                                               IRExpr_ITE(binop(Iop_CmpEQ32,
   8654                                                                binop(Iop_And32,
   8655                                                                      mkU32(rs),
   8656                                                                      mkU32(0x7)
   8657                                                                     ),
   8658                                                                mkU32(0x0)),
   8659                                                          mkexpr(t1),
   8660                                                          mkexpr(t0))),
   8661                                          unop(Iop_32to8,
   8662                                               IRExpr_ITE(binop(Iop_CmpEQ32,
   8663                                                                binop(Iop_And32,
   8664                                                                      mkU32(rs),
   8665                                                                      mkU32(0x7)
   8666                                                                     ),
   8667                                                                mkU32(0x0)),
   8668                                                          mkexpr(t2),
   8669                                                          mkexpr(t3)))),
   8670                                    binop(Iop_8HLto16,
   8671                                          unop(Iop_32to8,
   8672                                               IRExpr_ITE(binop(Iop_CmpEQ32,
   8673                                                                binop(Iop_And32,
   8674                                                                      mkU32(rs),
   8675                                                                      mkU32(0x7)
   8676                                                                     ),
   8677                                                                mkU32(0x0)),
   8678                                                          mkexpr(t5),
   8679                                                          mkexpr(t6))),
   8680                                          unop(Iop_32to8,
   8681                                               IRExpr_ITE(binop(Iop_CmpEQ32,
   8682                                                                binop(Iop_And32,
   8683                                                                      mkU32(rs),
   8684                                                                      mkU32(0x7)
   8685                                                                     ),
   8686                                                                mkU32(0x0)),
   8687                                                          mkexpr(t8),
   8688                                                          mkexpr(t9))))));
   8689                      break;
   8690                   }
   8691                   case 0x7: {  /* SHRAV_R.QB */
   8692                      DIP("shrav_r.qb r%u, r%u, r%u", rd, rt, rs);
   8693                      vassert(!mode64);
   8694                      t0 = newTemp(Ity_I32);
   8695                      t1 = newTemp(Ity_I8);
   8696                      t2 = newTemp(Ity_I32);
   8697                      t3 = newTemp(Ity_I8);
   8698                      t4 = newTemp(Ity_I32);
   8699                      t5 = newTemp(Ity_I8);
   8700                      t6 = newTemp(Ity_I32);
   8701                      t7 = newTemp(Ity_I8);
   8702                      t8 = newTemp(Ity_I8);
   8703                      t9 = newTemp(Ity_I32);
   8704 
   8705                      assign(t9, binop(Iop_And32, getIReg(rs), mkU32(0x7)));
   8706                      assign(t8, unop(Iop_32to8,
   8707                                      binop(Iop_Sub32, mkexpr(t9), mkU32(0x1))));
   8708                      assign(t0, unop(Iop_8Sto32,
   8709                                      unop(Iop_16to8,
   8710                                           unop(Iop_32to16, getIReg(rt)))));
   8711                      assign(t1, unop(Iop_32to8,
   8712                                      binop(Iop_Sar32,
   8713                                            binop(Iop_Add32,
   8714                                                  mkexpr(t0),
   8715                                                  binop(Iop_Shl32,
   8716                                                        mkU32(0x1),
   8717                                                        mkexpr(t8))),
   8718                                            unop(Iop_32to8,
   8719                                                 mkexpr(t9)))));
   8720 
   8721                      assign(t2, unop(Iop_8Sto32,
   8722                                      unop(Iop_16HIto8,
   8723                                           unop(Iop_32to16, getIReg(rt)))));
   8724                      assign(t3, unop(Iop_32to8,
   8725                                      binop(Iop_Sar32,
   8726                                            binop(Iop_Add32,
   8727                                                  mkexpr(t2),
   8728                                                  binop(Iop_Shl32,
   8729                                                        mkU32(0x1),
   8730                                                        mkexpr(t8))),
   8731                                            unop(Iop_32to8, mkexpr(t9)))));
   8732 
   8733                      assign(t4, unop(Iop_8Sto32,
   8734                                      unop(Iop_16to8,
   8735                                           unop(Iop_32HIto16, getIReg(rt)))));
   8736                      assign(t5, unop(Iop_32to8,
   8737                                      binop(Iop_Sar32,
   8738                                            binop(Iop_Add32,
   8739                                                  mkexpr(t4),
   8740                                                  binop(Iop_Shl32,
   8741                                                        mkU32(0x1),
   8742                                                        mkexpr(t8))),
   8743                                            unop(Iop_32to8, mkexpr(t9)))));
   8744 
   8745                      assign(t6, unop(Iop_8Sto32,
   8746                                      unop(Iop_16HIto8,
   8747                                           unop(Iop_32HIto16, getIReg(rt)))));
   8748                      assign(t7, unop(Iop_32to8,
   8749                                      binop(Iop_Sar32,
   8750                                            binop(Iop_Add32,
   8751                                                  mkexpr(t6),
   8752                                                  binop(Iop_Shl32,
   8753                                                        mkU32(0x1),
   8754                                                        mkexpr(t8))),
   8755                                            unop(Iop_32to8, mkexpr(t9)))));
   8756                      putIReg(rd, IRExpr_ITE(binop(Iop_CmpEQ32,
   8757                                                   mkexpr(t9),
   8758                                                   mkU32(0x0)),
   8759                                             getIReg(rt),
   8760                                             binop(Iop_16HLto32,
   8761                                                   binop(Iop_8HLto16,
   8762                                                         mkexpr(t7),
   8763                                                         mkexpr(t5)),
   8764                                                   binop(Iop_8HLto16,
   8765                                                         mkexpr(t3),
   8766                                                         mkexpr(t1)))));
   8767                      break;
   8768                   }
   8769                   case 0x8: {  /* SHLL.PH */
   8770                      DIP("shll.ph r%u, r%u, %u", rd, rt, rs);
   8771                      vassert(!mode64);
   8772                      t0 = newTemp(Ity_I32);
   8773                      t1 = newTemp(Ity_I32);
   8774                      t2 = newTemp(Ity_I32);
   8775                      t3 = newTemp(Ity_I32);
   8776                      t4 = newTemp(Ity_I32);
   8777                      t5 = newTemp(Ity_I32);
   8778                      t6 = newTemp(Ity_I32);
   8779                      t7 = newTemp(Ity_I32);
   8780 
   8781                      if (0 == rs) {
   8782                         putIReg(rd, getIReg(rt));
   8783                      } else {
   8784                         /* Shift lower 16 bits. */
   8785                         assign(t0, binop(Iop_Shl32,
   8786                                          unop(Iop_16Sto32,
   8787                                               unop(Iop_32to16, getIReg(rt))),
   8788                                          mkU8(rs)));
   8789 
   8790                         assign(t1, unop(Iop_1Uto32,
   8791                                         binop(Iop_CmpNE32,
   8792                                                binop(Iop_Sar32,
   8793                                                      mkexpr(t0),
   8794                                                      mkU8(16)),
   8795                                                mkU32(0))));
   8796                         assign(t2, unop(Iop_1Uto32,
   8797                                         binop(Iop_CmpNE32,
   8798                                               binop(Iop_Sar32,
   8799                                                     mkexpr(t0),
   8800                                                     mkU8(16)),
   8801                                               mkU32(0xffffffff))));
   8802                         assign(t3, binop(Iop_And32,
   8803                                          mkexpr(t1),
   8804                                          mkexpr(t2)));
   8805                         putDSPControl(IRExpr_ITE(binop(Iop_CmpEQ32,
   8806                                                        mkexpr(t3),
   8807                                                        mkU32(0x1)),
   8808                                                  binop(Iop_Or32,
   8809                                                        getDSPControl(),
   8810                                                        mkU32(0x400000)),
   8811                                                  getDSPControl()));
   8812                         putDSPControl(IRExpr_ITE(binop(Iop_CmpEQ32,
   8813                                                        binop(Iop_And32,
   8814                                                              getIReg(rt),
   8815                                                              mkU32(0x00008000)),
   8816                                                        binop(Iop_And32,
   8817                                                              mkexpr(t0),
   8818                                                              mkU32(0x00008000))
   8819                                                       ),
   8820                                                  getDSPControl(),
   8821                                                  binop(Iop_Or32,
   8822                                                        getDSPControl(),
   8823                                                        mkU32(0x400000))));
   8824                         /* Shift higher 16 bits. */
   8825                         assign(t4, binop(Iop_Shl32,
   8826                                          unop(Iop_16Sto32,
   8827                                               unop(Iop_32HIto16, getIReg(rt))),
   8828                                          mkU8(rs)));
   8829 
   8830                         assign(t5, unop(Iop_1Uto32,
   8831                                         binop(Iop_CmpNE32,
   8832                                                binop(Iop_Sar32,
   8833                                                      mkexpr(t4),
   8834                                                      mkU8(16)),
   8835                                                mkU32(0))));
   8836                         assign(t6, unop(Iop_1Uto32,
   8837                                         binop(Iop_CmpNE32,
   8838                                               binop(Iop_Sar32,
   8839                                                     mkexpr(t4),
   8840                                                     mkU8(16)),
   8841                                               mkU32(0xffffffff))));
   8842                         assign(t7, binop(Iop_And32,
   8843                                          mkexpr(t5),
   8844                                          mkexpr(t6)));
   8845                         putDSPControl(IRExpr_ITE(binop(Iop_CmpEQ32,
   8846                                                        mkexpr(t7),
   8847                                                        mkU32(0x1)),
   8848                                                  binop(Iop_Or32,
   8849                                                        getDSPControl(),
   8850                                                        mkU32(0x400000)),
   8851                                                  getDSPControl()));
   8852                         putDSPControl(IRExpr_ITE(binop(Iop_CmpEQ32,
   8853                                                        mkexpr(t7),
   8854                                                        mkU32(0x1)),
   8855                                                  binop(Iop_Or32,
   8856                                                        getDSPControl(),
   8857                                                        mkU32(0x400000)),
   8858                                                  getDSPControl()));
   8859                         putDSPControl(IRExpr_ITE(binop(Iop_CmpEQ32,
   8860                                                        binop(Iop_And32,
   8861                                                              getIReg(rt),
   8862                                                              mkU32(0x80000000)),
   8863                                                        binop(Iop_Shl32,
   8864                                                              binop(Iop_And32,
   8865                                                                    mkexpr(t4),
   8866                                                                    mkU32(0x00008000)),
   8867                                                              mkU8(16))
   8868                                                       ),
   8869                                                  getDSPControl(),
   8870                                                  binop(Iop_Or32,
   8871                                                        getDSPControl(),
   8872                                                        mkU32(0x400000))));
   8873                         putIReg(rd, binop(Iop_16HLto32,
   8874                                           unop(Iop_32to16, mkexpr(t4)),
   8875                                           unop(Iop_32to16, mkexpr(t0))));
   8876                      }
   8877                      break;
   8878                   }
   8879                   case 0x9: {  /* SHRA.PH */
   8880                      DIP("shra.ph r%u, r%u, %u", rd, rt, rs);
   8881                      vassert(!mode64);
   8882                      t0 = newTemp(Ity_I32);
   8883                      t1 = newTemp(Ity_I32);
   8884                      if (0 == rs) {
   8885                         putIReg(rd, getIReg(rt));
   8886                      } else {
   8887                         assign(t0, binop(Iop_Sar32,
   8888                                          unop(Iop_16Sto32,
   8889                                               unop(Iop_32to16, getIReg(rt))),
   8890                                          mkU8(rs)));
   8891                         assign(t1, binop(Iop_Sar32,
   8892                                          unop(Iop_16Sto32,
   8893                                               unop(Iop_32HIto16, getIReg(rt))),
   8894                                          mkU8(rs)));
   8895                         putIReg(rd, binop(Iop_16HLto32,
   8896                                           unop(Iop_32to16, mkexpr(t1)),
   8897                                           unop(Iop_32to16, mkexpr(t0))));
   8898                      }
   8899                      break;
   8900                   }
   8901                   case 0xA: {  /* SHLLV.PH */
   8902                      DIP("shllv.ph r%u, r%u, r%u", rd, rt, rs);
   8903                      vassert(!mode64);
   8904                      t0 = newTemp(Ity_I32);
   8905                      t2 = newTemp(Ity_I32);
   8906                      t3 = newTemp(Ity_I1);
   8907                      t4 = newTemp(Ity_I1);
   8908                      t5 = newTemp(Ity_I32);
   8909                      t6 = newTemp(Ity_I32);
   8910                      t7 = newTemp(Ity_I1);
   8911                      t8 = newTemp(Ity_I1);
   8912                      t9 = newTemp(Ity_I32);
   8913                      t10 = newTemp(Ity_I32);
   8914                      t11 = newTemp(Ity_I32);
   8915                      t12 = newTemp(Ity_I1);
   8916                      t13 = newTemp(Ity_I1);
   8917 
   8918                      assign(t0, binop(Iop_And32, getIReg(rs), mkU32(0x0f)));
   8919 
   8920                      /* Shift lower 16 bits. */
   8921                      assign(t2, binop(Iop_Shl32,
   8922                                       unop(Iop_16Sto32,
   8923                                            unop(Iop_32to16, getIReg(rt))),
   8924                                       unop(Iop_32to8, mkexpr(t0))));
   8925 
   8926                      assign(t3, binop(Iop_CmpNE32,
   8927                                       unop(Iop_16Sto32,
   8928                                            unop(Iop_32HIto16, mkexpr(t2))),
   8929                                       mkU32(0x00000000)));
   8930                      assign(t4, binop(Iop_CmpNE32,
   8931                                       unop(Iop_16Sto32,
   8932                                            unop(Iop_32HIto16, mkexpr(t2))),
   8933                                       mkU32(0xffffffff)));
   8934                      assign(t10, binop(Iop_And32,
   8935                                        unop(Iop_1Sto32, mkexpr(t3)),
   8936                                        unop(Iop_1Sto32, mkexpr(t4))));
   8937                      assign(t5, binop(Iop_Shr32,
   8938                                       binop(Iop_And32,
   8939                                             getIReg(rt),
   8940                                             mkU32(0x00008000)),
   8941                                       mkU8(15)));
   8942                      assign(t12, binop(Iop_CmpEQ32,
   8943                                        mkexpr(t5),
   8944                                        binop(Iop_Shr32,
   8945                                              binop(Iop_And32,
   8946                                                    mkexpr(t2),
   8947                                                    mkU32(0x00008000)),
   8948                                              mkU8(15))));
   8949 
   8950                      putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32,
   8951                                                     mkexpr(t10),
   8952                                                     mkU32(0x0)),
   8953                                               binop(Iop_Or32,
   8954                                                     getDSPControl(),
   8955                                                     mkU32(0x400000)),
   8956                                               IRExpr_ITE(mkexpr(t12),
   8957                                                          getDSPControl(),
   8958                                                          binop(Iop_Or32,
   8959                                                                getDSPControl(),
   8960                                                                mkU32(0x400000)))
   8961                                              ));
   8962                      /* Shift higher 16 bits. */
   8963                      assign(t6, binop(Iop_Shl32,
   8964                                       unop(Iop_16Sto32,
   8965                                            unop(Iop_32HIto16, getIReg(rt))),
   8966                                       unop(Iop_32to8, mkexpr(t0))));
   8967 
   8968                      assign(t7, binop(Iop_CmpNE32,
   8969                                       unop(Iop_16Sto32,
   8970                                            unop(Iop_32HIto16, mkexpr(t6))),
   8971                                       mkU32(0x00000000)));
   8972                      assign(t8, binop(Iop_CmpNE32,
   8973                                       unop(Iop_16Sto32,
   8974                                            unop(Iop_32HIto16, mkexpr(t6))),
   8975                                       mkU32(0xffffffff)));
   8976                      assign(t11, binop(Iop_And32,
   8977                                        unop(Iop_1Sto32, mkexpr(t7)),
   8978                                        unop(Iop_1Sto32, mkexpr(t8))));
   8979 
   8980                      assign(t9, binop(Iop_Shr32,
   8981                                       binop(Iop_And32,
   8982                                             getIReg(rt),
   8983                                             mkU32(0x80000000)),
   8984                                       mkU8(31)));
   8985                      assign(t13, binop(Iop_CmpEQ32,
   8986                                        mkexpr(t9),
   8987                                        binop(Iop_Shr32,
   8988                                              binop(Iop_And32,
   8989                                                    mkexpr(t6),
   8990                                                    mkU32(0x00008000)),
   8991                                              mkU8(15))));
   8992 
   8993                      putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32,
   8994                                                     mkexpr(t11),
   8995                                                     mkU32(0x0)),
   8996                                               binop(Iop_Or32,
   8997                                                     getDSPControl(),
   8998                                                     mkU32(0x400000)),
   8999                                               IRExpr_ITE(mkexpr(t13),
   9000                                                          getDSPControl(),
   9001                                                          binop(Iop_Or32,
   9002                                                                getDSPControl(),
   9003                                                                mkU32(0x400000)))
   9004                                              ));
   9005 
   9006                      putIReg(rd, binop(Iop_16HLto32,
   9007                                        unop(Iop_32to16, mkexpr(t6)),
   9008                                        unop(Iop_32to16, mkexpr(t2))));
   9009                      break;
   9010                   }
   9011                   case 0xB: {  /* SHRAV.PH */
   9012                      DIP("shrav.ph r%u, r%u, r%u", rd, rt, rs);
   9013                      vassert(!mode64);
   9014                      t0 = newTemp(Ity_I32);
   9015                      t1 = newTemp(Ity_I1);
   9016                      t2 = newTemp(Ity_I32);
   9017                      t3 = newTemp(Ity_I32);
   9018 
   9019                      assign(t0, binop(Iop_And32, getIReg(rs), mkU32(0x0f)));
   9020                      assign(t1, binop(Iop_CmpEQ32, mkexpr(t0), mkU32(0x0)));
   9021                      assign(t2, binop(Iop_Sar32,
   9022                                       unop(Iop_16Sto32,
   9023                                            unop(Iop_32to16, getIReg(rt))),
   9024                                       unop(Iop_32to8, mkexpr(t0))));
   9025                      assign(t3, binop(Iop_Sar32,
   9026                                       unop(Iop_16Sto32,
   9027                                            unop(Iop_32HIto16, getIReg(rt))),
   9028                                       unop(Iop_32to8, mkexpr(t0))));
   9029                      putIReg(rd,
   9030                              binop(Iop_16HLto32,
   9031                                    IRExpr_ITE(mkexpr(t1),
   9032                                               unop(Iop_32HIto16, getIReg(rt)),
   9033                                               unop(Iop_32to16, mkexpr(t3))),
   9034                                    IRExpr_ITE(mkexpr(t1),
   9035                                               unop(Iop_32to16, getIReg(rt)),
   9036                                               unop(Iop_32to16, mkexpr(t2)))));
   9037                      break;
   9038                   }
   9039                   case 0xC: {  /* SHLL_S.PH */
   9040                      DIP("shll_s.ph r%u, r%u, %u", rd, rt, rs);
   9041                      vassert(!mode64);
   9042                      t0 = newTemp(Ity_I32);
   9043                      t1 = newTemp(Ity_I32);
   9044                      t2 = newTemp(Ity_I32);
   9045                      t3 = newTemp(Ity_I32);
   9046                      t4 = newTemp(Ity_I32);
   9047                      t5 = newTemp(Ity_I32);
   9048                      t6 = newTemp(Ity_I32);
   9049                      t7 = newTemp(Ity_I32);
   9050                      t8 = newTemp(Ity_I32);
   9051                      t9 = newTemp(Ity_I32);
   9052                      t10 = newTemp(Ity_I32);
   9053                      t11 = newTemp(Ity_I32);
   9054                      t12 = newTemp(Ity_I32);
   9055                      t13 = newTemp(Ity_I32);
   9056                      t14 = newTemp(Ity_I32);
   9057 
   9058                      if (0 == rs) {
   9059                         putIReg(rd, getIReg(rt));
   9060                      } else {
   9061                         /* Shift lower 16 bits. */
   9062                         assign(t0, binop(Iop_Shl32,
   9063                                          unop(Iop_16Sto32,
   9064                                               unop(Iop_32to16, getIReg(rt))),
   9065                                          mkU8(rs)));
   9066 
   9067                         assign(t1, unop(Iop_1Uto32,
   9068                                         binop(Iop_CmpNE32,
   9069                                                binop(Iop_Sar32,
   9070                                                      mkexpr(t0),
   9071                                                      mkU8(16)),
   9072                                                mkU32(0))));
   9073                         assign(t2, unop(Iop_1Uto32,
   9074                                         binop(Iop_CmpNE32,
   9075                                               binop(Iop_Sar32,
   9076                                                     mkexpr(t0),
   9077                                                     mkU8(16)),
   9078                                               mkU32(0xffffffff))));
   9079                         assign(t3, binop(Iop_And32,
   9080                                          mkexpr(t1),
   9081                                          mkexpr(t2)));
   9082                         putDSPControl(IRExpr_ITE(binop(Iop_CmpEQ32,
   9083                                                        mkexpr(t3),
   9084                                                        mkU32(0x1)),
   9085                                                  binop(Iop_Or32,
   9086                                                        getDSPControl(),
   9087                                                        mkU32(0x400000)),
   9088                                                  getDSPControl()));
   9089                         putDSPControl(IRExpr_ITE(binop(Iop_CmpEQ32,
   9090                                                        binop(Iop_And32,
   9091                                                              getIReg(rt),
   9092                                                              mkU32(0x00008000)),
   9093                                                        binop(Iop_And32,
   9094                                                              mkexpr(t0),
   9095                                                              mkU32(0x00008000))
   9096                                                       ),
   9097                                                  getDSPControl(),
   9098                                                  binop(Iop_Or32,
   9099                                                        getDSPControl(),
   9100                                                        mkU32(0x400000))));
   9101                         assign(t8,
   9102                                IRExpr_ITE(binop(Iop_CmpEQ32,
   9103                                                 mkexpr(t3),
   9104                                                 mkU32(0x1)),
   9105                                           IRExpr_ITE(binop(Iop_CmpEQ32,
   9106                                                            binop(Iop_And32,
   9107                                                                  getIReg(rt),
   9108                                                                  mkU32(0x8000)),
   9109                                                            mkU32(0)),
   9110                                                      mkU32(0x00007fff),
   9111                                                      mkU32(0x00008000)),
   9112                                           binop(Iop_And32,
   9113                                                 mkexpr(t0),
   9114                                                 mkU32(0x0000ffff))));
   9115                         assign(t10,
   9116                                IRExpr_ITE(binop(Iop_CmpEQ32,
   9117                                                 binop(Iop_And32,
   9118                                                       getIReg(rt),
   9119                                                       mkU32(0x00008000)),
   9120                                                 binop(Iop_And32,
   9121                                                       mkexpr(t0),
   9122                                                       mkU32(0x00008000))),
   9123                                           mkexpr(t8),
   9124                                           IRExpr_ITE(binop(Iop_CmpEQ32,
   9125                                                            binop(Iop_And32,
   9126                                                                  getIReg(rt),
   9127                                                                  mkU32(0x8000)),
   9128                                                            mkU32(0)),
   9129                                                      mkU32(0x00007fff),
   9130                                                      mkU32(0x00008000))));
   9131                         /* Shift higher 16 bits. */
   9132                         assign(t4, binop(Iop_Shl32,
   9133                                          unop(Iop_16Sto32,
   9134                                               unop(Iop_32HIto16, getIReg(rt))),
   9135                                          mkU8(rs)));
   9136 
   9137                         assign(t5, unop(Iop_1Uto32,
   9138                                         binop(Iop_CmpNE32,
   9139                                                binop(Iop_Sar32,
   9140                                                      mkexpr(t4),
   9141                                                      mkU8(16)),
   9142                                                mkU32(0))));
   9143                         assign(t6, unop(Iop_1Uto32,
   9144                                         binop(Iop_CmpNE32,
   9145                                               binop(Iop_Sar32,
   9146                                                     mkexpr(t4),
   9147                                                     mkU8(16)),
   9148                                               mkU32(0xffffffff))));
   9149                         assign(t7, binop(Iop_And32,
   9150                                          mkexpr(t5),
   9151                                          mkexpr(t6)));
   9152                         putDSPControl(IRExpr_ITE(binop(Iop_CmpEQ32,
   9153                                                        mkexpr(t7),
   9154                                                        mkU32(0x1)),
   9155                                                  binop(Iop_Or32,
   9156                                                        getDSPControl(),
   9157                                                        mkU32(0x400000)),
   9158                                                  getDSPControl()));
   9159                         putDSPControl(IRExpr_ITE(binop(Iop_CmpEQ32,
   9160                                                        mkexpr(t7),
   9161                                                        mkU32(0x1)),
   9162                                                  binop(Iop_Or32,
   9163                                                        getDSPControl(),
   9164                                                        mkU32(0x400000)),
   9165                                                  getDSPControl()));
   9166                         assign(t12, binop(Iop_Shl32,
   9167                                           binop(Iop_And32,
   9168                                                 mkexpr(t4),
   9169                                                 mkU32(0x8000)),
   9170                                           mkU8(16)));
   9171                         putDSPControl(IRExpr_ITE(binop(Iop_CmpEQ32,
   9172                                                        binop(Iop_And32,
   9173                                                              getIReg(rt),
   9174                                                              mkU32(0x80000000)),
   9175                                                        mkexpr(t12)),
   9176                                                  getDSPControl(),
   9177                                                  binop(Iop_Or32,
   9178                                                        getDSPControl(),
   9179                                                        mkU32(0x400000))));
   9180                         assign(t13, IRExpr_ITE(binop(Iop_CmpEQ32,
   9181                                                      binop(Iop_And32,
   9182                                                            getIReg(rt),
   9183                                                            mkU32(0x80000000)),
   9184                                                      mkU32(0)),
   9185                                                mkU32(0x7fff0000),
   9186                                                mkU32(0x80000000)));
   9187                         assign(t9,
   9188                                IRExpr_ITE(binop(Iop_CmpEQ32,
   9189                                                 mkexpr(t7),
   9190                                                 mkU32(0x1)),
   9191                                           mkexpr(t13),
   9192                                           binop(Iop_Shl32,
   9193                                                 binop(Iop_And32,
   9194                                                       mkexpr(t4),
   9195                                                       mkU32(0x0000ffff)),
   9196                                                 mkU8(16))));
   9197                         assign(t14, IRExpr_ITE(binop(Iop_CmpEQ32,
   9198                                                      binop(Iop_And32,
   9199                                                            getIReg(rt),
   9200                                                            mkU32(0x80000000)),
   9201                                                      mkU32(0)),
   9202                                                mkU32(0x7fff0000),
   9203                                                mkU32(0x80000000)));
   9204                         assign(t11,
   9205                                IRExpr_ITE(binop(Iop_CmpEQ32,
   9206                                                 binop(Iop_And32,
   9207                                                       getIReg(rt),
   9208                                                       mkU32(0x80000000)),
   9209                                                 binop(Iop_Shl32,
   9210                                                       binop(Iop_And32,
   9211                                                             mkexpr(t4),
   9212                                                             mkU32(0x00008000)),
   9213                                                       mkU8(16))),
   9214                                           mkexpr(t9),
   9215                                           mkexpr(t14)));
   9216                         putIReg(rd, binop(Iop_Or32,
   9217                                           mkexpr(t10),
   9218                                           mkexpr(t11)));
   9219                      }
   9220                      break;
   9221                   }
   9222                   case 0xD: {  /* SHRA_R.PH */
   9223                      DIP("shra.ph r%u, r%u, %u", rd, rt, rs);
   9224                      vassert(!mode64);
   9225                      t0 = newTemp(Ity_I32);
   9226                      t1 = newTemp(Ity_I32);
   9227                      if (0 == rs) {
   9228                         putIReg(rd, getIReg(rt));
   9229                      } else {
   9230                         assign(t0, binop(Iop_Sar32,
   9231                                          binop(Iop_Add32,
   9232                                                unop(Iop_16Sto32,
   9233                                                     unop(Iop_32to16,
   9234                                                          getIReg(rt))),
   9235                                                binop(Iop_Shl32,
   9236                                                      mkU32(0x1),
   9237                                                      mkU8(rs-1))),
   9238                                          mkU8(rs)));
   9239                         assign(t1, binop(Iop_Sar32,
   9240                                          binop(Iop_Add32,
   9241                                                unop(Iop_16Sto32,
   9242                                                     unop(Iop_32HIto16,
   9243                                                          getIReg(rt))),
   9244                                                binop(Iop_Shl32,
   9245                                                      mkU32(0x1),
   9246                                                      mkU8(rs-1))),
   9247                                          mkU8(rs)));
   9248                         putIReg(rd, binop(Iop_16HLto32,
   9249                                           unop(Iop_32to16, mkexpr(t1)),
   9250                                           unop(Iop_32to16, mkexpr(t0))));
   9251                      }
   9252                      break;
   9253                   }
   9254                   case 0xE: {  /* SHLLV_S.PH */
   9255                      DIP("shllv_s.ph r%u, r%u, r%u", rd, rt, rs);
   9256                      vassert(!mode64);
   9257                      t0 = newTemp(Ity_I32);
   9258                      t2 = newTemp(Ity_I32);
   9259                      t3 = newTemp(Ity_I1);
   9260                      t4 = newTemp(Ity_I1);
   9261                      t5 = newTemp(Ity_I32);
   9262                      t6 = newTemp(Ity_I32);
   9263                      t7 = newTemp(Ity_I1);
   9264                      t8 = newTemp(Ity_I1);
   9265                      t9 = newTemp(Ity_I32);
   9266                      t10 = newTemp(Ity_I32);
   9267                      t11 = newTemp(Ity_I32);
   9268                      t12 = newTemp(Ity_I1);
   9269                      t13 = newTemp(Ity_I1);
   9270                      t14 = newTemp(Ity_I16);
   9271                      t15 = newTemp(Ity_I16);
   9272                      t16 = newTemp(Ity_I16);
   9273                      t17 = newTemp(Ity_I16);
   9274 
   9275                      assign(t0, binop(Iop_And32, getIReg(rs), mkU32(0x0f)));
   9276 
   9277                      /* Shift lower 16 bits. */
   9278                      assign(t2, binop(Iop_Shl32,
   9279                                       unop(Iop_16Sto32,
   9280                                            unop(Iop_32to16, getIReg(rt))),
   9281                                       unop(Iop_32to8, mkexpr(t0))));
   9282 
   9283                      assign(t3, binop(Iop_CmpNE32,
   9284                                       unop(Iop_16Sto32,
   9285                                            unop(Iop_32HIto16, mkexpr(t2))),
   9286                                       mkU32(0x00000000)));
   9287                      assign(t4, binop(Iop_CmpNE32,
   9288                                       unop(Iop_16Sto32,
   9289                                            unop(Iop_32HIto16, mkexpr(t2))),
   9290                                       mkU32(0xffffffff)));
   9291                      assign(t10, binop(Iop_And32,
   9292                                        unop(Iop_1Sto32, mkexpr(t3)),
   9293                                        unop(Iop_1Sto32, mkexpr(t4))));
   9294                      assign(t5, binop(Iop_Shr32,
   9295                                        binop(Iop_And32,
   9296                                              getIReg(rt),
   9297                                              mkU32(0x00008000)),
   9298                                        mkU8(15)));
   9299                      assign(t12, binop(Iop_CmpEQ32,
   9300                                        mkexpr(t5),
   9301                                        binop(Iop_Shr32,
   9302                                              binop(Iop_And32,
   9303                                                    mkexpr(t2),
   9304                                                    mkU32(0x00008000)),
   9305                                              mkU8(15))));
   9306 
   9307                      putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32,
   9308                                                     mkexpr(t10),
   9309                                                     mkU32(0x0)),
   9310                                               binop(Iop_Or32,
   9311                                                     getDSPControl(),
   9312                                                     mkU32(0x400000)),
   9313                                               IRExpr_ITE(mkexpr(t12),
   9314                                                          getDSPControl(),
   9315                                                          binop(Iop_Or32,
   9316                                                                getDSPControl(),
   9317                                                                mkU32(0x400000)))
   9318                                              ));
   9319                      assign(t14, IRExpr_ITE(binop(Iop_CmpNE32,
   9320                                                   mkexpr(t5),
   9321                                                   mkU32(0x0)),
   9322                                             mkU16(0x8000),
   9323                                             mkU16(0x7fff)));
   9324                      assign(t15, IRExpr_ITE(binop(Iop_CmpNE32,
   9325                                                   mkexpr(t10),
   9326                                                   mkU32(0x0)),
   9327                                             mkexpr(t14),
   9328                                             IRExpr_ITE(mkexpr(t12),
   9329                                                        unop(Iop_32to16,
   9330                                                             mkexpr(t2)),
   9331                                                        mkexpr(t14))));
   9332                      /* Shift higher 16 bits. */
   9333                      assign(t6, binop(Iop_Shl32,
   9334                                       unop(Iop_16Sto32,
   9335                                            unop(Iop_32HIto16, getIReg(rt))),
   9336                                       unop(Iop_32to8, mkexpr(t0))));
   9337 
   9338                      assign(t7, binop(Iop_CmpNE32,
   9339                                       unop(Iop_16Sto32,
   9340                                            unop(Iop_32HIto16, mkexpr(t6))),
   9341                                       mkU32(0x00000000)));
   9342                      assign(t8, binop(Iop_CmpNE32,
   9343                                       unop(Iop_16Sto32,
   9344                                            unop(Iop_32HIto16, mkexpr(t6))),
   9345                                       mkU32(0xffffffff)));
   9346                      assign(t11, binop(Iop_And32,
   9347                                        unop(Iop_1Sto32, mkexpr(t7)),
   9348                                        unop(Iop_1Sto32, mkexpr(t8))));
   9349 
   9350                      assign(t9, binop(Iop_Shr32,
   9351                                       binop(Iop_And32,
   9352                                             getIReg(rt),
   9353                                             mkU32(0x80000000)),
   9354                                       mkU8(31)));
   9355                      assign(t13, binop(Iop_CmpEQ32,
   9356                                        mkexpr(t9),
   9357                                        binop(Iop_Shr32,
   9358                                              binop(Iop_And32,
   9359                                                    mkexpr(t6),
   9360                                                    mkU32(0x00008000)),
   9361                                              mkU8(15))));
   9362 
   9363                      putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32,
   9364                                                     mkexpr(t11),
   9365                                                     mkU32(0x0)),
   9366                                               binop(Iop_Or32,
   9367                                                     getDSPControl(),
   9368                                                     mkU32(0x400000)),
   9369                                               IRExpr_ITE(mkexpr(t13),
   9370                                                          getDSPControl(),
   9371                                                          binop(Iop_Or32,
   9372                                                                getDSPControl(),
   9373                                                                mkU32(0x400000)))
   9374                                              ));
   9375 
   9376                      assign(t16, IRExpr_ITE(binop(Iop_CmpNE32,
   9377                                                   mkexpr(t9),
   9378                                                   mkU32(0x0)),
   9379                                             mkU16(0x8000),
   9380                                             mkU16(0x7fff)));
   9381                      assign(t17, IRExpr_ITE(binop(Iop_CmpNE32,
   9382                                                   mkexpr(t11),
   9383                                                   mkU32(0x0)),
   9384                                             mkexpr(t16),
   9385                                             IRExpr_ITE(mkexpr(t13),
   9386                                                        unop(Iop_32to16,
   9387                                                             mkexpr(t6)),
   9388                                                        mkexpr(t16))));
   9389 
   9390                      putIReg(rd, binop(Iop_16HLto32, mkexpr(t17), mkexpr(t15)));
   9391                      break;
   9392                   }
   9393                   case 0xF: {  /* SHRAV_R.PH */
   9394                      DIP("shrav_r.ph r%u, r%u, r%u", rd, rt, rs);
   9395                      vassert(!mode64);
   9396                      t0 = newTemp(Ity_I32);
   9397                      t1 = newTemp(Ity_I1);
   9398                      t2 = newTemp(Ity_I8);
   9399                      t3 = newTemp(Ity_I32);
   9400                      t4 = newTemp(Ity_I32);
   9401 
   9402                      assign(t0, binop(Iop_And32, getIReg(rs), mkU32(0x0f)));
   9403                      assign(t1, binop(Iop_CmpEQ32, mkexpr(t0), mkU32(0x0)));
   9404                      assign(t2, unop(Iop_32to8,
   9405                                      binop(Iop_Sub32, mkexpr(t0), mkU32(1))));
   9406 
   9407                      assign(t3, binop(Iop_Sar32,
   9408                                       binop(Iop_Add32,
   9409                                             unop(Iop_16Sto32,
   9410                                                  unop(Iop_32to16, getIReg(rt))),
   9411                                             binop(Iop_Shl32,
   9412                                                   mkU32(0x1),
   9413                                                   mkexpr(t2))),
   9414                                       unop(Iop_32to8, mkexpr(t0))));
   9415                      assign(t4, binop(Iop_Sar32,
   9416                                       binop(Iop_Add32,
   9417                                             unop(Iop_16Sto32,
   9418                                                  unop(Iop_32HIto16,
   9419                                                       getIReg(rt))),
   9420                                             binop(Iop_Shl32,
   9421                                                   mkU32(0x1),
   9422                                                   mkexpr(t2))),
   9423                                       unop(Iop_32to8, mkexpr(t0))));
   9424 
   9425                      putIReg(rd, binop(Iop_16HLto32,
   9426                                        IRExpr_ITE(mkexpr(t1),
   9427                                                   unop(Iop_32HIto16,
   9428                                                        getIReg(rt)),
   9429                                                   unop(Iop_32to16,
   9430                                                        mkexpr(t4))),
   9431                                        IRExpr_ITE(mkexpr(t1),
   9432                                                   unop(Iop_32to16, getIReg(rt)),
   9433                                                   unop(Iop_32to16,
   9434                                                        mkexpr(t3)))));
   9435                      break;
   9436                   }
   9437                   case 0x14: {  /* SHLL_S.W */
   9438                      DIP("shll_s.w r%u, r%u, %u", rd, rt, rs);
   9439                      vassert(!mode64);
   9440                      t0 = newTemp(Ity_I32);
   9441                      t1 = newTemp(Ity_I32);
   9442                      t2 = newTemp(Ity_I32);
   9443                      t3 = newTemp(Ity_I32);
   9444                      t4 = newTemp(Ity_I32);
   9445                      t5 = newTemp(Ity_I32);
   9446 
   9447                      if (0 == rs) {
   9448                         putIReg(rd, getIReg(rt));
   9449                      } else {
   9450                         /* t0-bits that will be discarded, sign extended to
   9451                            32bits. */
   9452                         assign(t0, binop(Iop_Sar32,
   9453                                          binop(Iop_And32,
   9454                                                getIReg(rt),
   9455                                                binop(Iop_Sar32,
   9456                                                      mkU32(0x80000000),
   9457                                                      mkU8(rs-1))),
   9458                                          mkU8(32-rs)));
   9459 
   9460                         assign(t1, IRExpr_ITE(binop(Iop_CmpEQ32,
   9461                                                     binop(Iop_And32,
   9462                                                           getIReg(rt),
   9463                                                           mkU32(0x80000000)),
   9464                                                     mkU32(0x0)),
   9465                                               mkU32(0x7fffffff),
   9466                                               mkU32(0x80000000)));
   9467 
   9468                         assign(t2, binop(Iop_Shl32, getIReg(rt), mkU8(rs)));
   9469                         assign(t3, IRExpr_ITE(binop(Iop_CmpEQ32,
   9470                                                     binop(Iop_And32,
   9471                                                           getIReg(rt),
   9472                                                           mkU32(0x80000000)),
   9473                                                     binop(Iop_And32,
   9474                                                           mkexpr(t2),
   9475                                                           mkU32(0x80000000))),
   9476                                               mkexpr(t2),
   9477                                               mkexpr(t1)));
   9478 
   9479                         assign(t4, IRExpr_ITE(binop(Iop_CmpNE32,
   9480                                                     mkexpr(t0),
   9481                                                     mkU32(0x0)),
   9482                                               IRExpr_ITE(binop(Iop_CmpNE32,
   9483                                                                mkexpr(t0),
   9484                                                                mkU32(0xffffffff)
   9485                                                               ),
   9486                                                          mkexpr(t1),
   9487                                                          mkexpr(t3)),
   9488                                               mkexpr(t3)));
   9489                         assign(t5, IRExpr_ITE(binop(Iop_CmpNE32,
   9490                                                     mkexpr(t0),
   9491                                                     mkU32(0xffffffff)),
   9492                                               binop(Iop_Or32,
   9493                                                     getDSPControl(),
   9494                                                     mkU32(0x400000)),
   9495                                               getDSPControl()));
   9496                         putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32,
   9497                                                        mkexpr(t0),
   9498                                                        mkU32(0x0)),
   9499                                                  mkexpr(t5),
   9500                                                  getDSPControl()));
   9501                         putDSPControl(IRExpr_ITE(binop(Iop_CmpEQ32,
   9502                                                        binop(Iop_And32,
   9503                                                              getIReg(rt),
   9504                                                              mkU32(0x80000000)),
   9505                                                        binop(Iop_And32,
   9506                                                              mkexpr(t2),
   9507                                                              mkU32(0x80000000))
   9508                                                             ),
   9509                                                  getDSPControl(),
   9510                                                  binop(Iop_Or32,
   9511                                                        getDSPControl(),
   9512                                                        mkU32(0x400000))));
   9513                         putIReg(rd, mkexpr(t4));
   9514                      }
   9515                      break;
   9516                   }
   9517                   case 0x15: {  /* SHRA_R.W */
   9518                      DIP("shra_r.w r%u, r%u, %u", rd, rt, rs);
   9519                      vassert(!mode64);
   9520                      if (0 == rs) {
   9521                         putIReg(rd, getIReg(rt));
   9522                      } else {
   9523                         putIReg(rd, binop(Iop_Add32,
   9524                                           binop(Iop_Sar32,
   9525                                                 getIReg(rt), mkU8(rs)),
   9526                                           binop(Iop_Shr32,
   9527                                                 binop(Iop_And32,
   9528                                                       getIReg(rt),
   9529                                                       binop(Iop_Shl32,
   9530                                                             mkU32(0x1),
   9531                                                             mkU8(rs-1))),
   9532                                                 mkU8(rs-1))));
   9533                      }
   9534                      break;
   9535                   }
   9536                   case 0x16: {  /* SHLLV_S.W */
   9537                      DIP("shllv_s.w r%u, r%u, r%u", rd, rt, rs);
   9538                      vassert(!mode64);
   9539                      t0 = newTemp(Ity_I32);
   9540                      t1 = newTemp(Ity_I1);
   9541                      t2 = newTemp(Ity_I32);
   9542                      t3 = newTemp(Ity_I64);
   9543                      t4 = newTemp(Ity_I1);
   9544                      t5 = newTemp(Ity_I1);
   9545                      t6 = newTemp(Ity_I32);
   9546                      t7 = newTemp(Ity_I1);
   9547                      t8 = newTemp(Ity_I32);
   9548 
   9549                      /* Check if shift amount is zero. */
   9550                      assign(t0, binop(Iop_And32, getIReg(rs), mkU32(0x1f)));
   9551                      assign(t1, binop(Iop_CmpEQ32, mkexpr(t0), mkU32(0x0)));
   9552 
   9553                      /* t2 = sign of the input value. */
   9554                      assign(t2, binop(Iop_Shr32,
   9555                                       binop(Iop_And32,
   9556                                             getIReg(rt),
   9557                                             mkU32(0x80000000)),
   9558                                       mkU8(31)));
   9559                      /* Shift left input value and check for overflow. */
   9560                      assign(t3, binop(Iop_Shl64,
   9561                                       unop(Iop_32Sto64, getIReg(rt)),
   9562                                       unop(Iop_32to8, mkexpr(t0))));
   9563                      assign(t4, binop(Iop_CmpNE32,
   9564                                       unop(Iop_64HIto32, mkexpr(t3)),
   9565                                       mkU32(0x00000000)));
   9566                      assign(t5, binop(Iop_CmpNE32,
   9567                                       unop(Iop_64HIto32, mkexpr(t3)),
   9568                                       mkU32(0xffffffff)));
   9569                      assign(t6, binop(Iop_And32,
   9570                                       unop(Iop_1Uto32, mkexpr(t4)),
   9571                                       unop(Iop_1Uto32, mkexpr(t5))));
   9572                      assign(t7, binop(Iop_CmpEQ32,
   9573                                       binop(Iop_Shr32,
   9574                                             binop(Iop_And32,
   9575                                                   getIReg(rt),
   9576                                                   mkU32(0x80000000)),
   9577                                             mkU8(31)),
   9578                                       binop(Iop_Shr32,
   9579                                             binop(Iop_And32,
   9580                                                   unop(Iop_64to32, mkexpr(t3)),
   9581                                                   mkU32(0x80000000)),
   9582                                             mkU8(31))));
   9583 
   9584                      putDSPControl(IRExpr_ITE(unop(Iop_32to1, mkexpr(t6)),
   9585                                                    binop(Iop_Or32,
   9586                                                          getDSPControl(),
   9587                                                          mkU32(0x400000)),
   9588                                               IRExpr_ITE(mkexpr(t7),
   9589                                                          getDSPControl(),
   9590                                                          binop(Iop_Or32,
   9591                                                                getDSPControl(),
   9592                                                                mkU32(0x400000)))
   9593                                              ));
   9594 
   9595                      assign(t8, IRExpr_ITE(unop(Iop_32to1,
   9596                                                 mkexpr(t2)),
   9597                                            mkU32(0x80000000),
   9598                                            mkU32(0x7fffffff)));
   9599                      putIReg(rd, IRExpr_ITE(unop(Iop_32to1, mkexpr(t6)),
   9600                                             IRExpr_ITE(unop(Iop_32to1,
   9601                                                             mkexpr(t2)),
   9602                                                        mkU32(0x80000000),
   9603                                                        mkU32(0x7fffffff)),
   9604                                             IRExpr_ITE(mkexpr(t7),
   9605                                                        unop(Iop_64to32,
   9606                                                             mkexpr(t3)),
   9607                                                        mkexpr(t8))));
   9608                      break;
   9609                   }
   9610                   case 0x17: {  /* SHRAV_R.W */
   9611                      DIP("shrav_r.w r%u, r%u, r%u", rd, rt, rs);
   9612                      vassert(!mode64);
   9613                      t0 = newTemp(Ity_I32);
   9614                      t1 = newTemp(Ity_I1);
   9615                      t2 = newTemp(Ity_I8);
   9616                      t3 = newTemp(Ity_I32);
   9617 
   9618                      assign(t0, binop(Iop_And32, getIReg(rs), mkU32(0x1f)));
   9619                      assign(t1, binop(Iop_CmpEQ32, mkexpr(t0), mkU32(0x0)));
   9620                      assign(t2, unop(Iop_32to8,
   9621                                      binop(Iop_Sub32, mkexpr(t0), mkU32(1))));
   9622 
   9623                      putIReg(rd, IRExpr_ITE(mkexpr(t1),
   9624                                             getIReg(rt),
   9625                                             binop(Iop_Sar32,
   9626                                                   binop(Iop_Add32,
   9627                                                         binop(Iop_Sar32,
   9628                                                               getIReg(rt),
   9629                                                               mkexpr(t2)),
   9630                                                         mkU32(0x1)),
   9631                                                   mkU8(1))));
   9632                      break;
   9633                   }
   9634                   case 0x19: {  /* SHRL.PH */
   9635                      DIP("shrl.ph r%u, r%u, %u", rd, rt, rs);
   9636                      vassert(!mode64);
   9637                      t0 = newTemp(Ity_I32);
   9638                      t1 = newTemp(Ity_I32);
   9639                      assign(t0, binop(Iop_Shr32,
   9640                                       unop(Iop_16Uto32,
   9641                                            unop(Iop_32to16, getIReg(rt))),
   9642                                       mkU8(rs)));
   9643                      assign(t1, binop(Iop_Shr32,
   9644                                       unop(Iop_16Uto32,
   9645                                            unop(Iop_32HIto16, getIReg(rt))),
   9646                                       mkU8(rs)));
   9647                      putIReg(rd, binop(Iop_16HLto32,
   9648                                        unop(Iop_32to16, mkexpr(t1)),
   9649                                        unop(Iop_32to16, mkexpr(t0))));
   9650                      break;
   9651                   }
   9652                   case 0x1B: {  /* SHRLV.PH */
   9653                      DIP("shrlv.ph r%u, r%u, r%u", rd, rt, rs);
   9654                      vassert(!mode64);
   9655                      t0 = newTemp(Ity_I32);
   9656                      t1 = newTemp(Ity_I1);
   9657                      t2 = newTemp(Ity_I32);
   9658                      t3 = newTemp(Ity_I32);
   9659                      t4 = newTemp(Ity_I16);
   9660                      t5 = newTemp(Ity_I16);
   9661 
   9662                      /* Get shift amount from lower 5 bits of rs
   9663                         and check if it is zero. */
   9664                      assign(t0, binop(Iop_And32, getIReg(rs), mkU32(0x0f)));
   9665                      assign(t1, binop(Iop_CmpEQ32, mkexpr(t0), mkU32(0x0)));
   9666 
   9667                      assign(t2, binop(Iop_Shr32,
   9668                                       unop(Iop_16Uto32,
   9669                                            unop(Iop_32to16, getIReg(rt))),
   9670                                       unop(Iop_32to8, mkexpr(t0))));
   9671                      assign(t3, binop(Iop_Shr32,
   9672                                       unop(Iop_16Uto32,
   9673                                            unop(Iop_32HIto16, getIReg(rt))),
   9674                                       unop(Iop_32to8, mkexpr(t0))));
   9675 
   9676                      assign(t4, IRExpr_ITE(mkexpr(t1),
   9677                                            unop(Iop_32HIto16, getIReg(rt)),
   9678                                            unop(Iop_32to16, mkexpr(t3))));
   9679                      assign(t5, IRExpr_ITE(mkexpr(t1),
   9680                                            unop(Iop_32to16, getIReg(rt)),
   9681                                            unop(Iop_32to16, mkexpr(t2))));
   9682                      putIReg(rd, binop(Iop_16HLto32, mkexpr(t4), mkexpr(t5)));
   9683                      break;
   9684                   }
   9685                   default:
   9686                      return -1;
   9687                }
   9688                break;  /* end of SHLL.QB */
   9689             }
   9690             case 0x18: {  /* ADDUH.QB/MUL.PH */
   9691                switch(sa) {
   9692                   case 0x00: {  /* ADDUH.QB */
   9693                      DIP("adduh.qb r%u, r%u, r%u", rd, rs, rt);
   9694                      vassert(!mode64);
   9695                      t0 = newTemp(Ity_I32);
   9696 
   9697                      assign(t0, binop(Iop_HAdd8Ux4, getIReg(rs), getIReg(rt)));
   9698 
   9699                      putIReg(rd, mkexpr(t0));
   9700                      break;
   9701                   }
   9702                   case 0x1: {  /* SUBUH.QB */
   9703                      DIP("subuh.qb r%u, r%u, r%u", rd, rs, rt);
   9704                      vassert(!mode64);
   9705                      t0 = newTemp(Ity_I32);
   9706 
   9707                      assign(t0, binop(Iop_HSub8Ux4, getIReg(rs), getIReg(rt)));
   9708 
   9709                      putIReg(rd, mkexpr(t0));
   9710                      break;
   9711                   }
   9712                   case 0x02: {  /* ADDUH_R.QB */
   9713                      DIP("adduh_r.qb r%u, r%u, r%u", rd, rs, rt);
   9714                      vassert(!mode64);
   9715                      t0 = newTemp(Ity_I32);
   9716                      t1 = newTemp(Ity_I32);
   9717                      t2 = newTemp(Ity_I8);
   9718                      t3 = newTemp(Ity_I32);
   9719                      t4 = newTemp(Ity_I32);
   9720                      t5 = newTemp(Ity_I8);
   9721                      t6 = newTemp(Ity_I32);
   9722                      t7 = newTemp(Ity_I32);
   9723                      t8 = newTemp(Ity_I8);
   9724                      t9 = newTemp(Ity_I32);
   9725                      t10 = newTemp(Ity_I32);
   9726                      t11 = newTemp(Ity_I8);
   9727 
   9728                      /* Extract input bytes, add values, add 1 and half the
   9729                         result. */
   9730                      assign(t0, unop(Iop_8Uto32,
   9731                                      unop(Iop_16to8,
   9732                                           unop(Iop_32to16, getIReg(rs)))));
   9733                      assign(t1, unop(Iop_8Uto32,
   9734                                      unop(Iop_16to8,
   9735                                           unop(Iop_32to16, getIReg(rt)))));
   9736                      assign(t2, unop(Iop_16to8,
   9737                                      unop(Iop_32to16,
   9738                                           binop(Iop_Shr32,
   9739                                                 binop(Iop_Add32,
   9740                                                       binop(Iop_Add32,
   9741                                                             mkexpr(t0),
   9742                                                             mkexpr(t1)),
   9743                                                       mkU32(0x00000001)),
   9744                                                 mkU8(0x01)))));
   9745 
   9746                      assign(t3, unop(Iop_8Uto32,
   9747                                      unop(Iop_16HIto8,
   9748                                           unop(Iop_32to16, getIReg(rs)))));
   9749                      assign(t4, unop(Iop_8Uto32,
   9750                                      unop(Iop_16HIto8,
   9751                                           unop(Iop_32to16, getIReg(rt)))));
   9752                      assign(t5, unop(Iop_16to8,
   9753                                      unop(Iop_32to16,
   9754                                           binop(Iop_Shr32,
   9755                                                 binop(Iop_Add32,
   9756                                                       binop(Iop_Add32,
   9757                                                             mkexpr(t3),
   9758                                                             mkexpr(t4)),
   9759                                                       mkU32(0x00000001)),
   9760                                                 mkU8(0x01)))));
   9761 
   9762                      assign(t6, unop(Iop_8Uto32,
   9763                                      unop(Iop_16to8,
   9764                                           unop(Iop_32HIto16, getIReg(rs)))));
   9765                      assign(t7, unop(Iop_8Uto32,
   9766                                      unop(Iop_16to8,
   9767                                           unop(Iop_32HIto16, getIReg(rt)))));
   9768                      assign(t8, unop(Iop_16to8,
   9769                                      unop(Iop_32to16,
   9770                                           binop(Iop_Shr32,
   9771                                                 binop(Iop_Add32,
   9772                                                       binop(Iop_Add32,
   9773                                                             mkexpr(t7),
   9774                                                             mkexpr(t6)),
   9775                                                       mkU32(0x00000001)),
   9776                                                 mkU8(0x01)))));
   9777 
   9778                      assign(t9, unop(Iop_8Uto32,
   9779                                      unop(Iop_16HIto8,
   9780                                           unop(Iop_32HIto16, getIReg(rs)))));
   9781                      assign(t10, unop(Iop_8Uto32,
   9782                                       unop(Iop_16HIto8,
   9783                                            unop(Iop_32HIto16, getIReg(rt)))));
   9784                      assign(t11, unop(Iop_16to8,
   9785                                       unop(Iop_32to16,
   9786                                            binop(Iop_Shr32,
   9787                                                  binop(Iop_Add32,
   9788                                                        binop(Iop_Add32,
   9789                                                              mkexpr(t9),
   9790                                                              mkexpr(t10)),
   9791                                                        mkU32(0x00000001)),
   9792                                                  mkU8(0x01)))));
   9793 
   9794                      putIReg(rd, binop(Iop_16HLto32,
   9795                                        binop(Iop_8HLto16,
   9796                                              mkexpr(t11), mkexpr(t8)),
   9797                                        binop(Iop_8HLto16,
   9798                                              mkexpr(t5), mkexpr(t2))));
   9799                      break;
   9800                   }
   9801                   case 0x3: {  /* SUBUH_R.QB */
   9802                      DIP("subuh_r.qb r%u, r%u, r%u", rd, rs, rt);
   9803                      vassert(!mode64);
   9804                      t1 = newTemp(Ity_I32);
   9805                      t2 = newTemp(Ity_I32);
   9806                      t3 = newTemp(Ity_I32);
   9807                      t4 = newTemp(Ity_I32);
   9808                      t5 = newTemp(Ity_I32);
   9809                      t6 = newTemp(Ity_I32);
   9810                      t7 = newTemp(Ity_I32);
   9811                      t8 = newTemp(Ity_I32);
   9812                      t9 = newTemp(Ity_I8);
   9813                      t10 = newTemp(Ity_I8);
   9814                      t11 = newTemp(Ity_I8);
   9815                      t12 = newTemp(Ity_I8);
   9816 
   9817                      /* Extract each byte of rs and rt. */
   9818                      assign(t1, unop(Iop_8Uto32,
   9819                                      unop(Iop_16to8,
   9820                                           unop(Iop_32to16, getIReg(rs)))));
   9821                      assign(t2, unop(Iop_8Uto32,
   9822                                      unop(Iop_16HIto8,
   9823                                           unop(Iop_32to16, getIReg(rs)))));
   9824                      assign(t3, unop(Iop_8Uto32,
   9825                                      unop(Iop_16to8,
   9826                                           unop(Iop_32HIto16, getIReg(rs)))));
   9827                      assign(t4, unop(Iop_8Uto32,
   9828                                      unop(Iop_16HIto8,
   9829                                           unop(Iop_32HIto16, getIReg(rs)))));
   9830 
   9831                      assign(t5, unop(Iop_8Uto32,
   9832                                      unop(Iop_16to8,
   9833                                           unop(Iop_32to16, getIReg(rt)))));
   9834                      assign(t6, unop(Iop_8Uto32,
   9835                                      unop(Iop_16HIto8,
   9836                                           unop(Iop_32to16, getIReg(rt)))));
   9837                      assign(t7, unop(Iop_8Uto32,
   9838                                      unop(Iop_16to8,
   9839                                           unop(Iop_32HIto16, getIReg(rt)))));
   9840                      assign(t8, unop(Iop_8Uto32,
   9841                                      unop(Iop_16HIto8,
   9842                                           unop(Iop_32HIto16, getIReg(rt)))));
   9843 
   9844                      /* Add 1 to each resulting byte and half the results. */
   9845                      assign(t9, unop(Iop_16to8,
   9846                                      unop(Iop_32to16,
   9847                                           binop(Iop_Shr32,
   9848                                                 binop(Iop_Add32,
   9849                                                       binop(Iop_Sub32,
   9850                                                             mkexpr(t1),
   9851                                                             mkexpr(t5)),
   9852                                                       mkU32(0x00000001)),
   9853                                                 mkU8(0x01)))));
   9854                      assign(t10, unop(Iop_16to8,
   9855                                       unop(Iop_32to16,
   9856                                            binop(Iop_Shr32,
   9857                                                  binop(Iop_Add32,
   9858                                                        binop(Iop_Sub32,
   9859                                                              mkexpr(t2),
   9860                                                              mkexpr(t6)),
   9861                                                        mkU32(0x00000001)),
   9862                                                  mkU8(0x01)))));
   9863                      assign(t11, unop(Iop_16to8,
   9864                                       unop(Iop_32to16,
   9865                                             binop(Iop_Shr32,
   9866                                                   binop(Iop_Add32,
   9867                                                         binop(Iop_Sub32,
   9868                                                               mkexpr(t3),
   9869                                                               mkexpr(t7)),
   9870                                                         mkU32(0x00000001)),
   9871                                                   mkU8(0x01)))));
   9872                      assign(t12, unop(Iop_16to8,
   9873                                       unop(Iop_32to16,
   9874                                            binop(Iop_Shr32,
   9875                                                  binop(Iop_Add32,
   9876                                                        binop(Iop_Sub32,
   9877                                                              mkexpr(t4),
   9878                                                              mkexpr(t8)),
   9879                                                        mkU32(0x00000001)),
   9880                                                  mkU8(0x01)))));
   9881 
   9882                      putIReg(rd, binop(Iop_16HLto32,
   9883                                        binop(Iop_8HLto16,
   9884                                              mkexpr(t12), mkexpr(t11)),
   9885                                        binop(Iop_8HLto16,
   9886                                              mkexpr(t10), mkexpr(t9))));
   9887                      break;
   9888                   }
   9889                   case 0x8: {  /* ADDQH.PH */
   9890                      DIP("addqh.ph r%u, r%u, r%u", rd, rs, rt);
   9891                      vassert(!mode64);
   9892                      t0 = newTemp(Ity_I32);
   9893                      t1 = newTemp(Ity_I16);
   9894                      t2 = newTemp(Ity_I32);
   9895                      t3 = newTemp(Ity_I16);
   9896 
   9897                      /* Add lower halfs of rs and rt
   9898                         and right shift the result by 1. */
   9899                      assign(t0, binop(Iop_Add32,
   9900                                       unop(Iop_16Sto32,
   9901                                            unop(Iop_32to16, getIReg(rs))),
   9902                                       unop(Iop_16Sto32,
   9903                                            unop(Iop_32to16, getIReg(rt)))));
   9904                      assign(t1, unop(Iop_32to16,
   9905                                      binop(Iop_Shr32,
   9906                                            binop(Iop_And32,
   9907                                                  mkexpr(t0),
   9908                                                  mkU32(0x0001fffe)),
   9909                                            mkU8(0x1))));
   9910                      /* Add higher halfs of rs and rt
   9911                         and right shift the result by 1. */
   9912                      assign(t2, binop(Iop_Add32,
   9913                                       unop(Iop_16Sto32,
   9914                                            unop(Iop_32HIto16, getIReg(rs))),
   9915                                       unop(Iop_16Sto32,
   9916                                            unop(Iop_32HIto16, getIReg(rt)))));
   9917                      assign(t3, unop(Iop_32to16,
   9918                                      binop(Iop_Shr32,
   9919                                            binop(Iop_And32,
   9920                                                  mkexpr(t2),
   9921                                                  mkU32(0x0001fffe)),
   9922                                            mkU8(0x1))));
   9923                      putIReg(rd, binop(Iop_16HLto32, mkexpr(t3), mkexpr(t1)));
   9924                      break;
   9925                   }
   9926                   case 0x9: {  /* SUBQH.PH */
   9927                      DIP("subqh.ph r%u, r%u, r%u", rd, rs, rt);
   9928                      vassert(!mode64);
   9929 
   9930                      putIReg(rd, binop(Iop_HSub16Sx2,
   9931                                        getIReg(rs), getIReg(rt)));
   9932                      break;
   9933                   }
   9934                   case 0xA: {/* ADDQH_R.PH */
   9935                      DIP("addqh_r.ph r%u, r%u, r%u", rd, rs, rt);
   9936                      vassert(!mode64);
   9937                      t0 = newTemp(Ity_I32);
   9938                      t1 = newTemp(Ity_I16);
   9939                      t2 = newTemp(Ity_I32);
   9940                      t3 = newTemp(Ity_I16);
   9941 
   9942                      /* Add lower halfs of rs and rt, add 1
   9943                         and right shift the result by 1. */
   9944                      assign(t0, binop(Iop_Add32,
   9945                                       unop(Iop_16Sto32,
   9946                                            unop(Iop_32to16, getIReg(rs))),
   9947                                       unop(Iop_16Sto32,
   9948                                            unop(Iop_32to16, getIReg(rt)))));
   9949                      assign(t1, unop(Iop_32to16,
   9950                                      binop(Iop_Shr32,
   9951                                            binop(Iop_And32,
   9952                                                  binop(Iop_Add32,
   9953                                                        mkexpr(t0),
   9954                                                        mkU32(0x1)),
   9955                                                  mkU32(0x0001fffe)),
   9956                                            mkU8(0x1))));
   9957                      /* Add higher halfs of rs and rt, add 1
   9958                         and right shift the result by 1. */
   9959                      assign(t2, binop(Iop_Add32,
   9960                                       unop(Iop_16Sto32,
   9961                                            unop(Iop_32HIto16, getIReg(rs))),
   9962                                       unop(Iop_16Sto32,
   9963                                            unop(Iop_32HIto16, getIReg(rt)))));
   9964                      assign(t3, unop(Iop_32to16,
   9965                                      binop(Iop_Shr32,
   9966                                            binop(Iop_And32,
   9967                                                  binop(Iop_Add32,
   9968                                                        mkexpr(t2),
   9969                                                        mkU32(0x1)),
   9970                                                  mkU32(0x0001fffe)),
   9971                                            mkU8(0x1))));
   9972 
   9973                      putIReg(rd, binop(Iop_16HLto32, mkexpr(t3), mkexpr(t1)));
   9974                      break;
   9975                   }
   9976                   case 0xB: {  /* SUBQH_R.PH */
   9977                      DIP("subqh_r.ph r%u, r%u, r%u", rd, rs, rt);
   9978                      vassert(!mode64);
   9979                      t0 = newTemp(Ity_I32);
   9980                      t1 = newTemp(Ity_I16);
   9981                      t2 = newTemp(Ity_I32);
   9982                      t3 = newTemp(Ity_I16);
   9983 
   9984                      /* Sub lower halfs of rs and rt, add 1
   9985                         and right shift the result by 1. */
   9986                      assign(t0, binop(Iop_Sub32,
   9987                                       unop(Iop_16Sto32,
   9988                                            unop(Iop_32to16, getIReg(rs))),
   9989                                       unop(Iop_16Sto32,
   9990                                            unop(Iop_32to16, getIReg(rt)))));
   9991                      assign(t1, unop(Iop_32to16,
   9992                                      binop(Iop_Shr32,
   9993                                            binop(Iop_And32,
   9994                                                  binop(Iop_Add32,
   9995                                                        mkexpr(t0),
   9996                                                        mkU32(0x1)),
   9997                                                  mkU32(0x0001fffe)),
   9998                                            mkU8(0x1))));
   9999                      /* Sub higher halfs of rs and rt, add 1
   10000                         and right shift the result by 1. */
   10001                      assign(t2, binop(Iop_Sub32,
   10002                                       unop(Iop_16Sto32,
   10003                                            unop(Iop_32HIto16, getIReg(rs))),
   10004                                       unop(Iop_16Sto32,
   10005                                            unop(Iop_32HIto16, getIReg(rt)))));
   10006                      assign(t3, unop(Iop_32to16,
   10007                                      binop(Iop_Shr32,
   10008                                            binop(Iop_And32,
   10009                                                  binop(Iop_Add32,
   10010                                                        mkexpr(t2),
   10011                                                        mkU32(0x1)),
   10012                                                  mkU32(0x0001fffe)),
   10013                                            mkU8(0x1))));
   10014 
   10015                      putIReg(rd, binop(Iop_16HLto32, mkexpr(t3), mkexpr(t1)));
   10016                      break;
   10017                   }
   10018                   case 0xC: {  /* MUL.PH */
   10019                      DIP("mul.ph r%u, r%u, r%u", rd, rs, rt);
   10020                      vassert(!mode64);
   10021                      t0 = newTemp(Ity_I32);
   10022                      t1 = newTemp(Ity_I32);
   10023                      t2 = newTemp(Ity_I32);
   10024 
   10025                      assign(t0,
   10026                             binop(Iop_Mul32,
   10027                                   unop(Iop_16Sto32,
   10028                                        unop(Iop_32HIto16, getIReg(rs))),
   10029                                   unop(Iop_16Sto32,
   10030                                        unop(Iop_32HIto16, getIReg(rt)))));
   10031                      /* DSP Control flag. */
   10032                      putDSPControl(IRExpr_ITE(unop(Iop_Not1,
   10033                                                    binop(Iop_CmpLE32S,
   10034                                                          mkexpr(t0),
   10035                                                          mkU32(0x7FFF))),
   10036                                               binop(Iop_Or32,
   10037                                                     getDSPControl(),
   10038                                                     mkU32(0x00200000)),
   10039                                               IRExpr_ITE(binop(Iop_CmpLT32S,
   10040                                                                mkexpr(t0),
   10041                                                                mkU32(0xFFFF8000)
   10042                                                              ),
   10043                                                          binop(Iop_Or32,
   10044                                                                getDSPControl(),
   10045                                                                mkU32(0x00200000)
   10046                                                               ),
   10047                                                          getDSPControl())));
   10048 
   10049                      assign(t1,
   10050                             binop(Iop_Mul32,
   10051                                   unop(Iop_16Sto32,
   10052                                        unop(Iop_32to16, getIReg(rs))),
   10053                                   unop(Iop_16Sto32,
   10054                                        unop(Iop_32to16, getIReg(rt)))));
   10055                      /* DSP Control flag. */
   10056                      putDSPControl(IRExpr_ITE(unop(Iop_Not1,
   10057                                                    binop(Iop_CmpLE32S,
   10058                                                          mkexpr(t1),
   10059                                                          mkU32(0x7FFF))),
   10060                                               binop(Iop_Or32,
   10061                                                     getDSPControl(),
   10062                                                     mkU32(0x00200000)),
   10063                                               IRExpr_ITE(binop(Iop_CmpLT32S,
   10064                                                                mkexpr(t1),
   10065                                                                mkU32(0xFFFF8000)
   10066                                                               ),
   10067                                                          binop(Iop_Or32,
   10068                                                                getDSPControl(),
   10069                                                                mkU32(0x00200000)
   10070                                                               ),
   10071                                                          getDSPControl())));
   10072 
   10073                      assign(t2, binop(Iop_16HLto32,
   10074                                       unop(Iop_32to16, mkexpr(t0)),
   10075                                       unop(Iop_32to16, mkexpr(t1))));
   10076                      putIReg(rd, mkexpr(t2));
   10077                      break;
   10078                   }
   10079                   case 0xE: {  /* MUL_S.PH */
   10080                      DIP("mul_s.ph r%u r%u, r%u", rd, rs, rt);
   10081                      vassert(!mode64);
   10082 
   10083                      t0 = newTemp(Ity_I32);
   10084                      t1 = newTemp(Ity_I32);
   10085                      t2 = newTemp(Ity_I32);
   10086                      t3 = newTemp(Ity_I32);
   10087                      t4 = newTemp(Ity_I32);
   10088 
   10089                      /* t0 - signed intermediate result. */
   10090                      assign(t0,
   10091                            binop(Iop_Mul32,
   10092                                  unop(Iop_16Sto32,
   10093                                       unop(Iop_32HIto16, getIReg(rs))),
   10094                                  unop(Iop_16Sto32,
   10095                                       unop(Iop_32HIto16, getIReg(rt)))));
   10096 
   10097                      assign(t1,
   10098                             IRExpr_ITE(unop(Iop_Not1,
   10099                                             binop(Iop_CmpLE32S,
   10100                                                   mkexpr(t0),
   10101                                                   mkU32(0x7FFF))),
   10102                                        mkU32(0x00007FFF),
   10103                                        IRExpr_ITE(binop(Iop_CmpLT32S,
   10104                                                         mkexpr(t0),
   10105                                                         mkU32(0xFFFF8000)),
   10106                                                   mkU32(0xFFFF8000),
   10107                                                   mkexpr(t0))));
   10108 
   10109                      /* DSP Control flag. */
   10110                      putDSPControl(IRExpr_ITE(unop(Iop_Not1,
   10111                                                    binop(Iop_CmpLE32S,
   10112                                                          mkexpr(t0),
   10113                                                          mkU32(0x7FFF))),
   10114                                               binop(Iop_Or32,
   10115                                                     getDSPControl(),
   10116                                                     mkU32(0x00200000)),
   10117                                               IRExpr_ITE(binop(Iop_CmpLT32S,
   10118                                                                mkexpr(t0),
   10119                                                                mkU32(0xFFFF8000)
   10120                                                               ),
   10121                                                          binop(Iop_Or32,
   10122                                                                getDSPControl(),
   10123                                                                mkU32(0x00200000)
   10124                                                               ),
   10125                                                          getDSPControl())));
   10126 
   10127                      /* t2 - signed intermediate result. */
   10128                      assign(t2, binop(Iop_Mul32,
   10129                                       unop(Iop_16Sto32,
   10130                                            unop(Iop_32to16, getIReg(rs))),
   10131                                       unop(Iop_16Sto32,
   10132                                            unop(Iop_32to16, getIReg(rt)))));
   10133 
   10134                      assign(t3, IRExpr_ITE(unop(Iop_Not1,
   10135                                                 binop(Iop_CmpLE32S,
   10136                                                       mkexpr(t2),
   10137                                                       mkU32(0x7FFF))),
   10138                                            mkU32(0x00007FFF),
   10139                                            IRExpr_ITE(binop(Iop_CmpLT32S,
   10140                                                             mkexpr(t2),
   10141                                                             mkU32(0xFFFF8000)),
   10142                                                       mkU32(0xFFFF8000),
   10143                                                       mkexpr(t2))));
   10144 
   10145                      /* DSP Control flag. */
   10146                      putDSPControl(IRExpr_ITE(unop(Iop_Not1,
   10147                                                    binop(Iop_CmpLE32S,
   10148                                                          mkexpr(t2),
   10149                                                          mkU32(0x7FFF))),
   10150                                               binop(Iop_Or32,
   10151                                                     getDSPControl(),
   10152                                                     mkU32(0x00200000)),
   10153                                               IRExpr_ITE(binop(Iop_CmpLT32S,
   10154                                                                mkexpr(t2),
   10155                                                                mkU32(0xFFFF8000)
   10156                                                               ),
   10157                                                          binop(Iop_Or32,
   10158                                                                getDSPControl(),
   10159                                                                mkU32(0x00200000)
   10160                                                               ),
   10161                                                          getDSPControl())));
   10162 
   10163                      assign(t4, binop(Iop_16HLto32,
   10164                                       unop(Iop_32to16, mkexpr(t1)),
   10165                                       unop(Iop_32to16, mkexpr(t3))));
   10166                      putIReg(rd, mkexpr(t4));
   10167                      break;
   10168                   }
   10169                   case 0x10: {  /* ADDQH.W */
   10170                      DIP("addqh.w r%u, r%u, r%u", rd, rs, rt);
   10171                      vassert(!mode64);
   10172                      t0 = newTemp(Ity_I64);
   10173                      t1 = newTemp(Ity_I64);
   10174 
   10175                      assign(t0, binop(Iop_Add64,
   10176                                       unop(Iop_32Sto64, getIReg(rs)),
   10177                                       unop(Iop_32Sto64, getIReg(rt))));
   10178                      assign(t1, binop(Iop_And64,
   10179                                       mkexpr(t0),
   10180                                       mkU64(0x00000001fffffffeULL)));
   10181                      putIReg(rd, unop(Iop_64to32,
   10182                                       binop(Iop_Shr64, mkexpr(t1), mkU8(0x1))));
   10183                      break;
   10184                   }
   10185                   case 0x11: {  /* SUBQH.W */
   10186                      DIP("subqh.w r%u, r%u, r%u", rd, rs, rt);
   10187                      vassert(!mode64);
   10188                      t0 = newTemp(Ity_I64);
   10189                      t1 = newTemp(Ity_I64);
   10190 
   10191                      assign(t0, binop(Iop_Sub64,
   10192                                       unop(Iop_32Sto64, getIReg(rs)),
   10193                                       unop(Iop_32Sto64, getIReg(rt))));
   10194                      assign(t1, binop(Iop_And64,
   10195                                       mkexpr(t0),
   10196                                       mkU64(0x00000001fffffffeULL)));
   10197                      putIReg(rd, unop(Iop_64to32,
   10198                                       binop(Iop_Shr64, mkexpr(t1), mkU8(0x1))));
   10199                      break;
   10200                   }
   10201                   case 0x12: {  /* ADDQH_R.W */
   10202                      DIP("addqh_r.w r%u, r%u, r%u", rd, rs, rt);
   10203                      vassert(!mode64);
   10204                      t0 = newTemp(Ity_I64);
   10205                      t1 = newTemp(Ity_I64);
   10206                      t2 = newTemp(Ity_I64);
   10207 
   10208                      assign(t0, binop(Iop_Add64,
   10209                                       unop(Iop_32Sto64, getIReg(rs)),
   10210                                       unop(Iop_32Sto64, getIReg(rt))));
   10211                      assign(t1, binop(Iop_Add64,
   10212                                       mkexpr(t0),
   10213                                       mkU64(0x0000000000000001ULL)));
   10214                      assign(t2, binop(Iop_And64,
   10215                                       mkexpr(t1),
   10216                                       mkU64(0x00000001fffffffeULL)));
   10217                      putIReg(rd, unop(Iop_64to32,
   10218                                       binop(Iop_Shr64, mkexpr(t2), mkU8(0x1))));
   10219                      break;
   10220                   }
   10221                   case 0x13: {  /* SUBQH_R.W */
   10222                      DIP("subqh_r.w r%u, r%u, r%u", rd, rs, rt);
   10223                      vassert(!mode64);
   10224                      t0 = newTemp(Ity_I64);
   10225                      t1 = newTemp(Ity_I64);
   10226                      t2 = newTemp(Ity_I64);
   10227 
   10228                      assign(t0, binop(Iop_Sub64,
   10229                                       unop(Iop_32Sto64, getIReg(rs)),
   10230                                       unop(Iop_32Sto64, getIReg(rt))));
   10231                      assign(t1, binop(Iop_Add64,
   10232                                       mkexpr(t0),
   10233                                       mkU64(0x0000000000000001ULL)));
   10234                      assign(t2, binop(Iop_And64,
   10235                                       mkexpr(t1),
   10236                                       mkU64(0x00000001fffffffeULL)));
   10237                      putIReg(rd, unop(Iop_64to32,
   10238                                       binop(Iop_Shr64, mkexpr(t2), mkU8(0x1))));
   10239                      break;
   10240                   }
   10241                   case 0x16: {  /* MULQ_S.W */
   10242                      DIP("mulq_s.w r%u, r%u, r%u", rd, rs, rt);
   10243                      vassert(!mode64);
   10244                      t0 = newTemp(Ity_I64);
   10245                      t1 = newTemp(Ity_I1);
   10246                      t2 = newTemp(Ity_I1);
   10247 
   10248                      assign(t0, binop(Iop_Shl64,
   10249                                       binop(Iop_MullS32,
   10250                                             getIReg(rt), getIReg(rs)),
   10251                                       mkU8(0x1)));
   10252                      assign(t1, binop(Iop_CmpEQ32,
   10253                                       getIReg(rt), mkU32(0x80000000)));
   10254                      assign(t2, binop(Iop_CmpEQ32,
   10255                                       getIReg(rs), mkU32(0x80000000)));
   10256 
   10257                      putDSPControl(IRExpr_ITE(mkexpr(t1),
   10258                                               IRExpr_ITE(mkexpr(t2),
   10259                                                          binop(Iop_Or32,
   10260                                                                getDSPControl(),
   10261                                                                mkU32(0x00200000)
   10262                                                               ),
   10263                                                          getDSPControl()),
   10264                                               getDSPControl()));
   10265                      putIReg(rd, IRExpr_ITE(mkexpr(t1),
   10266                                             IRExpr_ITE(mkexpr(t2),
   10267                                                        mkU32(0x7fffffff),
   10268                                                        unop(Iop_64HIto32,
   10269                                                             mkexpr(t0))),
   10270                                             unop(Iop_64HIto32, mkexpr(t0))));
   10271                      break;
   10272                   }
   10273                   case 0x17: {  /* MULQ_RS.W */
   10274                      DIP("mulq_rs.w r%u, r%u, r%u", rd, rs, rt);
   10275                      vassert(!mode64);
   10276                      t0 = newTemp(Ity_I64);
   10277                      t1 = newTemp(Ity_I1);
   10278                      t2 = newTemp(Ity_I1);
   10279 
   10280                      assign(t0, binop(Iop_Add64,
   10281                                       binop(Iop_Shl64,
   10282                                             binop(Iop_MullS32,
   10283                                                   getIReg(rt),
   10284                                                   getIReg(rs)),
   10285                                             mkU8(0x1)),
   10286                                       mkU64(0x0000000080000000ULL)));
   10287                      assign(t1,
   10288                             binop(Iop_CmpEQ32, getIReg(rt), mkU32(0x80000000)));
   10289                      assign(t2,
   10290                             binop(Iop_CmpEQ32, getIReg(rs), mkU32(0x80000000)));
   10291                      putDSPControl(IRExpr_ITE(mkexpr(t1),
   10292                                               IRExpr_ITE(mkexpr(t2),
   10293                                                          binop(Iop_Or32,
   10294                                                                getDSPControl(),
   10295                                                                mkU32(0x00200000)
   10296                                                               ),
   10297                                                          getDSPControl()),
   10298                                               getDSPControl()));
   10299                      putIReg(rd, IRExpr_ITE(mkexpr(t1),
   10300                                             IRExpr_ITE(mkexpr(t2),
   10301                                                        mkU32(0x7fffffff),
   10302                                                        unop(Iop_64HIto32,
   10303                                                             mkexpr(t0))),
   10304                                             unop(Iop_64HIto32, mkexpr(t0))));
   10305                      break;
   10306                   }
   10307                   default:
   10308                      return -1;
   10309                }
   10310                break;  /* end of ADDUH.QB/MUL.PH */
   10311             }
   10312             case 0x30: {  /* DPAQ.W.PH */
   10313                switch(sa) {
   10314                   case 0x0: {  /* DPA.W.PH */
   10315                      DIP("dpa.w.ph ac%u, r%u, r%u", ac, rs, rt);
   10316                      vassert(!mode64);
   10317 
   10318                      t0 = newTemp(Ity_I64);
   10319                      t1 = newTemp(Ity_I64);
   10320                      t2 = newTemp(Ity_I64);
   10321 
   10322                      assign(t0,
   10323                             unop(Iop_32Sto64,
   10324                                  binop(Iop_Mul32,
   10325                                        unop(Iop_16Sto32,
   10326                                             unop(Iop_32HIto16, getIReg(rs))),
   10327                                        unop(Iop_16Sto32,
   10328                                             unop(Iop_32HIto16, getIReg(rt))))));
   10329                      assign(t1,
   10330                             unop(Iop_32Sto64,
   10331                                  binop(Iop_Mul32,
   10332                                        unop(Iop_16Sto32,
   10333                                             unop(Iop_32to16, getIReg(rs))),
   10334                                        unop(Iop_16Sto32,
   10335                                             unop(Iop_32to16, getIReg(rt))))));
   10336                      assign(t2,
   10337                             binop(Iop_Add64,
   10338                                   getAcc(ac),
   10339                                   binop(Iop_Add64, mkexpr(t0), mkexpr(t1))));
   10340                      putAcc(ac, mkexpr(t2));
   10341                      break;
   10342                   }
   10343                   case 0x1: {  /* DPS.W.PH */
   10344                      DIP("dps.w.ph ac%u, r%u, r%u", ac, rs, rt);
   10345                      vassert(!mode64);
   10346 
   10347                      t0 = newTemp(Ity_I64);
   10348                      t1 = newTemp(Ity_I64);
   10349                      t2 = newTemp(Ity_I64);
   10350 
   10351                      assign(t0,
   10352                             unop(Iop_32Sto64,
   10353                                  binop(Iop_Mul32,
   10354                                        unop(Iop_16Sto32,
   10355                                             unop(Iop_32HIto16, getIReg(rs))),
   10356                                        unop(Iop_16Sto32,
   10357                                             unop(Iop_32HIto16, getIReg(rt))))));
   10358                      assign(t1,
   10359                             unop(Iop_32Sto64,
   10360                                  binop(Iop_Mul32,
   10361                                        unop(Iop_16Sto32,
   10362                                             unop(Iop_32to16, getIReg(rs))),
   10363                                        unop(Iop_16Sto32,
   10364                                             unop(Iop_32to16, getIReg(rt))))));
   10365                      assign(t2,
   10366                             binop(Iop_Sub64,
   10367                                   getAcc(ac),
   10368                                   binop(Iop_Add64, mkexpr(t0), mkexpr(t1))));
   10369                      putAcc(ac, mkexpr(t2));
   10370                      break;
   10371                   }
   10372                   case 0x2: {  /* MULSA.W.PH */
   10373                      DIP("mulsa.w.ph ac%u, r%u, r%u", ac, rs, rt);
   10374                      vassert(!mode64);
   10375                      t0 = newTemp(Ity_I32);
   10376                      t1 = newTemp(Ity_I32);
   10377                      t2 = newTemp(Ity_I32);
   10378                      t3 = newTemp(Ity_I1);
   10379                      t4 = newTemp(Ity_I64);
   10380 
   10381                      assign(t4, getAcc(ac));
   10382                      assign(t0, binop(Iop_Mul32,
   10383                                       unop(Iop_16Sto32,
   10384                                            unop(Iop_32to16, getIReg(rt))),
   10385                                       unop(Iop_16Sto32,
   10386                                            unop(Iop_32to16, getIReg(rs)))));
   10387                      assign(t1, binop(Iop_Mul32,
   10388                                       unop(Iop_16Sto32,
   10389                                            unop(Iop_32HIto16, getIReg(rt))),
   10390                                       unop(Iop_16Sto32,
   10391                                            unop(Iop_32HIto16, getIReg(rs)))));
   10392                      assign(t2, binop(Iop_Sub32, mkexpr(t1), mkexpr(t0)));
   10393                      putAcc(ac, binop(Iop_Add64,
   10394                                       mkexpr(t4),
   10395                                       unop(Iop_32Sto64, mkexpr(t2))));
   10396                      break;
   10397                   }
   10398                   case 0x3: {  /* DPAU.H.QBL */
   10399                      DIP("dpau.h.qbl ac%u, r%u, r%u", ac, rs, rt);
   10400                      vassert(!mode64);
   10401                      t0 = newTemp(Ity_I32);
   10402                      t1 = newTemp(Ity_I32);
   10403                      t2 = newTemp(Ity_I64);
   10404                      t3 = newTemp(Ity_I64);
   10405 
   10406                      assign(t0,
   10407                             binop(Iop_Mul32,
   10408                                   unop(Iop_8Uto32,
   10409                                        unop(Iop_16HIto8,
   10410                                             unop(Iop_32HIto16, getIReg(rs)))),
   10411                                   unop(Iop_8Uto32,
   10412                                        unop(Iop_16HIto8,
   10413                                             unop(Iop_32HIto16, getIReg(rt))))));
   10414                      assign(t1,
   10415                             binop(Iop_Mul32,
   10416                                   unop(Iop_8Uto32,
   10417                                        unop(Iop_16to8,
   10418                                             unop(Iop_32HIto16, getIReg(rs)))),
   10419                                   unop(Iop_8Uto32,
   10420                                        unop(Iop_16to8,
   10421                                             unop(Iop_32HIto16, getIReg(rt))))));
   10422                      assign(t2,
   10423                             unop(Iop_32Uto64,
   10424                                  binop(Iop_Add32,
   10425                                        mkexpr(t0),
   10426                                        mkexpr(t1))));
   10427                      assign(t3,
   10428                             binop(Iop_Add64, getAcc(ac), mkexpr(t2)));
   10429                      putAcc(ac, mkexpr(t3));
   10430                      break;
   10431                   }
   10432                   case 0x4: {  /* DPAQ_S.W.PH */
   10433                      DIP("dpaq_s.w.ph ac%u, r%u, r%u", ac, rs, rt);
   10434                      vassert(!mode64);
   10435                      t0 = newTemp(Ity_I64);
   10436                      t1 = newTemp(Ity_I64);
   10437                      t2 = newTemp(Ity_I1);
   10438                      t3 = newTemp(Ity_I1);
   10439                      t4 = newTemp(Ity_I64);
   10440                      t5 = newTemp(Ity_I64);
   10441                      t6 = newTemp(Ity_I1);
   10442                      t7 = newTemp(Ity_I1);
   10443                      t8 = newTemp(Ity_I64);
   10444                      t9 = newTemp(Ity_I64);
   10445 
   10446                      assign(t0, getAcc(ac));
   10447 
   10448                      assign(t1, binop(Iop_Shl64,
   10449                                       binop(Iop_MullS32,
   10450                                             unop(Iop_16Sto32,
   10451                                                  unop(Iop_32HIto16,
   10452                                                       getIReg(rs))),
   10453                                             unop(Iop_16Sto32,
   10454                                                  unop(Iop_32HIto16,
   10455                                                       getIReg(rt)))),
   10456                                       mkU8(0x1)));
   10457                      assign(t2, binop(Iop_CmpEQ32,
   10458                                       unop(Iop_16Uto32,
   10459                                            unop(Iop_32HIto16, getIReg(rs))),
   10460                                       mkU32(0x00008000)));
   10461                      assign(t3, binop(Iop_CmpEQ32,
   10462                                       unop(Iop_16Uto32,
   10463                                            unop(Iop_32HIto16, getIReg(rt))),
   10464                                       mkU32(0x00008000)));
   10465                      assign(t4,
   10466                             IRExpr_ITE(mkexpr(t2),
   10467                                        IRExpr_ITE(mkexpr(t3),
   10468                                                   mkU64(0x000000007fffffffULL),
   10469                                                   mkexpr(t1)),
   10470                                        mkexpr(t1)));
   10471 
   10472                      putDSPControl(IRExpr_ITE(mkexpr(t2),
   10473                                               IRExpr_ITE(mkexpr(t3),
   10474                                                          binop(Iop_Or32,
   10475                                                                getDSPControl(),
   10476                                                                binop(Iop_Shl32,
   10477                                                                      mkU32(0x1),
   10478                                                                      mkU8(ac+16)
   10479                                                                     )
   10480                                                               ),
   10481                                                          getDSPControl()),
   10482                                               getDSPControl()));
   10483 
   10484                      assign(t5, binop(Iop_Shl64,
   10485                                       binop(Iop_MullS32,
   10486                                             unop(Iop_16Sto32,
   10487                                                  unop(Iop_32to16, getIReg(rs))),
   10488                                             unop(Iop_16Sto32,
   10489                                                  unop(Iop_32to16, getIReg(rt)))
   10490                                            ),
   10491                                       mkU8(0x1)));
   10492                      assign(t6, binop(Iop_CmpEQ32,
   10493                                       unop(Iop_16Uto32,
   10494                                            unop(Iop_32to16, getIReg(rs))),
   10495                                       mkU32(0x00008000)));
   10496                      assign(t7, binop(Iop_CmpEQ32,
   10497                                       unop(Iop_16Uto32,
   10498                                            unop(Iop_32to16, getIReg(rt))),
   10499                                       mkU32(0x00008000)));
   10500                      assign(t8,
   10501                             IRExpr_ITE(mkexpr(t6),
   10502                                        IRExpr_ITE(mkexpr(t7),
   10503                                                   mkU64(0x000000007fffffffULL),
   10504                                                   mkexpr(t5)),
   10505                                        mkexpr(t5)));
   10506 
   10507                      putDSPControl(IRExpr_ITE(mkexpr(t6),
   10508                                               IRExpr_ITE(mkexpr(t7),
   10509                                                          binop(Iop_Or32,
   10510                                                                getDSPControl(),
   10511                                                                binop(Iop_Shl32,
   10512                                                                      mkU32(0x1),
   10513                                                                      mkU8(ac+16)
   10514                                                                     )
   10515                                                               ),
   10516                                                          getDSPControl()),
   10517                                               getDSPControl()));
   10518 
   10519                      assign(t9, binop(Iop_Add64,
   10520                                       binop(Iop_Add64, mkexpr(t4), mkexpr(t8)),
   10521                                       mkexpr(t0)));
   10522                      putAcc(ac, mkexpr(t9));
   10523                      break;
   10524                   }
   10525                   case 0x5: {  /* DPSQ_S.W.PH */
   10526                      DIP("dpsq_s.w.ph ac%u r%u, r%u", ac, rs, rt);
   10527                      vassert(!mode64);
   10528                      t0 = newTemp(Ity_I64);
   10529                      t1 = newTemp(Ity_I64);
   10530                      t2 = newTemp(Ity_I1);
   10531                      t3 = newTemp(Ity_I1);
   10532                      t4 = newTemp(Ity_I64);
   10533                      t5 = newTemp(Ity_I64);
   10534                      t6 = newTemp(Ity_I1);
   10535                      t7 = newTemp(Ity_I1);
   10536                      t8 = newTemp(Ity_I64);
   10537                      t9 = newTemp(Ity_I64);
   10538 
   10539                      assign(t0, getAcc(ac));
   10540 
   10541                      assign(t1, binop(Iop_Shl64,
   10542                                       binop(Iop_MullS32,
   10543                                             unop(Iop_16Sto32,
   10544                                                  unop(Iop_32HIto16,
   10545                                                       getIReg(rs))),
   10546                                             unop(Iop_16Sto32,
   10547                                                  unop(Iop_32HIto16,
   10548                                                       getIReg(rt)))),
   10549                                       mkU8(0x1)));
   10550                      assign(t2, binop(Iop_CmpEQ32,
   10551                                       unop(Iop_16Uto32,
   10552                                            unop(Iop_32HIto16, getIReg(rs))),
   10553                                       mkU32(0x00008000)));
   10554                      assign(t3, binop(Iop_CmpEQ32,
   10555                                       unop(Iop_16Uto32,
   10556                                            unop(Iop_32HIto16, getIReg(rt))),
   10557                                       mkU32(0x00008000)));
   10558                      assign(t4,
   10559                             IRExpr_ITE(mkexpr(t2),
   10560                                        IRExpr_ITE(mkexpr(t3),
   10561                                                   mkU64(0x000000007fffffffULL),
   10562                                                   mkexpr(t1)),
   10563                                        mkexpr(t1)));
   10564 
   10565                      putDSPControl(IRExpr_ITE(mkexpr(t2),
   10566                                               IRExpr_ITE(mkexpr(t3),
   10567                                                          binop(Iop_Or32,
   10568                                                                getDSPControl(),
   10569                                                                binop(Iop_Shl32,
   10570                                                                      mkU32(0x1),
   10571                                                                      mkU8(ac+16)
   10572                                                                     )
   10573                                                               ),
   10574                                                          getDSPControl()),
   10575                                               getDSPControl()));
   10576 
   10577                      assign(t5,
   10578                             binop(Iop_Shl64,
   10579                                   binop(Iop_MullS32,
   10580                                         unop(Iop_16Sto32,
   10581                                              unop(Iop_32to16, getIReg(rs))),
   10582                                         unop(Iop_16Sto32,
   10583                                              unop(Iop_32to16, getIReg(rt)))),
   10584                                   mkU8(0x1)));
   10585                      assign(t6, binop(Iop_CmpEQ32,
   10586                                       unop(Iop_16Uto32,
   10587                                            unop(Iop_32to16, getIReg(rs))),
   10588                                       mkU32(0x00008000)));
   10589                      assign(t7, binop(Iop_CmpEQ32,
   10590                                       unop(Iop_16Uto32,
   10591                                            unop(Iop_32to16, getIReg(rt))),
   10592                                       mkU32(0x00008000)));
   10593                      assign(t8,
   10594                             IRExpr_ITE(mkexpr(t6),
   10595                                        IRExpr_ITE(mkexpr(t7),
   10596                                                   mkU64(0x000000007fffffffULL),
   10597                                                   mkexpr(t5)),
   10598                                        mkexpr(t5)));
   10599 
   10600                      putDSPControl(IRExpr_ITE(mkexpr(t6),
   10601                                               IRExpr_ITE(mkexpr(t7),
   10602                                                          binop(Iop_Or32,
   10603                                                                getDSPControl(),
   10604                                                                binop(Iop_Shl32,
   10605                                                                      mkU32(0x1),
   10606                                                                      mkU8(ac+16)
   10607                                                                     )
   10608                                                               ),
   10609                                                          getDSPControl()),
   10610                                               getDSPControl()));
   10611 
   10612                      assign(t9,
   10613                             binop(Iop_Sub64,
   10614                                   mkexpr(t0),
   10615                                   binop(Iop_Add64, mkexpr(t4), mkexpr(t8))));
   10616                      putAcc(ac, mkexpr(t9));
   10617                      break;
   10618                   }
   10619                   case 0x6: {  /* MULSAQ_S.W.PH */
   10620                      DIP("mulsaq_s.w.ph ac%u r%u, r%u", ac, rs, rt);
   10621                      vassert(!mode64);
   10622 
   10623                      t0 = newTemp(Ity_I32);
   10624                      t1 = newTemp(Ity_I32);
   10625                      t2 = newTemp(Ity_I32);
   10626                      t3 = newTemp(Ity_I32);
   10627                      t4 = newTemp(Ity_I32);
   10628                      t5 = newTemp(Ity_I32);
   10629                      t6 = newTemp(Ity_I64);
   10630                      t7 = newTemp(Ity_I64);
   10631                      t8 = newTemp(Ity_I32);
   10632                      t9 = newTemp(Ity_I32);
   10633 
   10634                      assign(t0, unop(Iop_16Sto32,
   10635                                      unop(Iop_32HIto16, getIReg(rs))));
   10636                      assign(t1, unop(Iop_16Sto32,
   10637                                      unop(Iop_32HIto16, getIReg(rt))));
   10638 
   10639                      assign(t8, binop(Iop_And32,
   10640                                       unop(Iop_1Sto32,
   10641                                            binop(Iop_CmpEQ32,
   10642                                                  unop(Iop_16Uto32,
   10643                                                       unop(Iop_32HIto16,
   10644                                                            getIReg(rs))),
   10645                                                  mkU32(0x8000))),
   10646                                     unop(Iop_1Sto32,
   10647                                          binop(Iop_CmpEQ32,
   10648                                                unop(Iop_16Uto32,
   10649                                                     unop(Iop_32HIto16,
   10650                                                          getIReg(rt))),
   10651                                                mkU32(0x8000)))));
   10652                      /* DSPControl_outflag:16+acc <- 1 */
   10653                      putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32,
   10654                                                     mkexpr(t8),
   10655                                                     mkU32(0x0)),
   10656                                               binop(Iop_Or32,
   10657                                                     getDSPControl(),
   10658                                                     binop(Iop_Shl32,
   10659                                                           mkU32(0x00010000),
   10660                                                           mkU8(ac))),
   10661                                               getDSPControl()));
   10662 
   10663                      /* tempB_31..0 */
   10664                      assign(t2,
   10665                             IRExpr_ITE(binop(Iop_CmpNE32,
   10666                                              mkexpr(t8), mkU32(0x0)),
   10667                                        mkU32(0x7FFFFFFF),
   10668                                        binop(Iop_Shl32,
   10669                                              binop(Iop_Mul32,
   10670                                                    mkexpr(t0), mkexpr(t1)),
   10671                                              mkU8(1))));
   10672 
   10673                      assign(t3, unop(Iop_16Sto32,
   10674                                      unop(Iop_32to16, getIReg(rs))));
   10675                      assign(t4, unop(Iop_16Sto32,
   10676                                      unop(Iop_32to16, getIReg(rt))));
   10677 
   10678                      assign(t9, binop(Iop_And32,
   10679                                       unop(Iop_1Sto32,
   10680                                            binop(Iop_CmpEQ32,
   10681                                                  unop(Iop_16Uto32,
   10682                                                       unop(Iop_32to16,
   10683                                                            getIReg(rs))),
   10684                                                  mkU32(0x8000))),
   10685                                       unop(Iop_1Sto32,
   10686                                            binop(Iop_CmpEQ32,
   10687                                                  unop(Iop_16Uto32,
   10688                                                       unop(Iop_32to16,
   10689                                                            getIReg(rt))),
   10690                                                  mkU32(0x8000)))));
   10691                      /* DSPControl_outflag:16+acc <- 1 */
   10692                      putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32,
   10693                                                     mkexpr(t9),
   10694                                                     mkU32(0x0)),
   10695                                               binop(Iop_Or32,
   10696                                                     getDSPControl(),
   10697                                                     binop(Iop_Shl32,
   10698                                                           mkU32(0x00010000),
   10699                                                           mkU8(ac))),
   10700                                               getDSPControl()));
   10701                      /* tempA_31..0 */
   10702                      assign(t5,
   10703                             IRExpr_ITE(binop(Iop_CmpNE32,
   10704                                              mkexpr(t9),
   10705                                              mkU32(0x0)),
   10706                                        mkU32(0x7FFFFFFF),
   10707                                        binop(Iop_Shl32,
   10708                                              binop(Iop_Mul32,
   10709                                                    mkexpr(t3),
   10710                                                    mkexpr(t4)),
   10711                                              mkU8(1))));
   10712                      /* dotp_63..0 */
   10713                      assign(t6,
   10714                             binop(Iop_Sub64,
   10715                                   unop(Iop_32Sto64, mkexpr(t2)),
   10716                                   unop(Iop_32Sto64, mkexpr(t5))));
   10717                      /* tempC_63..0 */
   10718                      assign(t7, binop(Iop_Add64, getAcc(ac), mkexpr(t6)));
   10719 
   10720                      putAcc(ac, mkexpr(t7));
   10721                      break;
   10722                   }
   10723                   case 0x7: {  /* DPAU.H.QBR */
   10724                      DIP("dpau.h.qbr ac%u, r%u, r%u", ac, rs, rt);
   10725                      vassert(!mode64);
   10726                      t0 = newTemp(Ity_I32);
   10727                      t1 = newTemp(Ity_I32);
   10728                      t2 = newTemp(Ity_I64);
   10729                      t3 = newTemp(Ity_I64);
   10730 
   10731                      assign(t0,
   10732                             binop(Iop_Mul32,
   10733                                   unop(Iop_8Uto32,
   10734                                        unop(Iop_16HIto8,
   10735                                             unop(Iop_32to16, getIReg(rs)))),
   10736                                   unop(Iop_8Uto32,
   10737                                        unop(Iop_16HIto8,
   10738                                             unop(Iop_32to16, getIReg(rt))))));
   10739                      assign(t1,
   10740                             binop(Iop_Mul32,
   10741                                   unop(Iop_8Uto32,
   10742                                        unop(Iop_16to8,
   10743                                             unop(Iop_32to16, getIReg(rs)))),
   10744                                   unop(Iop_8Uto32,
   10745                                        unop(Iop_16to8,
   10746                                             unop(Iop_32to16, getIReg(rt))))));
   10747                      assign(t2, unop(Iop_32Uto64,
   10748                                      binop(Iop_Add32, mkexpr(t0), mkexpr(t1))));
   10749                      assign(t3, binop(Iop_Add64, getAcc(ac), mkexpr(t2)));
   10750                      putAcc(ac, mkexpr(t3));
   10751                      break;
   10752                   }
   10753                   case 0x8: {  /* DPAX.W.PH */
   10754                      DIP("dpax.w.ph ac%u, r%u, r%u", ac, rs, rt);
   10755                      vassert(!mode64);
   10756                      t0 = newTemp(Ity_I64);
   10757                      t1 = newTemp(Ity_I64);
   10758                      t2 = newTemp(Ity_I64);
   10759 
   10760                      assign(t0,
   10761                             unop(Iop_32Sto64,
   10762                                  binop(Iop_Mul32,
   10763                                        unop(Iop_16Sto32,
   10764                                             unop(Iop_32HIto16, getIReg(rs))),
   10765                                        unop(Iop_16Sto32,
   10766                                             unop(Iop_32to16, getIReg(rt))))));
   10767                      assign(t1,
   10768                             unop(Iop_32Sto64,
   10769                                  binop(Iop_Mul32,
   10770                                        unop(Iop_16Sto32,
   10771                                             unop(Iop_32to16, getIReg(rs))),
   10772                                        unop(Iop_16Sto32,
   10773                                             unop(Iop_32HIto16, getIReg(rt))))));
   10774                      assign(t2,
   10775                             binop(Iop_Add64,
   10776                                   getAcc(ac),
   10777                                   binop(Iop_Add64, mkexpr(t0), mkexpr(t1))));
   10778                      putAcc(ac, mkexpr(t2));
   10779                      break;
   10780                   }
   10781                   case 0x9: {  /* DPSX.W.PH */
   10782                      DIP("dpsx.w.ph ac%u r%u, r%u", ac, rs, rt);
   10783                      vassert(!mode64);
   10784 
   10785                      t0 = newTemp(Ity_I64);
   10786                      t1 = newTemp(Ity_I64);
   10787                      t2 = newTemp(Ity_I64);
   10788 
   10789                      assign(t0,
   10790                             unop(Iop_32Sto64,
   10791                                  binop(Iop_Mul32,
   10792                                        unop(Iop_16Sto32,
   10793                                             unop(Iop_32HIto16, getIReg(rs))),
   10794                                        unop(Iop_16Sto32,
   10795                                             unop(Iop_32to16, getIReg(rt))))));
   10796                      assign(t1,
   10797                             unop(Iop_32Sto64,
   10798                                  binop(Iop_Mul32,
   10799                                        unop(Iop_16Sto32,
   10800                                             unop(Iop_32to16, getIReg(rs))),
   10801                                        unop(Iop_16Sto32,
   10802                                             unop(Iop_32HIto16, getIReg(rt))))));
   10803                      assign(t2,
   10804                             binop(Iop_Sub64,
   10805                                   getAcc(ac),
   10806                                   binop(Iop_Add64, mkexpr(t0), mkexpr(t1))));
   10807                      putAcc(ac, mkexpr(t2));
   10808                      break;
   10809                   }
   10810                   case 0xB: {  /* DPSU.H.QBL */
   10811                      DIP("dpsu.h.qbl ac%u, r%u, r%u", ac, rs, rt);
   10812                      vassert(!mode64);
   10813 
   10814                      t0 = newTemp(Ity_I32);
   10815                      t1 = newTemp(Ity_I32);
   10816                      t2 = newTemp(Ity_I64);
   10817                      t3 = newTemp(Ity_I64);
   10818 
   10819                      assign(t0,
   10820                             binop(Iop_Mul32,
   10821                                   unop(Iop_8Uto32,
   10822                                        unop(Iop_16HIto8,
   10823                                             unop(Iop_32HIto16, getIReg(rs)))),
   10824                                   unop(Iop_8Uto32,
   10825                                        unop(Iop_16HIto8,
   10826                                             unop(Iop_32HIto16, getIReg(rt))))));
   10827                      assign(t1,
   10828                             binop(Iop_Mul32,
   10829                                   unop(Iop_8Uto32,
   10830                                        unop(Iop_16to8,
   10831                                             unop(Iop_32HIto16, getIReg(rs)))),
   10832                                   unop(Iop_8Uto32,
   10833                                        unop(Iop_16to8,
   10834                                             unop(Iop_32HIto16, getIReg(rt))))));
   10835                      assign(t2,
   10836                             unop(Iop_32Uto64,
   10837                                  binop(Iop_Add32, mkexpr(t0), mkexpr(t1))));
   10838                      assign(t3,
   10839                             binop(Iop_Sub64, getAcc(ac), mkexpr(t2)));
   10840                      putAcc(ac, mkexpr(t3));
   10841                      break;
   10842                   }
   10843                   case 0xC: {  /* DPAQ_SA.L.W */
   10844                      DIP("dpaq_sa.l.w ac%u, r%u, r%u", ac, rs, rt);
   10845                      vassert(!mode64);
   10846                      t0 = newTemp(Ity_I64);
   10847                      t1 = newTemp(Ity_I64);
   10848                      t2 = newTemp(Ity_I1);
   10849                      t3 = newTemp(Ity_I1);
   10850                      t4 = newTemp(Ity_I64);
   10851                      t5 = newTemp(Ity_I64);
   10852                      t6 = newTemp(Ity_I64);
   10853                      t7 = newTemp(Ity_I64);
   10854                      t8 = newTemp(Ity_I1);
   10855                      t9 = newTemp(Ity_I1);
   10856 
   10857                      assign(t0, getAcc(ac));
   10858 
   10859                      assign(t1, binop(Iop_Shl64,
   10860                                       binop(Iop_MullS32,
   10861                                             getIReg(rs), getIReg(rt)),
   10862                                       mkU8(0x1)));
   10863 
   10864                      assign(t2, binop(Iop_CmpEQ32,
   10865                                       getIReg(rs),
   10866                                       mkU32(0x80000000)));
   10867                      assign(t3, binop(Iop_CmpEQ32,
   10868                                       getIReg(rt),
   10869                                       mkU32(0x80000000)));
   10870 
   10871                      assign(t4,
   10872                             IRExpr_ITE(mkexpr(t2),
   10873                                        IRExpr_ITE(mkexpr(t3),
   10874                                                   mkU64(0x7fffffffffffffffULL),
   10875                                                   mkexpr(t1)),
   10876                                        mkexpr(t1)));
   10877 
   10878                      putDSPControl(IRExpr_ITE(mkexpr(t2),
   10879                                               IRExpr_ITE(mkexpr(t3),
   10880                                                          binop(Iop_Or32,
   10881                                                                getDSPControl(),
   10882                                                                binop(Iop_Shl32,
   10883                                                                      mkU32(0x1),
   10884                                                                      mkU8(ac+16)
   10885                                                                     )
   10886                                                               ),
   10887                                                          getDSPControl()),
   10888                                               getDSPControl()));
   10889 
   10890                      assign(t5, binop(Iop_Add64,
   10891                                       unop(Iop_32Uto64,
   10892                                            unop(Iop_64to32, mkexpr(t0))),
   10893                                       unop(Iop_32Uto64,
   10894                                            unop(Iop_64to32, mkexpr(t4)))));
   10895                      assign(t6,
   10896                             binop(Iop_Add64,
   10897                                   binop(Iop_Add64,
   10898                                         unop(Iop_32Sto64,
   10899                                              unop(Iop_64HIto32, mkexpr(t0))),
   10900                                         unop(Iop_32Sto64,
   10901                                              unop(Iop_64HIto32, mkexpr(t4)))),
   10902                                   unop(Iop_32Uto64,
   10903                                        binop(Iop_And32,
   10904                                              unop(Iop_64HIto32, mkexpr(t5)),
   10905                                              mkU32(0x1)))));
   10906                      assign(t7, binop(Iop_32HLto64,
   10907                                       unop(Iop_64to32, mkexpr(t6)),
   10908                                       unop(Iop_64to32, mkexpr(t5))));
   10909                      assign(t8, binop(Iop_CmpEQ32,
   10910                                       binop(Iop_Shr32,
   10911                                             binop(Iop_And32,
   10912                                                   unop(Iop_64to32, mkexpr(t6)),
   10913                                                   mkU32(0x80000000)),
   10914                                             mkU8(31)),
   10915                                       binop(Iop_And32,
   10916                                             unop(Iop_64HIto32, mkexpr(t6)),
   10917                                             mkU32(0x00000001))));
   10918                      assign(t9, binop(Iop_CmpEQ32,
   10919                                       binop(Iop_And32,
   10920                                             unop(Iop_64HIto32,
   10921                                                  mkexpr(t6)),
   10922                                             mkU32(0x00000001)),
   10923                                       mkU32(0x1)));
   10924                      putDSPControl(IRExpr_ITE(mkexpr(t8),
   10925                                               getDSPControl(),
   10926                                               binop(Iop_Or32,
   10927                                                     getDSPControl(),
   10928                                                     binop(Iop_Shl32,
   10929                                                           mkU32(0x1),
   10930                                                           mkU8(ac+16)))));
   10931                      putAcc(ac,
   10932                             IRExpr_ITE(mkexpr(t8),
   10933                                        mkexpr(t7),
   10934                                        IRExpr_ITE(mkexpr(t9),
   10935                                                   mkU64(0x8000000000000000ULL),
   10936                                                   mkU64(0x7fffffffffffffffULL)))
   10937                            );
   10938                      break;
   10939                   }
   10940                   case 0xD: {  /* DPSQ_SA.L.W */
   10941                      DIP("dpsq_sa.l.w ac%u, r%u, r%u", ac, rs, rt);
   10942                      vassert(!mode64);
   10943                      t0 = newTemp(Ity_I64);
   10944                      t1 = newTemp(Ity_I64);
   10945                      t2 = newTemp(Ity_I1);
   10946                      t3 = newTemp(Ity_I1);
   10947                      t4 = newTemp(Ity_I64);
   10948                      t5 = newTemp(Ity_I64);
   10949                      t6 = newTemp(Ity_I64);
   10950                      t7 = newTemp(Ity_I64);
   10951                      t8 = newTemp(Ity_I1);
   10952                      t9 = newTemp(Ity_I1);
   10953 
   10954                      assign(t0, getAcc(ac));
   10955 
   10956                      assign(t1, binop(Iop_Shl64,
   10957                                       binop(Iop_MullS32,
   10958                                             getIReg(rs), getIReg(rt)),
   10959                                       mkU8(0x1)));
   10960 
   10961                      assign(t2, binop(Iop_CmpEQ32,
   10962                                       getIReg(rs),
   10963                                       mkU32(0x80000000)));
   10964                      assign(t3, binop(Iop_CmpEQ32,
   10965                                       getIReg(rt),
   10966                                       mkU32(0x80000000)));
   10967 
   10968                      assign(t4,
   10969                             IRExpr_ITE(mkexpr(t2),
   10970                                        IRExpr_ITE(mkexpr(t3),
   10971                                                   mkU64(0x7fffffffffffffffULL),
   10972                                                   mkexpr(t1)),
   10973                                        mkexpr(t1)));
   10974 
   10975                      putDSPControl(IRExpr_ITE(mkexpr(t2),
   10976                                               IRExpr_ITE(mkexpr(t3),
   10977                                                          binop(Iop_Or32,
   10978                                                                getDSPControl(),
   10979                                                                binop(Iop_Shl32,
   10980                                                                      mkU32(0x1),
   10981                                                                      mkU8(ac+16)
   10982                                                                     )
   10983                                                               ),
   10984                                                          getDSPControl()),
   10985                                               getDSPControl()));
   10986 
   10987                      assign(t5, binop(Iop_Sub64,
   10988                                       unop(Iop_32Uto64,
   10989                                            unop(Iop_64to32, mkexpr(t0))),
   10990                                       unop(Iop_32Uto64,
   10991                                            unop(Iop_64to32, mkexpr(t4)))));
   10992                      assign(t6, binop(Iop_Sub64,
   10993                                       binop(Iop_Add64,
   10994                                             unop(Iop_32Sto64,
   10995                                                  unop(Iop_64HIto32, mkexpr(t0))
   10996                                                 ),
   10997                                             unop(Iop_32Sto64,
   10998                                                  unop(Iop_1Sto32,
   10999                                                       binop(Iop_CmpLT32U,
   11000                                                             unop(Iop_64to32,
   11001                                                                  mkexpr(t0)),
   11002                                                             unop(Iop_64to32,
   11003                                                                 mkexpr(t4)))))),
   11004                                       unop(Iop_32Sto64,
   11005                                            unop(Iop_64HIto32, mkexpr(t4)))));
   11006                      assign(t7, binop(Iop_32HLto64,
   11007                                       unop(Iop_64to32, mkexpr(t6)),
   11008                                       unop(Iop_64to32, mkexpr(t5))));
   11009                      assign(t8, binop(Iop_CmpEQ32,
   11010                                       binop(Iop_Shr32,
   11011                                             binop(Iop_And32,
   11012                                                   unop(Iop_64to32, mkexpr(t6)),
   11013                                                   mkU32(0x80000000)),
   11014                                             mkU8(31)),
   11015                                       binop(Iop_And32,
   11016                                             unop(Iop_64HIto32, mkexpr(t6)),
   11017                                             mkU32(0x00000001))));
   11018                      assign(t9, binop(Iop_CmpEQ32,
   11019                                       binop(Iop_And32,
   11020                                             unop(Iop_64HIto32, mkexpr(t6)),
   11021                                             mkU32(0x00000001)),
   11022                                       mkU32(0x1)));
   11023                      putDSPControl(IRExpr_ITE(mkexpr(t8),
   11024                                               getDSPControl(),
   11025                                               binop(Iop_Or32,
   11026                                                     getDSPControl(),
   11027                                                     binop(Iop_Shl32,
   11028                                                           mkU32(0x1),
   11029                                                           mkU8(ac+16)))));
   11030                      putAcc(ac,
   11031                             IRExpr_ITE(mkexpr(t8),
   11032                                        mkexpr(t7),
   11033                                        IRExpr_ITE(mkexpr(t9),
   11034                                                   mkU64(0x8000000000000000ULL),
   11035                                                   mkU64(0x7fffffffffffffffULL)))
   11036                            );
   11037                      break;
   11038                   }
   11039                   case 0xF: {  /* DPSU.H.QBR */
   11040                      DIP("dpsu.h.qbr ac%u r%u, r%u", ac, rs, rt);
   11041                      vassert(!mode64);
   11042 
   11043                      t0 = newTemp(Ity_I32);
   11044                      t1 = newTemp(Ity_I32);
   11045                      t2 = newTemp(Ity_I64);
   11046                      t3 = newTemp(Ity_I64);
   11047 
   11048                      assign(t0,
   11049                             binop(Iop_Mul32,
   11050                                   unop(Iop_8Uto32,
   11051                                        unop(Iop_16HIto8,
   11052                                             unop(Iop_32to16, getIReg(rs)))),
   11053                                   unop(Iop_8Uto32,
   11054                                        unop(Iop_16HIto8,
   11055                                             unop(Iop_32to16, getIReg(rt))))));
   11056                      assign(t1,
   11057                             binop(Iop_Mul32,
   11058                                   unop(Iop_8Uto32,
   11059                                        unop(Iop_16to8,
   11060                                             unop(Iop_32to16, getIReg(rs)))),
   11061                                   unop(Iop_8Uto32,
   11062                                        unop(Iop_16to8,
   11063                                             unop(Iop_32to16, getIReg(rt))))));
   11064                      assign(t2, unop(Iop_32Uto64,
   11065                                      binop(Iop_Add32, mkexpr(t0), mkexpr(t1))));
   11066                      assign(t3, binop(Iop_Sub64, getAcc(ac), mkexpr(t2)));
   11067                      putAcc(ac, mkexpr(t3));
   11068 
   11069                      break;
   11070                   }
   11071                   case 0x10: {  /* MAQ_SA.W.PHL */
   11072                      DIP("maq_sa.w.phl ac%u, r%u, r%u", ac, rs, rt);
   11073                      vassert(!mode64);
   11074                      t0 = newTemp(Ity_I64);
   11075                      t1 = newTemp(Ity_I64);
   11076                      t2 = newTemp(Ity_I1);
   11077                      t3 = newTemp(Ity_I1);
   11078                      t4 = newTemp(Ity_I64);
   11079                      t5 = newTemp(Ity_I64);
   11080                      t6 = newTemp(Ity_I1);
   11081                      t7 = newTemp(Ity_I64);
   11082 
   11083                      assign(t0, getAcc(ac));
   11084                      assign(t1, unop(Iop_32Sto64,
   11085                                      binop(Iop_Shl32,
   11086                                            binop(Iop_Mul32,
   11087                                                  unop(Iop_16Sto32,
   11088                                                       unop(Iop_32HIto16,
   11089                                                            getIReg(rs))),
   11090                                                  unop(Iop_16Sto32,
   11091                                                       unop(Iop_32HIto16,
   11092                                                            getIReg(rt)))),
   11093                                            mkU8(0x1))));
   11094 
   11095                      /* If both input arguments are equal 0x8000, saturate
   11096                         intermediate product and write to DSPControl register.
   11097                      */
   11098                      assign(t2, binop(Iop_CmpEQ32,
   11099                                       unop(Iop_16Uto32,
   11100                                            unop(Iop_32HIto16, getIReg(rs))),
   11101                                       mkU32(0x00008000)));
   11102                      assign(t3, binop(Iop_CmpEQ32,
   11103                                       unop(Iop_16Uto32,
   11104                                            unop(Iop_32HIto16, getIReg(rt))),
   11105                                       mkU32(0x00008000)));
   11106 
   11107                      assign(t4,
   11108                             IRExpr_ITE(mkexpr(t2),
   11109                                        IRExpr_ITE(mkexpr(t3),
   11110                                                   mkU64(0x000000007fffffffULL),
   11111                                                   mkexpr(t1)),
   11112                                        mkexpr(t1)));
   11113 
   11114                      putDSPControl(IRExpr_ITE(mkexpr(t2),
   11115                                               IRExpr_ITE(mkexpr(t3),
   11116                                                          binop(Iop_Or32,
   11117                                                                getDSPControl(),
   11118                                                                binop(Iop_Shl32,
   11119                                                                      mkU32(0x1),
   11120                                                                      mkU8(ac+16)
   11121                                                                     )
   11122                                                               ),
   11123                                                          getDSPControl()),
   11124                                               getDSPControl()));
   11125                      /* Add intermediate product and value in the
   11126                         accumulator. */
   11127                      assign(t5, binop(Iop_Add64, mkexpr(t0), mkexpr(t4)));
   11128 
   11129                      /* Compare bits 31 and 32 of the value in t5. */
   11130                      assign(t6, binop(Iop_CmpEQ32,
   11131                                       binop(Iop_Shr32,
   11132                                             binop(Iop_And32,
   11133                                                   unop(Iop_64to32, mkexpr(t5)),
   11134                                                   mkU32(0x80000000)),
   11135                                             mkU8(31)),
   11136                                       binop(Iop_And32,
   11137                                             unop(Iop_64HIto32, mkexpr(t5)),
   11138                                             mkU32(1))));
   11139                      putDSPControl(IRExpr_ITE(mkexpr(t6),
   11140                                               getDSPControl(),
   11141                                               binop(Iop_Or32,
   11142                                                     getDSPControl(),
   11143                                                     binop(Iop_Shl32,
   11144                                                           mkU32(0x1),
   11145                                                           mkU8(ac+16)))));
   11146                      assign(t7,
   11147                             IRExpr_ITE(mkexpr(t6),
   11148                                        mkexpr(t5),
   11149                                        IRExpr_ITE(binop(Iop_CmpEQ32,
   11150                                                         binop(Iop_And32,
   11151                                                               unop(Iop_64HIto32,
   11152                                                                    mkexpr(t5)),
   11153                                                               mkU32(1)),
   11154                                                         mkU32(0x0)),
   11155                                                   mkU64(0x000000007fffffffULL),
   11156                                                   mkU64(0xffffffff80000000ULL)))
   11157                            );
   11158                      putAcc(ac, mkexpr(t7));
   11159                      break;
   11160                   }
   11161                   case 0x12: {  /* MAQ_SA.W.PHR */
   11162                      DIP("maq_sa.w.phr ac%u, r%u, r%u", ac, rs, rt);
   11163                      vassert(!mode64);
   11164                      t0 = newTemp(Ity_I64);
   11165                      t1 = newTemp(Ity_I64);
   11166                      t2 = newTemp(Ity_I1);
   11167                      t3 = newTemp(Ity_I1);
   11168                      t4 = newTemp(Ity_I64);
   11169                      t5 = newTemp(Ity_I64);
   11170                      t6 = newTemp(Ity_I1);
   11171                      t7 = newTemp(Ity_I64);
   11172 
   11173                      assign(t0, getAcc(ac));
   11174                      assign(t1, unop(Iop_32Sto64,
   11175                                      binop(Iop_Shl32,
   11176                                            binop(Iop_Mul32,
   11177                                                  unop(Iop_16Sto32,
   11178                                                       unop(Iop_32to16,
   11179                                                            getIReg(rs))),
   11180                                                  unop(Iop_16Sto32,
   11181                                                       unop(Iop_32to16,
   11182                                                            getIReg(rt)))),
   11183                                            mkU8(0x1))));
   11184 
   11185                      /* If both input arguments are equal 0x8000, saturate
   11186                         intermediate product and write to DSPControl
   11187                         register. */
   11188                      assign(t2, binop(Iop_CmpEQ32,
   11189                                       unop(Iop_16Uto32,
   11190                                            unop(Iop_32to16, getIReg(rs))),
   11191                                       mkU32(0x00008000)));
   11192                      assign(t3, binop(Iop_CmpEQ32,
   11193                                       unop(Iop_16Uto32,
   11194                                            unop(Iop_32to16, getIReg(rt))),
   11195                                       mkU32(0x00008000)));
   11196 
   11197                      assign(t4,
   11198                             IRExpr_ITE(mkexpr(t2),
   11199                                        IRExpr_ITE(mkexpr(t3),
   11200                                                   mkU64(0x000000007fffffffULL),
   11201                                                   mkexpr(t1)),
   11202                                        mkexpr(t1)));
   11203 
   11204                      putDSPControl(IRExpr_ITE(mkexpr(t2),
   11205                                               IRExpr_ITE(mkexpr(t3),
   11206                                                          binop(Iop_Or32,
   11207                                                                getDSPControl(),
   11208                                                                binop(Iop_Shl32,
   11209                                                                      mkU32(0x1),
   11210                                                                      mkU8(ac+16)
   11211                                                                     )
   11212                                                               ),
   11213                                                          getDSPControl()),
   11214                                               getDSPControl()));
   11215                      /* Add intermediate product and value in the
   11216                         accumulator. */
   11217                      assign(t5, binop(Iop_Add64, mkexpr(t0), mkexpr(t4)));
   11218 
   11219                      /* Compare bits 31 and 32 of the value in t5. */
   11220                      assign(t6, binop(Iop_CmpEQ32,
   11221                                       binop(Iop_Shr32,
   11222                                             binop(Iop_And32,
   11223                                                   unop(Iop_64to32, mkexpr(t5)),
   11224                                                   mkU32(0x80000000)),
   11225                                             mkU8(31)),
   11226                                       binop(Iop_And32,
   11227                                             unop(Iop_64HIto32, mkexpr(t5)),
   11228                                             mkU32(1))));
   11229                      putDSPControl(IRExpr_ITE(mkexpr(t6),
   11230                                               getDSPControl(),
   11231                                               binop(Iop_Or32,
   11232                                                     getDSPControl(),
   11233                                                     binop(Iop_Shl32,
   11234                                                           mkU32(0x1),
   11235                                                           mkU8(ac+16)))));
   11236                      assign(t7,
   11237                             IRExpr_ITE(mkexpr(t6),
   11238                                        mkexpr(t5),
   11239                                        IRExpr_ITE(binop(Iop_CmpEQ32,
   11240                                                         binop(Iop_And32,
   11241                                                               unop(Iop_64HIto32,
   11242                                                                    mkexpr(t5)),
   11243                                                               mkU32(1)),
   11244                                                         mkU32(0x0)),
   11245                                                   mkU64(0x000000007fffffffULL),
   11246                                                   mkU64(0xffffffff80000000ULL)))
   11247                            );
   11248                      putAcc(ac, mkexpr(t7));
   11249                      break;
   11250                   }
   11251                   case 0x14: {  /* MAQ_S.W.PHL */
   11252                      DIP("maq_s.w.phl ac%u, r%u, r%u", ac, rs, rt);
   11253                      vassert(!mode64);
   11254                      t0 = newTemp(Ity_I32);
   11255                      t1 = newTemp(Ity_I32);
   11256                      t2 = newTemp(Ity_I32);
   11257                      t3 = newTemp(Ity_I1);
   11258                      t4 = newTemp(Ity_I32);
   11259                      t5 = newTemp(Ity_I64);
   11260 
   11261                      assign(t5, getAcc(ac));
   11262 
   11263                      assign(t0, unop(Iop_16Sto32,
   11264                                      unop(Iop_32HIto16, getIReg(rs))));
   11265                      assign(t1, unop(Iop_16Sto32,
   11266                                      unop(Iop_32HIto16, getIReg(rt))));
   11267 
   11268                      assign(t2, binop(Iop_And32,
   11269                                       unop(Iop_1Sto32,
   11270                                            binop(Iop_CmpEQ32,
   11271                                                  binop(Iop_And32,
   11272                                                        mkexpr(t0),
   11273                                                        mkU32(0xffff)),
   11274                                                  mkU32(0x8000))),
   11275                                       unop(Iop_1Sto32,
   11276                                            binop(Iop_CmpEQ32,
   11277                                                  binop(Iop_And32,
   11278                                                        mkexpr(t1),
   11279                                                        mkU32(0xffff)),
   11280                                                  mkU32(0x8000)))));
   11281 
   11282                      assign(t3, binop(Iop_CmpEQ32, mkexpr(t2), mkU32(0x0)));
   11283 
   11284                      putDSPControl(IRExpr_ITE(mkexpr(t3),
   11285                                               getDSPControl(),
   11286                                               binop(Iop_Or32,
   11287                                                     getDSPControl(),
   11288                                                     binop(Iop_Shl32,
   11289                                                           mkU32(0x1),
   11290                                                           mkU8(ac+16)))));
   11291 
   11292                      assign(t4, unop(Iop_64to32,
   11293                                      binop(Iop_MullS32,
   11294                                            mkexpr(t0), mkexpr(t1))));
   11295                      putAcc(ac, IRExpr_ITE(mkexpr(t3),
   11296                                            binop(Iop_Add64,
   11297                                                  unop(Iop_32Sto64,
   11298                                                       binop(Iop_Shl32,
   11299                                                             mkexpr(t4),
   11300                                                             mkU8(0x1))),
   11301                                                  mkexpr(t5)),
   11302                                            binop(Iop_Add64,
   11303                                                  mkexpr(t5),
   11304                                                  unop(Iop_32Sto64,
   11305                                                       mkU32(0x7fffffff)))));
   11306                      break;
   11307                   }
   11308                   case 0x16: {  /* MAQ_S.W.PHR */
   11309                      DIP("maq_s.w.phr ac%u, r%u, r%u", ac, rs, rt);
   11310                      vassert(!mode64);
   11311                      t0 = newTemp(Ity_I32);
   11312                      t1 = newTemp(Ity_I32);
   11313                      t2 = newTemp(Ity_I32);
   11314                      t3 = newTemp(Ity_I1);
   11315                      t4 = newTemp(Ity_I32);
   11316                      t5 = newTemp(Ity_I64);
   11317 
   11318                      assign(t5, getAcc(ac));
   11319 
   11320                      assign(t0, unop(Iop_16Sto32,
   11321                                      unop(Iop_32to16, getIReg(rs))));
   11322                      assign(t1, unop(Iop_16Sto32,
   11323                                      unop(Iop_32to16, getIReg(rt))));
   11324 
   11325                      assign(t2, binop(Iop_And32,
   11326                                       unop(Iop_1Sto32,
   11327                                            binop(Iop_CmpEQ32,
   11328                                                  binop(Iop_And32,
   11329                                                        mkexpr(t0),
   11330                                                        mkU32(0xffff)),
   11331                                                  mkU32(0x8000))),
   11332                                       unop(Iop_1Sto32,
   11333                                            binop(Iop_CmpEQ32,
   11334                                                  binop(Iop_And32,
   11335                                                        mkexpr(t1),
   11336                                                        mkU32(0xffff)),
   11337                                                  mkU32(0x8000)))));
   11338 
   11339                      assign(t3, binop(Iop_CmpEQ32, mkexpr(t2), mkU32(0x0)));
   11340 
   11341                      putDSPControl(IRExpr_ITE(mkexpr(t3),
   11342                                               getDSPControl(),
   11343                                               binop(Iop_Or32,
   11344                                                     getDSPControl(),
   11345                                                     binop(Iop_Shl32,
   11346                                                           mkU32(0x1),
   11347                                                           mkU8(ac+16)))));
   11348 
   11349                      assign(t4, unop(Iop_64to32,
   11350                                      binop(Iop_MullS32,
   11351                                            mkexpr(t0), mkexpr(t1))));
   11352                      putAcc(ac, IRExpr_ITE(mkexpr(t3),
   11353                                            binop(Iop_Add64,
   11354                                                  unop(Iop_32Sto64,
   11355                                                       binop(Iop_Shl32,
   11356                                                             mkexpr(t4),
   11357                                                             mkU8(0x1))),
   11358                                                  mkexpr(t5)),
   11359                                            binop(Iop_Add64,
   11360                                                  mkexpr(t5),
   11361                                                  unop(Iop_32Sto64,
   11362                                                       mkU32(0x7fffffff)))));
   11363                      break;
   11364                   }
   11365                   case 0x18: {  /* DPAQX_S.W.PH */
   11366                      DIP("dpaqx_s.w.ph ac%u, r%u, r%u", ac, rs, rt);
   11367                      vassert(!mode64);
   11368                      t0 = newTemp(Ity_I64);
   11369                      t1 = newTemp(Ity_I64);
   11370                      t2 = newTemp(Ity_I1);
   11371                      t3 = newTemp(Ity_I1);
   11372                      t4 = newTemp(Ity_I64);
   11373                      t5 = newTemp(Ity_I64);
   11374                      t6 = newTemp(Ity_I1);
   11375                      t7 = newTemp(Ity_I1);
   11376                      t8 = newTemp(Ity_I64);
   11377                      t9 = newTemp(Ity_I64);
   11378 
   11379                      assign(t0, getAcc(ac));
   11380 
   11381                      assign(t1, binop(Iop_Shl64,
   11382                                       binop(Iop_MullS32,
   11383                                             unop(Iop_16Sto32,
   11384                                                  unop(Iop_32HIto16,
   11385                                                       getIReg(rs))),
   11386                                             unop(Iop_16Sto32,
   11387                                                  unop(Iop_32to16,
   11388                                                       getIReg(rt)))),
   11389                                       mkU8(0x1)));
   11390                      assign(t2, binop(Iop_CmpEQ32,
   11391                                       unop(Iop_16Uto32,
   11392                                            unop(Iop_32HIto16, getIReg(rs))),
   11393                                       mkU32(0x00008000)));
   11394                      assign(t3, binop(Iop_CmpEQ32,
   11395                                       unop(Iop_16Uto32,
   11396                                            unop(Iop_32to16, getIReg(rt))),
   11397                                       mkU32(0x00008000)));
   11398                      assign(t4,
   11399                             IRExpr_ITE(mkexpr(t2),
   11400                                        IRExpr_ITE(mkexpr(t3),
   11401                                                   mkU64(0x000000007fffffffULL),
   11402                                                   mkexpr(t1)),
   11403                                        mkexpr(t1)));
   11404 
   11405                      putDSPControl(IRExpr_ITE(mkexpr(t2),
   11406                                               IRExpr_ITE(mkexpr(t3),
   11407                                                          binop(Iop_Or32,
   11408                                                                getDSPControl(),
   11409                                                                binop(Iop_Shl32,
   11410                                                                   mkU32(0x1),
   11411                                                                   mkU8(ac+16))),
   11412                                                          getDSPControl()),
   11413                                               getDSPControl()));
   11414 
   11415                      assign(t5, binop(Iop_Shl64,
   11416                                       binop(Iop_MullS32,
   11417                                             unop(Iop_16Sto32,
   11418                                                  unop(Iop_32to16,
   11419                                                       getIReg(rs))),
   11420                                             unop(Iop_16Sto32,
   11421                                                  unop(Iop_32HIto16,
   11422                                                       getIReg(rt)))),
   11423                                       mkU8(0x1)));
   11424                      assign(t6, binop(Iop_CmpEQ32,
   11425                                       unop(Iop_16Uto32,
   11426                                            unop(Iop_32to16, getIReg(rs))),
   11427                                       mkU32(0x00008000)));
   11428                      assign(t7, binop(Iop_CmpEQ32,
   11429                                       unop(Iop_16Uto32,
   11430                                            unop(Iop_32HIto16, getIReg(rt))),
   11431                                       mkU32(0x00008000)));
   11432                      assign(t8,
   11433                             IRExpr_ITE(mkexpr(t6),
   11434                                        IRExpr_ITE(mkexpr(t7),
   11435                                                   mkU64(0x000000007fffffffULL),
   11436                                                   mkexpr(t5)),
   11437                                        mkexpr(t5)));
   11438 
   11439                      putDSPControl(IRExpr_ITE(mkexpr(t6),
   11440                                               IRExpr_ITE(mkexpr(t7),
   11441                                                          binop(Iop_Or32,
   11442                                                                getDSPControl(),
   11443                                                                binop(Iop_Shl32,
   11444                                                                      mkU32(0x1),
   11445                                                                      mkU8(ac+16)
   11446                                                                     )
   11447                                                               ),
   11448                                                          getDSPControl()),
   11449                                               getDSPControl()));
   11450 
   11451                      assign(t9, binop(Iop_Add64,
   11452                                       binop(Iop_Add64, mkexpr(t4), mkexpr(t8)),
   11453                                       mkexpr(t0)));
   11454                      putAcc(ac, mkexpr(t9));
   11455                      break;
   11456                   }
   11457                   case 0x19: {  /* DPSQX_S.W.PH */
   11458                      DIP("dpsqx_s.w.ph ac%u, r%u, r%u", ac, rs, rt);
   11459                      vassert(!mode64);
   11460                      t0 = newTemp(Ity_I64);
   11461                      t1 = newTemp(Ity_I64);
   11462                      t2 = newTemp(Ity_I1);
   11463                      t3 = newTemp(Ity_I1);
   11464                      t4 = newTemp(Ity_I64);
   11465                      t5 = newTemp(Ity_I64);
   11466                      t6 = newTemp(Ity_I1);
   11467                      t7 = newTemp(Ity_I1);
   11468                      t8 = newTemp(Ity_I64);
   11469                      t9 = newTemp(Ity_I64);
   11470 
   11471                      assign(t0, getAcc(ac));
   11472 
   11473                      assign(t1, binop(Iop_Shl64,
   11474                                       binop(Iop_MullS32,
   11475                                             unop(Iop_16Sto32,
   11476                                                  unop(Iop_32HIto16,
   11477                                                       getIReg(rs))),
   11478                                             unop(Iop_16Sto32,
   11479                                                  unop(Iop_32to16,
   11480                                                       getIReg(rt)))),
   11481                                       mkU8(0x1)));
   11482                      assign(t2, binop(Iop_CmpEQ32,
   11483                                       unop(Iop_16Uto32,
   11484                                            unop(Iop_32HIto16, getIReg(rs))),
   11485                                       mkU32(0x00008000)));
   11486                      assign(t3, binop(Iop_CmpEQ32,
   11487                                       unop(Iop_16Uto32,
   11488                                            unop(Iop_32to16, getIReg(rt))),
   11489                                       mkU32(0x00008000)));
   11490                      assign(t4,
   11491                             IRExpr_ITE(mkexpr(t2),
   11492                                        IRExpr_ITE(mkexpr(t3),
   11493                                                   mkU64(0x000000007fffffffULL),
   11494                                                   mkexpr(t1)),
   11495                                        mkexpr(t1)));
   11496 
   11497                      putDSPControl(IRExpr_ITE(mkexpr(t2),
   11498                                               IRExpr_ITE(mkexpr(t3),
   11499                                                          binop(Iop_Or32,
   11500                                                                getDSPControl(),
   11501                                                                binop(Iop_Shl32,
   11502                                                                      mkU32(0x1),
   11503                                                                      mkU8(ac+16)
   11504                                                                     )
   11505                                                               ),
   11506                                                          getDSPControl()),
   11507                                               getDSPControl()));
   11508 
   11509                      assign(t5, binop(Iop_Shl64,
   11510                                       binop(Iop_MullS32,
   11511                                             unop(Iop_16Sto32,
   11512                                                  unop(Iop_32to16,
   11513                                                       getIReg(rs))),
   11514                                             unop(Iop_16Sto32,
   11515                                                  unop(Iop_32HIto16,
   11516                                                       getIReg(rt)))),
   11517                                       mkU8(0x1)));
   11518                      assign(t6, binop(Iop_CmpEQ32,
   11519                                       unop(Iop_16Uto32,
   11520                                            unop(Iop_32to16, getIReg(rs))),
   11521                                       mkU32(0x00008000)));
   11522                      assign(t7, binop(Iop_CmpEQ32,
   11523                                       unop(Iop_16Uto32,
   11524                                            unop(Iop_32HIto16, getIReg(rt))),
   11525                                       mkU32(0x00008000)));
   11526                      assign(t8,
   11527                             IRExpr_ITE(mkexpr(t6),
   11528                                        IRExpr_ITE(mkexpr(t7),
   11529                                                   mkU64(0x000000007fffffffULL),
   11530                                                   mkexpr(t5)),
   11531                                        mkexpr(t5)));
   11532 
   11533                      putDSPControl(IRExpr_ITE(mkexpr(t6),
   11534                                               IRExpr_ITE(mkexpr(t7),
   11535                                                          binop(Iop_Or32,
   11536                                                                getDSPControl(),
   11537                                                                binop(Iop_Shl32,
   11538                                                                      mkU32(0x1),
   11539                                                                      mkU8(ac+16)
   11540                                                                     )
   11541                                                               ),
   11542                                                          getDSPControl()),
   11543                                               getDSPControl()));
   11544 
   11545                      assign(t9, binop(Iop_Sub64,
   11546                                      mkexpr(t0),
   11547                                      binop(Iop_Add64, mkexpr(t4), mkexpr(t8))));
   11548                      putAcc(ac, mkexpr(t9));
   11549                      break;
   11550                   }
   11551                   case 0x1A: {  /* DPAQX_SA.W.PH */
   11552                      DIP("dpaqx_sa.w.ph ac%u, r%u, r%u", ac, rs, rt);
   11553                      vassert(!mode64);
   11554                      t0 = newTemp(Ity_I64);
   11555                      t1 = newTemp(Ity_I64);
   11556                      t2 = newTemp(Ity_I1);
   11557                      t3 = newTemp(Ity_I1);
   11558                      t4 = newTemp(Ity_I64);
   11559                      t5 = newTemp(Ity_I64);
   11560                      t6 = newTemp(Ity_I1);
   11561                      t7 = newTemp(Ity_I1);
   11562                      t8 = newTemp(Ity_I64);
   11563                      t9 = newTemp(Ity_I64);
   11564                      t10 = newTemp(Ity_I32);
   11565 
   11566                      assign(t0, getAcc(ac));
   11567                      /* Calculate the first cross dot product and saturate if
   11568                         needed. */
   11569                      assign(t1, unop(Iop_32Sto64,
   11570                                      binop(Iop_Shl32,
   11571                                            binop(Iop_Mul32,
   11572                                                  unop(Iop_16Sto32,
   11573                                                       unop(Iop_32HIto16,
   11574                                                            getIReg(rs))),
   11575                                                  unop(Iop_16Sto32,
   11576                                                       unop(Iop_32to16,
   11577                                                            getIReg(rt)))),
   11578                                            mkU8(0x1))));
   11579 
   11580                      /* If both input arguments are equal 0x8000, saturate
   11581                         intermediate product and write to DSPControl
   11582                         register. */
   11583                      assign(t2, binop(Iop_CmpEQ32,
   11584                                       unop(Iop_16Uto32,
   11585                                            unop(Iop_32HIto16, getIReg(rs))),
   11586                                       mkU32(0x00008000)));
   11587                      assign(t3, binop(Iop_CmpEQ32,
   11588                                       unop(Iop_16Uto32,
   11589                                            unop(Iop_32to16, getIReg(rt))),
   11590                                       mkU32(0x00008000)));
   11591 
   11592                      assign(t4, IRExpr_ITE(binop(Iop_CmpNE32,
   11593                                                  binop(Iop_And32,
   11594                                                        unop(Iop_1Sto32,
   11595                                                             mkexpr(t2)),
   11596                                                        unop(Iop_1Sto32,
   11597                                                             mkexpr(t3))),
   11598                                                  mkU32(0)),
   11599                                            mkU64(0x000000007fffffffULL),
   11600                                            mkexpr(t1)));
   11601 
   11602                      putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32,
   11603                                                     binop(Iop_And32,
   11604                                                           unop(Iop_1Sto32,
   11605                                                                mkexpr(t2)),
   11606                                                           unop(Iop_1Sto32,
   11607                                                                mkexpr(t3))),
   11608                                                     mkU32(0)),
   11609                                               binop(Iop_Or32,
   11610                                                     getDSPControl(),
   11611                                                     binop(Iop_Shl32,
   11612                                                           mkU32(0x1),
   11613                                                           mkU8(ac+16))),
   11614                                               getDSPControl()));
   11615                      /* Calculate second cross dot product and saturate if
   11616                         needed. */
   11617                      assign(t5, unop(Iop_32Sto64,
   11618                                      binop(Iop_Shl32,
   11619                                            binop(Iop_Mul32,
   11620                                                  unop(Iop_16Sto32,
   11621                                                       unop(Iop_32to16,
   11622                                                            getIReg(rs))),
   11623                                                  unop(Iop_16Sto32,
   11624                                                       unop(Iop_32HIto16,
   11625                                                            getIReg(rt)))),
   11626                                            mkU8(0x1))));
   11627 
   11628                      /* If both input arguments are equal 0x8000, saturate
   11629                         intermediate product and write to DSPControl
   11630                         register. */
   11631                      assign(t6, binop(Iop_CmpEQ32,
   11632                                       unop(Iop_16Uto32,
   11633                                            unop(Iop_32to16, getIReg(rs))),
   11634                                       mkU32(0x00008000)));
   11635                      assign(t7, binop(Iop_CmpEQ32,
   11636                                       unop(Iop_16Uto32,
   11637                                            unop(Iop_32HIto16, getIReg(rt))),
   11638                                       mkU32(0x00008000)));
   11639 
   11640                      assign(t8, IRExpr_ITE(binop(Iop_CmpNE32,
   11641                                                  binop(Iop_And32,
   11642                                                        unop(Iop_1Sto32,
   11643                                                             mkexpr(t6)),
   11644                                                        unop(Iop_1Sto32,
   11645                                                             mkexpr(t7))),
   11646                                                  mkU32(0)),
   11647                                            mkU64(0x000000007fffffffULL),
   11648                                            mkexpr(t5)));
   11649 
   11650                      putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32,
   11651                                                     binop(Iop_And32,
   11652                                                           unop(Iop_1Sto32,
   11653                                                                mkexpr(t6)),
   11654                                                           unop(Iop_1Sto32,
   11655                                                                mkexpr(t7))),
   11656                                                     mkU32(0)),
   11657                                               binop(Iop_Or32,
   11658                                                     getDSPControl(),
   11659                                                     binop(Iop_Shl32,
   11660                                                           mkU32(0x1),
   11661                                                           mkU8(ac+16))),
   11662                                               getDSPControl()));
   11663                      /* Subtract intermediate products from value in the
   11664                         accumulator. */
   11665                      assign(t9,
   11666                             binop(Iop_Add64,
   11667                                   mkexpr(t0),
   11668                                   binop(Iop_Add64, mkexpr(t8), mkexpr(t4))));
   11669 
   11670                      putAcc(ac,
   11671                             IRExpr_ITE(binop(Iop_CmpEQ32,
   11672                                              binop(Iop_And32,
   11673                                                    unop(Iop_64HIto32,
   11674                                                         mkexpr(t9)),
   11675                                                    mkU32(0x80000000)),
   11676                                              mkU32(0x0)),
   11677                                        IRExpr_ITE(binop(Iop_CmpNE32,
   11678                                                         unop(Iop_64HIto32,
   11679                                                              binop(Iop_Shl64,
   11680                                                                    mkexpr(t9),
   11681                                                                    mkU8(1))),
   11682                                                         mkU32(0x0)),
   11683                                                   mkU64(0x000000007fffffffULL),
   11684                                                   mkexpr(t9)),
   11685                                        IRExpr_ITE(binop(Iop_CmpNE32,
   11686                                                         unop(Iop_64HIto32,
   11687                                                              binop(Iop_Shl64,
   11688                                                                    mkexpr(t9),
   11689                                                                    mkU8(1))),
   11690                                                         mkU32(0xffffffff)),
   11691                                                   mkU64(0xffffffff80000000ULL),
   11692                                                   mkexpr(t9))));
   11693                      assign(t10, IRExpr_ITE(binop(Iop_CmpEQ32,
   11694                                                   unop(Iop_64to32,
   11695                                                        mkexpr(t9)),
   11696                                                   unop(Iop_64to32,
   11697                                                        getAcc(ac))),
   11698                                            getDSPControl(),
   11699                                            binop(Iop_Or32,
   11700                                                  getDSPControl(),
   11701                                                  binop(Iop_Shl32,
   11702                                                        mkU32(0x1),
   11703                                                        mkU8(ac+16)))));
   11704                      putDSPControl(IRExpr_ITE(binop(Iop_CmpEQ32,
   11705                                                     unop(Iop_64HIto32,
   11706                                                          mkexpr(t9)),
   11707                                                     unop(Iop_64HIto32,
   11708                                                          getAcc(ac))),
   11709                                               mkexpr(t10),
   11710                                               binop(Iop_Or32,
   11711                                                     getDSPControl(),
   11712                                                     binop(Iop_Shl32,
   11713                                                           mkU32(0x1),
   11714                                                           mkU8(ac+16)))));
   11715                      break;
   11716                   }
   11717                   case 0x1B: {  /* DPSQX_SA.W.PH */
   11718                      DIP("dpsqx_sa.w.ph ac%u, r%u, r%u", ac, rs, rt);
   11719                      vassert(!mode64);
   11720                      t0 = newTemp(Ity_I64);
   11721                      t1 = newTemp(Ity_I64);
   11722                      t2 = newTemp(Ity_I1);
   11723                      t3 = newTemp(Ity_I1);
   11724                      t4 = newTemp(Ity_I64);
   11725                      t5 = newTemp(Ity_I64);
   11726                      t6 = newTemp(Ity_I1);
   11727                      t7 = newTemp(Ity_I1);
   11728                      t8 = newTemp(Ity_I64);
   11729                      t9 = newTemp(Ity_I64);
   11730                      t10 = newTemp(Ity_I32);
   11731 
   11732                      assign(t0, getAcc(ac));
   11733                      /* Calculate the first cross dot product and saturate if
   11734                         needed. */
   11735                      assign(t1, unop(Iop_32Sto64,
   11736                                      binop(Iop_Shl32,
   11737                                            binop(Iop_Mul32,
   11738                                                  unop(Iop_16Sto32,
   11739                                                       unop(Iop_32HIto16,
   11740                                                            getIReg(rs))),
   11741                                                  unop(Iop_16Sto32,
   11742                                                       unop(Iop_32to16,
   11743                                                            getIReg(rt)))),
   11744                                            mkU8(0x1))));
   11745 
   11746                      /* If both input arguments are equal 0x8000, saturate
   11747                         intermediate product and write to DSPControl
   11748                         register. */
   11749                      assign(t2, binop(Iop_CmpEQ32,
   11750                                       unop(Iop_16Uto32,
   11751                                            unop(Iop_32HIto16, getIReg(rs))),
   11752                                       mkU32(0x00008000)));
   11753                      assign(t3, binop(Iop_CmpEQ32,
   11754                                       unop(Iop_16Uto32,
   11755                                            unop(Iop_32to16, getIReg(rt))),
   11756                                       mkU32(0x00008000)));
   11757 
   11758                      assign(t4, IRExpr_ITE(binop(Iop_CmpNE32,
   11759                                                  binop(Iop_And32,
   11760                                                        unop(Iop_1Sto32,
   11761                                                             mkexpr(t2)),
   11762                                                        unop(Iop_1Sto32,
   11763                                                             mkexpr(t3))),
   11764                                                  mkU32(0)),
   11765                                            mkU64(0x000000007fffffffULL),
   11766                                            mkexpr(t1)));
   11767 
   11768                      putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32,
   11769                                                     binop(Iop_And32,
   11770                                                           unop(Iop_1Sto32,
   11771                                                                mkexpr(t2)),
   11772                                                           unop(Iop_1Sto32,
   11773                                                                mkexpr(t3))),
   11774                                                     mkU32(0)),
   11775                                               binop(Iop_Or32,
   11776                                                     getDSPControl(),
   11777                                                     binop(Iop_Shl32,
   11778                                                           mkU32(0x1),
   11779                                                           mkU8(ac+16))),
   11780                                               getDSPControl()));
   11781                      /* Calculate second cross dot product and saturate if
   11782                         needed. */
   11783                      assign(t5, unop(Iop_32Sto64,
   11784                                      binop(Iop_Shl32,
   11785                                            binop(Iop_Mul32,
   11786                                                  unop(Iop_16Sto32,
   11787                                                       unop(Iop_32to16,
   11788                                                            getIReg(rs))),
   11789                                                  unop(Iop_16Sto32,
   11790                                                       unop(Iop_32HIto16,
   11791                                                            getIReg(rt)))),
   11792                                            mkU8(0x1))));
   11793 
   11794                      /* If both input arguments are equal 0x8000, saturate
   11795                         intermediate product and write to DSPControl
   11796                         register. */
   11797                      assign(t6, binop(Iop_CmpEQ32,
   11798                                       unop(Iop_16Uto32,
   11799                                            unop(Iop_32to16, getIReg(rs))),
   11800                                       mkU32(0x00008000)));
   11801                      assign(t7, binop(Iop_CmpEQ32,
   11802                                       unop(Iop_16Uto32,
   11803                                            unop(Iop_32HIto16, getIReg(rt))),
   11804                                       mkU32(0x00008000)));
   11805 
   11806                      assign(t8, IRExpr_ITE(binop(Iop_CmpNE32,
   11807                                                  binop(Iop_And32,
   11808                                                        unop(Iop_1Sto32,
   11809                                                             mkexpr(t6)),
   11810                                                        unop(Iop_1Sto32,
   11811                                                             mkexpr(t7))),
   11812                                                  mkU32(0)),
   11813                                            mkU64(0x000000007fffffffULL),
   11814                                            mkexpr(t5)));
   11815 
   11816                      putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32,
   11817                                                     binop(Iop_And32,
   11818                                                           unop(Iop_1Sto32,
   11819                                                                mkexpr(t6)),
   11820                                                           unop(Iop_1Sto32,
   11821                                                                mkexpr(t7))),
   11822                                                     mkU32(0)),
   11823                                               binop(Iop_Or32,
   11824                                                     getDSPControl(),
   11825                                                     binop(Iop_Shl32,
   11826                                                           mkU32(0x1),
   11827                                                           mkU8(ac+16))),
   11828                                               getDSPControl()));
   11829                      /* Subtract intermediate products from value in the
   11830                         accumulator. */
   11831                      assign(t9,
   11832                             binop(Iop_Sub64,
   11833                                   mkexpr(t0),
   11834                                   binop(Iop_Add64, mkexpr(t8), mkexpr(t4))));
   11835 
   11836                      putAcc(ac,
   11837                             IRExpr_ITE(binop(Iop_CmpEQ32,
   11838                                              binop(Iop_And32,
   11839                                                    unop(Iop_64HIto32,
   11840                                                         mkexpr(t9)),
   11841                                                    mkU32(0x80000000)),
   11842                                              mkU32(0x0)),
   11843                                        IRExpr_ITE(binop(Iop_CmpNE32,
   11844                                                         unop(Iop_64HIto32,
   11845                                                              binop(Iop_Shl64,
   11846                                                                    mkexpr(t9),
   11847                                                                    mkU8(1))),
   11848                                                         mkU32(0x0)),
   11849                                                   mkU64(0x000000007fffffffULL),
   11850                                                   mkexpr(t9)),
   11851                                        IRExpr_ITE(binop(Iop_CmpNE32,
   11852                                                         unop(Iop_64HIto32,
   11853                                                              binop(Iop_Shl64,
   11854                                                                    mkexpr(t9),
   11855                                                                    mkU8(1))),
   11856                                                         mkU32(0xffffffff)),
   11857                                                   mkU64(0xffffffff80000000ULL),
   11858                                                   mkexpr(t9))));
   11859                      assign(t10, IRExpr_ITE(binop(Iop_CmpEQ32,
   11860                                                   unop(Iop_64to32,
   11861                                                        mkexpr(t9)),
   11862                                                   unop(Iop_64to32,
   11863                                                        getAcc(ac))),
   11864                                            getDSPControl(),
   11865                                            binop(Iop_Or32,
   11866                                                  getDSPControl(),
   11867                                                  binop(Iop_Shl32,
   11868                                                        mkU32(0x1),
   11869                                                        mkU8(ac+16)))));
   11870                      putDSPControl(IRExpr_ITE(binop(Iop_CmpEQ32,
   11871                                                     unop(Iop_64HIto32,
   11872                                                          mkexpr(t9)),
   11873                                                     unop(Iop_64HIto32,
   11874                                                          getAcc(ac))),
   11875                                               mkexpr(t10),
   11876                                               binop(Iop_Or32,
   11877                                                     getDSPControl(),
   11878                                                     binop(Iop_Shl32,
   11879                                                           mkU32(0x1),
   11880                                                           mkU8(ac+16)))));
   11881                      break;
   11882                   }
   11883                   default:
   11884                      return -1;
   11885                }
   11886                break;  /* end of DPAQ.W.PH */
   11887             }
   11888             case 0x31: {  /* APPEND */
   11889                switch(sa) {
   11890                   case 0x0: {  /* APPEND */
   11891                      DIP("append r%u, r%u, %u", rt, rs, rd);
   11892                      vassert(!mode64);
   11893                      t1 = newTemp(Ity_I32);
   11894                      t2 = newTemp(Ity_I32);
   11895                      t3 = newTemp(Ity_I32);
   11896 
   11897                      assign(t1, binop(Iop_Shl32, getIReg(rt), mkU8(rd)));
   11898 
   11899                      if (31 == rd) {
   11900                         putIReg(rt, binop(Iop_Or32,
   11901                                           mkexpr(t1),
   11902                                           binop(Iop_And32,
   11903                                                 getIReg(rs),
   11904                                                 mkU32(0x7fffffff))));
   11905                      } else if (1 == rd) {
   11906                         putIReg(rt,
   11907                                 binop(Iop_Or32,
   11908                                       mkexpr(t1),
   11909                                       binop(Iop_And32,
   11910                                             getIReg(rs), mkU32(0x1))));
   11911                      } else {
   11912                         assign(t2,
   11913                                unop(Iop_Not32,
   11914                                     binop(Iop_Shl32,
   11915                                           mkU32(0xffffffff), mkU8(rd))));
   11916 
   11917                         putIReg(rt, binop(Iop_Or32,
   11918                                           mkexpr(t1),
   11919                                           binop(Iop_And32,
   11920                                                 getIReg(rs), mkexpr(t2))));
   11921                      }
   11922                      break;
   11923                   }
   11924                   case 0x1: {  /* PREPEND */
   11925                      DIP("prepend r%u, r%u, %u", rt, rs, rd);
   11926                      vassert(!mode64);
   11927                      t1 = newTemp(Ity_I32);
   11928                      t2 = newTemp(Ity_I32);
   11929                      t3 = newTemp(Ity_I32);
   11930 
   11931                      if (0 != rd) {
   11932                         assign(t1, binop(Iop_Shr32, getIReg(rt), mkU8(rd)));
   11933 
   11934                         if (31 == rd) {
   11935                            putIReg(rt, binop(Iop_Or32,
   11936                                              mkexpr(t1),
   11937                                              binop(Iop_Shl32,
   11938                                                    binop(Iop_And32,
   11939                                                          getIReg(rs),
   11940                                                          mkU32(0x7fffffff)),
   11941                                                    mkU8(1))));
   11942                         } else if (1 == rd) {
   11943                            putIReg(rt, binop(Iop_Or32,
   11944                                              mkexpr(t1),
   11945                                              binop(Iop_Shl32,
   11946                                                    binop(Iop_And32,
   11947                                                          getIReg(rs),
   11948                                                          mkU32(0x1)),
   11949                                                    mkU8(31))));
   11950                         } else {
   11951                            assign(t2, binop(Iop_Add32, mkU32(rd), mkU32(0x1)));
   11952 
   11953                            assign(t3, unop(Iop_Not32,
   11954                                            binop(Iop_Shl32,
   11955                                                  mkU32(0xffffffff),
   11956                                                  unop(Iop_32to8, mkexpr(t2)))));
   11957 
   11958                            putIReg(rt, binop(Iop_Or32,
   11959                                              mkexpr(t1),
   11960                                              binop(Iop_Shl32,
   11961                                                    binop(Iop_And32,
   11962                                                          getIReg(rs),
   11963                                                          mkexpr(t3)),
   11964                                                    mkU8(32-rd))));
   11965                         }
   11966                      }
   11967                      break;
   11968                   }
   11969                   case 0x10: {  /* BALIGN */
   11970                      DIP("balign r%u, r%u, %u", rt, rs, rd);
   11971                      vassert(!mode64);
   11972                      t1 = newTemp(Ity_I32);
   11973                      t2 = newTemp(Ity_I32);
   11974                      t3 = newTemp(Ity_I32);
   11975 
   11976                      if ((2 != rd) && (0 != rd)) {
   11977                         assign(t1, binop(Iop_Shl32,
   11978                                          binop(Iop_And32,
   11979                                                mkU32(rd), mkU32(0x3)),
   11980                                          mkU8(0x3)));
   11981                         assign(t2, binop(Iop_Shl32,
   11982                                          getIReg(rt),
   11983                                          unop(Iop_32to8, mkexpr(t1))));
   11984                         assign(t3, binop(Iop_Shr32,
   11985                                          getIReg(rs),
   11986                                          unop(Iop_32to8,
   11987                                               binop(Iop_Shl32,
   11988                                                     binop(Iop_Sub32,
   11989                                                           mkU32(0x4),
   11990                                                           binop(Iop_And32,
   11991                                                                 mkU32(rd),
   11992                                                                 mkU32(0x3))),
   11993                                                     mkU8(0x3)))));
   11994                         putIReg(rt, binop(Iop_Or32, mkexpr(t2), mkexpr(t3)));
   11995                      }
   11996                      break;
   11997                   }
   11998                   default:
   11999                      return -1;
   12000                }
   12001                break;  /* end of APPEND */
   12002             }
   12003             default:
   12004                return -1;
   12005          }
   12006          break;
   12007       }
   12008       default:
   12009             return -1;
   12010    }
   12011    return 0;
   12012 }
   12013 
   12014 /*------------------------------------------------------------*/
   12015 /*---          Disassemble a single instruction            ---*/
   12016 /*------------------------------------------------------------*/
   12017 
   12018 /* Disassemble a single instruction into IR. The instruction is
   12019    located in host memory at guest_instr, and has guest IP of
   12020    guest_PC_curr_instr, which will have been set before the call
   12021    here. */
   12022 
   12023 static DisResult disInstr_MIPS_WRK ( Bool(*resteerOkFn) (/*opaque */void *,
   12024                                                                     Addr),
   12025                                      Bool         resteerCisOk,
   12026                                      void*        callback_opaque,
   12027                                      Long         delta64,
   12028                                      const VexArchInfo* archinfo,
   12029                                      const VexAbiInfo*  abiinfo,
   12030                                      Bool         sigill_diag )
   12031 {
   12032    IRTemp t0, t1 = 0, t2, t3, t4, t5, t6, t7;
   12033 
   12034    UInt opcode, cins, rs, rt, rd, sa, ft, fs, fd, fmt, tf, nd, function,
   12035         trap_code, imm, instr_index, p, msb, lsb, size, rot, sel;
   12036    /* Additional variables for instruction fields in DSP ASE insructions */
   12037    UInt ac;
   12038 
   12039    DisResult dres;
   12040 
   12041    static IRExpr *lastn = NULL;  /* last jump addr */
   12042    static IRStmt *bstmt = NULL;  /* branch (Exit) stmt */
   12043 
   12044    /* The running delta */
   12045    Int delta = (Int) delta64;
   12046 
   12047    /* Holds eip at the start of the insn, so that we can print
   12048       consistent error messages for unimplemented insns. */
   12049    Int delta_start = delta;
   12050 
   12051    /* Are we in a delay slot ? */
   12052    Bool delay_slot_branch, likely_delay_slot, delay_slot_jump;
   12053 
   12054    /* Set result defaults. */
   12055    dres.whatNext = Dis_Continue;
   12056    dres.len = 0;
   12057    dres.continueAt = 0;
   12058    dres.jk_StopHere = Ijk_INVALID;
   12059 
   12060    delay_slot_branch = likely_delay_slot = delay_slot_jump = False;
   12061 
   12062    const UChar *code = guest_code + delta;
   12063    cins = getUInt(code);
   12064    DIP("\t0x%llx:\t0x%08x\t", (Addr64)guest_PC_curr_instr, cins);
   12065 
   12066    if (delta != 0) {
   12067       if (branch_or_jump(guest_code + delta - 4)) {
   12068          if (lastn == NULL && bstmt == NULL) {
   12069             vassert(0);
   12070          } else {
   12071             dres.whatNext = Dis_StopHere;
   12072             if (lastn != NULL) {
   12073                delay_slot_jump = True;
   12074             } else if (bstmt != NULL) {
   12075                delay_slot_branch = True;
   12076             }
   12077          }
   12078       }
   12079 
   12080       if (branch_or_link_likely(guest_code + delta - 4)) {
   12081          likely_delay_slot = True;
   12082       }
   12083    }
   12084 
   12085    /* Spot "Special" instructions (see comment at top of file). */
   12086    {
   12087       /* Spot the 16-byte preamble:
   12088        ****mips32****
   12089        "srl $0, $0, 13
   12090        "srl $0, $0, 29
   12091        "srl $0, $0, 3
   12092        "srl $0, $0, 19
   12093 
   12094        ****mips64****
   12095        dsll $0, $0, 3
   12096        dsll $0, $0, 13
   12097        dsll $0, $0, 29
   12098        dsll $0, $0, 19 */
   12099 
   12100       UInt word1 = mode64 ? 0xF8  : 0x342;
   12101       UInt word2 = mode64 ? 0x378 : 0x742;
   12102       UInt word3 = mode64 ? 0x778 : 0xC2;
   12103       UInt word4 = mode64 ? 0x4F8 : 0x4C2;
   12104       if (getUInt(code + 0) == word1 && getUInt(code + 4) == word2 &&
   12105           getUInt(code + 8) == word3 && getUInt(code + 12) == word4) {
   12106          /* Got a "Special" instruction preamble. Which one is it? */
   12107          if (getUInt(code + 16) == 0x01ad6825 /* or $13, $13, $13 */ ) {
   12108             /* $11 = client_request ( $12 ) */
   12109             DIP("$11 = client_request ( $12 )");
   12110             if (mode64)
   12111                putPC(mkU64(guest_PC_curr_instr + 20));
   12112             else
   12113                putPC(mkU32(guest_PC_curr_instr + 20));
   12114             dres.jk_StopHere = Ijk_ClientReq;
   12115             dres.whatNext    = Dis_StopHere;
   12116 
   12117             goto decode_success;
   12118          } else if (getUInt(code + 16) == 0x01ce7025 /* or $14, $14, $14 */ ) {
   12119             /* $11 = guest_NRADDR */
   12120             DIP("$11 = guest_NRADDR");
   12121             dres.len = 20;
   12122             delta += 20;
   12123             if (mode64)
   12124                putIReg(11, IRExpr_Get(offsetof(VexGuestMIPS64State,
   12125                                                guest_NRADDR), Ity_I64));
   12126             else
   12127                putIReg(11, IRExpr_Get(offsetof(VexGuestMIPS32State,
   12128                                                guest_NRADDR), Ity_I32));
   12129             goto decode_success;
   12130          } else if (getUInt(code + 16) == 0x01ef7825 /* or $15, $15, $15 */ ) {
   12131             /*  branch-and-link-to-noredir $25 */
   12132             DIP("branch-and-link-to-noredir $25");
   12133             if (mode64)
   12134                putIReg(31, mkU64(guest_PC_curr_instr + 20));
   12135             else
   12136                putIReg(31, mkU32(guest_PC_curr_instr + 20));
   12137             putPC(getIReg(25));
   12138             dres.jk_StopHere = Ijk_NoRedir;
   12139             dres.whatNext    = Dis_StopHere;
   12140             goto decode_success;
   12141          } else if (getUInt(code + 16) == 0x016b5825 /* or $11,$11,$11 */ ) {
   12142            /* IR injection */
   12143             DIP("IR injection");
   12144 #if defined (_MIPSEL)
   12145             vex_inject_ir(irsb, Iend_LE);
   12146 #elif defined (_MIPSEB)
   12147             vex_inject_ir(irsb, Iend_BE);
   12148 #endif
   12149             if (mode64) {
   12150                stmt(IRStmt_Put(offsetof(VexGuestMIPS64State, guest_CMSTART),
   12151                                mkU64(guest_PC_curr_instr)));
   12152                stmt(IRStmt_Put(offsetof(VexGuestMIPS64State, guest_CMLEN),
   12153                                mkU64(20)));
   12154 
   12155                putPC(mkU64(guest_PC_curr_instr + 20));
   12156             } else {
   12157                stmt(IRStmt_Put(offsetof(VexGuestMIPS32State, guest_CMSTART),
   12158                                mkU32(guest_PC_curr_instr)));
   12159                stmt(IRStmt_Put(offsetof(VexGuestMIPS32State, guest_CMLEN),
   12160                                mkU32(20)));
   12161 
   12162                putPC(mkU32(guest_PC_curr_instr + 20));
   12163             }
   12164             dres.whatNext    = Dis_StopHere;
   12165             dres.jk_StopHere = Ijk_InvalICache;
   12166             dres.len = 20;
   12167             delta += 20;
   12168             goto decode_success;
   12169          }
   12170 
   12171          /* We don't know what it is.  Set opc1/opc2 so decode_failure
   12172             can print the insn following the Special-insn preamble. */
   12173          delta += 16;
   12174          goto decode_failure;
   12175        /*NOTREACHED*/}
   12176    }
   12177 
   12178    opcode = get_opcode(cins);
   12179    imm = get_imm(cins);
   12180    rs = get_rs(cins);
   12181    rt = get_rt(cins);
   12182    rd = get_rd(cins);
   12183    sa = get_sa(cins);
   12184    fs = get_fs(cins);
   12185    fd = get_fd(cins);
   12186    ft = get_ft(cins);
   12187    tf = get_tf(cins);
   12188    nd = get_nd(cins);
   12189    sel = get_sel(cins);
   12190    fmt = get_fmt(cins);
   12191    instr_index = get_instr_index(cins);
   12192    trap_code = get_code(cins);
   12193    function = get_function(cins);
   12194    IRType ty = mode64 ? Ity_I64 : Ity_I32;
   12195    IRType tyF = fp_mode64 ? Ity_F64 : Ity_F32;
   12196 
   12197    ac = get_acNo(cins);
   12198 
   12199    switch (opcode) {
   12200 
   12201    case 0x03:     /* JAL */
   12202       DIP("jal 0x%x", instr_index);
   12203       if (mode64) {
   12204          putIReg(31, mkU64(guest_PC_curr_instr + 8));
   12205          t0 = newTemp(ty);
   12206          assign(t0, mkU64((guest_PC_curr_instr & 0xFFFFFFFFF0000000ULL) |
   12207                           (instr_index << 2)));
   12208       } else {
   12209          putIReg(31, mkU32(guest_PC_curr_instr + 8));
   12210          t0 = newTemp(ty);
   12211          assign(t0, mkU32((guest_PC_curr_instr & 0xF0000000) |
   12212                           (instr_index << 2)));
   12213       }
   12214       lastn = mkexpr(t0);
   12215       break;
   12216    case 0x02:     /* J */
   12217       DIP("j 0x%x", instr_index);
   12218       t0 = newTemp(ty);
   12219       if (mode64)
   12220          assign(t0, mkU64((guest_PC_curr_instr & 0xFFFFFFFFF0000000ULL) |
   12221                           (instr_index << 2)));
   12222       else
   12223          assign(t0, mkU32((guest_PC_curr_instr & 0xF0000000) |
   12224                           (instr_index << 2)));
   12225       lastn = mkexpr(t0);
   12226       break;
   12227 
   12228    case 0x11: {  /* COP1 */
   12229       if (fmt == 0x3 && fd == 0 && function == 0) {  /* MFHC1 */
   12230          DIP("mfhc1 r%u, f%u", rt, fs);
   12231          if (fp_mode64) {
   12232             t0 = newTemp(Ity_I64);
   12233             t1 = newTemp(Ity_I32);
   12234             assign(t0, unop(Iop_ReinterpF64asI64, getDReg(fs)));
   12235             assign(t1, unop(Iop_64HIto32, mkexpr(t0)));
   12236             putIReg(rt, mkWidenFrom32(ty, mkexpr(t1), True));
   12237          } else {
   12238             ILLEGAL_INSTRUCTON;
   12239          }
   12240          break;
   12241       } else if (fmt == 0x7 && fd == 0 && function == 0) {  /* MTHC1 */
   12242          DIP("mthc1 r%u, f%u", rt, fs);
   12243          if (fp_mode64) {
   12244             t0 = newTemp(Ity_I64);
   12245             assign(t0, binop(Iop_32HLto64, getIReg(rt),
   12246                              unop(Iop_ReinterpF32asI32,
   12247                                   getLoFromF64(Ity_F64 /* 32FPR mode. */,
   12248                                                getDReg(fs)))));
   12249             putDReg(fs, unop(Iop_ReinterpI64asF64, mkexpr(t0)));
   12250          } else {
   12251             ILLEGAL_INSTRUCTON;
   12252          }
   12253          break;
   12254       } else if (fmt == 0x8) {  /* BC */
   12255          /* FcConditionalCode(bc1_cc) */
   12256          UInt bc1_cc = get_bc1_cc(cins);
   12257          t1 = newTemp(Ity_I1);
   12258          t2 = newTemp(Ity_I32);
   12259          t3 = newTemp(Ity_I1);
   12260 
   12261          assign(t1, binop(Iop_CmpEQ32, mkU32(0), mkU32(bc1_cc)));
   12262          assign(t2, IRExpr_ITE(mkexpr(t1),
   12263                                binop(Iop_And32,
   12264                                      binop(Iop_Shr32, getFCSR(), mkU8(23)),
   12265                                      mkU32(0x1)),
   12266                                binop(Iop_And32,
   12267                                      binop(Iop_Shr32, getFCSR(),
   12268                                            mkU8(24 + bc1_cc)),
   12269                                      mkU32(0x1))));
   12270 
   12271          if (tf == 1 && nd == 0) {
   12272             /* branch on true */
   12273             DIP("bc1t %u, %u", bc1_cc, imm);
   12274             assign(t3, binop(Iop_CmpEQ32, mkU32(1), mkexpr(t2)));
   12275             dis_branch(False, mkexpr(t3), imm, &bstmt);
   12276             break;
   12277          } else if (tf == 0 && nd == 0) {
   12278             /* branch on false */
   12279             DIP("bc1f %u, %u", bc1_cc, imm);
   12280             assign(t3, binop(Iop_CmpEQ32, mkU32(0), mkexpr(t2)));
   12281             dis_branch(False, mkexpr(t3), imm, &bstmt);
   12282             break;
   12283          } else if (nd == 1 && tf == 0) {
   12284             DIP("bc1fl %u, %u", bc1_cc, imm);
   12285             lastn = dis_branch_likely(binop(Iop_CmpNE32, mkexpr(t2),
   12286                                             mkU32(0x0)), imm);
   12287             break;
   12288          } else if (nd == 1 && tf == 1) {
   12289             DIP("bc1tl %u, %u", bc1_cc, imm);
   12290             lastn = dis_branch_likely(binop(Iop_CmpEQ32, mkexpr(t2),
   12291                                             mkU32(0x0)), imm);
   12292             break;
   12293          } else
   12294             goto decode_failure;
   12295       } else {
   12296          switch (function) {
   12297             case 0x4: {  /* SQRT.fmt */
   12298                switch (fmt) {
   12299                   case 0x10: {  /* S */
   12300                      IRExpr *rm = get_IR_roundingmode();
   12301                      putFReg(fd, mkWidenFromF32(tyF, binop(Iop_SqrtF32, rm,
   12302                                  getLoFromF64(tyF, getFReg(fs)))));
   12303                      break;
   12304                   }
   12305                   case 0x11: {  /* D */
   12306                      IRExpr *rm = get_IR_roundingmode();
   12307                      putDReg(fd, binop(Iop_SqrtF64, rm, getDReg(fs)));
   12308                      break;
   12309                   }
   12310                   default:
   12311                      goto decode_failure;
   12312                   }
   12313                }
   12314                break;
   12315             case 0x5:  /* abs.fmt */
   12316                switch (fmt) {
   12317                   case 0x10:  /* S */
   12318                      DIP("abs.s f%u, f%u", fd, fs);
   12319                      putFReg(fd, mkWidenFromF32(tyF, unop(Iop_AbsF32,
   12320                                  getLoFromF64(tyF, getFReg(fs)))));
   12321                      break;
   12322                   case 0x11:  /* D  */
   12323                      DIP("abs.d f%u, f%u", fd, fs);
   12324                      putDReg(fd, unop(Iop_AbsF64, getDReg(fs)));
   12325                      break;
   12326                   default:
   12327                      goto decode_failure;
   12328                }
   12329                break;  /* case 0x5 */
   12330 
   12331             case 0x02:  /* MUL.fmt */
   12332                switch (fmt) {
   12333                   case 0x11: {  /* D */
   12334                      DIP("mul.d f%u, f%u, f%u", fd, fs, ft);
   12335                      IRExpr *rm = get_IR_roundingmode();
   12336                      putDReg(fd, triop(Iop_MulF64, rm, getDReg(fs),
   12337                                        getDReg(ft)));
   12338                      break;
   12339                   }
   12340                   case 0x10: {  /* S */
   12341                      DIP("mul.s f%u, f%u, f%u", fd, fs, ft);
   12342                      IRExpr *rm = get_IR_roundingmode();
   12343                      putFReg(fd, mkWidenFromF32(tyF, triop(Iop_MulF32, rm,
   12344                                  getLoFromF64(tyF, getFReg(fs)),
   12345                                  getLoFromF64(tyF, getFReg(ft)))));
   12346                      break;
   12347                   }
   12348                   default:
   12349                      goto decode_failure;
   12350                }
   12351                break;  /* MUL.fmt */
   12352 
   12353             case 0x03:  /* DIV.fmt */
   12354                switch (fmt) {
   12355                   case 0x11: {  /* D */
   12356                      DIP("div.d f%u, f%u, f%u", fd, fs, ft);
   12357                      IRExpr *rm = get_IR_roundingmode();
   12358                      putDReg(fd, triop(Iop_DivF64, rm, getDReg(fs),
   12359                                  getDReg(ft)));
   12360                      break;
   12361                   }
   12362                   case 0x10: {  /* S */
   12363                      DIP("div.s f%u, f%u, f%u", fd, fs, ft);
   12364                      calculateFCSR(fs, ft, DIVS, False, 2);
   12365                      IRExpr *rm = get_IR_roundingmode();
   12366                      putFReg(fd, mkWidenFromF32(tyF, triop(Iop_DivF32, rm,
   12367                                  getLoFromF64(tyF, getFReg(fs)),
   12368                                  getLoFromF64(tyF, getFReg(ft)))));
   12369                      break;
   12370                   }
   12371                   default:
   12372                      goto decode_failure;
   12373                }
   12374                break;  /* DIV.fmt */
   12375 
   12376             case 0x01:  /* SUB.fmt */
   12377                switch (fmt) {
   12378                   case 0x11: {  /* D */
   12379                      DIP("sub.d f%u, f%u, f%u", fd, fs, ft);
   12380                      calculateFCSR(fs, ft, SUBD, False, 2);
   12381                      IRExpr *rm = get_IR_roundingmode();
   12382                      putDReg(fd, triop(Iop_SubF64, rm, getDReg(fs),
   12383                                        getDReg(ft)));
   12384                      break;
   12385                   }
   12386                   case 0x10: {  /* S */
   12387                      DIP("sub.s f%u, f%u, f%u", fd, fs, ft);
   12388                      calculateFCSR(fs, ft, SUBS, True, 2);
   12389                      IRExpr *rm = get_IR_roundingmode();
   12390                      putFReg(fd, mkWidenFromF32(tyF, triop(Iop_SubF32, rm,
   12391                                  getLoFromF64(tyF, getFReg(fs)),
   12392                                  getLoFromF64(tyF, getFReg(ft)))));
   12393                      break;
   12394                   }
   12395                   default:
   12396                      goto decode_failure;
   12397                }
   12398                break;  /* SUB.fmt */
   12399 
   12400             case 0x06:  /* MOV.fmt */
   12401                switch (fmt) {
   12402                   case 0x11:  /* D */
   12403                      DIP("mov.d f%u, f%u", fd, fs);
   12404                      if (fp_mode64) {
   12405                         putDReg(fd, getDReg(fs));
   12406                      } else {
   12407                         putFReg(fd, getFReg(fs));
   12408                         putFReg(fd + 1, getFReg(fs + 1));
   12409                      }
   12410                      break;
   12411                   case 0x10:  /* S */
   12412                      DIP("mov.s f%u, f%u", fd, fs);
   12413                      putFReg(fd, getFReg(fs));
   12414                      break;
   12415                   default:
   12416                      goto decode_failure;
   12417                }
   12418                break;  /* MOV.fmt */
   12419 
   12420             case 0x7:  /* neg.fmt */
   12421                switch (fmt) {
   12422                   case 0x10:  /* S */
   12423                      DIP("neg.s f%u, f%u", fd, fs);
   12424                      putFReg(fd, mkWidenFromF32(tyF, unop(Iop_NegF32,
   12425                                  getLoFromF64(tyF, getFReg(fs)))));
   12426                      break;
   12427                   case 0x11:  /* D */
   12428                      DIP("neg.d f%u, f%u", fd, fs);
   12429                      putDReg(fd, unop(Iop_NegF64, getDReg(fs)));
   12430                      break;
   12431                   default:
   12432                      goto decode_failure;
   12433                }
   12434                break;  /* case 0x7 */
   12435 
   12436             case 0x08:  /* ROUND.L.fmt */
   12437                switch (fmt) {
   12438                   case 0x10:  /* S */
   12439                      DIP("round.l.s f%u, f%u", fd, fs);
   12440                      if (fp_mode64) {
   12441                         calculateFCSR(fs, 0, ROUNDLS, True, 1);
   12442                         t0 = newTemp(Ity_I64);
   12443 
   12444                         assign(t0, binop(Iop_F32toI64S, mkU32(0x0),
   12445                                          getLoFromF64(Ity_F64, getFReg(fs))));
   12446 
   12447                         putDReg(fd, unop(Iop_ReinterpI64asF64, mkexpr(t0)));
   12448                      } else {
   12449                         ILLEGAL_INSTRUCTON;
   12450                      }
   12451                      break;
   12452                   case 0x11:  /* D */
   12453                      DIP("round.l.d f%u, f%u", fd, fs);
   12454                      if (fp_mode64) {
   12455                         calculateFCSR(fs, 0, ROUNDLD, False, 1);
   12456                         putDReg(fd, binop(Iop_RoundF64toInt, mkU32(0x0),
   12457                                           getDReg(fs)));
   12458                      } else {
   12459                         ILLEGAL_INSTRUCTON;
   12460                      }
   12461                      break;
   12462                   default:
   12463                     goto decode_failure;
   12464 
   12465                }
   12466                break;  /* ROUND.L.fmt */
   12467 
   12468             case 0x09:  /* TRUNC.L.fmt */
   12469                switch (fmt) {
   12470                   case 0x10:  /* S */
   12471                      DIP("trunc.l.s f%u, f%u", fd, fs);
   12472                      if (fp_mode64) {
   12473                         calculateFCSR(fs, 0, TRUNCLS, True, 1);
   12474                         t0 = newTemp(Ity_I64);
   12475                         assign(t0, binop(Iop_F32toI64S, mkU32(0x3),
   12476                                          getLoFromF64(Ity_F64, getFReg(fs))));
   12477 
   12478                         putDReg(fd, unop(Iop_ReinterpI64asF64, mkexpr(t0)));
   12479                      } else {
   12480                         ILLEGAL_INSTRUCTON;
   12481                      }
   12482                      break;
   12483                   case 0x11:  /* D */
   12484                      DIP("trunc.l.d f%u, f%u", fd, fs);
   12485                      if (fp_mode64) {
   12486                         calculateFCSR(fs, 0, TRUNCLD, False, 1);
   12487                         putDReg(fd, binop(Iop_RoundF64toInt, mkU32(0x3),
   12488                                           getDReg(fs)));
   12489                      } else {
   12490                         ILLEGAL_INSTRUCTON;
   12491                      }
   12492                      break;
   12493                   default:
   12494                      goto decode_failure;
   12495                  }
   12496               break;  /* TRUNC.L.fmt */
   12497 
   12498             case 0x15:  /* RECIP.fmt */
   12499                switch (fmt) {
   12500                   case 0x10: {  /* S */
   12501                      DIP("recip.s f%u, f%u", fd, fs);
   12502                      IRExpr *rm = get_IR_roundingmode();
   12503                      putFReg(fd, mkWidenFromF32(tyF, triop(Iop_DivF32,
   12504                                  rm, unop(Iop_ReinterpI32asF32,
   12505                                  mkU32(ONE_SINGLE)), getLoFromF64(tyF,
   12506                                  getFReg(fs)))));
   12507                      break;
   12508                   }
   12509                   case 0x11: {  /* D */
   12510                      DIP("recip.d f%u, f%u", fd, fs);
   12511                      IRExpr *rm = get_IR_roundingmode();
   12512                      /* putDReg(fd, 1.0/getDreg(fs)); */
   12513                      putDReg(fd, triop(Iop_DivF64, rm,
   12514                                  unop(Iop_ReinterpI64asF64,
   12515                                  mkU64(ONE_DOUBLE)), getDReg(fs)));
   12516                      break;
   12517                   }
   12518                default:
   12519                   goto decode_failure;
   12520 
   12521                }
   12522                break;  /* case 0x15 */
   12523 
   12524             case 0x13:  /* MOVN.fmt */
   12525                switch (fmt) {
   12526                case 0x10:  /* S */
   12527                   DIP("movn.s f%u, f%u, r%u", fd, fs, rt);
   12528                   t1 = newTemp(Ity_F64);
   12529                   t2 = newTemp(Ity_F64);
   12530                   t3 = newTemp(Ity_I1);
   12531                   t4 = newTemp(Ity_F64);
   12532                   if (mode64) {
   12533                      assign(t1, getFReg(fs));
   12534                      assign(t2, getFReg(fd));
   12535                      assign(t3, binop(Iop_CmpNE64, mkU64(0), getIReg(rt)));
   12536                   } else {
   12537                      if (fp_mode64) {
   12538                         assign(t1, getFReg(fs));
   12539                         assign(t2, getFReg(fd));
   12540                         assign(t3, binop(Iop_CmpNE32, mkU32(0), getIReg(rt)));
   12541                      } else {
   12542                         assign(t1, unop(Iop_F32toF64, getFReg(fs)));
   12543                         assign(t2, unop(Iop_F32toF64, getFReg(fd)));
   12544                         assign(t3, binop(Iop_CmpNE32, mkU32(0), getIReg(rt)));
   12545                      }
   12546                   }
   12547 
   12548                   assign(t4, IRExpr_ITE(mkexpr(t3), mkexpr(t1), mkexpr(t2)));
   12549                   if (fp_mode64) {
   12550                      IRTemp f = newTemp(Ity_F64);
   12551                      IRTemp fd_hi = newTemp(Ity_I32);
   12552                      t5 = newTemp(Ity_I64);
   12553                      assign(f, getFReg(fd));
   12554                      assign(fd_hi, unop(Iop_64HIto32, unop(Iop_ReinterpF64asI64,
   12555                                         mkexpr(f))));
   12556 
   12557                      assign(t5, mkWidenFrom32(Ity_I64, unop(Iop_64to32,
   12558                                 unop(Iop_ReinterpF64asI64, mkexpr(t4))), True));
   12559 
   12560                      putFReg(fd, unop (Iop_ReinterpI64asF64, mkexpr(t5)));
   12561                   } else
   12562                      putFReg(fd, binop(Iop_F64toF32, get_IR_roundingmode(),
   12563                                        mkexpr(t4)));
   12564                   break;
   12565                case 0x11:  /* D */
   12566                   DIP("movn.d f%u, f%u, r%u", fd, fs, rt);
   12567 
   12568                   t3 = newTemp(Ity_I1);
   12569                   t4 = newTemp(Ity_F64);
   12570 
   12571                   if (mode64)
   12572                      assign(t3, binop(Iop_CmpNE64, mkU64(0), getIReg(rt)));
   12573                   else
   12574                      assign(t3, binop(Iop_CmpNE32, mkU32(0), getIReg(rt)));
   12575 
   12576                   putDReg(fd, IRExpr_ITE(mkexpr(t3), getDReg(fs), getDReg(fd)));
   12577                   break;
   12578                default:
   12579                   goto decode_failure;
   12580                }
   12581                break;  /* MOVN.fmt */
   12582 
   12583             case 0x12:  /* MOVZ.fmt */
   12584                switch (fmt) {
   12585                case 0x10:  /* S */
   12586                   DIP("movz.s f%u, f%u, r%u", fd, fs, rt);
   12587 
   12588                   t1 = newTemp(Ity_F64);
   12589                   t2 = newTemp(Ity_F64);
   12590                   t3 = newTemp(Ity_I1);
   12591                   t4 = newTemp(Ity_F64);
   12592                   if (fp_mode64) {
   12593                      assign(t1, getFReg(fs));
   12594                      assign(t2, getFReg(fd));
   12595                      if (mode64)
   12596                         assign(t3, binop(Iop_CmpEQ64, mkU64(0), getIReg(rt)));
   12597                      else
   12598                         assign(t3, binop(Iop_CmpEQ32, mkU32(0), getIReg(rt)));
   12599                   } else {
   12600                      assign(t1, unop(Iop_F32toF64, getFReg(fs)));
   12601                      assign(t2, unop(Iop_F32toF64, getFReg(fd)));
   12602                      assign(t3, binop(Iop_CmpEQ32, mkU32(0), getIReg(rt)));
   12603                   }
   12604                   assign(t4, IRExpr_ITE(mkexpr(t3), mkexpr(t1), mkexpr(t2)));
   12605 
   12606                  if (fp_mode64) {
   12607                      IRTemp f = newTemp(Ity_F64);
   12608                      IRTemp fd_hi = newTemp(Ity_I32);
   12609                      t7 = newTemp(Ity_I64);
   12610                      assign(f, getFReg(fd));
   12611                      assign(fd_hi, unop(Iop_64HIto32,
   12612                                    unop(Iop_ReinterpF64asI64, mkexpr(f))));
   12613                      assign(t7, mkWidenFrom32(Ity_I64, unop(Iop_64to32,
   12614                                 unop(Iop_ReinterpF64asI64, mkexpr(t4))), True));
   12615 
   12616                      putFReg(fd, unop(Iop_ReinterpI64asF64, mkexpr(t7)));
   12617                   } else
   12618                      putFReg(fd, binop(Iop_F64toF32, get_IR_roundingmode(),
   12619                                        mkexpr(t4)));
   12620 
   12621                   break;
   12622                case 0x11:  /* D */
   12623                   DIP("movz.d f%u, f%u, r%u", fd, fs, rt);
   12624                   t3 = newTemp(Ity_I1);
   12625                   t4 = newTemp(Ity_F64);
   12626                   if (mode64)
   12627                      assign(t3, binop(Iop_CmpEQ64, mkU64(0), getIReg(rt)));
   12628                   else
   12629                      assign(t3, binop(Iop_CmpEQ32, mkU32(0), getIReg(rt)));
   12630 
   12631                   putDReg(fd, IRExpr_ITE(mkexpr(t3), getDReg(fs), getDReg(fd)));
   12632                   break;
   12633                default:
   12634                   goto decode_failure;
   12635                }
   12636                break;  /* MOVZ.fmt */
   12637 
   12638             case 0x11:  /* MOVT.fmt */
   12639                if (tf == 1) {
   12640                   UInt mov_cc = get_mov_cc(cins);
   12641                   switch (fmt) {  /* MOVCF = 010001 */
   12642                   case 0x11:  /* D */
   12643                      DIP("movt.d f%u, f%u, %u", fd, fs, mov_cc);
   12644                      t1 = newTemp(Ity_I1);
   12645                      t2 = newTemp(Ity_I32);
   12646                      t3 = newTemp(Ity_I1);
   12647                      t4 = newTemp(Ity_F64);
   12648 
   12649                      assign(t1, binop(Iop_CmpEQ32, mkU32(0), mkU32(mov_cc)));
   12650                      assign(t2, IRExpr_ITE(mkexpr(t1),
   12651                                            binop(Iop_And32,
   12652                                                  binop(Iop_Shr32, getFCSR(),
   12653                                                        mkU8(23)),
   12654                                                  mkU32(0x1)),
   12655                                            binop(Iop_And32,
   12656                                                  binop(Iop_Shr32, getFCSR(),
   12657                                                        mkU8(24 + mov_cc)),
   12658                                                  mkU32(0x1))
   12659                                            ));
   12660 
   12661                      assign(t3, binop(Iop_CmpEQ32, mkU32(1), mkexpr(t2)));
   12662                      assign(t4, IRExpr_ITE(mkexpr(t3),
   12663                                            getDReg(fs), getDReg(fd)));
   12664                      putDReg(fd, mkexpr(t4));
   12665                      break;
   12666                   case 0x10:  /* S */
   12667                      DIP("movt.s f%u, f%u, %u", fd, fs, mov_cc);
   12668                      t1 = newTemp(Ity_I1);
   12669                      t2 = newTemp(Ity_I32);
   12670                      t3 = newTemp(Ity_I1);
   12671                      t4 = newTemp(Ity_F64);
   12672                      t5 = newTemp(Ity_F64);
   12673                      t6 = newTemp(Ity_F64);
   12674                      t7 = newTemp(Ity_I64);
   12675 
   12676                      if (fp_mode64) {
   12677                         assign(t5, getFReg(fs));
   12678                         assign(t6, getFReg(fd));
   12679                      } else {
   12680                         assign(t5, unop(Iop_F32toF64, getFReg(fs)));
   12681                         assign(t6, unop(Iop_F32toF64, getFReg(fd)));
   12682                      }
   12683 
   12684                      assign(t1, binop(Iop_CmpEQ32, mkU32(0), mkU32(mov_cc)));
   12685                      assign(t2, IRExpr_ITE(mkexpr(t1),
   12686                                            binop(Iop_And32,
   12687                                                  binop(Iop_Shr32, getFCSR(),
   12688                                                        mkU8(23)),
   12689                                                  mkU32(0x1)),
   12690                                            binop(Iop_And32,
   12691                                                  binop(Iop_Shr32, getFCSR(),
   12692                                                        mkU8(24 + mov_cc)),
   12693                                                  mkU32(0x1))
   12694                                            ));
   12695 
   12696                      assign(t3, binop(Iop_CmpEQ32, mkU32(1), mkexpr(t2)));
   12697                      assign(t4, IRExpr_ITE(mkexpr(t3),
   12698                                            mkexpr(t5), mkexpr(t6)));
   12699 
   12700                      if (fp_mode64) {
   12701                         IRTemp f = newTemp(Ity_F64);
   12702                         IRTemp fd_hi = newTemp(Ity_I32);
   12703                         assign(f, getFReg(fd));
   12704                         assign(fd_hi, unop(Iop_64HIto32,
   12705                                       unop(Iop_ReinterpF64asI64, mkexpr(f))));
   12706                         assign(t7, mkWidenFrom32(Ity_I64, unop(Iop_64to32,
   12707                                       unop(Iop_ReinterpF64asI64, mkexpr(t4))),
   12708                                       True));
   12709 
   12710                         putFReg(fd, unop(Iop_ReinterpI64asF64, mkexpr(t7)));
   12711                      } else
   12712                         putFReg(fd, binop(Iop_F64toF32, get_IR_roundingmode(),
   12713                                           mkexpr(t4)));
   12714                      break;
   12715                   default:
   12716                      goto decode_failure;
   12717                   }
   12718                } else if (tf == 0)  /* movf.fmt */
   12719                {
   12720                   UInt mov_cc = get_mov_cc(cins);
   12721                   switch (fmt)  /* MOVCF = 010001 */
   12722                   {
   12723                   case 0x11:  /* D */
   12724                      DIP("movf.d f%u, f%u, %u", fd, fs, mov_cc);
   12725                      t1 = newTemp(Ity_I1);
   12726                      t2 = newTemp(Ity_I32);
   12727                      t3 = newTemp(Ity_I1);
   12728                      t4 = newTemp(Ity_F64);
   12729 
   12730                      assign(t1, binop(Iop_CmpEQ32, mkU32(0), mkU32(mov_cc)));
   12731                      assign(t2, IRExpr_ITE(mkexpr(t1),
   12732                                            binop(Iop_And32,
   12733                                                  binop(Iop_Shr32, getFCSR(),
   12734                                                        mkU8(23)),
   12735                                                  mkU32(0x1)),
   12736                                            binop(Iop_And32,
   12737                                                  binop(Iop_Shr32, getFCSR(),
   12738                                                        mkU8(24 + mov_cc)),
   12739                                                  mkU32(0x1))
   12740                                            ));
   12741 
   12742                      assign(t3, binop(Iop_CmpEQ32, mkU32(0), mkexpr(t2)));
   12743                      assign(t4, IRExpr_ITE(mkexpr(t3),
   12744                                            getDReg(fs), getDReg(fd)));
   12745                      putDReg(fd, mkexpr(t4));
   12746                      break;
   12747                   case 0x10:  /* S */
   12748                      DIP("movf.s f%u, f%u, %u", fd, fs, mov_cc);
   12749                      t1 = newTemp(Ity_I1);
   12750                      t2 = newTemp(Ity_I32);
   12751                      t3 = newTemp(Ity_I1);
   12752                      t4 = newTemp(Ity_F64);
   12753                      t5 = newTemp(Ity_F64);
   12754                      t6 = newTemp(Ity_F64);
   12755 
   12756                      if (fp_mode64) {
   12757                         assign(t5, getFReg(fs));
   12758                         assign(t6, getFReg(fd));
   12759                      } else {
   12760                         assign(t5, unop(Iop_F32toF64, getFReg(fs)));
   12761                         assign(t6, unop(Iop_F32toF64, getFReg(fd)));
   12762                      }
   12763 
   12764                      assign(t1, binop(Iop_CmpEQ32, mkU32(0), mkU32(mov_cc)));
   12765                      assign(t2, IRExpr_ITE(mkexpr(t1),
   12766                                            binop(Iop_And32,
   12767                                                  binop(Iop_Shr32, getFCSR(),
   12768                                                        mkU8(23)),
   12769                                                  mkU32(0x1)),
   12770                                            binop(Iop_And32,
   12771                                                  binop(Iop_Shr32, getFCSR(),
   12772                                                        mkU8(24 + mov_cc)),
   12773                                                  mkU32(0x1))
   12774                                            ));
   12775 
   12776                      assign(t3, binop(Iop_CmpEQ32, mkU32(0), mkexpr(t2)));
   12777                      assign(t4, IRExpr_ITE(mkexpr(t3),
   12778                                            mkexpr(t5), mkexpr(t6)));
   12779 
   12780                      if (fp_mode64) {
   12781                         IRTemp f = newTemp(Ity_F64);
   12782                         IRTemp fd_hi = newTemp(Ity_I32);
   12783                         t7 = newTemp(Ity_I64);
   12784                         assign(f, getFReg(fd));
   12785                         assign(fd_hi, unop(Iop_64HIto32,
   12786                                       unop(Iop_ReinterpF64asI64, mkexpr(f))));
   12787                         assign(t7, mkWidenFrom32(Ity_I64, unop(Iop_64to32,
   12788                                    unop(Iop_ReinterpF64asI64, mkexpr(t4))),
   12789                                    True));
   12790 
   12791                         putFReg(fd, unop(Iop_ReinterpI64asF64, mkexpr(t7)));
   12792                      } else
   12793                         putFReg(fd, binop(Iop_F64toF32, get_IR_roundingmode(),
   12794                                           mkexpr(t4)));
   12795                      break;
   12796                   default:
   12797                      goto decode_failure;
   12798                   }
   12799                }
   12800 
   12801                break;  /* MOVT.fmt */
   12802 
   12803             case 0x0:  /* add.fmt */
   12804                switch (fmt) {
   12805                case 0x10: {  /* S */
   12806                   DIP("add.s f%u, f%u, f%u", fd, fs, ft);
   12807                   calculateFCSR(fs, ft, ADDS, True, 2);
   12808                   IRExpr *rm = get_IR_roundingmode();
   12809                   putFReg(fd, mkWidenFromF32(tyF, triop(Iop_AddF32, rm,
   12810                               getLoFromF64(tyF, getFReg(fs)),
   12811                               getLoFromF64(tyF, getFReg(ft)))));
   12812                   break;
   12813                }
   12814                case 0x11: {  /* D */
   12815                   DIP("add.d f%u, f%u, f%u", fd, fs, ft);
   12816                   calculateFCSR(fs, ft, ADDD, False, 2);
   12817                   IRExpr *rm = get_IR_roundingmode();
   12818                   putDReg(fd, triop(Iop_AddF64, rm, getDReg(fs), getDReg(ft)));
   12819                   break;
   12820                }
   12821 
   12822                case 0x4:  /* MTC1 (Move Word to Floating Point) */
   12823                   DIP("mtc1 r%u, f%u", rt, fs);
   12824                   if (fp_mode64) {
   12825                      t0 = newTemp(Ity_I32);
   12826                      t1 = newTemp(Ity_F32);
   12827                      assign(t0, mkNarrowTo32(ty, getIReg(rt)));
   12828                      assign(t1, unop(Iop_ReinterpI32asF32, mkexpr(t0)));
   12829 
   12830                      putFReg(fs, mkWidenFromF32(tyF, mkexpr(t1)));
   12831                   } else
   12832                      putFReg(fs, unop(Iop_ReinterpI32asF32, getIReg(rt)));
   12833                   break;
   12834 
   12835                case 0x5:  /* Doubleword Move to Floating Point DMTC1; MIPS64 */
   12836                   DIP("dmtc1 r%u, f%u", rt, fs);
   12837                   vassert(mode64);
   12838                   putFReg(fs, unop(Iop_ReinterpI64asF64, getIReg(rt)));
   12839                   break;
   12840 
   12841                case 0x0:  /* MFC1 */
   12842                   DIP("mfc1 r%u, f%u", rt, fs);
   12843                   if (fp_mode64) {
   12844                      t0 = newTemp(Ity_I64);
   12845                      t1 = newTemp(Ity_I32);
   12846                      assign(t0, unop(Iop_ReinterpF64asI64, getFReg(fs)));
   12847                      assign(t1, unop(Iop_64to32, mkexpr(t0)));
   12848                      putIReg(rt, mkWidenFrom32(ty, mkexpr(t1), True));
   12849                   } else
   12850                      putIReg(rt, unop(Iop_ReinterpF32asI32, getFReg(fs)));
   12851                   break;
   12852 
   12853                case 0x1:  /* Doubleword Move from Floating Point DMFC1;
   12854                              MIPS64 */
   12855                   DIP("dmfc1 r%u, f%u", rt, fs);
   12856                   putIReg(rt, unop(Iop_ReinterpF64asI64, getFReg(fs)));
   12857                   break;
   12858 
   12859                case 0x6:  /* CTC1 */
   12860                   DIP("ctc1 r%u, f%u", rt, fs);
   12861                   t0 = newTemp(Ity_I32);
   12862                   t1 = newTemp(Ity_I32);
   12863                   t2 = newTemp(Ity_I32);
   12864                   t3 = newTemp(Ity_I32);
   12865                   t4 = newTemp(Ity_I32);
   12866                   t5 = newTemp(Ity_I32);
   12867                   t6 = newTemp(Ity_I32);
   12868                   assign(t0, mkNarrowTo32(ty, getIReg(rt)));
   12869                   if (fs == 25) {  /* FCCR */
   12870                      assign(t1, binop(Iop_Shl32, binop(Iop_And32, mkexpr(t0),
   12871                                       mkU32(0x000000FE)), mkU8(24)));
   12872                      assign(t2, binop(Iop_And32, mkexpr(t0),
   12873                                       mkU32(0x01000000)));
   12874                      assign(t3, binop(Iop_Shl32, binop(Iop_And32, mkexpr(t0),
   12875                                       mkU32(0x00000001)), mkU8(23)));
   12876                      assign(t4, binop(Iop_And32, mkexpr(t0),
   12877                                       mkU32(0x007FFFFF)));
   12878                      putFCSR(binop(Iop_Or32, binop(Iop_Or32, mkexpr(t1),
   12879                                    mkexpr(t2)), binop(Iop_Or32, mkexpr(t3),
   12880                                    mkexpr(t4))));
   12881                   } else if (fs == 26) {  /* FEXR */
   12882                      assign(t1, binop(Iop_And32, getFCSR(), mkU32(0xFFFC0000)));
   12883                      assign(t2, binop(Iop_And32, mkexpr(t0),
   12884                                       mkU32(0x0003F000)));
   12885                      assign(t3, binop(Iop_And32, getFCSR(), mkU32(0x00000F80)));
   12886                      assign(t4, binop(Iop_And32, mkexpr(t0),
   12887                                       mkU32(0x0000007C)));
   12888                      assign(t5, binop(Iop_And32, getFCSR(), mkU32(0x00000003)));
   12889                      putFCSR(binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Or32,
   12890                                    mkexpr(t1), mkexpr(t2)), binop(Iop_Or32,
   12891                                    mkexpr(t3), mkexpr(t4))), mkexpr(t5)));
   12892                   } else if (fs == 28) {
   12893                      assign(t1, binop(Iop_And32, getFCSR(), mkU32(0xFE000000)));
   12894                      assign(t2, binop(Iop_Shl32, binop(Iop_And32, mkexpr(t0),
   12895                                 mkU32(0x00000002)), mkU8(22)));
   12896                      assign(t3, binop(Iop_And32, getFCSR(), mkU32(0x00FFF000)));
   12897                      assign(t4, binop(Iop_And32, mkexpr(t0),
   12898                                 mkU32(0x00000F80)));
   12899                      assign(t5, binop(Iop_And32, getFCSR(), mkU32(0x0000007C)));
   12900                      assign(t6, binop(Iop_And32, mkexpr(t0),
   12901                                 mkU32(0x00000003)));
   12902                      putFCSR(binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Or32,
   12903                                    mkexpr(t1), mkexpr(t2)), binop(Iop_Or32,
   12904                                    mkexpr(t3), mkexpr(t4))), binop(Iop_Or32,
   12905                                    mkexpr(t5), mkexpr(t6))));
   12906                   } else if (fs == 31) {
   12907                      putFCSR(mkexpr(t0));
   12908                   }
   12909                   break;
   12910                case 0x2:  /* CFC1 */
   12911                   DIP("cfc1 r%u, f%u", rt, fs);
   12912                   t0 = newTemp(Ity_I32);
   12913                   t1 = newTemp(Ity_I32);
   12914                   t2 = newTemp(Ity_I32);
   12915                   t3 = newTemp(Ity_I32);
   12916                   t4 = newTemp(Ity_I32);
   12917                   t5 = newTemp(Ity_I32);
   12918                   t6 = newTemp(Ity_I32);
   12919                   assign(t0, getFCSR());
   12920                   if (fs == 0) {
   12921                      putIReg(rt, mkWidenFrom32(ty,
   12922                              IRExpr_Get(offsetof(VexGuestMIPS32State,
   12923                                                  guest_FIR),
   12924                                        Ity_I32),
   12925                              False));
   12926                   } else if (fs == 25) {
   12927                      assign(t1, mkU32(0x000000FF));
   12928                      assign(t2, binop(Iop_Shr32, binop(Iop_And32, mkexpr(t0),
   12929                                       mkU32(0xFE000000)), mkU8(25)));
   12930                      assign(t3, binop(Iop_Shr32, binop(Iop_And32, mkexpr(t0),
   12931                                       mkU32(0x00800000)), mkU8(23)));
   12932                      putIReg(rt, mkWidenFrom32(ty, binop(Iop_Or32,
   12933                                  binop(Iop_Or32, mkexpr(t1), mkexpr(t2)),
   12934                                  mkexpr(t3)), False));
   12935                   } else if (fs == 26) {
   12936                      assign(t1, mkU32(0xFFFFF07C));
   12937                      assign(t2, binop(Iop_And32, mkexpr(t0),
   12938                                 mkU32(0x0003F000)));
   12939                      assign(t3, binop(Iop_And32, mkexpr(t0),
   12940                                       mkU32(0x0000007C)));
   12941                      putIReg(rt, mkWidenFrom32(ty, binop(Iop_Or32,
   12942                                  binop(Iop_Or32, mkexpr(t1), mkexpr(t2)),
   12943                                  mkexpr(t3)), False));
   12944                   } else if (fs == 28) {
   12945                      assign(t1, mkU32(0x00000F87));
   12946                      assign(t2, binop(Iop_And32, mkexpr(t0),
   12947                                       mkU32(0x00000F83)));
   12948                      assign(t3, binop(Iop_Shr32, binop(Iop_And32, mkexpr(t0),
   12949                                       mkU32(0x01000000)), mkU8(22)));
   12950                      putIReg(rt, mkWidenFrom32(ty, binop(Iop_Or32,
   12951                                  binop(Iop_Or32, mkexpr(t1), mkexpr(t2)),
   12952                                  mkexpr(t3)), False));
   12953                   } else if (fs == 31) {
   12954                      putIReg(rt, mkWidenFrom32(ty, getFCSR(), False));
   12955                   }
   12956                   break;
   12957                default:
   12958                   goto decode_failure;
   12959                }
   12960                break;
   12961 
   12962             case 0x21:  /* CVT.D */
   12963                switch (fmt) {
   12964                   case 0x10:  /* S */
   12965                      DIP("cvt.d.s f%u, f%u", fd, fs);
   12966                      calculateFCSR(fs, 0, CVTDS, True, 1);
   12967                      if (fp_mode64) {
   12968                         t0 = newTemp(Ity_I64);
   12969                         t1 = newTemp(Ity_I32);
   12970                         t3 = newTemp(Ity_F32);
   12971                         t4 = newTemp(Ity_F32);
   12972                         /* get lo half of FPR */
   12973                         assign(t0, unop(Iop_ReinterpF64asI64, getFReg(fs)));
   12974 
   12975                         assign(t1, unop(Iop_64to32, mkexpr(t0)));
   12976 
   12977                         assign(t3, unop(Iop_ReinterpI32asF32, mkexpr(t1)));
   12978 
   12979                         putFReg(fd, unop(Iop_F32toF64, mkexpr(t3)));
   12980                      } else
   12981                         putDReg(fd, unop(Iop_F32toF64, getFReg(fs)));
   12982                      break;
   12983 
   12984                   case 0x14:
   12985                      DIP("cvt.d.w %u, %u", fd, fs);
   12986                      calculateFCSR(fs, 0, CVTDW, True, 1);
   12987                      if (fp_mode64) {
   12988                         t0 = newTemp(Ity_I64);
   12989                         t1 = newTemp(Ity_I32);
   12990                         t3 = newTemp(Ity_F32);
   12991                         t4 = newTemp(Ity_F32);
   12992                         /* get lo half of FPR */
   12993                         assign(t0, unop(Iop_ReinterpF64asI64, getFReg(fs)));
   12994 
   12995                         assign(t1, unop(Iop_64to32, mkexpr(t0)));
   12996                         putDReg(fd,unop(Iop_I32StoF64, mkexpr(t1)));
   12997                         break;
   12998                      } else {
   12999                         t0 = newTemp(Ity_I32);
   13000                         assign(t0, unop(Iop_ReinterpF32asI32, getFReg(fs)));
   13001                         putDReg(fd, unop(Iop_I32StoF64, mkexpr(t0)));
   13002                         break;
   13003                      }
   13004 
   13005                   case 0x15: {  /* L */
   13006                      if (fp_mode64) {
   13007                         DIP("cvt.d.l %u, %u", fd, fs);
   13008                         calculateFCSR(fs, 0, CVTDL, False, 1);
   13009                         t0 = newTemp(Ity_I64);
   13010                         assign(t0, unop(Iop_ReinterpF64asI64, getFReg(fs)));
   13011 
   13012                         putFReg(fd, binop(Iop_I64StoF64,
   13013                                           get_IR_roundingmode(), mkexpr(t0)));
   13014                         break;
   13015                      } else
   13016                         goto decode_failure;
   13017                   }
   13018                   default:
   13019                      goto decode_failure;
   13020                }
   13021                break;  /* CVT.D */
   13022 
   13023             case 0x20:  /* cvt.s */
   13024                switch (fmt) {
   13025                   case 0x14:  /* W */
   13026                      DIP("cvt.s.w %u, %u", fd, fs);
   13027                      calculateFCSR(fs, 0, CVTSW, True, 1);
   13028                      if (fp_mode64) {
   13029                         t0 = newTemp(Ity_I64);
   13030                         t1 = newTemp(Ity_I32);
   13031                         t3 = newTemp(Ity_F32);
   13032                         t4 = newTemp(Ity_F32);
   13033                         /* get lo half of FPR */
   13034                         assign(t0, unop(Iop_ReinterpF64asI64, getFReg(fs)));
   13035 
   13036                         assign(t1, unop(Iop_64to32, mkexpr(t0)));
   13037                         putFReg(fd, mkWidenFromF32(tyF, binop(Iop_I32StoF32,
   13038                                     get_IR_roundingmode(), mkexpr(t1))));
   13039                      } else {
   13040                         t0 = newTemp(Ity_I32);
   13041                         assign(t0, unop(Iop_ReinterpF32asI32, getFReg(fs)));
   13042                         putFReg(fd, binop(Iop_I32StoF32, get_IR_roundingmode(),
   13043                                     mkexpr(t0)));
   13044                      }
   13045                      break;
   13046 
   13047                   case 0x11:  /* D */
   13048                      DIP("cvt.s.d %u, %u", fd, fs);
   13049                      calculateFCSR(fs, 0, CVTSD, False, 1);
   13050                      t0 = newTemp(Ity_F32);
   13051                      assign(t0, binop(Iop_F64toF32, get_IR_roundingmode(),
   13052                                       getDReg(fs)));
   13053                      putFReg(fd, mkWidenFromF32(tyF, mkexpr(t0)));
   13054                      break;
   13055 
   13056                   case 0x15:  /* L */
   13057                      DIP("cvt.s.l %u, %u", fd, fs);
   13058                      calculateFCSR(fs, 0, CVTSL, False, 1);
   13059                      t0 = newTemp(Ity_I64);
   13060                      assign(t0, unop(Iop_ReinterpF64asI64, getFReg(fs)));
   13061 
   13062                      putFReg(fd, mkWidenFromF32(tyF, binop(Iop_I64StoF32,
   13063                                  get_IR_roundingmode(), mkexpr(t0))));
   13064                      break;
   13065 
   13066                   default:
   13067                      goto decode_failure;
   13068                }
   13069                break;  /* cvt.s */
   13070 
   13071             case 0x24:  /* cvt.w */
   13072                switch (fmt) {
   13073                case 0x10:  /* S */
   13074                   DIP("cvt.w.s %u, %u", fd, fs);
   13075                   calculateFCSR(fs, 0, CVTWS, True, 1);
   13076                   putFReg(fd,
   13077                           mkWidenFromF32(tyF,
   13078                                          binop(Iop_RoundF32toInt,
   13079                                                get_IR_roundingmode(),
   13080                                                getLoFromF64(tyF, getFReg(fs))))
   13081                          );
   13082                   break;
   13083 
   13084                case 0x11:
   13085                   DIP("cvt.w.d %u, %u", fd, fs);
   13086                   calculateFCSR(fs, 0, CVTWD, False, 1);
   13087                   t0 = newTemp(Ity_I32);
   13088                   t1 = newTemp(Ity_F32);
   13089                   assign(t0, binop(Iop_F64toI32S, get_IR_roundingmode(),
   13090                                    getDReg(fs)));
   13091                   assign(t1, unop(Iop_ReinterpI32asF32, mkexpr(t0)));
   13092                   putFReg(fd, mkWidenFromF32(tyF, mkexpr(t1)));
   13093                   break;
   13094 
   13095                default:
   13096                   goto decode_failure;
   13097 
   13098                }
   13099                break;
   13100 
   13101             case 0x25:  /* cvt.l */
   13102                switch (fmt) {
   13103                   case 0x10:  /* S */
   13104                      DIP("cvt.l.s %u, %u", fd, fs);
   13105                      if (fp_mode64) {
   13106                         calculateFCSR(fs, 0, CVTLS, True, 1);
   13107                         t0 = newTemp(Ity_I64);
   13108 
   13109                         assign(t0, binop(Iop_F32toI64S, get_IR_roundingmode(),
   13110                                          getLoFromF64(tyF, getFReg(fs))));
   13111 
   13112                         putDReg(fd, unop(Iop_ReinterpI64asF64, mkexpr(t0)));
   13113                      } else {
   13114                         ILLEGAL_INSTRUCTON;
   13115                      }
   13116                      break;
   13117 
   13118                   case 0x11: {  /* D */
   13119                      DIP("cvt.l.d %u, %u", fd, fs);
   13120                      if (fp_mode64) {
   13121                         calculateFCSR(fs, 0, CVTLD, False, 1);
   13122                         putDReg(fd, binop(Iop_RoundF64toInt,
   13123                                 get_IR_roundingmode(), getDReg(fs)));
   13124                      } else {
   13125                         ILLEGAL_INSTRUCTON;
   13126                      }
   13127                      break;
   13128                   }
   13129 
   13130                   default:
   13131                      goto decode_failure;
   13132                }
   13133                break;
   13134 
   13135             case 0x0B:  /* FLOOR.L.fmt */
   13136                switch (fmt) {
   13137                   case 0x10:  /* S */
   13138                      DIP("floor.l.s %u, %u", fd, fs);
   13139                      if (fp_mode64) {
   13140                         calculateFCSR(fs, 0, FLOORLS, True, 1);
   13141                         t0 = newTemp(Ity_I64);
   13142 
   13143                         assign(t0, binop(Iop_F32toI64S, mkU32(0x1),
   13144                                          getLoFromF64(tyF, getFReg(fs))));
   13145 
   13146                         putDReg(fd, unop(Iop_ReinterpI64asF64, mkexpr(t0)));
   13147                      } else {
   13148                         ILLEGAL_INSTRUCTON;
   13149                      }
   13150                      break;
   13151 
   13152                   case 0x11:  /* D */
   13153                      DIP("floor.l.d %u, %u", fd, fs);
   13154                      if (fp_mode64) {
   13155                         calculateFCSR(fs, 0, FLOORLD, False, 1);
   13156                         putDReg(fd, binop(Iop_RoundF64toInt, mkU32(0x1),
   13157                                           getDReg(fs)));
   13158                      } else {
   13159                         ILLEGAL_INSTRUCTON;
   13160                      }
   13161                      break;
   13162                   default:
   13163                      goto decode_failure;
   13164                }
   13165                break;
   13166 
   13167             case 0x0C:  /* ROUND.W.fmt */
   13168                switch (fmt) {
   13169                   case 0x10:  /* S */
   13170                      DIP("round.w.s f%u, f%u", fd, fs);
   13171                      calculateFCSR(fs, 0, ROUNDWS, True, 1);
   13172                      if (fp_mode64) {
   13173                         t0 = newTemp(Ity_I64);
   13174                         t1 = newTemp(Ity_I32);
   13175                         t3 = newTemp(Ity_F32);
   13176                         t4 = newTemp(Ity_F32);
   13177                         /* get lo half of FPR */
   13178                         assign(t0, unop(Iop_ReinterpF64asI64, getFReg(fs)));
   13179 
   13180                         assign(t1, unop(Iop_64to32, mkexpr(t0)));
   13181 
   13182                         assign(t3, unop(Iop_ReinterpI32asF32, mkexpr(t1)));
   13183 
   13184                         assign(t4, binop(Iop_RoundF32toInt, mkU32(0x0),
   13185                                          mkexpr(t3)));
   13186 
   13187                         putFReg(fd, mkWidenFromF32(tyF, mkexpr(t4)));
   13188                      } else
   13189                         putFReg(fd, binop(Iop_RoundF32toInt, mkU32(0x0),
   13190                                           getFReg(fs)));
   13191                      break;
   13192 
   13193                   case 0x11:  /* D */
   13194                      DIP("round.w.d f%u, f%u", fd, fs);
   13195                      calculateFCSR(fs, 0, ROUNDWD, False, 1);
   13196                      if (fp_mode64) {
   13197                         t0 = newTemp(Ity_I32);
   13198                         assign(t0, binop(Iop_F64toI32S, mkU32(0x0),
   13199                                          getDReg(fs)));
   13200                         putFReg(fd, mkWidenFromF32(tyF,
   13201                                     unop(Iop_ReinterpI32asF32, mkexpr(t0))));
   13202                      } else {
   13203                         t0 = newTemp(Ity_I32);
   13204 
   13205                         assign(t0, binop(Iop_F64toI32S, mkU32(0x0),
   13206                                          getDReg(fs)));
   13207 
   13208                         putFReg(fd, unop(Iop_ReinterpI32asF32, mkexpr(t0)));
   13209                      }
   13210                      break;
   13211                   default:
   13212                      goto decode_failure;
   13213 
   13214                   }
   13215                   break;  /* ROUND.W.fmt */
   13216 
   13217             case 0x0F:  /* FLOOR.W.fmt */
   13218                switch (fmt) {
   13219                   case 0x10:  /* S */
   13220                      DIP("floor.w.s f%u, f%u", fd, fs);
   13221                      calculateFCSR(fs, 0, FLOORWS, True, 1);
   13222                      if (fp_mode64) {
   13223                         t0 = newTemp(Ity_I64);
   13224                         t1 = newTemp(Ity_I32);
   13225                         t3 = newTemp(Ity_F32);
   13226                         t4 = newTemp(Ity_F32);
   13227                         /* get lo half of FPR */
   13228                         assign(t0, unop(Iop_ReinterpF64asI64, getFReg(fs)));
   13229 
   13230                         assign(t1, unop(Iop_64to32, mkexpr(t0)));
   13231 
   13232                         assign(t3, unop(Iop_ReinterpI32asF32, mkexpr(t1)));
   13233 
   13234                         assign(t4, binop(Iop_RoundF32toInt, mkU32(0x1),
   13235                                          mkexpr(t3)));
   13236 
   13237                         putFReg(fd, mkWidenFromF32(tyF, mkexpr(t4)));
   13238                      } else
   13239                         putFReg(fd, binop(Iop_RoundF32toInt, mkU32(0x1),
   13240                                          getFReg(fs)));
   13241                      break;
   13242 
   13243                   case 0x11:  /* D */
   13244                      DIP("floor.w.d f%u, f%u", fd, fs);
   13245                      calculateFCSR(fs, 0, FLOORWD, False, 1);
   13246                      if (fp_mode64) {
   13247                         t0 = newTemp(Ity_I32);
   13248                         assign(t0, binop(Iop_F64toI32S, mkU32(0x1),
   13249                                          getDReg(fs)));
   13250                         putFReg(fd, mkWidenFromF32(tyF,
   13251                                     unop(Iop_ReinterpI32asF32, mkexpr(t0))));
   13252                         break;
   13253                      } else {
   13254                         t0 = newTemp(Ity_I32);
   13255 
   13256                         assign(t0, binop(Iop_F64toI32S, mkU32(0x1),
   13257                                          getDReg(fs)));
   13258 
   13259                         putFReg(fd, unop(Iop_ReinterpI32asF32, mkexpr(t0)));
   13260                         break;
   13261                      }
   13262                   default:
   13263                      goto decode_failure;
   13264 
   13265                }
   13266                break;  /* FLOOR.W.fmt */
   13267 
   13268             case 0x0D:  /* TRUNC.W */
   13269                switch (fmt) {
   13270                   case 0x10:  /* S */
   13271                      DIP("trunc.w.s %u, %u", fd, fs);
   13272                      calculateFCSR(fs, 0, TRUNCWS, True, 1);
   13273                      if (fp_mode64) {
   13274                         t0 = newTemp(Ity_I64);
   13275                         t1 = newTemp(Ity_I32);
   13276                         t3 = newTemp(Ity_F32);
   13277                         t4 = newTemp(Ity_F32);
   13278                         /* get lo half of FPR */
   13279                         assign(t0, unop(Iop_ReinterpF64asI64, getFReg(fs)));
   13280 
   13281                         assign(t1, unop(Iop_64to32, mkexpr(t0)));
   13282 
   13283                         assign(t3, unop(Iop_ReinterpI32asF32, mkexpr(t1)));
   13284 
   13285                         assign(t4, binop(Iop_RoundF32toInt, mkU32(0x3),
   13286                                          mkexpr(t3)));
   13287 
   13288                         putFReg(fd, mkWidenFromF32(tyF, mkexpr(t4)));
   13289                      } else
   13290                         putFReg(fd, binop(Iop_RoundF32toInt, mkU32(0x3),
   13291                                        getFReg(fs)));
   13292                      break;
   13293                   case 0x11:  /* D */
   13294                      DIP("trunc.w.d %u, %u", fd, fs);
   13295                      calculateFCSR(fs, 0, TRUNCWD, False, 1);
   13296                      if (fp_mode64) {
   13297                         t0 = newTemp(Ity_I32);
   13298 
   13299                         assign(t0, binop(Iop_F64toI32S, mkU32(0x3),
   13300                                          getFReg(fs)));
   13301 
   13302                         putFReg(fd, mkWidenFromF32(tyF,
   13303                                     unop(Iop_ReinterpI32asF32, mkexpr(t0))));
   13304                      } else {
   13305                         t0 = newTemp(Ity_I32);
   13306 
   13307                         assign(t0, binop(Iop_F64toI32S, mkU32(0x3),
   13308                                          getDReg(fs)));
   13309 
   13310                         putFReg(fd, unop(Iop_ReinterpI32asF32, mkexpr(t0)));
   13311                      }
   13312                      break;
   13313                   default:
   13314                      goto decode_failure;
   13315 
   13316                }
   13317                break;
   13318 
   13319             case 0x0E:  /* CEIL.W.fmt */
   13320                switch (fmt) {
   13321                   case 0x10:  /* S */
   13322                      DIP("ceil.w.s %u, %u", fd, fs);
   13323                      calculateFCSR(fs, 0, CEILWS, True, 1);
   13324                      if (fp_mode64) {
   13325                         t0 = newTemp(Ity_I64);
   13326                         t1 = newTemp(Ity_I32);
   13327                         t3 = newTemp(Ity_F32);
   13328                         t4 = newTemp(Ity_F32);
   13329                         /* get lo half of FPR */
   13330                         assign(t0, unop(Iop_ReinterpF64asI64, getFReg(fs)));
   13331 
   13332                         assign(t1, unop(Iop_64to32, mkexpr(t0)));
   13333 
   13334                         assign(t3, unop(Iop_ReinterpI32asF32, mkexpr(t1)));
   13335 
   13336                         assign(t4, binop(Iop_RoundF32toInt, mkU32(0x2),
   13337                                          mkexpr(t3)));
   13338 
   13339                         putFReg(fd, mkWidenFromF32(tyF, mkexpr(t4)));
   13340                      } else
   13341                         putFReg(fd, binop(Iop_RoundF32toInt, mkU32(0x2),
   13342                                           getFReg(fs)));
   13343                      break;
   13344 
   13345                   case 0x11:  /* D */
   13346                      DIP("ceil.w.d %u, %u", fd, fs);
   13347                      calculateFCSR(fs, 0, CEILWD, False, 1);
   13348                      if (!fp_mode64) {
   13349                         t0 = newTemp(Ity_I32);
   13350                         assign(t0, binop(Iop_F64toI32S, mkU32(0x2),
   13351                                          getDReg(fs)));
   13352                         putFReg(fd, unop(Iop_ReinterpI32asF32, mkexpr(t0)));
   13353                      } else {
   13354                         t0 = newTemp(Ity_I32);
   13355                         assign(t0, binop(Iop_F64toI32S, mkU32(0x2),
   13356                                          getDReg(fs)));
   13357                         putFReg(fd, mkWidenFromF32(tyF,
   13358                                     unop(Iop_ReinterpI32asF32, mkexpr(t0))));
   13359                      }
   13360                      break;
   13361                   default:
   13362                      goto decode_failure;
   13363 
   13364                }
   13365                break;
   13366 
   13367             case 0x0A:  /* CEIL.L.fmt */
   13368                switch (fmt) {
   13369                   case 0x10:  /* S */
   13370                      DIP("ceil.l.s %u, %u", fd, fs);
   13371                      if (fp_mode64) {
   13372                         calculateFCSR(fs, 0, CEILLS, True, 1);
   13373                         t0 = newTemp(Ity_I64);
   13374 
   13375                         assign(t0, binop(Iop_F32toI64S, mkU32(0x2),
   13376                                    getLoFromF64(tyF, getFReg(fs))));
   13377 
   13378                         putFReg(fd, unop(Iop_ReinterpI64asF64, mkexpr(t0)));
   13379                      } else {
   13380                         ILLEGAL_INSTRUCTON;
   13381                      }
   13382                      break;
   13383 
   13384                   case 0x11:  /* D */
   13385                      DIP("ceil.l.d %u, %u", fd, fs);
   13386                      if (fp_mode64) {
   13387                         calculateFCSR(fs, 0, CEILLD, False, 1);
   13388                         putDReg(fd, binop(Iop_RoundF64toInt, mkU32(0x2),
   13389                                           getDReg(fs)));
   13390                      } else {
   13391                         ILLEGAL_INSTRUCTON;
   13392                      }
   13393                      break;
   13394 
   13395                   default:
   13396                      goto decode_failure;
   13397 
   13398                }
   13399                break;
   13400 
   13401             case 0x16:  /* RSQRT.fmt */
   13402                switch (fmt) {
   13403                   case 0x10: {  /* S */
   13404                      DIP("rsqrt.s %u, %u", fd, fs);
   13405                      IRExpr *rm = get_IR_roundingmode();
   13406                      putFReg(fd, mkWidenFromF32(tyF, triop(Iop_DivF32, rm,
   13407                                  unop(Iop_ReinterpI32asF32, mkU32(ONE_SINGLE)),
   13408                                  binop(Iop_SqrtF32, rm, getLoFromF64(tyF,
   13409                                  getFReg(fs))))));
   13410                      break;
   13411                   }
   13412                   case 0x11: {  /* D */
   13413                      DIP("rsqrt.d %u, %u", fd, fs);
   13414                      IRExpr *rm = get_IR_roundingmode();
   13415                      putDReg(fd, triop(Iop_DivF64, rm,
   13416                                  unop(Iop_ReinterpI64asF64,
   13417                                  mkU64(ONE_DOUBLE)),
   13418                                  binop(Iop_SqrtF64, rm, getDReg(fs))));
   13419                      break;
   13420                   }
   13421                   default:
   13422                      goto decode_failure;
   13423 
   13424                }
   13425                break;
   13426 
   13427             default:
   13428                if (dis_instr_CCondFmt(cins))
   13429                   break;
   13430                goto decode_failure;
   13431 
   13432             }
   13433 
   13434          }
   13435       }
   13436       break;  /* COP1 */
   13437    case 0x10:  /* COP0 */
   13438       if (rs == 0) {  /* MFC0 */
   13439          DIP("mfc0 r%u, r%u, %u", rt, rd, sel);
   13440          IRTemp   val  = newTemp(Ity_I32);
   13441          IRExpr** args = mkIRExprVec_3 (IRExpr_BBPTR(), mkU32(rd), mkU32(sel));
   13442          IRDirty *d = unsafeIRDirty_1_N(val,
   13443                                         0,
   13444                                         "mips32_dirtyhelper_mfc0",
   13445                                         &mips32_dirtyhelper_mfc0,
   13446                                         args);
   13447          stmt(IRStmt_Dirty(d));
   13448          putIReg(rt, mkexpr(val));
   13449       } else if (rs == 1) {
   13450          /* Doubleword Move from Coprocessor 0 - DMFC0; MIPS64 */
   13451          DIP("dmfc0 r%u, r%u, %u", rt, rd, sel);
   13452          IRTemp   val  = newTemp(Ity_I64);
   13453          IRExpr** args = mkIRExprVec_3 (IRExpr_BBPTR(), mkU64(rd), mkU64(sel));
   13454          IRDirty *d = unsafeIRDirty_1_N(val,
   13455                                         0,
   13456                                         "mips64_dirtyhelper_dmfc0",
   13457                                         &mips64_dirtyhelper_dmfc0,
   13458                                         args);
   13459          stmt(IRStmt_Dirty(d));
   13460          putDReg(rt, mkexpr(val));
   13461       } else
   13462          goto decode_failure;
   13463       break;
   13464 
   13465    case 0x31:  /* LWC1 */
   13466       /* Load Word to Floating Point - LWC1 (MIPS32) */
   13467       DIP("lwc1 f%u, %u(r%u)", ft, imm, rs);
   13468       if (fp_mode64) {
   13469          t1 = newTemp(Ity_F32);
   13470          t2 = newTemp(Ity_I64);
   13471          if (mode64) {
   13472             t0 = newTemp(Ity_I64);
   13473             /* new LO */
   13474             assign(t0, binop(Iop_Add64, getIReg(rs),
   13475                              mkU64(extend_s_16to64(imm))));
   13476          } else {
   13477             t0 = newTemp(Ity_I32);
   13478             /* new LO */
   13479             assign(t0, binop(Iop_Add32, getIReg(rs),
   13480                              mkU32(extend_s_16to32(imm))));
   13481          }
   13482          assign(t1, load(Ity_F32, mkexpr(t0)));
   13483          assign(t2, mkWidenFrom32(Ity_I64, unop(Iop_ReinterpF32asI32,
   13484                                                 mkexpr(t1)), True));
   13485          putDReg(ft, unop(Iop_ReinterpI64asF64, mkexpr(t2)));
   13486       } else {
   13487          t0 = newTemp(Ity_I32);
   13488          assign(t0, binop(Iop_Add32, getIReg(rs),
   13489                            mkU32(extend_s_16to32(imm))));
   13490          putFReg(ft, load(Ity_F32, mkexpr(t0)));
   13491       }
   13492       break;
   13493 
   13494    case 0x39:  /* SWC1 */
   13495       DIP("swc1 f%u, %u(r%u)", ft, imm, rs);
   13496       if (fp_mode64) {
   13497          t0 = newTemp(Ity_I64);
   13498          t2 = newTemp(Ity_I32);
   13499          LOAD_STORE_PATTERN;
   13500          assign(t0, unop(Iop_ReinterpF64asI64, getFReg(ft)));
   13501          assign(t2, unop(Iop_64to32, mkexpr(t0)));
   13502          store(mkexpr(t1), unop(Iop_ReinterpI32asF32, mkexpr(t2)));
   13503       } else {
   13504          LOAD_STORE_PATTERN;
   13505          store(mkexpr(t1), getFReg(ft));
   13506       }
   13507       break;
   13508 
   13509    case 0x33:  /* PREF */
   13510       DIP("pref");
   13511       break;
   13512 
   13513    case 0x35:
   13514       /* Load Doubleword to Floating Point - LDC1 (MIPS32) */
   13515       DIP("ldc1 f%u, %u(%u)", rt, imm, rs);
   13516       LOAD_STORE_PATTERN;
   13517       putDReg(ft, load(Ity_F64, mkexpr(t1)));
   13518       break;
   13519 
   13520    case 0x3D:
   13521       /* Store Doubleword from Floating Point - SDC1 */
   13522       DIP("sdc1 f%u, %u(%u)", ft, imm, rs);
   13523       LOAD_STORE_PATTERN;
   13524       store(mkexpr(t1), getDReg(ft));
   13525       break;
   13526 
   13527    case 0x23:  /* LW */
   13528       DIP("lw r%u, %u(r%u)", rt, imm, rs);
   13529       LOAD_STORE_PATTERN;
   13530       putIReg(rt, mkWidenFrom32(ty, load(Ity_I32, mkexpr(t1)), True));
   13531       break;
   13532 
   13533    case 0x20:  /* LB */
   13534       DIP("lb r%u, %u(r%u)", rt, imm, rs);
   13535       LOAD_STORE_PATTERN;
   13536       if (mode64)
   13537          putIReg(rt, unop(Iop_8Sto64, load(Ity_I8, mkexpr(t1))));
   13538       else
   13539          putIReg(rt, unop(Iop_8Sto32, load(Ity_I8, mkexpr(t1))));
   13540       break;
   13541 
   13542    case 0x24:  /* LBU */
   13543       DIP("lbu r%u, %u(r%u)", rt, imm, rs);
   13544       LOAD_STORE_PATTERN;
   13545       if (mode64)
   13546          putIReg(rt, unop(Iop_8Uto64, load(Ity_I8, mkexpr(t1))));
   13547       else
   13548          putIReg(rt, unop(Iop_8Uto32, load(Ity_I8, mkexpr(t1))));
   13549       break;
   13550 
   13551    case 0x21:  /* LH */
   13552       DIP("lh r%u, %u(r%u)", rt, imm, rs);
   13553       LOAD_STORE_PATTERN;
   13554       if (mode64)
   13555          putIReg(rt, unop(Iop_16Sto64, load(Ity_I16, mkexpr(t1))));
   13556       else
   13557          putIReg(rt, unop(Iop_16Sto32, load(Ity_I16, mkexpr(t1))));
   13558       break;
   13559 
   13560    case 0x25:  /* LHU */
   13561       DIP("lhu r%u, %u(r%u)", rt, imm, rs);
   13562       LOAD_STORE_PATTERN;
   13563       if (mode64)
   13564          putIReg(rt, unop(Iop_16Uto64, load(Ity_I16, mkexpr(t1))));
   13565       else
   13566          putIReg(rt, unop(Iop_16Uto32, load(Ity_I16, mkexpr(t1))));
   13567       break;
   13568 
   13569    case 0x0F:  /* LUI */
   13570       p = (imm << 16);
   13571       DIP("lui r%u, imm: 0x%x", rt, imm);
   13572       if (mode64)
   13573          putIReg(rt, mkU64(extend_s_32to64(p)));
   13574       else
   13575          putIReg(rt, mkU32(p));
   13576       break;
   13577 
   13578    case 0x13:  /* COP1X */
   13579       switch (function) {
   13580       case 0x0: {  /* LWXC1 */
   13581          /* Load Word  Indexed to Floating Point - LWXC1 (MIPS32r2) */
   13582          DIP("lwxc1 f%u, r%u(r%u)", fd, rt, rs);
   13583          if (fp_mode64) {
   13584             t0 = newTemp(Ity_I64);
   13585             t1 = newTemp(Ity_I32);
   13586             t3 = newTemp(Ity_F32);
   13587             t4 = newTemp(Ity_I64);
   13588 
   13589             t2 = newTemp(ty);
   13590             /* new LO */
   13591             assign(t2, binop(mode64 ? Iop_Add64 : Iop_Add32, getIReg(rs),
   13592                              getIReg(rt)));
   13593             assign(t3, load(Ity_F32, mkexpr(t2)));
   13594 
   13595             assign(t4, mkWidenFrom32(Ity_I64, unop(Iop_ReinterpF32asI32,
   13596                                                    mkexpr(t3)), True));
   13597 
   13598             putFReg(fd, unop(Iop_ReinterpI64asF64, mkexpr(t4)));
   13599          } else {
   13600             t0 = newTemp(Ity_I32);
   13601             assign(t0, binop(Iop_Add32, getIReg(rs), getIReg(rt)));
   13602             putFReg(fd, load(Ity_F32, mkexpr(t0)));
   13603          }
   13604          break;
   13605       }
   13606 
   13607       case 0x1: {  /* LDXC1 */
   13608          /* Load Doubleword  Indexed to Floating Point
   13609             LDXC1 (MIPS32r2 and MIPS64) */
   13610          if (fp_mode64) {
   13611             DIP("ldxc1 f%u, r%u(r%u)", fd, rt, rs);
   13612             t0 = newTemp(ty);
   13613             assign(t0, binop(mode64 ? Iop_Add64 : Iop_Add32, getIReg(rs),
   13614                              getIReg(rt)));
   13615             putFReg(fd, load(Ity_F64, mkexpr(t0)));
   13616             break;
   13617          } else {
   13618             t0 = newTemp(Ity_I32);
   13619             assign(t0, binop(Iop_Add32, getIReg(rs), getIReg(rt)));
   13620 
   13621             t1 = newTemp(Ity_I32);
   13622             assign(t1, binop(Iop_Add32, mkexpr(t0), mkU32(4)));
   13623 
   13624 #if defined (_MIPSEL)
   13625             putFReg(fd, load(Ity_F32, mkexpr(t0)));
   13626             putFReg(fd + 1, load(Ity_F32, mkexpr(t1)));
   13627 #elif defined (_MIPSEB)
   13628             putFReg(fd + 1, load(Ity_F32, mkexpr(t0)));
   13629             putFReg(fd, load(Ity_F32, mkexpr(t1)));
   13630 #endif
   13631             break;
   13632          }
   13633       }
   13634 
   13635       case 0x5:  /* Load Doubleword Indexed Unaligned to Floating Point - LUXC1;
   13636                     MIPS32r2 */
   13637          DIP("luxc1 f%u, r%u(r%u)", fd, rt, rs);
   13638          t0 = newTemp(Ity_I64);
   13639          t1 = newTemp(Ity_I64);
   13640          assign(t0, binop(Iop_Add64, getIReg(rs), getIReg(rt)));
   13641          assign(t1, binop(Iop_And64, mkexpr(t0),
   13642                                      mkU64(0xfffffffffffffff8ULL)));
   13643          putFReg(fd, load(Ity_F64, mkexpr(t1)));
   13644          break;
   13645 
   13646       case 0x8: {  /* Store Word Indexed from Floating Point - SWXC1 */
   13647          DIP("swxc1 f%u, r%u(r%u)", ft, rt, rs);
   13648          if (fp_mode64) {
   13649             t0 = newTemp(ty);
   13650             assign(t0, binop(mode64 ? Iop_Add64 : Iop_Add32, getIReg(rs),
   13651                              getIReg(rt)));
   13652             store(mkexpr(t0), getLoFromF64(tyF, getFReg(fs)));
   13653 
   13654          } else {
   13655             t0 = newTemp(Ity_I32);
   13656             assign(t0, binop(Iop_Add32, getIReg(rs), getIReg(rt)));
   13657 
   13658             store(mkexpr(t0), getFReg(fs));
   13659          }
   13660          break;
   13661       }
   13662       case 0x9: {  /* Store Doubleword Indexed from Floating Point - SDXC1 */
   13663          DIP("sdc1 f%u, %u(%u)", ft, imm, rs);
   13664          if (fp_mode64) {
   13665             t0 = newTemp(ty);
   13666             assign(t0, binop(mode64 ? Iop_Add64 : Iop_Add32, getIReg(rs),
   13667                              getIReg(rt)));
   13668             store(mkexpr(t0), getFReg(fs));
   13669          } else {
   13670             t0 = newTemp(Ity_I32);
   13671             assign(t0, binop(Iop_Add32, getIReg(rs), getIReg(rt)));
   13672 
   13673             t1 = newTemp(Ity_I32);
   13674             assign(t1, binop(Iop_Add32, mkexpr(t0), mkU32(4)));
   13675 
   13676 #if defined (_MIPSEL)
   13677             store(mkexpr(t0), getFReg(fs));
   13678             store(mkexpr(t1), getFReg(fs + 1));
   13679 #elif defined (_MIPSEB)
   13680             store(mkexpr(t0), getFReg(fs + 1));
   13681             store(mkexpr(t1), getFReg(fs));
   13682 #endif
   13683          }
   13684          break;
   13685       }
   13686       case 0xD:  /* Store Doubleword Indexed Unaligned from Floating Point -
   13687                     SUXC1; MIPS64 MIPS32r2 */
   13688          DIP("suxc1 f%u, r%u(r%u)", fd, rt, rs);
   13689          t0 = newTemp(Ity_I64);
   13690          t1 = newTemp(Ity_I64);
   13691          assign(t0, binop(Iop_Add64, getIReg(rs), getIReg(rt)));
   13692          assign(t1, binop(Iop_And64, mkexpr(t0), mkU64(0xfffffffffffffff8ULL)));
   13693          store(mkexpr(t1), getFReg(fs));
   13694          break;
   13695 
   13696       case 0x0F: {
   13697          DIP("prefx");
   13698          break;
   13699       }
   13700       case 0x20:  {  /* MADD.S */
   13701          DIP("madd.s f%u, f%u, f%u, f%u", fd, fmt, fs, ft);
   13702          IRExpr *rm = get_IR_roundingmode();
   13703          t1 = newTemp(Ity_F32);
   13704          assign(t1, qop(Iop_MAddF32, rm,
   13705                         getLoFromF64(tyF, getFReg(fmt)),
   13706                         getLoFromF64(tyF, getFReg(fs)),
   13707                         getLoFromF64(tyF, getFReg(ft))));
   13708          putFReg(fd, mkWidenFromF32(tyF, mkexpr(t1)));
   13709          break;  /* MADD.S */
   13710       }
   13711       case 0x21: {  /* MADD.D */
   13712          DIP("madd.d f%u, f%u, f%u, f%u", fd, fmt, fs, ft);
   13713          IRExpr *rm = get_IR_roundingmode();
   13714          putDReg(fd, qop(Iop_MAddF64, rm, getDReg(fmt), getDReg(fs),
   13715                          getDReg(ft)));
   13716          break;  /* MADD.D */
   13717       }
   13718       case 0x28: {  /* MSUB.S */
   13719          DIP("msub.s f%u, f%u, f%u, f%u", fd, fmt, fs, ft);
   13720          IRExpr *rm = get_IR_roundingmode();
   13721          t1 = newTemp(Ity_F32);
   13722          assign(t1, qop(Iop_MSubF32, rm,
   13723                         getLoFromF64(tyF, getFReg(fmt)),
   13724                         getLoFromF64(tyF, getFReg(fs)),
   13725                         getLoFromF64(tyF, getFReg(ft))));
   13726          putFReg(fd, mkWidenFromF32(tyF, mkexpr(t1)));
   13727          break;  /* MSUB.S */
   13728       }
   13729       case 0x29: {  /* MSUB.D */
   13730          DIP("msub.d f%u, f%u, f%u, f%u", fd, fmt, fs, ft);
   13731          IRExpr *rm = get_IR_roundingmode();
   13732          putDReg(fd, qop(Iop_MSubF64, rm, getDReg(fmt), getDReg(fs),
   13733                          getDReg(ft)));
   13734          break;  /* MSUB.D */
   13735       }
   13736       case 0x30: {  /* NMADD.S */
   13737          DIP("nmadd.s f%u, f%u, f%u, f%u", fd, fmt, fs, ft);
   13738          IRExpr *rm = get_IR_roundingmode();
   13739          t1 = newTemp(Ity_F32);
   13740          assign(t1, qop(Iop_MAddF32, rm,
   13741                         getLoFromF64(tyF, getFReg(fmt)),
   13742                         getLoFromF64(tyF, getFReg(fs)),
   13743                         getLoFromF64(tyF, getFReg(ft))));
   13744 
   13745          putFReg(fd, mkWidenFromF32(tyF, unop(Iop_NegF32, mkexpr(t1))));
   13746          break;  /* NMADD.S */
   13747       }
   13748       case 0x31: {  /* NMADD.D */
   13749          DIP("nmadd.d f%u, f%u, f%u, f%u", fd, fmt, fs, ft);
   13750          IRExpr *rm = get_IR_roundingmode();
   13751          t1 = newTemp(Ity_F64);
   13752          assign(t1, qop(Iop_MAddF64, rm, getDReg(fmt), getDReg(fs),
   13753                         getDReg(ft)));
   13754          putDReg(fd, unop(Iop_NegF64, mkexpr(t1)));
   13755          break;  /* NMADD.D */
   13756       }
   13757       case 0x38: {  /* NMSUBB.S */
   13758          DIP("nmsub.s f%u, f%u, f%u, f%u", fd, fmt, fs, ft);
   13759          IRExpr *rm = get_IR_roundingmode();
   13760          t1 = newTemp(Ity_F32);
   13761          assign(t1, qop(Iop_MSubF32, rm,
   13762                         getLoFromF64(tyF, getFReg(fmt)),
   13763                         getLoFromF64(tyF, getFReg(fs)),
   13764                         getLoFromF64(tyF, getFReg(ft))));
   13765 
   13766          putFReg(fd, mkWidenFromF32(tyF, unop(Iop_NegF32, mkexpr(t1))));
   13767          break;  /* NMSUBB.S */
   13768       }
   13769       case 0x39: {  /* NMSUBB.D */
   13770          DIP("nmsub.d f%u, f%u, f%u, f%u", fd, fmt, fs, ft);
   13771          IRExpr *rm = get_IR_roundingmode();
   13772          t1 = newTemp(Ity_F64);
   13773          assign(t1, qop(Iop_MSubF64, rm, getDReg(fmt), getDReg(fs),
   13774                         getDReg(ft)));
   13775          putDReg(fd, unop(Iop_NegF64, mkexpr(t1)));
   13776          break;  /* NMSUBB.D */
   13777       }
   13778 
   13779       default:
   13780          goto decode_failure;
   13781       }
   13782       break;
   13783 
   13784    case 0x22:  /* LWL */
   13785       DIP("lwl r%u, %u(r%u)", rt, imm, rs);
   13786       if (mode64) {
   13787          /* t1 = addr */
   13788          t1 = newTemp(Ity_I64);
   13789 #if defined (_MIPSEL)
   13790          assign(t1, binop(Iop_Add64, getIReg(rs), mkU64(extend_s_16to64(imm))));
   13791 #elif defined (_MIPSEB)
   13792          assign(t1, binop(Iop_Xor64,
   13793                           mkU64(0x03),
   13794                           binop(Iop_Add64,
   13795                                 getIReg(rs),
   13796                                 mkU64(extend_s_16to64(imm)))));
   13797 #endif
   13798          /* t2 = word addr */
   13799          /* t4 = addr mod 4 */
   13800          LWX_SWX_PATTERN64;
   13801 
   13802          /* t3 = word content - shifted */
   13803          t3 = newTemp(Ity_I32);
   13804          assign(t3, binop(Iop_Shl32,
   13805                           load(Ity_I32, mkexpr(t2)),
   13806                           narrowTo(Ity_I8,
   13807                                    binop(Iop_Shl32,
   13808                                          binop(Iop_Sub32,
   13809                                                mkU32(0x03),
   13810                                                mkexpr(t4)),
   13811                                          mkU8(3)))));
   13812 
   13813          /* rt content - adjusted */
   13814          t5 = newTemp(Ity_I32);
   13815          assign(t5, binop(Iop_And32,
   13816                           mkNarrowTo32(ty, getIReg(rt)),
   13817                           binop(Iop_Shr32,
   13818                                 mkU32(0x00FFFFFF),
   13819                                       narrowTo(Ity_I8, binop(Iop_Mul32,
   13820                                                              mkU32(0x08),
   13821                                                              mkexpr(t4))))));
   13822 
   13823          putIReg(rt, mkWidenFrom32(ty, binop(Iop_Or32, mkexpr(t5),
   13824                                              mkexpr(t3)), True));
   13825       } else {
   13826          /* t1 = addr */
   13827          t1 = newTemp(Ity_I32);
   13828 #if defined (_MIPSEL)
   13829          assign(t1, binop(Iop_Add32, getIReg(rs), mkU32(extend_s_16to32(imm))));
   13830 #elif defined (_MIPSEB)
   13831          assign(t1, binop(Iop_Xor32, mkU32(0x3), binop(Iop_Add32, getIReg(rs),
   13832                                      mkU32(extend_s_16to32(imm)))));
   13833 #endif
   13834 
   13835          /* t2 = word addr */
   13836          /* t4 = addr mod 4 */
   13837          LWX_SWX_PATTERN;
   13838 
   13839          /* t3 = word content - shifted */
   13840          t3 = newTemp(Ity_I32);
   13841          assign(t3, binop(Iop_Shl32, load(Ity_I32, mkexpr(t2)), narrowTo(Ity_I8,
   13842                     binop(Iop_Shl32, binop(Iop_Sub32, mkU32(0x03), mkexpr(t4)),
   13843                     mkU8(3)))));
   13844 
   13845          /* rt content  - adjusted */
   13846          t5 = newTemp(Ity_I32);
   13847          assign(t5, binop(Iop_And32,
   13848                           getIReg(rt),
   13849                           binop(Iop_Shr32,
   13850                                 mkU32(0x00FFFFFF),
   13851                                       narrowTo(Ity_I8, binop(Iop_Mul32,
   13852                                                              mkU32(0x08),
   13853                                                              mkexpr(t4))))));
   13854 
   13855          putIReg(rt, binop(Iop_Or32, mkexpr(t5), mkexpr(t3)));
   13856       }
   13857       break;
   13858 
   13859    case 0x26:  /* LWR */
   13860       DIP("lwr r%u, %u(r%u)", rt, imm, rs);
   13861       if (mode64) {
   13862          /* t1 = addr */
   13863          t1 = newTemp(Ity_I64);
   13864 #if defined (_MIPSEL)
   13865          assign(t1, binop(Iop_Add64, getIReg(rs), mkU64(extend_s_16to64(imm))));
   13866 #elif defined (_MIPSEB)
   13867          assign(t1, binop(Iop_Xor64,
   13868                           mkU64(0x3),
   13869                           binop(Iop_Add64,
   13870                                 getIReg(rs),
   13871                                 mkU64(extend_s_16to64(imm)))));
   13872 #endif
   13873          /* t2 = word addr */
   13874          /* t4 = addr mod 4 */
   13875          LWX_SWX_PATTERN64;
   13876 
   13877          /* t3 = word content - shifted */
   13878          t3 = newTemp(Ity_I32);
   13879          assign(t3, binop(Iop_Shr32,
   13880                           load(Ity_I32, mkexpr(t2)),
   13881                           narrowTo(Ity_I8,
   13882                                    binop(Iop_Shl32, mkexpr(t4), mkU8(0x03)))));
   13883 
   13884          /* rt content  - adjusted */
   13885          t5 = newTemp(Ity_I32);
   13886          assign(t5, binop(Iop_And32, mkNarrowTo32(ty, getIReg(rt)),
   13887                 unop(Iop_Not32, binop(Iop_Shr32, mkU32(0xFFFFFFFF),
   13888                 narrowTo(Ity_I8, binop(Iop_Shl32, mkexpr(t4), mkU8(0x3)))))));
   13889 
   13890          putIReg(rt, mkWidenFrom32(ty, binop(Iop_Or32, mkexpr(t5),
   13891                                        mkexpr(t3)), True));
   13892 
   13893       } else {
   13894          /* t1 = addr */
   13895          t1 = newTemp(Ity_I32);
   13896 #if defined (_MIPSEL)
   13897          assign(t1, binop(Iop_Add32, getIReg(rs), mkU32(extend_s_16to32(imm))));
   13898 #elif defined (_MIPSEB)
   13899          assign(t1, binop(Iop_Xor32, mkU32(0x3), binop(Iop_Add32, getIReg(rs),
   13900                                      mkU32(extend_s_16to32(imm)))));
   13901 #endif
   13902 
   13903          /* t2 = word addr */
   13904          /* t4 = addr mod 4 */
   13905          LWX_SWX_PATTERN;
   13906 
   13907          /* t3 = word content - shifted */
   13908          t3 = newTemp(Ity_I32);
   13909          assign(t3, binop(Iop_Shr32, load(Ity_I32, mkexpr(t2)),
   13910                     narrowTo(Ity_I8, binop(Iop_Shl32, mkexpr(t4),
   13911                     mkU8(3)))));
   13912 
   13913          /* rt content  - adjusted */
   13914          t5 = newTemp(Ity_I32);
   13915          assign(t5, binop(Iop_And32, getIReg(rt), unop(Iop_Not32,
   13916                     binop(Iop_Shr32, mkU32(0xFFFFFFFF), narrowTo(Ity_I8,
   13917                           binop(Iop_Shl32, mkexpr(t4), mkU8(0x3)))))));
   13918 
   13919          putIReg(rt, binop(Iop_Or32, mkexpr(t5), mkexpr(t3)));
   13920       }
   13921       break;
   13922 
   13923    case 0x2B:  /* SW */
   13924       DIP("sw r%u, %u(r%u)", rt, imm, rs);
   13925       LOAD_STORE_PATTERN;
   13926       store(mkexpr(t1), mkNarrowTo32(ty, getIReg(rt)));
   13927       break;
   13928 
   13929    case 0x2C: {  /* SDL rt, offset(base) MIPS64 */
   13930       DIP("sdl r%u, %u(r%u)", rt, imm, rs);
   13931       vassert(mode64);
   13932       IRTemp A_byte = newTemp(Ity_I8);
   13933       IRTemp B_byte = newTemp(Ity_I8);
   13934       IRTemp C_byte = newTemp(Ity_I8);
   13935       IRTemp D_byte = newTemp(Ity_I8);
   13936       IRTemp E_byte = newTemp(Ity_I8);
   13937       IRTemp F_byte = newTemp(Ity_I8);
   13938       IRTemp G_byte = newTemp(Ity_I8);
   13939       IRTemp H_byte = newTemp(Ity_I8);
   13940       IRTemp B_pos  = newTemp(Ity_I64);
   13941       IRTemp C_pos  = newTemp(Ity_I64);
   13942       IRTemp D_pos  = newTemp(Ity_I64);
   13943       IRTemp E_pos  = newTemp(Ity_I64);
   13944       IRTemp F_pos  = newTemp(Ity_I64);
   13945       IRTemp G_pos  = newTemp(Ity_I64);
   13946 
   13947       /* H byte */
   13948       assign(H_byte, getByteFromReg(rt, 0));
   13949       /* G byte */
   13950       assign(G_byte, getByteFromReg(rt, 1));
   13951       /* F byte */
   13952       assign(F_byte, getByteFromReg(rt, 2));
   13953       /* E byte */
   13954       assign(E_byte, getByteFromReg(rt, 3));
   13955       /* D byte */
   13956       assign(D_byte, getByteFromReg(rt, 4));
   13957       /* C byte */
   13958       assign(C_byte, getByteFromReg(rt, 5));
   13959       /* B byte */
   13960       assign(B_byte, getByteFromReg(rt, 6));
   13961       /* A byte */
   13962       assign(A_byte, getByteFromReg(rt, 7));
   13963 
   13964       /* t1 = addr */
   13965       t1 = newTemp(Ity_I64);
   13966       assign(t1, binop(Iop_Add64, getIReg(rs), mkU64(extend_s_16to64(imm))));
   13967 
   13968       /* t2 = word addr */
   13969       t2 = newTemp(Ity_I64);
   13970       assign(t2, binop(Iop_And64, mkexpr(t1), mkU64(0xFFFFFFFFFFFFFFF8ULL)));
   13971 
   13972       /* t3 = addr mod 7 */
   13973       t3 = newTemp(Ity_I64);
   13974       assign(t3, binop(Iop_And64, mkexpr(t1), mkU64(0x7)));
   13975 
   13976 #if defined (_MIPSEL)
   13977       /* Calculate X_byte position. */
   13978       assign(B_pos, IRExpr_ITE(binop(Iop_CmpLT64U, mkexpr(t3), mkU64(0x1)),
   13979                                mkU64(0x0),
   13980                                mkU64(0x1)));
   13981 
   13982       assign(C_pos, IRExpr_ITE(binop(Iop_CmpLT64U, mkexpr(t3), mkU64(0x2)),
   13983                                mkU64(0x0),
   13984                                mkU64(0x2)));
   13985 
   13986       assign(D_pos, IRExpr_ITE(binop(Iop_CmpLT64U, mkexpr(t3), mkU64(0x3)),
   13987                                mkU64(0x0),
   13988                                mkU64(0x3)));
   13989 
   13990       assign(E_pos, IRExpr_ITE(binop(Iop_CmpLT64U, mkexpr(t3), mkU64(0x4)),
   13991                                mkU64(0x0),
   13992                                mkU64(0x4)));
   13993 
   13994       assign(F_pos, IRExpr_ITE(binop(Iop_CmpLT64U, mkexpr(t3), mkU64(0x5)),
   13995                                mkU64(0x0),
   13996                                mkU64(0x5)));
   13997 
   13998       assign(G_pos, IRExpr_ITE(binop(Iop_CmpEQ64, mkexpr(t3), mkU64(0x7)),
   13999                                mkU64(0x1),
   14000                                mkU64(0x0)));
   14001 
   14002       /* Store X_byte on the right place. */
   14003       store(mkexpr(t2), mkexpr(H_byte));
   14004       store(binop(Iop_Add64, mkexpr(t2), mkexpr(G_pos)), mkexpr(G_byte));
   14005       store(binop(Iop_Sub64, mkexpr(t1), mkexpr(F_pos)), mkexpr(F_byte));
   14006       store(binop(Iop_Sub64, mkexpr(t1), mkexpr(E_pos)), mkexpr(E_byte));
   14007       store(binop(Iop_Sub64, mkexpr(t1), mkexpr(D_pos)), mkexpr(D_byte));
   14008       store(binop(Iop_Sub64, mkexpr(t1), mkexpr(C_pos)), mkexpr(C_byte));
   14009       store(binop(Iop_Sub64, mkexpr(t1), mkexpr(B_pos)), mkexpr(B_byte));
   14010       store(mkexpr(t1), mkexpr(A_byte));
   14011 
   14012 #else /* _MIPSEB */
   14013       /* Calculate X_byte position. */
   14014       assign(B_pos, IRExpr_ITE(binop(Iop_CmpEQ64, mkexpr(t3), mkU64(0x7)),
   14015                                mkU64(0x0),
   14016                                mkU64(0x1)));
   14017 
   14018       assign(C_pos, IRExpr_ITE(binop(Iop_CmpLT64U, mkexpr(t3), mkU64(0x6)),
   14019                                mkU64(0x2),
   14020                                mkU64(0x0)));
   14021 
   14022       assign(D_pos, IRExpr_ITE(binop(Iop_CmpLT64U, mkexpr(t3), mkU64(0x5)),
   14023                                mkU64(0x3),
   14024                                mkU64(0x0)));
   14025 
   14026       assign(E_pos, IRExpr_ITE(binop(Iop_CmpLT64U, mkexpr(t3), mkU64(0x4)),
   14027                                mkU64(0x4),
   14028                                mkU64(0x0)));
   14029 
   14030       assign(F_pos, IRExpr_ITE(binop(Iop_CmpLT64U, mkexpr(t3), mkU64(0x3)),
   14031                                mkU64(0x5),
   14032                                mkU64(0x0)));
   14033 
   14034       assign(G_pos, IRExpr_ITE(binop(Iop_CmpEQ64, mkexpr(t3), mkU64(0x0)),
   14035                                mkU64(0x6),
   14036                                mkU64(0x7)));
   14037 
   14038       /* Store X_byte on the right place. */
   14039       store(binop(Iop_Add64, mkexpr(t2), mkU64(0x7)), mkexpr(H_byte));
   14040       store(binop(Iop_Add64, mkexpr(t2), mkexpr(G_pos)), mkexpr(G_byte));
   14041       store(binop(Iop_Add64, mkexpr(t1), mkexpr(F_pos)), mkexpr(F_byte));
   14042       store(binop(Iop_Add64, mkexpr(t1), mkexpr(E_pos)), mkexpr(E_byte));
   14043       store(binop(Iop_Add64, mkexpr(t1), mkexpr(D_pos)), mkexpr(D_byte));
   14044       store(binop(Iop_Add64, mkexpr(t1), mkexpr(C_pos)), mkexpr(C_byte));
   14045       store(binop(Iop_Add64, mkexpr(t1), mkexpr(B_pos)), mkexpr(B_byte));
   14046       store(mkexpr(t1), mkexpr(A_byte));
   14047 #endif
   14048 
   14049       break;
   14050    }
   14051 
   14052    case 0x2D: {
   14053       /* SDR rt, offset(base) - MIPS64 */
   14054       vassert(mode64);
   14055       DIP("sdr r%u, %u(r%u)", rt, imm, rs);
   14056       IRTemp A_byte = newTemp(Ity_I8);
   14057       IRTemp B_byte = newTemp(Ity_I8);
   14058       IRTemp C_byte = newTemp(Ity_I8);
   14059       IRTemp D_byte = newTemp(Ity_I8);
   14060       IRTemp E_byte = newTemp(Ity_I8);
   14061       IRTemp F_byte = newTemp(Ity_I8);
   14062       IRTemp G_byte = newTemp(Ity_I8);
   14063       IRTemp H_byte = newTemp(Ity_I8);
   14064       IRTemp B_pos  = newTemp(Ity_I64);
   14065       IRTemp C_pos  = newTemp(Ity_I64);
   14066       IRTemp D_pos  = newTemp(Ity_I64);
   14067       IRTemp E_pos  = newTemp(Ity_I64);
   14068       IRTemp F_pos  = newTemp(Ity_I64);
   14069       IRTemp G_pos  = newTemp(Ity_I64);
   14070 
   14071       /* H byte */
   14072       assign(H_byte, getByteFromReg(rt, 0));
   14073       /* G byte */
   14074       assign(G_byte, getByteFromReg(rt, 1));
   14075       /* F byte */
   14076       assign(F_byte, getByteFromReg(rt, 2));
   14077       /* E byte */
   14078       assign(E_byte, getByteFromReg(rt, 3));
   14079       /* D byte */
   14080       assign(D_byte, getByteFromReg(rt, 4));
   14081       /* C byte */
   14082       assign(C_byte, getByteFromReg(rt, 5));
   14083       /* B byte */
   14084       assign(B_byte, getByteFromReg(rt, 6));
   14085       /* A byte */
   14086       assign(A_byte, getByteFromReg(rt, 7));
   14087 
   14088       /* t1 = addr */
   14089       t1 = newTemp(Ity_I64);
   14090       assign(t1, binop(Iop_Add64, getIReg(rs), mkU64(extend_s_16to64(imm))));
   14091 
   14092       /* t2 = word addr */
   14093       t2 = newTemp(Ity_I64);
   14094       assign(t2, binop(Iop_And64, mkexpr(t1), mkU64(0xFFFFFFFFFFFFFFF8ULL)));
   14095 
   14096       /* t3 = addr mod 7 */
   14097       t3 = newTemp(Ity_I64);
   14098       assign(t3, binop(Iop_And64, mkexpr(t1), mkU64(0x7)));
   14099 
   14100 #if defined (_MIPSEL)
   14101       /* Calculate X_byte position. */
   14102       assign(B_pos, IRExpr_ITE(binop(Iop_CmpLT64U, mkU64(0x1), mkexpr(t3)),
   14103                                mkU64(0x0),
   14104                                mkU64(0x6)));
   14105 
   14106       assign(C_pos, IRExpr_ITE(binop(Iop_CmpLT64U, mkU64(0x2), mkexpr(t3)),
   14107                                mkU64(0x0),
   14108                                mkU64(0x5)));
   14109 
   14110       assign(D_pos, IRExpr_ITE(binop(Iop_CmpLT64U, mkU64(0x3), mkexpr(t3)),
   14111                                mkU64(0x0),
   14112                                mkU64(0x4)));
   14113 
   14114       assign(E_pos, IRExpr_ITE(binop(Iop_CmpLT64U, mkU64(0x4), mkexpr(t3)),
   14115                                mkU64(0x0),
   14116                                mkU64(0x3)));
   14117 
   14118       assign(F_pos, IRExpr_ITE(binop(Iop_CmpLT64U, mkU64(0x5), mkexpr(t3)),
   14119                                mkU64(0x0),
   14120                                mkU64(0x2)));
   14121 
   14122       assign(G_pos, IRExpr_ITE(binop(Iop_CmpEQ64, mkexpr(t3), mkU64(0x7)),
   14123                                mkU64(0x0),
   14124                                mkU64(0x1)));
   14125 
   14126       /* Store X_byte on the right place. */
   14127       store(binop(Iop_Add64, mkexpr(t2), mkU64(0x7)), mkexpr(A_byte));
   14128       store(binop(Iop_Add64, mkexpr(t1), mkexpr(B_pos)), mkexpr(B_byte));
   14129       store(binop(Iop_Add64, mkexpr(t1), mkexpr(C_pos)), mkexpr(C_byte));
   14130       store(binop(Iop_Add64, mkexpr(t1), mkexpr(D_pos)), mkexpr(D_byte));
   14131       store(binop(Iop_Add64, mkexpr(t1), mkexpr(E_pos)), mkexpr(E_byte));
   14132       store(binop(Iop_Add64, mkexpr(t1), mkexpr(F_pos)), mkexpr(F_byte));
   14133       store(binop(Iop_Add64, mkexpr(t1), mkexpr(G_pos)), mkexpr(G_byte));
   14134       store(mkexpr(t1), mkexpr(H_byte));
   14135 
   14136 #else /* _MIPSEB */
   14137       /* Calculate X_byte position. */
   14138       assign(B_pos, IRExpr_ITE(binop(Iop_CmpLT64U, mkU64(0x5), mkexpr(t3)),
   14139                                mkU64(0x6),
   14140                                mkU64(0x0)));
   14141 
   14142       assign(C_pos, IRExpr_ITE(binop(Iop_CmpLT64U, mkU64(0x4), mkexpr(t3)),
   14143                                mkU64(0x5),
   14144                                mkU64(0x0)));
   14145 
   14146       assign(D_pos, IRExpr_ITE(binop(Iop_CmpLT64U, mkU64(0x3), mkexpr(t3)),
   14147                                mkU64(0x4),
   14148                                mkU64(0x0)));
   14149 
   14150       assign(E_pos, IRExpr_ITE(binop(Iop_CmpLT64U, mkU64(0x2), mkexpr(t3)),
   14151                                mkU64(0x3),
   14152                                mkU64(0x0)));
   14153 
   14154       assign(F_pos, IRExpr_ITE(binop(Iop_CmpLT64U, mkU64(0x1), mkexpr(t3)),
   14155                                mkU64(0x2),
   14156                                mkU64(0x0)));
   14157 
   14158       assign(G_pos, IRExpr_ITE(binop(Iop_CmpEQ64, mkexpr(t3), mkU64(0x0)),
   14159                                mkU64(0x0),
   14160                                mkU64(0x1)));
   14161 
   14162       /* Store X_byte on the right place. */
   14163       store(mkexpr(t2), mkexpr(A_byte));
   14164       store(binop(Iop_Sub64, mkexpr(t1), mkexpr(B_pos)), mkexpr(B_byte));
   14165       store(binop(Iop_Sub64, mkexpr(t1), mkexpr(C_pos)), mkexpr(C_byte));
   14166       store(binop(Iop_Sub64, mkexpr(t1), mkexpr(D_pos)), mkexpr(D_byte));
   14167       store(binop(Iop_Sub64, mkexpr(t1), mkexpr(E_pos)), mkexpr(E_byte));
   14168       store(binop(Iop_Sub64, mkexpr(t1), mkexpr(F_pos)), mkexpr(F_byte));
   14169       store(binop(Iop_Sub64, mkexpr(t1), mkexpr(G_pos)), mkexpr(G_byte));
   14170       store(mkexpr(t1), mkexpr(H_byte));
   14171 #endif
   14172       break;
   14173    }
   14174 
   14175    case 0x28:  /* SB */
   14176       DIP("sb r%u, %u(r%u)", rt, imm, rs);
   14177       LOAD_STORE_PATTERN;
   14178       store(mkexpr(t1), narrowTo(Ity_I8, getIReg(rt)));
   14179       break;
   14180 
   14181    case 0x29:  /* SH */
   14182       DIP("sh r%u, %u(r%u)", rt, imm, rs);
   14183       LOAD_STORE_PATTERN;
   14184       store(mkexpr(t1), narrowTo(Ity_I16, getIReg(rt)));
   14185       break;
   14186 
   14187    case 0x2A:  /* SWL */
   14188       DIP("swl r%u, %u(r%u)", rt, imm, rs);
   14189       if (mode64) {
   14190          IRTemp E_byte = newTemp(Ity_I8);
   14191          IRTemp F_byte = newTemp(Ity_I8);
   14192          IRTemp G_byte = newTemp(Ity_I8);
   14193          IRTemp H_byte = newTemp(Ity_I8);
   14194          IRTemp F_pos  = newTemp(Ity_I64);
   14195          IRTemp G_pos  = newTemp(Ity_I64);
   14196 
   14197          /* H byte */
   14198          assign(H_byte, getByteFromReg(rt, 0));
   14199          /* G byte */
   14200          assign(G_byte, getByteFromReg(rt, 1));
   14201          /* F byte */
   14202          assign(F_byte, getByteFromReg(rt, 2));
   14203          /* E byte */
   14204          assign(E_byte, getByteFromReg(rt, 3));
   14205 
   14206          /* t1 = addr */
   14207          t1 = newTemp(Ity_I64);
   14208          assign(t1, binop(Iop_Add64, getIReg(rs), mkU64(extend_s_16to64(imm))));
   14209 
   14210          /* t2 = word addr */
   14211          t2 = newTemp(Ity_I64);
   14212          assign(t2, binop(Iop_And64, mkexpr(t1), mkU64(0xFFFFFFFFFFFFFFFCULL)));
   14213 
   14214          /* t3 = addr mod 4 */
   14215          t3 = newTemp(Ity_I64);
   14216          assign(t3, binop(Iop_And64, mkexpr(t1), mkU64(0x3)));
   14217 
   14218 #if defined (_MIPSEL)
   14219          /* Calculate X_byte position. */
   14220          assign(F_pos, IRExpr_ITE(binop(Iop_CmpEQ64, mkexpr(t3), mkU64(0x0)),
   14221                                   mkU64(0x0),
   14222                                   mkU64(0x1)));
   14223 
   14224          assign(G_pos, IRExpr_ITE(binop(Iop_CmpEQ64, mkexpr(t3), mkU64(0x3)),
   14225                                   mkU64(0x1),
   14226                                   mkU64(0x0)));
   14227 
   14228          /* Store X_byte on the right place. */
   14229          store(mkexpr(t2), mkexpr(H_byte));
   14230          store(binop(Iop_Add64, mkexpr(t2), mkexpr(G_pos)), mkexpr(G_byte));
   14231          store(binop(Iop_Sub64, mkexpr(t1), mkexpr(F_pos)), mkexpr(F_byte));
   14232          store(mkexpr(t1), mkexpr(E_byte));
   14233 
   14234 #else    /* _MIPSEB */
   14235          /* Calculate X_byte position. */
   14236          assign(F_pos, IRExpr_ITE(binop(Iop_CmpEQ64, mkexpr(t3), mkU64(0x3)),
   14237                                   mkU64(0x0),
   14238                                   mkU64(0x1)));
   14239 
   14240          assign(G_pos, IRExpr_ITE(binop(Iop_CmpEQ64, mkexpr(t3), mkU64(0x0)),
   14241                                   mkU64(0x2),
   14242                                   mkU64(0x3)));
   14243 
   14244          store(binop(Iop_Add64, mkexpr(t2), mkU64(3)), mkexpr(H_byte));
   14245          store(binop(Iop_Add64, mkexpr(t2), mkexpr(G_pos)), mkexpr(G_byte));
   14246          store(binop(Iop_Add64, mkexpr(t1), mkexpr(F_pos)), mkexpr(F_byte));
   14247          store(mkexpr(t1), mkexpr(E_byte));
   14248 
   14249 #endif
   14250       } else {
   14251          IRTemp E_byte = newTemp(Ity_I8);
   14252          IRTemp F_byte = newTemp(Ity_I8);
   14253          IRTemp G_byte = newTemp(Ity_I8);
   14254          IRTemp H_byte = newTemp(Ity_I8);
   14255          IRTemp F_pos  = newTemp(Ity_I32);
   14256          IRTemp G_pos  = newTemp(Ity_I32);
   14257 
   14258          /* H byte */
   14259          assign(H_byte, getByteFromReg(rt, 0));
   14260          /* G byte */
   14261          assign(G_byte, getByteFromReg(rt, 1));
   14262          /* F byte */
   14263          assign(F_byte, getByteFromReg(rt, 2));
   14264          /* E byte */
   14265          assign(E_byte, getByteFromReg(rt, 3));
   14266 
   14267          /* t1 = addr */
   14268          t1 = newTemp(Ity_I32);
   14269          assign(t1, binop(Iop_Add32, getIReg(rs), mkU32(extend_s_16to32(imm))));
   14270 
   14271          /* t2 = word addr */
   14272          t2 = newTemp(Ity_I32);
   14273          assign(t2, binop(Iop_And32, mkexpr(t1), mkU32(0xFFFFFFFCULL)));
   14274 
   14275          /* t3 = addr mod 4 */
   14276          t3 = newTemp(Ity_I32);
   14277          assign(t3, binop(Iop_And32, mkexpr(t1), mkU32(0x3)));
   14278 
   14279 #if defined (_MIPSEL)
   14280          /* Calculate X_byte position. */
   14281          assign(F_pos, IRExpr_ITE(binop(Iop_CmpEQ32, mkexpr(t3), mkU32(0x0)),
   14282                                   mkU32(0x0),
   14283                                   mkU32(0x1)));
   14284 
   14285          assign(G_pos, IRExpr_ITE(binop(Iop_CmpEQ32, mkexpr(t3), mkU32(0x3)),
   14286                                   mkU32(0x1),
   14287                                   mkU32(0x0)));
   14288 
   14289          /* Store X_byte on the right place. */
   14290          store(mkexpr(t2), mkexpr(H_byte));
   14291          store(binop(Iop_Add32, mkexpr(t2), mkexpr(G_pos)), mkexpr(G_byte));
   14292          store(binop(Iop_Sub32, mkexpr(t1), mkexpr(F_pos)), mkexpr(F_byte));
   14293          store(mkexpr(t1), mkexpr(E_byte));
   14294 
   14295 #else    /* _MIPSEB */
   14296          /* Calculate X_byte position. */
   14297          assign(F_pos, IRExpr_ITE(binop(Iop_CmpEQ32, mkexpr(t3), mkU32(0x3)),
   14298                                   mkU32(0x0),
   14299                                   mkU32(0x1)));
   14300 
   14301          assign(G_pos, IRExpr_ITE(binop(Iop_CmpEQ32, mkexpr(t3), mkU32(0x0)),
   14302                                   mkU32(0x2),
   14303                                   mkU32(0x3)));
   14304 
   14305          store(binop(Iop_Add32, mkexpr(t2), mkU32(3)), mkexpr(H_byte));
   14306          store(binop(Iop_Add32, mkexpr(t2), mkexpr(G_pos)), mkexpr(G_byte));
   14307          store(binop(Iop_Add32, mkexpr(t1), mkexpr(F_pos)), mkexpr(F_byte));
   14308          store(mkexpr(t1), mkexpr(E_byte));
   14309 
   14310 #endif
   14311       }
   14312       break;
   14313 
   14314    case 0x2E:  /* SWR */
   14315       DIP("swr r%u, %u(r%u)", rt, imm, rs);
   14316       if (mode64) {
   14317          IRTemp E_byte = newTemp(Ity_I8);
   14318          IRTemp F_byte = newTemp(Ity_I8);
   14319          IRTemp G_byte = newTemp(Ity_I8);
   14320          IRTemp H_byte = newTemp(Ity_I8);
   14321          IRTemp F_pos  = newTemp(Ity_I64);
   14322          IRTemp G_pos  = newTemp(Ity_I64);
   14323 
   14324          /* H byte */
   14325          assign(H_byte, getByteFromReg(rt, 0));
   14326          /* G byte */
   14327          assign(G_byte, getByteFromReg(rt, 1));
   14328          /* F byte */
   14329          assign(F_byte, getByteFromReg(rt, 2));
   14330          /* E byte */
   14331          assign(E_byte, getByteFromReg(rt, 3));
   14332 
   14333          /* t1 = addr */
   14334          t1 = newTemp(Ity_I64);
   14335          assign(t1, binop(Iop_Add64, getIReg(rs), mkU64(extend_s_16to64(imm))));
   14336 
   14337          /* t2 = word addr */
   14338          t2 = newTemp(Ity_I64);
   14339          assign(t2, binop(Iop_And64, mkexpr(t1), mkU64(0xFFFFFFFFFFFFFFFCULL)));
   14340 
   14341          /* t3 = addr mod 4 */
   14342          t3 = newTemp(Ity_I64);
   14343          assign(t3, binop(Iop_And64, mkexpr(t1), mkU64(0x3)));
   14344 
   14345 #if defined (_MIPSEL)
   14346          /* Calculate X_byte position. */
   14347          assign(F_pos, IRExpr_ITE(binop(Iop_CmpEQ64, mkexpr(t3), mkU64(0x0)),
   14348                                   mkU64(0x2),
   14349                                   mkU64(0x3)));
   14350 
   14351          assign(G_pos, IRExpr_ITE(binop(Iop_CmpEQ64, mkexpr(t3), mkU64(0x3)),
   14352                                   mkU64(0x0),
   14353                                   mkU64(0x1)));
   14354 
   14355          /* Store X_byte on the right place. */
   14356          store(binop(Iop_Add64, mkexpr(t2), mkU64(0x3)), mkexpr(E_byte));
   14357          store(binop(Iop_Add64, mkexpr(t2), mkexpr(F_pos)), mkexpr(F_byte));
   14358          store(binop(Iop_Add64, mkexpr(t1), mkexpr(G_pos)), mkexpr(G_byte));
   14359          store(mkexpr(t1), mkexpr(H_byte));
   14360 
   14361 #else    /* _MIPSEB */
   14362          /* Calculate X_byte position. */
   14363          assign(F_pos, IRExpr_ITE(binop(Iop_CmpEQ64, mkexpr(t3), mkU64(0x3)),
   14364                                   mkU64(0x1),
   14365                                   mkU64(0x0)));
   14366 
   14367          assign(G_pos, IRExpr_ITE(binop(Iop_CmpEQ64, mkexpr(t3), mkU64(0x0)),
   14368                                   mkU64(0x0),
   14369                                   mkU64(0x1)));
   14370 
   14371          /* Store X_byte on the right place. */
   14372          store(mkexpr(t2), mkexpr(E_byte));
   14373          store(binop(Iop_Add64, mkexpr(t2), mkexpr(F_pos)), mkexpr(F_byte));
   14374          store(binop(Iop_Sub64, mkexpr(t1), mkexpr(G_pos)), mkexpr(G_byte));
   14375          store(mkexpr(t1), mkexpr(H_byte));
   14376 #endif
   14377       } else {
   14378          IRTemp E_byte = newTemp(Ity_I8);
   14379          IRTemp F_byte = newTemp(Ity_I8);
   14380          IRTemp G_byte = newTemp(Ity_I8);
   14381          IRTemp H_byte = newTemp(Ity_I8);
   14382          IRTemp F_pos  = newTemp(Ity_I32);
   14383          IRTemp G_pos  = newTemp(Ity_I32);
   14384 
   14385          /* H byte */
   14386          assign(H_byte, getByteFromReg(rt, 0));
   14387          /* G byte */
   14388          assign(G_byte, getByteFromReg(rt, 1));
   14389          /* F byte */
   14390          assign(F_byte, getByteFromReg(rt, 2));
   14391          /* E byte */
   14392          assign(E_byte, getByteFromReg(rt, 3));
   14393 
   14394          /* t1 = addr */
   14395          t1 = newTemp(Ity_I32);
   14396          assign(t1, binop(Iop_Add32, getIReg(rs), mkU32(extend_s_16to32(imm))));
   14397 
   14398          /* t2 = word addr */
   14399          t2 = newTemp(Ity_I32);
   14400          assign(t2, binop(Iop_And32, mkexpr(t1), mkU32(0xFFFFFFFCULL)));
   14401 
   14402          /* t3 = addr mod 4 */
   14403          t3 = newTemp(Ity_I32);
   14404          assign(t3, binop(Iop_And32, mkexpr(t1), mkU32(0x3)));
   14405 
   14406 #if defined (_MIPSEL)
   14407          /* Calculate X_byte position. */
   14408          assign(F_pos, IRExpr_ITE(binop(Iop_CmpEQ32, mkexpr(t3), mkU32(0x0)),
   14409                                   mkU32(0x2),
   14410                                   mkU32(0x3)));
   14411 
   14412          assign(G_pos, IRExpr_ITE(binop(Iop_CmpEQ32, mkexpr(t3), mkU32(0x3)),
   14413                                   mkU32(0x0),
   14414                                   mkU32(0x1)));
   14415 
   14416          /* Store X_byte on the right place. */
   14417          store(binop(Iop_Add32, mkexpr(t2), mkU32(0x3)), mkexpr(E_byte));
   14418          store(binop(Iop_Add32, mkexpr(t2), mkexpr(F_pos)), mkexpr(F_byte));
   14419          store(binop(Iop_Add32, mkexpr(t1), mkexpr(G_pos)), mkexpr(G_byte));
   14420          store(mkexpr(t1), mkexpr(H_byte));
   14421 
   14422 #else    /* _MIPSEB */
   14423          /* Calculate X_byte position. */
   14424          assign(F_pos, IRExpr_ITE(binop(Iop_CmpEQ32, mkexpr(t3), mkU32(0x3)),
   14425                                   mkU32(0x1),
   14426                                   mkU32(0x0)));
   14427 
   14428          assign(G_pos, IRExpr_ITE(binop(Iop_CmpEQ32, mkexpr(t3), mkU32(0x0)),
   14429                                   mkU32(0x0),
   14430                                   mkU32(0x1)));
   14431 
   14432          /* Store X_byte on the right place. */
   14433          store(mkexpr(t2), mkexpr(E_byte));
   14434          store(binop(Iop_Add32, mkexpr(t2), mkexpr(F_pos)), mkexpr(F_byte));
   14435          store(binop(Iop_Sub32, mkexpr(t1), mkexpr(G_pos)), mkexpr(G_byte));
   14436          store(mkexpr(t1), mkexpr(H_byte));
   14437 #endif
   14438       }
   14439       break;
   14440 
   14441    case 0x1C:  /* Special2 */
   14442       switch (function) {
   14443          /* Cavium Specific instructions */
   14444          case 0x03: case 0x32: case 0x33:  /* DMUL, CINS , CINS32 */
   14445          case 0x3A: case 0x3B: case 0x2B:  /* EXT,  EXT32, SNE    */
   14446          /* CVM Compare Instructions */
   14447          case 0x2A: case 0x2E: case 0x2F:  /* SEQ,  SEQI,  SNEI   */
   14448          /* CPU Load, Store, Memory, and Control Instructions */
   14449          case 0x18: case 0x19:             /* SAA, SAAD */
   14450          case 0x1F:                        /* LAA, LAAD, LAI, LAID */
   14451          case 0x28: case 0x2C: case 0x2D:  /* BADDU, POP, DPOP */
   14452             if (VEX_MIPS_COMP_ID(archinfo->hwcaps) == VEX_PRID_COMP_CAVIUM) {
   14453                if (dis_instr_CVM(cins))
   14454                   break;
   14455                goto decode_failure;
   14456             } else {
   14457                goto decode_failure;
   14458             }
   14459          break;
   14460 
   14461          case 0x02: {  /* MUL */
   14462             DIP("mul r%u, r%u, r%u", rd, rs, rt);
   14463             if (mode64) {
   14464                IRTemp tmpRs32 = newTemp(Ity_I32);
   14465                IRTemp tmpRt32 = newTemp(Ity_I32);
   14466                IRTemp tmpRes = newTemp(Ity_I32);
   14467 
   14468                assign(tmpRs32, mkNarrowTo32(ty, getIReg(rs)));
   14469                assign(tmpRt32, mkNarrowTo32(ty, getIReg(rt)));
   14470                assign(tmpRes, binop(Iop_Mul32,
   14471                                     mkexpr(tmpRs32), mkexpr(tmpRt32)));
   14472                putIReg(rd, mkWidenFrom32(ty, mkexpr(tmpRes), True));
   14473             } else
   14474                putIReg(rd, binop(Iop_Mul32, getIReg(rs), getIReg(rt)));
   14475             break;
   14476          }
   14477 
   14478          case 0x00: {  /* MADD */
   14479             if (mode64) {
   14480                DIP("madd r%u, r%u", rs, rt);
   14481                t1 = newTemp(Ity_I32);
   14482                t2 = newTemp(Ity_I32);
   14483                t3 = newTemp(Ity_I64);
   14484                t4 = newTemp(Ity_I64);
   14485                t5 = newTemp(Ity_I64);
   14486                t6 = newTemp(Ity_I32);
   14487 
   14488                assign(t1, mkNarrowTo32(ty, getHI()));
   14489                assign(t2, mkNarrowTo32(ty, getLO()));
   14490 
   14491                assign(t3, binop(Iop_MullS32, mkNarrowTo32(ty, getIReg(rs)),
   14492                                              mkNarrowTo32(ty, getIReg(rt))));
   14493 
   14494                assign(t4, binop(Iop_32HLto64, mkexpr(t1), mkexpr(t2)));
   14495                assign(t5, binop(Iop_Add64, mkexpr(t3), mkexpr(t4)));
   14496 
   14497                putHI(mkWidenFrom32(ty, unop(Iop_64HIto32, mkexpr(t5)), True));
   14498                putLO(mkWidenFrom32(ty, unop(Iop_64to32, mkexpr(t5)), True));
   14499             } else {
   14500                if ( (1 <= ac) && ( 3 >= ac) ) {
   14501                   if (VEX_MIPS_PROC_DSP(archinfo->hwcaps)) {
   14502                      /* If DSP is present -> DSP ASE MADD */
   14503                      UInt retVal = disDSPInstr_MIPS_WRK ( cins );
   14504                      if (0 != retVal ) {
   14505                         goto decode_failure_dsp;
   14506                      }
   14507                      break;
   14508                   } else {
   14509                      goto decode_failure_dsp;
   14510                   }
   14511                } else {
   14512                   DIP("madd r%u, r%u", rs, rt);
   14513                   t1 = newTemp(Ity_I32);
   14514                   t2 = newTemp(Ity_I32);
   14515                   t3 = newTemp(Ity_I64);
   14516                   t4 = newTemp(Ity_I32);
   14517                   t5 = newTemp(Ity_I32);
   14518                   t6 = newTemp(Ity_I32);
   14519 
   14520                   assign(t1, getHI());
   14521                   assign(t2, getLO());
   14522 
   14523                   assign(t3, binop(Iop_MullS32, getIReg(rs), getIReg(rt)));
   14524 
   14525                   assign(t4, binop(Iop_Add32, mkexpr(t2), unop(Iop_64to32,
   14526                                                                mkexpr(t3))));
   14527 
   14528                   assign(t5, unop(Iop_1Uto32, binop(Iop_CmpLT32U, mkexpr(t4),
   14529                                               unop(Iop_64to32, mkexpr(t3)))));
   14530                   assign(t6, binop(Iop_Add32, mkexpr(t5), mkexpr(t1)));
   14531 
   14532                   putHI(binop(Iop_Add32, mkexpr(t6), unop(Iop_64HIto32,
   14533                                                           mkexpr(t3))));
   14534                   putLO(mkexpr(t4));
   14535                   break;
   14536                }
   14537             }
   14538             break;
   14539          }
   14540 
   14541       case 0x01: {  /* MADDU */
   14542          if (mode64) {
   14543             DIP("maddu r%u, r%u", rs, rt);
   14544             t1 = newTemp(Ity_I32);
   14545             t2 = newTemp(Ity_I32);
   14546             t3 = newTemp(Ity_I64);
   14547             t4 = newTemp(Ity_I64);
   14548             t5 = newTemp(Ity_I64);
   14549             t6 = newTemp(Ity_I32);
   14550 
   14551             assign(t1, mkNarrowTo32(ty, getHI()));
   14552             assign(t2, mkNarrowTo32(ty, getLO()));
   14553 
   14554             assign(t3, binop(Iop_MullU32, mkNarrowTo32(ty, getIReg(rs)),
   14555                                           mkNarrowTo32(ty, getIReg(rt))));
   14556 
   14557             assign(t4, binop(Iop_32HLto64, mkexpr(t1), mkexpr(t2)));
   14558             assign(t5, binop(Iop_Add64, mkexpr(t3), mkexpr(t4)));
   14559 
   14560             putHI(mkWidenFrom32(ty, unop(Iop_64HIto32, mkexpr(t5)), True));
   14561             putLO(mkWidenFrom32(ty, unop(Iop_64to32, mkexpr(t5)), True));
   14562          } else {
   14563             if ( (1 <= ac) && ( 3 >= ac) ) {
   14564                if (VEX_MIPS_PROC_DSP(archinfo->hwcaps)) {
   14565                   /* If DSP is present -> DSP ASE MADDU */
   14566                   UInt retVal = disDSPInstr_MIPS_WRK ( cins );
   14567                   if (0 != retVal ) {
   14568                      goto decode_failure_dsp;
   14569                   }
   14570                   break;
   14571                } else {
   14572                   goto decode_failure_dsp;
   14573                }
   14574             } else {
   14575                DIP("maddu r%u, r%u", rs, rt);
   14576                t1 = newTemp(Ity_I32);
   14577                t2 = newTemp(Ity_I32);
   14578                t3 = newTemp(Ity_I64);
   14579                t4 = newTemp(Ity_I32);
   14580                t5 = newTemp(Ity_I32);
   14581                t6 = newTemp(Ity_I32);
   14582 
   14583                assign(t1, getHI());
   14584                assign(t2, getLO());
   14585 
   14586                assign(t3, binop(Iop_MullU32, getIReg(rs), getIReg(rt)));
   14587 
   14588                assign(t4, binop(Iop_Add32, mkexpr(t2), unop(Iop_64to32,
   14589                                                             mkexpr(t3))));
   14590                assign(t5, unop(Iop_1Uto32, binop(Iop_CmpLT32U, mkexpr(t4),
   14591                                            unop(Iop_64to32, mkexpr(t3)))));
   14592                assign(t6, binop(Iop_Add32, mkexpr(t5), mkexpr(t1)));
   14593 
   14594                putHI(binop(Iop_Add32, mkexpr(t6), unop(Iop_64HIto32,
   14595                                                       mkexpr(t3))));
   14596                putLO(mkexpr(t4));
   14597                break;
   14598             }
   14599          }
   14600          break;
   14601       }
   14602 
   14603       case 0x04: {  /* MSUB */
   14604          if (mode64) {
   14605             DIP("msub r%u, r%u", rs, rt);
   14606             t1 = newTemp(Ity_I32);
   14607             t2 = newTemp(Ity_I32);
   14608             t3 = newTemp(Ity_I64);
   14609             t4 = newTemp(Ity_I64);
   14610             t5 = newTemp(Ity_I64);
   14611             t6 = newTemp(Ity_I32);
   14612 
   14613             assign(t1, mkNarrowTo32(ty, getHI()));
   14614             assign(t2, mkNarrowTo32(ty, getLO()));
   14615 
   14616             assign(t3, binop(Iop_MullS32, mkNarrowTo32(ty, getIReg(rs)),
   14617                                           mkNarrowTo32(ty, getIReg(rt))));
   14618 
   14619             assign(t4, binop(Iop_32HLto64, mkexpr(t1), mkexpr(t2)));
   14620             assign(t5, binop(Iop_Sub64, mkexpr(t4), mkexpr(t3)));
   14621 
   14622             putHI(mkWidenFrom32(ty, unop(Iop_64HIto32, mkexpr(t5)), True));
   14623             putLO(mkWidenFrom32(ty, unop(Iop_64to32, mkexpr(t5)), True));
   14624          } else {
   14625             if ( (1 <= ac) && ( 3 >= ac) ) {
   14626                if (VEX_MIPS_PROC_DSP(archinfo->hwcaps)) {
   14627                   /* If DSP is present -> DSP ASE MSUB */
   14628                   UInt retVal = disDSPInstr_MIPS_WRK ( cins );
   14629                   if (0 != retVal ) {
   14630                      goto decode_failure_dsp;
   14631                   }
   14632                   break;
   14633                } else {
   14634                   goto decode_failure_dsp;
   14635                }
   14636             } else {
   14637                DIP("msub r%u, r%u", rs, rt);
   14638                t1 = newTemp(Ity_I32);
   14639                t2 = newTemp(Ity_I32);
   14640                t3 = newTemp(Ity_I64);
   14641                t4 = newTemp(Ity_I32);
   14642                t5 = newTemp(Ity_I1);
   14643                t6 = newTemp(Ity_I32);
   14644 
   14645                assign(t1, getHI());
   14646                assign(t2, getLO());
   14647 
   14648                assign(t3, binop(Iop_MullS32, getIReg(rs), getIReg(rt)));
   14649                assign(t4, unop(Iop_64to32, mkexpr(t3)));  /* new lo */
   14650 
   14651                /* if lo<lo(mul) hi = hi - 1 */
   14652                assign(t5, binop(Iop_CmpLT32U,
   14653                                  mkexpr(t2),
   14654                                  mkexpr(t4)));
   14655 
   14656                assign(t6, IRExpr_ITE(mkexpr(t5),
   14657                                        binop(Iop_Sub32, mkexpr(t1), mkU32(0x1)),
   14658                                        mkexpr(t1)));
   14659 
   14660                putHI(binop(Iop_Sub32, mkexpr(t6), unop(Iop_64HIto32,
   14661                                                       mkexpr(t3))));
   14662                putLO(binop(Iop_Sub32, mkexpr(t2), mkexpr(t4)));
   14663                break;
   14664             }
   14665          }
   14666          break;
   14667       }
   14668 
   14669       case 0x05: {  /* MSUBU */
   14670          if (mode64) {
   14671             DIP("msubu r%u, r%u", rs, rt);
   14672             t1 = newTemp(Ity_I32);
   14673             t2 = newTemp(Ity_I32);
   14674             t3 = newTemp(Ity_I64);
   14675             t4 = newTemp(Ity_I64);
   14676             t5 = newTemp(Ity_I64);
   14677             t6 = newTemp(Ity_I32);
   14678 
   14679             assign(t1, mkNarrowTo32(ty, getHI()));
   14680             assign(t2, mkNarrowTo32(ty, getLO()));
   14681 
   14682             assign(t3, binop(Iop_MullU32, mkNarrowTo32(ty, getIReg(rs)),
   14683                                           mkNarrowTo32(ty, getIReg(rt))));
   14684 
   14685             assign(t4, binop(Iop_32HLto64, mkexpr(t1), mkexpr(t2)));
   14686             assign(t5, binop(Iop_Sub64, mkexpr(t4), mkexpr(t3)));
   14687 
   14688             putHI(mkWidenFrom32(ty, unop(Iop_64HIto32, mkexpr(t5)), True));
   14689             putLO(mkWidenFrom32(ty, unop(Iop_64to32, mkexpr(t5)), True));
   14690          } else {
   14691             if ( (1 <= ac) && ( 3 >= ac) ) {
   14692                if (VEX_MIPS_PROC_DSP(archinfo->hwcaps)) {
   14693                   /* If DSP is present -> DSP ASE MSUBU */
   14694                   UInt retVal = disDSPInstr_MIPS_WRK ( cins );
   14695                   if (0 != retVal ) {
   14696                      goto decode_failure_dsp;
   14697                   }
   14698                   break;
   14699                } else {
   14700                   goto decode_failure_dsp;
   14701                }
   14702             } else {
   14703                DIP("msubu r%u, r%u", rs, rt);
   14704                t1 = newTemp(Ity_I32);
   14705                t2 = newTemp(Ity_I32);
   14706                t3 = newTemp(Ity_I64);
   14707                t4 = newTemp(Ity_I32);
   14708                t5 = newTemp(Ity_I1);
   14709                t6 = newTemp(Ity_I32);
   14710 
   14711                assign(t1, getHI());
   14712                assign(t2, getLO());
   14713 
   14714                assign(t3, binop(Iop_MullU32, getIReg(rs), getIReg(rt)));
   14715                assign(t4, unop(Iop_64to32, mkexpr(t3)));  /* new lo */
   14716 
   14717                /* if lo<lo(mul) hi = hi - 1 */
   14718                assign(t5, binop(Iop_CmpLT32U,
   14719                                  mkexpr(t2),
   14720                                  mkexpr(t4)));
   14721 
   14722                assign(t6, IRExpr_ITE(mkexpr(t5),
   14723                                     binop(Iop_Sub32,
   14724                                           mkexpr(t1),
   14725                                           mkU32(0x1)),
   14726                                     mkexpr(t1)));
   14727 
   14728                putHI(binop(Iop_Sub32, mkexpr(t6), unop(Iop_64HIto32,
   14729                                                       mkexpr(t3))));
   14730                putLO(binop(Iop_Sub32, mkexpr(t2), mkexpr(t4)));
   14731                break;
   14732             }
   14733          }
   14734          break;
   14735       }
   14736 
   14737       case 0x6:  /* dmul MIPS64 - Netlogic */
   14738          DIP("dmul r%u, r%u, r%u", rd, rs, rt);
   14739          t0 = newTemp(Ity_I128);
   14740 
   14741          assign(t0, binop(Iop_MullU64, getIReg(rs), getIReg(rt)));
   14742 
   14743          putIReg(rd, unop(Iop_128to64, mkexpr(t0)));
   14744          break;
   14745 
   14746       case 0x10:  /* LDADDW - Swap Word - Netlogic */
   14747          DIP("ldaddw r%u, r%u", rt, rs);
   14748          t0 = newTemp(Ity_I32);
   14749          t1 = newTemp(Ity_I32);
   14750          t2 = newTemp(Ity_I32);
   14751          t3 = newTemp(Ity_I64);
   14752          t4 = newTemp(Ity_I32);
   14753          t5 = newTemp(Ity_I32);
   14754          t6 = newTemp(Ity_I32);
   14755 
   14756          /* v = GPR[rt] */
   14757          assign(t0, mkNarrowTo32(ty, getIReg(rt)));
   14758 
   14759          /* GPR[rt] = memory[base]; */
   14760          assign(t1, load(Ity_I32, getIReg(rs)));
   14761          putIReg(rt, mkWidenFrom32(ty, mkexpr(t1), True));
   14762 
   14763          /* memory[base] = memory[base] + v; */
   14764          store(getIReg(rs), binop(Iop_Add32, mkexpr(t0), mkexpr(t1)));
   14765          break;
   14766 
   14767       case 0x12:  /* LDADDD - Swap Word - Netlogic */
   14768          DIP("ldaddw r%u, r%u", rt, rs);
   14769          t0 = newTemp(Ity_I64);
   14770          t1 = newTemp(Ity_I64);
   14771 
   14772          /*  v = GPR[rt] */
   14773          assign(t0, getIReg(rt));
   14774 
   14775          /* GPR[rt] = memory[base]; */
   14776          assign(t1, load(Ity_I64, getIReg(rs)));
   14777          putIReg(rt, mkexpr(t1));
   14778 
   14779          /* memory[base] = memory[base] + v; */
   14780          store(getIReg(rs), binop(Iop_Add64, mkexpr(t0), mkexpr(t1)));
   14781          break;
   14782 
   14783       case 0x14:  /* SWAPW - Swap Word - Netlogic */
   14784          DIP("swapw r%u, r%u", rt, rs);
   14785          t0 = newTemp(Ity_I32);
   14786          t1 = newTemp(Ity_I32);
   14787          assign(t0, mkNarrowTo32(ty, getIReg(rt)));
   14788          assign(t1, load(Ity_I32, getIReg(rs)));
   14789          putIReg(rt, mkWidenFrom32(ty, mkexpr(t1), True));
   14790          store(getIReg(rs), mkexpr(t0));
   14791          break;
   14792 
   14793       case 0x16:  /* SWAPD - Swap Double - Netlogic */
   14794          DIP("swapw r%u, r%u", rt, rs);
   14795          t0 = newTemp(Ity_I64);
   14796          t1 = newTemp(Ity_I64);
   14797          assign(t0, getIReg(rt));
   14798          assign(t1, load(Ity_I64, getIReg(rs)));
   14799          putIReg(rt, mkexpr(t1));
   14800          store(getIReg(rs), mkexpr(t0));
   14801          break;
   14802 
   14803       case 0x20: {  /* CLZ */
   14804          DIP("clz r%u, r%u", rd, rs);
   14805          if (mode64) {
   14806             IRTemp tmpClz32 = newTemp(Ity_I32);
   14807             IRTemp tmpRs32 = newTemp(Ity_I32);
   14808 
   14809             assign(tmpRs32, mkNarrowTo32(ty, getIReg(rs)));
   14810             assign(tmpClz32, unop(Iop_Clz32, mkexpr(tmpRs32)));
   14811             putIReg(rd, mkWidenFrom32(ty, mkexpr(tmpClz32), True));
   14812          } else {
   14813             t1 = newTemp(Ity_I1);
   14814             assign(t1, binop(Iop_CmpEQ32, getIReg(rs), mkU32(0)));
   14815             putIReg(rd, IRExpr_ITE(mkexpr(t1),
   14816                                    mkU32(0x00000020),
   14817                                    unop(Iop_Clz32, getIReg(rs))));
   14818          }
   14819          break;
   14820       }
   14821 
   14822       case 0x21: {  /* CLO */
   14823          DIP("clo r%u, r%u", rd, rs);
   14824          if (mode64) {
   14825             IRTemp tmpClo32 = newTemp(Ity_I32);
   14826             IRTemp tmpRs32 = newTemp(Ity_I32);
   14827             assign(tmpRs32, mkNarrowTo32(ty, getIReg(rs)));
   14828 
   14829             t1 = newTemp(Ity_I1);
   14830             assign(t1, binop(Iop_CmpEQ32, mkexpr(tmpRs32), mkU32(0xffffffff)));
   14831             assign(tmpClo32, IRExpr_ITE(mkexpr(t1),
   14832                       mkU32(0x00000020),
   14833                       unop(Iop_Clz32, unop(Iop_Not32, mkexpr(tmpRs32)))));
   14834 
   14835             putIReg(rd, mkWidenFrom32(ty, mkexpr(tmpClo32), True));
   14836             break;
   14837          } else {
   14838             t1 = newTemp(Ity_I1);
   14839             assign(t1, binop(Iop_CmpEQ32, getIReg(rs), mkU32(0xffffffff)));
   14840             putIReg(rd, IRExpr_ITE(mkexpr(t1),
   14841                                    mkU32(0x00000020),
   14842                                    unop(Iop_Clz32,
   14843                                         unop(Iop_Not32, getIReg(rs)))));
   14844             break;
   14845          }
   14846       }
   14847 
   14848       case 0x24:  /* Count Leading Zeros in Doubleword - DCLZ; MIPS64 */
   14849          DIP("dclz r%u, r%u", rd, rs);
   14850          t1 = newTemp(Ity_I1);
   14851          assign(t1, binop(Iop_CmpEQ64, getIReg(rs), mkU64(0)));
   14852          putIReg(rd, IRExpr_ITE(mkexpr(t1),
   14853                      mkU64(0x00000040),
   14854                      unop(Iop_Clz64, getIReg(rs))));
   14855          break;
   14856 
   14857       case 0x25:  /* Count Leading Ones in Doubleword - DCLO; MIPS64 */
   14858          DIP("dclo r%u, r%u", rd, rs);
   14859          t1 = newTemp(Ity_I1);
   14860          assign(t1, binop(Iop_CmpEQ64, getIReg(rs),
   14861                                         mkU64(0xffffffffffffffffULL)));
   14862          putIReg(rd, IRExpr_ITE(mkexpr(t1),
   14863                                 mkU64(0x40),
   14864                                 unop(Iop_Clz64, unop(Iop_Not64,
   14865                                                      getIReg(rs)))));
   14866          break;
   14867 
   14868       default:
   14869          goto decode_failure;
   14870       }
   14871       break;
   14872 
   14873    case 0x1F:  /* Special3 */
   14874       switch (function) {
   14875          case 0x01: {
   14876             /* Doubleword Extract Bit Field - DEXTM; MIPS64r2 */
   14877             msb = get_msb(cins);
   14878             lsb = get_lsb(cins);
   14879             size = msb + 1;
   14880             UInt srcPos = lsb;
   14881             UInt dstSz = msb + 33;
   14882             t1 = newTemp(Ity_I64);
   14883             DIP("dextm r%u, r%u, %u, %u", rt, rs, lsb, msb + 1);
   14884 
   14885             UChar lsAmt = 64 - (srcPos + dstSz);  /* left shift amount; */
   14886             UChar rsAmt = 64 - dstSz;  /* right shift amount; */
   14887 
   14888             assign(t1, binop(Iop_Shl64, getIReg(rs), mkU8(lsAmt)));
   14889             putIReg(rt, binop(Iop_Shr64, mkexpr(t1), mkU8(rsAmt)));
   14890 
   14891             break;
   14892          }
   14893          case 0x02: {
   14894             /* Doubleword Extract Bit Field Upper - DEXTU; MIPS64r2 */
   14895             msb = get_msb(cins);
   14896             lsb = get_lsb(cins);
   14897             size = msb + 1;
   14898             UInt srcPos = lsb + 32;
   14899             UInt dstSz = msb + 1;
   14900             DIP("dextu r%u, r%u, %u, %u", rt, rs, srcPos, dstSz);
   14901             t1 = newTemp(Ity_I64);
   14902 
   14903             vassert(srcPos >= 32 && srcPos < 64);
   14904             vassert(dstSz > 0 && dstSz <= 32);
   14905             vassert((srcPos + dstSz) > 32 && (srcPos + dstSz) <= 64);
   14906 
   14907             UChar lsAmt = 64 - (srcPos + dstSz);  /* left shift amount; */
   14908             UChar rsAmt = 64 - dstSz;  /* right shift amount; */
   14909 
   14910             assign(t1, binop(Iop_Shl64, getIReg(rs), mkU8(lsAmt)));
   14911             putIReg(rt, binop(Iop_Shr64, mkexpr(t1), mkU8(rsAmt)));
   14912             break;
   14913          }
   14914          case 0x05: {
   14915             /* Doubleword Insert Bit Field Middle - DINSM; MIPS64r2 */
   14916             msb = get_msb(cins);
   14917             lsb = get_lsb(cins);
   14918             size = msb + 1;
   14919             UInt dstPos = lsb;
   14920             UInt srcSz = msb - lsb + 33;
   14921             t1 = newTemp(ty);
   14922             t2 = newTemp(ty);
   14923             t3 = newTemp(ty);
   14924             t4 = newTemp(ty);
   14925             IRTemp tmpT1 = newTemp(ty);
   14926             IRTemp tmpT2 = newTemp(ty);
   14927             IRTemp tmpT3 = newTemp(ty);
   14928             IRTemp tmpT4 = newTemp(ty);
   14929             IRTemp tmpT5 = newTemp(ty);
   14930             IRTemp tmpT6 = newTemp(ty);
   14931             IRTemp tmpT7 = newTemp(ty);
   14932             IRTemp tmpRs = newTemp(ty);
   14933             IRTemp tmpRt = newTemp(ty);
   14934             IRTemp tmpRd = newTemp(ty);
   14935 
   14936             assign(tmpRs, getIReg(rs));
   14937             assign(tmpRt, getIReg(rt));
   14938             DIP("dinsm r%u, r%u, %u, %u", rt, rs, lsb, msb);
   14939 
   14940             UChar lsAmt = dstPos + srcSz - 1;   /* left shift amount; */
   14941             UChar rsAmt = dstPos + srcSz - 1;   /* right shift amount; */
   14942 
   14943             assign(t1, binop(Iop_Shr64, mkexpr(tmpRt), mkU8(rsAmt)));
   14944             assign(tmpT1, binop(Iop_Shr64, mkexpr(t1), mkU8(1)));
   14945             assign(t2, binop(Iop_Shl64, mkexpr(tmpT1), mkU8(lsAmt)));
   14946             assign(tmpT2, binop(Iop_Shl64, mkexpr(t2), mkU8(1)));
   14947 
   14948             lsAmt = 63 - dstPos; /* left shift amount; */
   14949             rsAmt = 63 - dstPos; /* right shift amount; */
   14950 
   14951             assign(t3, binop(Iop_Shl64, mkexpr(tmpRt), mkU8(lsAmt)));
   14952             assign(tmpT3, binop(Iop_Shl64, mkexpr(t3), mkU8(1)));
   14953             assign(t4, binop(Iop_Shr64, mkexpr(tmpT3), mkU8(rsAmt)));
   14954             assign(tmpT4, binop(Iop_Shr64, mkexpr(t4), mkU8(1)));
   14955 
   14956             /* extract size from src register */
   14957             lsAmt = 64 - srcSz;  /* left shift amount; */
   14958             rsAmt = 64 - (lsb + srcSz);   /* right shift amount; */
   14959 
   14960             assign(tmpT5, binop(Iop_Shl64, mkexpr(tmpRs), mkU8(lsAmt)));
   14961             assign(tmpT6, binop(Iop_Shr64, mkexpr(tmpT5), mkU8(rsAmt)));
   14962 
   14963             assign(tmpT7, binop(Iop_Or64, mkexpr(tmpT2), mkexpr(tmpT4)));
   14964             assign(tmpRd, binop(Iop_Or64, mkexpr(tmpT6), mkexpr(tmpT7)));
   14965             putIReg(rt, mkexpr(tmpRd));
   14966             break;
   14967          }
   14968          case 0x06: {
   14969             /* Doubleword Insert Bit Field Upper - DINSU; MIPS64r2 */
   14970             msb = get_msb(cins);
   14971             lsb = get_lsb(cins);
   14972             size = msb + 1;
   14973             UInt dstPos = lsb + 32;
   14974             UInt srcSz = msb - lsb + 1;
   14975             IRTemp tmpT1 = newTemp(ty);
   14976             IRTemp tmpT2 = newTemp(ty);
   14977             IRTemp tmpT3 = newTemp(ty);
   14978             IRTemp tmpT4 = newTemp(ty);
   14979             IRTemp tmpT5 = newTemp(ty);
   14980             IRTemp tmpT6 = newTemp(ty);
   14981             IRTemp tmpT7 = newTemp(ty);
   14982             IRTemp tmpT8 = newTemp(ty);
   14983             IRTemp tmpT9 = newTemp(ty);
   14984             IRTemp tmpRs = newTemp(ty);
   14985             IRTemp tmpRt = newTemp(ty);
   14986             IRTemp tmpRd = newTemp(ty);
   14987 
   14988             assign(tmpRs, getIReg(rs));
   14989             assign(tmpRt, getIReg(rt));
   14990             DIP("dinsu r%u, r%u, %u, %u", rt, rs, lsb, msb);
   14991 
   14992             UChar lsAmt = 64 - srcSz;  /* left shift amount; */
   14993             UChar rsAmt = 64 - (dstPos + srcSz);  /* right shift amount; */
   14994             assign(tmpT1, binop(Iop_Shl64, mkexpr(tmpRs), mkU8(lsAmt)));
   14995             assign(tmpT2, binop(Iop_Shr64, mkexpr(tmpT1), mkU8(rsAmt)));
   14996 
   14997             lsAmt = 64 - dstPos;  /* left shift amount; */
   14998             rsAmt = 64 - dstPos;  /* right shift amount; */
   14999             assign(tmpT3, binop(Iop_Shl64, mkexpr(tmpRt), mkU8(lsAmt)));
   15000             assign(tmpT4, binop(Iop_Shr64, mkexpr(tmpT3), mkU8(rsAmt)));
   15001 
   15002             lsAmt = dstPos;  /* left shift amount; */
   15003             rsAmt = srcSz;  /* right shift amount; */
   15004             assign(tmpT5, binop(Iop_Shr64, mkexpr(tmpRt), mkU8(rsAmt)));
   15005             assign(tmpT6, binop(Iop_Shr64, mkexpr(tmpT5), mkU8(lsAmt)));
   15006 
   15007             assign(tmpT7, binop(Iop_Shl64, mkexpr(tmpT6), mkU8(rsAmt)));
   15008             assign(tmpT8, binop(Iop_Shl64, mkexpr(tmpT7), mkU8(lsAmt)));
   15009 
   15010             assign(tmpT9, binop(Iop_Or64, mkexpr(tmpT8), mkexpr(tmpT4)));
   15011             assign(tmpRd, binop(Iop_Or64, mkexpr(tmpT2), mkexpr(tmpT9)));
   15012             putIReg(rt, mkexpr(tmpRd));
   15013             break;
   15014          }
   15015          case 0x07: {
   15016             /* Doubleword Insert Bit Field - DINS; MIPS64r2 */
   15017             IRTemp tmp1 = newTemp(ty);
   15018             IRTemp tmpT1 = newTemp(ty);
   15019             IRTemp tmpT2 = newTemp(ty);
   15020             IRTemp tmpT3 = newTemp(ty);
   15021             IRTemp tmpT4 = newTemp(ty);
   15022             IRTemp tmpT5 = newTemp(ty);
   15023             IRTemp tmpT6 = newTemp(ty);
   15024             IRTemp tmpT7 = newTemp(ty);
   15025             IRTemp tmpT8 = newTemp(ty);
   15026             IRTemp tmpT9 = newTemp(ty);
   15027             IRTemp tmp = newTemp(ty);
   15028             IRTemp tmpRs = newTemp(ty);
   15029             IRTemp tmpRt = newTemp(ty);
   15030             IRTemp tmpRd = newTemp(ty);
   15031 
   15032             assign(tmpRs, getIReg(rs));
   15033             assign(tmpRt, getIReg(rt));
   15034 
   15035             msb = get_msb(cins);
   15036             lsb = get_lsb(cins);
   15037             size = msb + 1;
   15038             DIP("dins r%u, r%u, %u, %u", rt, rs, lsb,
   15039                 msb - lsb + 1);
   15040             UChar lsAmt = 63 - lsb;  /* left shift amount; */
   15041             UChar rsAmt = 63 - lsb;  /* right shift amount; */
   15042             assign(tmp, binop(Iop_Shl64, mkexpr(tmpRt), mkU8(lsAmt)));
   15043             assign(tmpT1, binop(Iop_Shl64, mkexpr(tmp), mkU8(1)));
   15044             assign(tmp1, binop(Iop_Shr64, mkexpr(tmpT1), mkU8(rsAmt)));
   15045             assign(tmpT2, binop(Iop_Shr64, mkexpr(tmp1), mkU8(1)));
   15046 
   15047             lsAmt = msb;  /* left shift amount; */
   15048             rsAmt = 1;  /*right shift amount; */
   15049             assign(tmpT3, binop(Iop_Shr64, mkexpr(tmpRt), mkU8(rsAmt)));
   15050             assign(tmpT4, binop(Iop_Shr64, mkexpr(tmpT3), mkU8(lsAmt)));
   15051             assign(tmpT5, binop(Iop_Shl64, mkexpr(tmpT4), mkU8(rsAmt)));
   15052             assign(tmpT6, binop(Iop_Shl64, mkexpr(tmpT5), mkU8(lsAmt)));
   15053 
   15054             lsAmt = 64 - (msb - lsb + 1);  /* left shift amount; */
   15055             rsAmt = 64 - (msb + 1);  /* right shift amount; */
   15056             assign(tmpT7, binop(Iop_Shl64, mkexpr(tmpRs), mkU8(lsAmt)));
   15057             assign(tmpT8, binop(Iop_Shr64, mkexpr(tmpT7), mkU8(rsAmt)));
   15058 
   15059             assign(tmpT9, binop(Iop_Or64, mkexpr(tmpT2), mkexpr(tmpT8)));
   15060             assign(tmpRd, binop(Iop_Or64, mkexpr(tmpT6), mkexpr(tmpT9)));
   15061             putIReg(rt, mkexpr(tmpRd));
   15062             break;
   15063          }
   15064       case 0x24:  /* DBSHFL */
   15065          lsb = get_lsb(cins);
   15066          IRTemp tmpRs = newTemp(ty);
   15067          IRTemp tmpRt = newTemp(ty);
   15068          IRTemp tmpRd = newTemp(ty);
   15069          assign(tmpRs, getIReg(rs));
   15070          assign(tmpRt, getIReg(rt));
   15071          switch (lsb) {
   15072             case 0x02: {  /* DSBH */
   15073                DIP("dsbh r%u, r%u", rd, rt);
   15074                IRTemp tmpT1 = newTemp(ty);
   15075                IRTemp tmpT2 = newTemp(ty);
   15076                IRTemp tmpT3 = newTemp(ty);
   15077                IRTemp tmpT4 = newTemp(ty);
   15078                IRTemp tmpT5 = newTemp(Ity_I64);
   15079                IRTemp tmpT6 = newTemp(ty);
   15080                assign(tmpT5, mkU64(0xFF00FF00FF00FF00ULL));
   15081                assign(tmpT6, mkU64(0x00FF00FF00FF00FFULL));
   15082                assign(tmpT1, binop(Iop_And64, mkexpr(tmpRt), mkexpr(tmpT5)));
   15083                assign(tmpT2, binop(Iop_Shr64, mkexpr(tmpT1), mkU8(8)));
   15084                assign(tmpT3, binop(Iop_And64, mkexpr(tmpRt), mkexpr(tmpT6)));
   15085                assign(tmpT4, binop(Iop_Shl64, mkexpr(tmpT3), mkU8(8)));
   15086                assign(tmpRd, binop(Iop_Or64, mkexpr(tmpT4), mkexpr(tmpT2)));
   15087                putIReg(rd, mkexpr(tmpRd));
   15088                break;
   15089             }
   15090             case 0x05: {  /* DSHD */
   15091                DIP("dshd r%u, r%u\n", rd, rt);
   15092                IRTemp tmpT1 = newTemp(ty);
   15093                IRTemp tmpT2 = newTemp(ty);
   15094                IRTemp tmpT3 = newTemp(ty);
   15095                IRTemp tmpT4 = newTemp(ty);
   15096                IRTemp tmpT5 = newTemp(Ity_I64);
   15097                IRTemp tmpT6 = newTemp(ty);
   15098                IRTemp tmpT7 = newTemp(ty);
   15099                IRTemp tmpT8 = newTemp(ty);
   15100                IRTemp tmpT9 = newTemp(ty);
   15101                assign(tmpT5, mkU64(0xFFFF0000FFFF0000ULL));
   15102                assign(tmpT6, mkU64(0x0000FFFF0000FFFFULL));
   15103                assign(tmpT1, binop(Iop_And64, mkexpr(tmpRt), mkexpr(tmpT5)));
   15104                assign(tmpT2, binop(Iop_Shr64, mkexpr(tmpT1), mkU8(16)));
   15105                assign(tmpT3, binop(Iop_And64, mkexpr(tmpRt), mkexpr(tmpT6)));
   15106                assign(tmpT4, binop(Iop_Shl64, mkexpr(tmpT3), mkU8(16)));
   15107                assign(tmpT7, binop(Iop_Or64, mkexpr(tmpT4), mkexpr(tmpT2)));
   15108                assign(tmpT8, binop(Iop_Shl64, mkexpr(tmpT7), mkU8(32)));
   15109                assign(tmpT9, binop(Iop_Shr64, mkexpr(tmpT7), mkU8(32)));
   15110                assign(tmpRd, binop(Iop_Or64, mkexpr(tmpT8), mkexpr(tmpT9)));
   15111                putIReg(rd, mkexpr(tmpRd));
   15112                break;
   15113             }
   15114          default:
   15115             vex_printf("\nop6o10 = %u", lsb);
   15116             goto decode_failure;;
   15117          }
   15118          break;
   15119       case 0x3B: {  /* RDHWR */
   15120          DIP("rdhwr r%u, r%u", rt, rd);
   15121             if (rd == 29) {
   15122                putIReg(rt, getULR());
   15123 #if defined(__mips__) && ((defined(__mips_isa_rev) && __mips_isa_rev >= 2))
   15124             } else if (rd == 1
   15125                        || (rd == 31
   15126                            && VEX_MIPS_COMP_ID(archinfo->hwcaps)
   15127                                                     == VEX_PRID_COMP_CAVIUM)) {
   15128                if (mode64) {
   15129                   IRTemp   val  = newTemp(Ity_I64);
   15130                   IRExpr** args = mkIRExprVec_2 (mkU64(rt), mkU64(rd));
   15131                   IRDirty *d = unsafeIRDirty_1_N(val,
   15132                                                  0,
   15133                                                  "mips64_dirtyhelper_rdhwr",
   15134                                                  &mips64_dirtyhelper_rdhwr,
   15135                                                  args);
   15136                   stmt(IRStmt_Dirty(d));
   15137                   putIReg(rt, mkexpr(val));
   15138                } else {
   15139                   IRTemp   val  = newTemp(Ity_I32);
   15140                   IRExpr** args = mkIRExprVec_2 (mkU32(rt), mkU32(rd));
   15141                   IRDirty *d = unsafeIRDirty_1_N(val,
   15142                                                  0,
   15143                                                  "mips32_dirtyhelper_rdhwr",
   15144                                                  &mips32_dirtyhelper_rdhwr,
   15145                                                  args);
   15146                   stmt(IRStmt_Dirty(d));
   15147                   putIReg(rt, mkexpr(val));
   15148                }
   15149 #endif
   15150             } else
   15151                goto decode_failure;
   15152             break;
   15153          }
   15154       case 0x04:  /* INS */
   15155          msb = get_msb(cins);
   15156          lsb = get_lsb(cins);
   15157          size = msb - lsb + 1;
   15158          DIP("ins size:%u msb:%u lsb:%u", size, msb, lsb);
   15159 
   15160          vassert(lsb + size <= 32);
   15161          vassert(lsb + size > 0);
   15162 
   15163          /* put size bits from rs at the pos in temporary */
   15164          t0 = newTemp(Ity_I32);
   15165          t3 = newTemp(Ity_I32);
   15166          /* shift left for 32 - size to clear leading bits and get zeros
   15167             at the end */
   15168          assign(t0, binop(Iop_Shl32, mkNarrowTo32(ty, getIReg(rs)),
   15169                           mkU8(32 - size)));
   15170          /* now set it at pos */
   15171          t1 = newTemp(Ity_I32);
   15172          assign(t1, binop(Iop_Shr32, mkexpr(t0), mkU8(32 - size - lsb)));
   15173 
   15174          if (lsb > 0) {
   15175             t2 = newTemp(Ity_I32);
   15176             /* clear everything but lower pos bits from rt */
   15177             assign(t2, binop(Iop_Shl32, mkNarrowTo32(ty, getIReg(rt)),
   15178                              mkU8(32 - lsb)));
   15179             assign(t3, binop(Iop_Shr32, mkexpr(t2), mkU8(32 - lsb)));
   15180          } else
   15181             assign(t3, mkU32(0));
   15182 
   15183          if (msb < 31) {
   15184             t4 = newTemp(Ity_I32);
   15185             /* clear everything but upper msb + 1 bits from rt */
   15186             assign(t4, binop(Iop_Shr32, mkNarrowTo32(ty, getIReg(rt)),
   15187                              mkU8(msb + 1)));
   15188             t5 = newTemp(Ity_I32);
   15189             assign(t5, binop(Iop_Shl32, mkexpr(t4), mkU8(msb + 1)));
   15190 
   15191             /* now combine these registers */
   15192             if (lsb > 0) {
   15193                t6 = newTemp(Ity_I32);
   15194                assign(t6, binop(Iop_Or32, mkexpr(t5), mkexpr(t1)));
   15195                putIReg(rt, mkWidenFrom32(ty, binop(Iop_Or32, mkexpr(t6),
   15196                                                    mkexpr(t3)), True));
   15197             } else {
   15198                putIReg(rt, mkWidenFrom32(ty, binop(Iop_Or32, mkexpr(t1),
   15199                                                    mkexpr(t5)), True));
   15200             }
   15201          } else {
   15202             putIReg(rt, mkWidenFrom32(ty, binop(Iop_Or32, mkexpr(t1),
   15203                                                 mkexpr(t3)), True));
   15204          }
   15205          break;
   15206 
   15207       case 0x00:  /* EXT */
   15208          msb = get_msb(cins);
   15209          lsb = get_lsb(cins);
   15210          size = msb + 1;
   15211          DIP("ext size:%u msb:%u lsb:%u", size, msb, lsb);
   15212          vassert(lsb + size <= 32);
   15213          vassert(lsb + size > 0);
   15214          /* put size bits from rs at the top of in temporary */
   15215          if (lsb + size < 32) {
   15216             t0 = newTemp(Ity_I32);
   15217             assign(t0, binop(Iop_Shl32, mkNarrowTo32(ty, getIReg(rs)),
   15218                              mkU8(32 - lsb - size)));
   15219 
   15220             putIReg(rt, mkWidenFrom32(ty, binop(Iop_Shr32, mkexpr(t0),
   15221                                                 mkU8(32 - size)), True));
   15222          } else {
   15223             putIReg(rt, mkWidenFrom32(ty, binop(Iop_Shr32,
   15224                                                 mkNarrowTo32(ty, getIReg(rs)),
   15225                                                 mkU8(32 - size)), True));
   15226          }
   15227          break;
   15228 
   15229       case 0x03:  /* Doubleword Extract Bit Field - DEXT; MIPS64r2 */
   15230          msb = get_msb(cins);
   15231          lsb = get_lsb(cins);
   15232          size = msb + 1;
   15233          DIP("dext r%u, r%u, %u, %u", rt, rs, lsb, msb + 1);
   15234          t1 = newTemp(Ity_I64);
   15235          vassert(lsb >= 0 && lsb < 32);
   15236          vassert(size > 0 && size <= 32);
   15237          vassert((lsb + size) > 0 && (lsb + size) <= 63);
   15238 
   15239          UChar lsAmt = 63 - (lsb + msb);  /* left shift amount; */
   15240          UChar rsAmt = 63 - msb;  /* right shift amount; */
   15241 
   15242          assign(t1, binop(Iop_Shl64, getIReg(rs), mkU8(lsAmt)));
   15243          putIReg(rt, binop(Iop_Shr64, mkexpr(t1), mkU8(rsAmt)));
   15244 
   15245          break;
   15246 
   15247       case 0x20:  /* BSHFL */
   15248          switch (sa) {
   15249             case 0x02:  /* WSBH */
   15250                DIP("wsbh r%u, r%u", rd, rt);
   15251                t0 = newTemp(Ity_I32);
   15252                t1 = newTemp(Ity_I32);
   15253                t2 = newTemp(Ity_I32);
   15254                t3 = newTemp(Ity_I32);
   15255                assign(t0, binop(Iop_Shl32, binop(Iop_And32, mkNarrowTo32(ty,
   15256                                            getIReg(rt)), mkU32(0x00FF0000)),
   15257                                            mkU8(0x8)));
   15258                assign(t1, binop(Iop_Shr32, binop(Iop_And32, mkNarrowTo32(ty,
   15259                                 getIReg(rt)), mkU32(0xFF000000)), mkU8(0x8)));
   15260                assign(t2, binop(Iop_Shl32, binop(Iop_And32, mkNarrowTo32(ty,
   15261                                 getIReg(rt)), mkU32(0x000000FF)), mkU8(0x8)));
   15262                assign(t3, binop(Iop_Shr32, binop(Iop_And32, mkNarrowTo32(ty,
   15263                                 getIReg(rt)), mkU32(0x0000FF00)), mkU8(0x8)));
   15264                putIReg(rd, mkWidenFrom32(ty, binop(Iop_Or32, binop(Iop_Or32,
   15265                                          mkexpr(t0), mkexpr(t1)),
   15266                                          binop(Iop_Or32, mkexpr(t2),
   15267                                          mkexpr(t3))), True));
   15268                break;
   15269 
   15270             case 0x10:  /* SEB */
   15271                DIP("seb r%u, r%u", rd, rt);
   15272                if (mode64)
   15273                   putIReg(rd, unop(Iop_8Sto64, unop(Iop_64to8, getIReg(rt))));
   15274                else
   15275                   putIReg(rd, unop(Iop_8Sto32, unop(Iop_32to8, getIReg(rt))));
   15276                break;
   15277 
   15278             case 0x18:  /* SEH */
   15279                DIP("seh r%u, r%u", rd, rt);
   15280                if (mode64)
   15281                   putIReg(rd, unop(Iop_16Sto64, unop(Iop_64to16, getIReg(rt))));
   15282                else
   15283                   putIReg(rd, unop(Iop_16Sto32, unop(Iop_32to16, getIReg(rt))));
   15284                break;
   15285 
   15286             default:
   15287                goto decode_failure;
   15288 
   15289          }
   15290          break;  /* BSHFL */
   15291 
   15292       /* --- MIPS32(r2) DSP ASE(r2) / Cavium Specfic (LX) instructions --- */
   15293       case 0xA:  /* LX */
   15294          if (VEX_MIPS_COMP_ID(archinfo->hwcaps) == VEX_PRID_COMP_CAVIUM) {
   15295             if (dis_instr_CVM(cins))
   15296                break;
   15297             goto decode_failure;
   15298          }
   15299       case 0xC:  /* INSV */
   15300       case 0x38: {  /* EXTR.W */
   15301          if (VEX_MIPS_PROC_DSP(archinfo->hwcaps)) {
   15302             UInt retVal = disDSPInstr_MIPS_WRK ( cins );
   15303             if (0 != retVal ) {
   15304                goto decode_failure_dsp;
   15305             }
   15306             break;
   15307          } else {
   15308             goto decode_failure_dsp;
   15309          }
   15310          break;
   15311       }
   15312       case 0x10: {  /* ADDU.QB */
   15313          switch(sa) {
   15314             case  0xC:  /* SUBU_S.PH */
   15315             case  0xD:  /* ADDU_S.PH */
   15316             case 0x1E: {  /* MULQ_S.PH */
   15317                if (VEX_MIPS_PROC_DSP2(archinfo->hwcaps)) {
   15318                   UInt retVal = disDSPInstr_MIPS_WRK ( cins );
   15319                   if (0 != retVal ) {
   15320                      goto decode_failure_dsp;
   15321                   }
   15322                   break;
   15323                } else {
   15324                   goto decode_failure_dsp;
   15325                }
   15326                break;
   15327             }
   15328             default: {
   15329                if (VEX_MIPS_PROC_DSP(archinfo->hwcaps)) {
   15330                   UInt retVal = disDSPInstr_MIPS_WRK ( cins );
   15331                   if (0 != retVal ) {
   15332                      goto decode_failure_dsp;
   15333                   }
   15334                   break;
   15335                } else {
   15336                   goto decode_failure_dsp;
   15337                }
   15338                break;
   15339             }
   15340          }
   15341          break;
   15342       }
   15343       case 0x11: {  /* CMPU.EQ.QB */
   15344          switch(sa) {
   15345             case 0x18:  /* CMPGDU.EQ.QB */
   15346             case 0x19:  /* CMPGDU.LT.QB */
   15347             case 0x1A:  /* CMPGDU.LE.QB */
   15348             case 0x0D:  /* PRECR.QB.PH */
   15349             case 0x1E:  /* PRECR_SRA.PH.W */
   15350             case 0x1F: {  /* PRECR_SRA_R.PH.W */
   15351                if (VEX_MIPS_PROC_DSP2(archinfo->hwcaps)) {
   15352                   UInt retVal = disDSPInstr_MIPS_WRK ( cins );
   15353                   if (0 != retVal ) {
   15354                      goto decode_failure_dsp;
   15355                   }
   15356                   break;
   15357                } else {
   15358                   goto decode_failure_dsp;
   15359                }
   15360                break;
   15361             }
   15362             default: {
   15363                if (VEX_MIPS_PROC_DSP(archinfo->hwcaps)) {
   15364                   UInt retVal = disDSPInstr_MIPS_WRK ( cins );
   15365                   if (0 != retVal ) {
   15366                      goto decode_failure_dsp;
   15367                   }
   15368                   break;
   15369                } else {
   15370                   goto decode_failure_dsp;
   15371                }
   15372                break;
   15373             }
   15374          }
   15375          break;
   15376       }
   15377       case 0x12: {  /* ABSQ_S.PH */
   15378          switch(sa){
   15379             case 0x1: {  /* ABSQ_S.QB */
   15380                if (VEX_MIPS_PROC_DSP2(archinfo->hwcaps)) {
   15381                   UInt retVal = disDSPInstr_MIPS_WRK ( cins );
   15382                   if (0 != retVal ) {
   15383                      goto decode_failure_dsp;
   15384                   }
   15385                   break;
   15386                } else {
   15387                   goto decode_failure_dsp;
   15388                }
   15389                break;
   15390             }
   15391             default: {
   15392                if (VEX_MIPS_PROC_DSP(archinfo->hwcaps)) {
   15393                   UInt retVal = disDSPInstr_MIPS_WRK ( cins );
   15394                   if (0 != retVal ) {
   15395                      goto decode_failure_dsp;
   15396                   }
   15397                   break;
   15398                } else {
   15399                   goto decode_failure_dsp;
   15400                }
   15401                break;
   15402             }
   15403          }
   15404          break;
   15405       }
   15406       case 0x13: {  /* SHLL.QB */
   15407          switch(sa) {
   15408             case 0x04:  /* SHRA.QB */
   15409             case 0x05:  /* SHRA_R.QB */
   15410             case 0x06:  /* SHRAV.QB */
   15411             case 0x07:  /* SHRAV_R.QB */
   15412             case 0x19:  /* SHLR.PH */
   15413             case 0x1B: {  /* SHLRV.PH */
   15414                if (VEX_MIPS_PROC_DSP2(archinfo->hwcaps)) {
   15415                   UInt retVal = disDSPInstr_MIPS_WRK ( cins );
   15416                   if (0 != retVal ) {
   15417                      goto decode_failure_dsp;
   15418                   }
   15419                   break;
   15420                } else {
   15421                   goto decode_failure_dsp;
   15422                }
   15423                break;
   15424             }
   15425             default: {
   15426                if (VEX_MIPS_PROC_DSP(archinfo->hwcaps)) {
   15427                   UInt retVal = disDSPInstr_MIPS_WRK ( cins );
   15428                   if (0 != retVal ) {
   15429                      goto decode_failure_dsp;
   15430                   }
   15431                   break;
   15432                } else {
   15433                   goto decode_failure_dsp;
   15434                }
   15435                break;
   15436             }
   15437          }
   15438          break;
   15439       }
   15440       case 0x30: {  /* DPAQ.W.PH */
   15441          switch(sa) {
   15442             case  0x0:  /* DPA.W.PH */
   15443             case 0x18:  /* DPAQX_S.W.PH */
   15444             case 0x1A:  /* DPAQX_SA.W.PH */
   15445             case  0x8:  /* DPAX.W.PH */
   15446             case  0x1:  /* DPS.W.PH */
   15447             case 0x19:  /* DPSQX_S.W.PH */
   15448             case 0x1B:  /* DPSQX_SA.W.PH */
   15449             case  0x9:  /* DPSX.W.PH */
   15450             case  0x2: {  /* MULSA.W.PH */
   15451                if (VEX_MIPS_PROC_DSP2(archinfo->hwcaps)) {
   15452                   UInt retVal = disDSPInstr_MIPS_WRK ( cins );
   15453                   if (0 != retVal ) {
   15454                      goto decode_failure_dsp;
   15455                   }
   15456                   break;
   15457                } else {
   15458                   goto decode_failure_dsp;
   15459                }
   15460                break;
   15461             }
   15462             default: {
   15463                if (VEX_MIPS_PROC_DSP(archinfo->hwcaps)) {
   15464                   UInt retVal = disDSPInstr_MIPS_WRK ( cins );
   15465                   if (0 != retVal ) {
   15466                      goto decode_failure_dsp;
   15467                   }
   15468                   break;
   15469                } else {
   15470                   goto decode_failure_dsp;
   15471                }
   15472                break;
   15473             }
   15474          }
   15475          break;
   15476       }
   15477       case 0x18:  /* ADDUH.QB/MUL.PH */
   15478       case 0x31: {  /* APPEND */
   15479          if (VEX_MIPS_PROC_DSP2(archinfo->hwcaps)) {
   15480             UInt retVal = disDSPInstr_MIPS_WRK ( cins );
   15481             if (0 != retVal ) {
   15482                goto decode_failure_dsp;
   15483             }
   15484             break;
   15485          } else {
   15486             goto decode_failure_dsp;
   15487          }
   15488       }
   15489       default:
   15490          goto decode_failure;
   15491 
   15492    }
   15493       break;  /* Special3 */
   15494 
   15495    case 0x3B:
   15496       if (0x3B == function &&
   15497           (VEX_MIPS_COMP_ID(archinfo->hwcaps) == VEX_PRID_COMP_BROADCOM)) {
   15498          /*RDHWR*/
   15499          DIP("rdhwr r%u, r%u", rt, rd);
   15500          if (rd == 29) {
   15501             putIReg(rt, getULR());
   15502          } else
   15503             goto decode_failure;
   15504          break;
   15505       } else {
   15506          goto decode_failure;
   15507       }
   15508 
   15509    case 0x00:  /* Special */
   15510 
   15511       switch (function) {
   15512       case 0x1: {
   15513          UInt mov_cc = get_mov_cc(cins);
   15514          if (tf == 0) {  /* MOVF */
   15515             DIP("movf r%u, r%u, %u", rd, rs, mov_cc);
   15516             t1 = newTemp(Ity_I1);
   15517             t2 = newTemp(Ity_I32);
   15518             t3 = newTemp(Ity_I1);
   15519 
   15520             assign(t1, binop(Iop_CmpEQ32, mkU32(0), mkU32(mov_cc)));
   15521             assign(t2, IRExpr_ITE(mkexpr(t1),
   15522                                   binop(Iop_And32,
   15523                                         binop(Iop_Shr32, getFCSR(),
   15524                                               mkU8(23)),
   15525                                         mkU32(0x1)),
   15526                                   binop(Iop_And32,
   15527                                         binop(Iop_Shr32, getFCSR(),
   15528                                               mkU8(24 + mov_cc)),
   15529                                         mkU32(0x1))
   15530                                   ));
   15531             assign(t3, binop(Iop_CmpEQ32, mkU32(0), mkexpr(t2)));
   15532             putIReg(rd, IRExpr_ITE(mkexpr(t3), getIReg(rs), getIReg(rd)));
   15533          } else if (tf == 1) {  /* MOVT */
   15534             DIP("movt r%u, r%u, %u", rd, rs, mov_cc);
   15535             t1 = newTemp(Ity_I1);
   15536             t2 = newTemp(Ity_I32);
   15537             t3 = newTemp(Ity_I1);
   15538 
   15539             assign(t1, binop(Iop_CmpEQ32, mkU32(0), mkU32(mov_cc)));
   15540             assign(t2, IRExpr_ITE(mkexpr(t1),
   15541                                   binop(Iop_And32,
   15542                                         binop(Iop_Shr32, getFCSR(),
   15543                                               mkU8(23)),
   15544                                         mkU32(0x1)),
   15545                                   binop(Iop_And32,
   15546                                         binop(Iop_Shr32, getFCSR(),
   15547                                               mkU8(24 + mov_cc)),
   15548                                         mkU32(0x1))
   15549                                   ));
   15550             assign(t3, binop(Iop_CmpEQ32, mkU32(1), mkexpr(t2)));
   15551             putIReg(rd, IRExpr_ITE(mkexpr(t3), getIReg(rs), getIReg(rd)));
   15552          }
   15553          break;
   15554       }
   15555       case 0x0A: {  /* MOVZ */
   15556          DIP("movz r%u, r%u, r%u", rd, rs, rt);
   15557          t1 = newTemp(ty);
   15558          t2 = newTemp(ty);
   15559          if (mode64) {
   15560             assign(t1, unop(Iop_32Sto64, unop(Iop_1Sto32, binop(Iop_CmpEQ64,
   15561                             getIReg(rt), mkU64(0x0)))));
   15562             assign(t2, unop(Iop_32Sto64, unop(Iop_1Sto32, binop(Iop_CmpNE64,
   15563                             getIReg(rt), mkU64(0x0)))));
   15564             putIReg(rd, binop(Iop_Add64, binop(Iop_And64, getIReg(rs),
   15565                         mkexpr(t1)), binop(Iop_And64, getIReg(rd),mkexpr(t2))));
   15566          } else {
   15567             assign(t1, unop(Iop_1Sto32, binop(Iop_CmpEQ32, getIReg(rt),
   15568                                               mkU32(0x0))));
   15569             assign(t2, unop(Iop_1Sto32, binop(Iop_CmpNE32, getIReg(rt),
   15570                                               mkU32(0x0))));
   15571             putIReg(rd, binop(Iop_Add32, binop(Iop_And32, getIReg(rs),
   15572                         mkexpr(t1)), binop(Iop_And32, getIReg(rd),
   15573                         mkexpr(t2))));
   15574          }
   15575          break;
   15576       }
   15577 
   15578       case 0x0B: {  /* MOVN */
   15579          DIP("movn r%u, r%u, r%u", rd, rs, rt);
   15580          t1 = newTemp(ty);
   15581          t2 = newTemp(ty);
   15582          if (mode64) {
   15583             assign(t1, unop(Iop_32Sto64, unop(Iop_1Sto32, binop(Iop_CmpEQ64,
   15584                             getIReg(rt), mkU64(0x0)))));
   15585             assign(t2, unop(Iop_32Sto64, unop(Iop_1Sto32, binop(Iop_CmpNE64,
   15586                             getIReg(rt), mkU64(0x0)))));
   15587             putIReg(rd, binop(Iop_Add64, binop(Iop_And64, getIReg(rs),
   15588                         mkexpr(t2)), binop(Iop_And64, getIReg(rd),
   15589                                            mkexpr(t1))));
   15590          } else {
   15591             assign(t1, unop(Iop_1Sto32, binop(Iop_CmpEQ32, getIReg(rt),
   15592                                               mkU32(0x0))));
   15593             assign(t2, unop(Iop_1Sto32, binop(Iop_CmpNE32, getIReg(rt),
   15594                                               mkU32(0x0))));
   15595             putIReg(rd, binop(Iop_Add32, binop(Iop_And32, getIReg(rs),
   15596                         mkexpr(t2)), binop(Iop_And32, getIReg(rd),
   15597                         mkexpr(t1))));
   15598          }
   15599          break;
   15600       }
   15601 
   15602       case 0x18:  {  /* MULT */
   15603          if ( (1 <= ac) && ( 3 >= ac) ) {
   15604             if (VEX_MIPS_PROC_DSP(archinfo->hwcaps)) {
   15605                /* If DSP is present -> DSP ASE MULT */
   15606                UInt retVal = disDSPInstr_MIPS_WRK ( cins );
   15607                if (0 != retVal ) {
   15608                   goto decode_failure_dsp;
   15609                }
   15610                break;
   15611             } else {
   15612                goto decode_failure_dsp;
   15613             }
   15614          } else {
   15615             DIP("mult r%u, r%u", rs, rt);
   15616             t2 = newTemp(Ity_I64);
   15617 
   15618             assign(t2, binop(Iop_MullS32, mkNarrowTo32(ty, getIReg(rs)),
   15619                                           mkNarrowTo32(ty, getIReg(rt))));
   15620 
   15621             putHI(mkWidenFrom32(ty, unop(Iop_64HIto32, mkexpr(t2)), True));
   15622             putLO(mkWidenFrom32(ty, unop(Iop_64to32, mkexpr(t2)), True));
   15623             break;
   15624          }
   15625       }
   15626       case 0x19:  {  /* MULTU */
   15627          if ( (1 <= ac) && ( 3 >= ac) ) {
   15628             if (VEX_MIPS_PROC_DSP(archinfo->hwcaps)) {
   15629                /* If DSP is present -> DSP ASE MULTU */
   15630                UInt retVal = disDSPInstr_MIPS_WRK ( cins );
   15631                if (0 != retVal ) {
   15632                   goto decode_failure_dsp;
   15633                }
   15634                break;
   15635             } else {
   15636                goto decode_failure_dsp;
   15637             }
   15638          } else {
   15639             DIP("multu r%u, r%u", rs, rt);
   15640             t2 = newTemp(Ity_I64);
   15641 
   15642             assign(t2, binop(Iop_MullU32, mkNarrowTo32(ty, getIReg(rs)),
   15643                                           mkNarrowTo32(ty, getIReg(rt))));
   15644 
   15645             putHI(mkWidenFrom32(ty, unop(Iop_64HIto32, mkexpr(t2)), True));
   15646             putLO(mkWidenFrom32(ty, unop(Iop_64to32, mkexpr(t2)), True));
   15647             break;
   15648          }
   15649       }
   15650       case 0x20: {  /* ADD */
   15651          DIP("add r%u, r%u, r%u", rd, rs, rt);
   15652          IRTemp tmpRs32 = newTemp(Ity_I32);
   15653          IRTemp tmpRt32 = newTemp(Ity_I32);
   15654 
   15655          assign(tmpRs32, mkNarrowTo32(ty, getIReg(rs)));
   15656          assign(tmpRt32, mkNarrowTo32(ty, getIReg(rt)));
   15657 
   15658          t0 = newTemp(Ity_I32);
   15659          t1 = newTemp(Ity_I32);
   15660          t2 = newTemp(Ity_I32);
   15661          t3 = newTemp(Ity_I32);
   15662          t4 = newTemp(Ity_I32);
   15663          /* dst = src0 + src1
   15664             if (sign(src0 ) != sign(src1 ))
   15665             goto no overflow;
   15666             if (sign(dst) == sign(src0 ))
   15667             goto no overflow;
   15668             we have overflow! */
   15669 
   15670          assign(t0, binop(Iop_Add32, mkexpr(tmpRs32), mkexpr(tmpRt32)));
   15671          assign(t1, binop(Iop_Xor32, mkexpr(tmpRs32), mkexpr(tmpRt32)));
   15672          assign(t2, unop(Iop_1Uto32,
   15673                          binop(Iop_CmpEQ32,
   15674                                binop(Iop_And32, mkexpr(t1), mkU32(0x80000000)),
   15675                                mkU32(0x80000000))));
   15676 
   15677          assign(t3, binop(Iop_Xor32, mkexpr(t0), mkexpr(tmpRs32)));
   15678          assign(t4, unop(Iop_1Uto32,
   15679                          binop(Iop_CmpNE32,
   15680                                binop(Iop_And32, mkexpr(t3), mkU32(0x80000000)),
   15681                                mkU32(0x80000000))));
   15682 
   15683          stmt(IRStmt_Exit(binop(Iop_CmpEQ32,
   15684                                 binop(Iop_Or32, mkexpr(t2), mkexpr(t4)),
   15685                                 mkU32(0)),
   15686                           Ijk_SigFPE_IntOvf,
   15687                           mode64 ? IRConst_U64(guest_PC_curr_instr + 4) :
   15688                                    IRConst_U32(guest_PC_curr_instr + 4),
   15689                           OFFB_PC));
   15690 
   15691          putIReg(rd,  mkWidenFrom32(ty, mkexpr(t0), True));
   15692          break;
   15693       }
   15694       case 0x1A:  /* DIV */
   15695          DIP("div r%u, r%u", rs, rt);
   15696          if (mode64) {
   15697             t2 = newTemp(Ity_I64);
   15698 
   15699             assign(t2, binop(Iop_DivModS64to32,
   15700                              getIReg(rs), mkNarrowTo32(ty, getIReg(rt))));
   15701 
   15702             putHI(mkWidenFrom32(ty, unop(Iop_64HIto32, mkexpr(t2)), True));
   15703             putLO(mkWidenFrom32(ty, unop(Iop_64to32, mkexpr(t2)), True));
   15704          } else {
   15705             t1 = newTemp(Ity_I64);
   15706             t2 = newTemp(Ity_I64);
   15707 
   15708             assign(t1, unop(Iop_32Sto64, getIReg(rs)));
   15709             assign(t2, binop(Iop_DivModS64to32, mkexpr(t1), getIReg(rt)));
   15710 
   15711             putHI(unop(Iop_64HIto32, mkexpr(t2)));
   15712             putLO(unop(Iop_64to32, mkexpr(t2)));
   15713          }
   15714          break;
   15715 
   15716       case 0x1B:  /* DIVU */
   15717          DIP("divu r%u, r%u", rs, rt);
   15718          if (mode64) {
   15719             t2 = newTemp(Ity_I64);
   15720 
   15721             assign(t2, binop(Iop_DivModU64to32,
   15722                              getIReg(rs), mkNarrowTo32(ty, getIReg(rt))));
   15723 
   15724             putHI(mkWidenFrom32(ty, unop(Iop_64HIto32, mkexpr(t2)), True));
   15725             putLO(mkWidenFrom32(ty, unop(Iop_64to32, mkexpr(t2)), True));
   15726          } else {
   15727             t1 = newTemp(Ity_I64);
   15728             t2 = newTemp(Ity_I64);
   15729             assign(t1, unop(Iop_32Uto64, getIReg(rs)));
   15730             assign(t2, binop(Iop_DivModU64to32, mkexpr(t1), getIReg(rt)));
   15731             putHI(unop(Iop_64HIto32, mkexpr(t2)));
   15732             putLO(unop(Iop_64to32, mkexpr(t2)));
   15733          }
   15734          break;
   15735 
   15736       case 0x1C:  /* Doubleword Multiply - DMULT; MIPS64 */
   15737          DIP("dmult r%u, r%u", rs, rt);
   15738          t0 = newTemp(Ity_I128);
   15739 
   15740          assign(t0, binop(Iop_MullS64, getIReg(rs), getIReg(rt)));
   15741 
   15742          putHI(unop(Iop_128HIto64, mkexpr(t0)));
   15743          putLO(unop(Iop_128to64, mkexpr(t0)));
   15744          break;
   15745 
   15746       case 0x1D:  /* Doubleword Multiply Unsigned - DMULTU; MIPS64 */
   15747          DIP("dmultu r%u, r%u", rs, rt);
   15748          t0 = newTemp(Ity_I128);
   15749 
   15750          assign(t0, binop(Iop_MullU64, getIReg(rs), getIReg(rt)));
   15751 
   15752          putHI(unop(Iop_128HIto64, mkexpr(t0)));
   15753          putLO(unop(Iop_128to64, mkexpr(t0)));
   15754          break;
   15755 
   15756       case 0x1E:  /* Doubleword Divide DDIV; MIPS64 */
   15757          DIP("ddiv r%u, r%u", rs, rt);
   15758          t1 = newTemp(Ity_I128);
   15759 
   15760          assign(t1, binop(Iop_DivModS64to64, getIReg(rs), getIReg(rt)));
   15761 
   15762          putHI(unop(Iop_128HIto64, mkexpr(t1)));
   15763          putLO(unop(Iop_128to64, mkexpr(t1)));
   15764          break;
   15765 
   15766       case 0x1F:  /* Doubleword Divide Unsigned DDIVU; MIPS64 check this */
   15767          DIP("ddivu r%u, r%u", rs, rt);
   15768          t1 = newTemp(Ity_I128);
   15769          t2 = newTemp(Ity_I128);
   15770 
   15771          assign(t1, binop(Iop_64HLto128, mkU64(0), getIReg(rs)));
   15772 
   15773          assign(t2, binop(Iop_DivModU128to64, mkexpr(t1), getIReg(rt)));
   15774 
   15775          putHI(unop(Iop_128HIto64, mkexpr(t2)));
   15776          putLO(unop(Iop_128to64, mkexpr(t2)));
   15777          break;
   15778 
   15779       case 0x10: {  /* MFHI */
   15780          if (VEX_MIPS_PROC_DSP(archinfo->hwcaps)) {
   15781             /* If DSP is present -> DSP ASE MFHI */
   15782             UInt retVal = disDSPInstr_MIPS_WRK ( cins );
   15783             if (0 != retVal ) {
   15784                goto decode_failure;
   15785             }
   15786             break;
   15787          } else {
   15788             DIP("mfhi r%u", rd);
   15789             putIReg(rd, getHI());
   15790             break;
   15791          }
   15792       }
   15793 
   15794       case 0x11:  {  /* MTHI */
   15795          if (VEX_MIPS_PROC_DSP(archinfo->hwcaps)) {
   15796             /* If DSP is present -> DSP ASE MTHI */
   15797             UInt retVal = disDSPInstr_MIPS_WRK ( cins );
   15798             if (0 != retVal ) {
   15799                goto decode_failure;
   15800             }
   15801             break;
   15802          } else {
   15803             DIP("mthi r%u", rs);
   15804             putHI(getIReg(rs));
   15805             break;
   15806          }
   15807       }
   15808 
   15809       case 0x12:  {  /* MFLO */
   15810          if (VEX_MIPS_PROC_DSP(archinfo->hwcaps)) {
   15811             /* If DSP is present -> DSP ASE MFLO */
   15812             UInt retVal = disDSPInstr_MIPS_WRK ( cins );
   15813             if (0 != retVal ) {
   15814                goto decode_failure;
   15815             }
   15816             break;
   15817          } else {
   15818             DIP("mflo r%u", rd);
   15819             putIReg(rd, getLO());
   15820             break;
   15821          }
   15822       }
   15823 
   15824       case 0x13:  {  /* MTLO */
   15825          if (VEX_MIPS_PROC_DSP(archinfo->hwcaps)) {
   15826             /* If DSP is present -> DSP ASE MTLO */
   15827             UInt retVal = disDSPInstr_MIPS_WRK ( cins );
   15828             if (0 != retVal ) {
   15829                goto decode_failure;
   15830             }
   15831             break;
   15832          } else {
   15833             DIP("mtlo r%u", rs);
   15834             putLO(getIReg(rs));
   15835             break;
   15836          }
   15837       }
   15838 
   15839       case 0x21:  /* ADDU */
   15840          DIP("addu r%u, r%u, r%u", rd, rs, rt);
   15841          if (mode64) {
   15842             ALU_PATTERN64(Iop_Add32);
   15843          } else {
   15844             ALU_PATTERN(Iop_Add32);
   15845          }
   15846          break;
   15847 
   15848       case 0x22: {  /* SUB */
   15849          DIP("sub r%u, r%u, r%u", rd, rs, rt);
   15850          IRTemp tmpRs32 = newTemp(Ity_I32);
   15851          IRTemp tmpRt32 = newTemp(Ity_I32);
   15852 
   15853          assign(tmpRs32, mkNarrowTo32(ty, getIReg(rs)));
   15854          assign(tmpRt32, mkNarrowTo32(ty, getIReg(rt)));
   15855          t0 = newTemp(Ity_I32);
   15856          t1 = newTemp(Ity_I32);
   15857          t2 = newTemp(Ity_I32);
   15858          t3 = newTemp(Ity_I32);
   15859          t4 = newTemp(Ity_I32);
   15860          t5 = newTemp(Ity_I32);
   15861          /* dst = src0 + (-1 * src1)
   15862             if(sign(src0 ) != sign((-1 * src1) ))
   15863             goto no overflow;
   15864             if(sign(dst) == sign(src0 ))
   15865             goto no overflow;
   15866             we have overflow! */
   15867 
   15868          assign(t5, binop(Iop_Mul32, mkexpr(tmpRt32), mkU32(-1)));
   15869          assign(t0, binop(Iop_Add32, mkexpr(tmpRs32), mkexpr(t5)));
   15870          assign(t1, binop(Iop_Xor32, mkexpr(tmpRs32), mkexpr(t5)));
   15871          assign(t2, unop(Iop_1Sto32, binop(Iop_CmpEQ32, binop(Iop_And32,
   15872                          mkexpr(t1), mkU32(0x80000000)), mkU32(0x80000000))));
   15873 
   15874          assign(t3, binop(Iop_Xor32, mkexpr(t0), mkexpr(tmpRs32)));
   15875          assign(t4, unop(Iop_1Sto32, binop(Iop_CmpNE32, binop(Iop_And32,
   15876                          mkexpr(t3), mkU32(0x80000000)), mkU32(0x80000000))));
   15877 
   15878          stmt(IRStmt_Exit(binop(Iop_CmpEQ32, binop(Iop_Or32, mkexpr(t2),
   15879                                 mkexpr(t4)), mkU32(0)), Ijk_SigFPE_IntOvf,
   15880                           mode64 ? IRConst_U64(guest_PC_curr_instr + 4) :
   15881                                    IRConst_U32(guest_PC_curr_instr + 4),
   15882                           OFFB_PC));
   15883 
   15884          putIReg(rd, mkWidenFrom32(ty, mkexpr(t0), True));
   15885          break;
   15886       }
   15887       case 0x23:  /* SUBU */
   15888          DIP("subu r%u, r%u, r%u", rd, rs, rt);
   15889          if (mode64) {
   15890             ALU_PATTERN64(Iop_Sub32);
   15891          } else {
   15892             ALU_PATTERN(Iop_Sub32);
   15893          }
   15894          break;
   15895 
   15896       case 0x24:  /* AND */
   15897          DIP("and r%u, r%u, r%u", rd, rs, rt);
   15898          if (mode64) {
   15899             ALU_PATTERN(Iop_And64);
   15900          } else {
   15901             ALU_PATTERN(Iop_And32);
   15902          }
   15903          break;
   15904 
   15905       case 0x25:  /* OR */
   15906          DIP("or r%u, r%u, r%u", rd, rs, rt);
   15907          if (mode64) {
   15908             ALU_PATTERN(Iop_Or64);
   15909          } else {
   15910             ALU_PATTERN(Iop_Or32);
   15911          }
   15912          break;
   15913 
   15914       case 0x26:  /* XOR */
   15915          DIP("xor r%u, r%u, r%u", rd, rs, rt);
   15916          if (mode64) {
   15917             ALU_PATTERN(Iop_Xor64);
   15918          } else {
   15919             ALU_PATTERN(Iop_Xor32);
   15920          }
   15921          break;
   15922 
   15923       case 0x27:  /* NOR */
   15924          DIP("nor r%u, r%u, r%u", rd, rs, rt);
   15925          if (mode64)
   15926             putIReg(rd, unop(Iop_Not64, binop(Iop_Or64, getIReg(rs),
   15927                                               getIReg(rt))));
   15928          else
   15929             putIReg(rd, unop(Iop_Not32, binop(Iop_Or32, getIReg(rs),
   15930                                               getIReg(rt))));
   15931          break;
   15932 
   15933       case 0x08:  /* JR */
   15934          DIP("jr r%u", rs);
   15935          t0 = newTemp(ty);
   15936          assign(t0, getIReg(rs));
   15937          lastn = mkexpr(t0);
   15938          break;
   15939 
   15940       case 0x09:  /* JALR */
   15941          DIP("jalr r%u r%u", rd, rs);
   15942          if (mode64) {
   15943             putIReg(rd, mkU64(guest_PC_curr_instr + 8));
   15944             t0 = newTemp(Ity_I64);
   15945             assign(t0, getIReg(rs));
   15946             lastn = mkexpr(t0);
   15947          } else {
   15948             putIReg(rd, mkU32(guest_PC_curr_instr + 8));
   15949             t0 = newTemp(Ity_I32);
   15950             assign(t0, getIReg(rs));
   15951             lastn = mkexpr(t0);
   15952          }
   15953          break;
   15954 
   15955       case 0x0C:  /* SYSCALL */
   15956          DIP("syscall");
   15957          if (mode64)
   15958             putPC(mkU64(guest_PC_curr_instr + 4));
   15959          else
   15960             putPC(mkU32(guest_PC_curr_instr + 4));
   15961          dres.jk_StopHere = Ijk_Sys_syscall;
   15962          dres.whatNext    = Dis_StopHere;
   15963          break;
   15964 
   15965       case 0x2A:  /* SLT */
   15966          DIP("slt r%u, r%u, r%u", rd, rs, rt);
   15967          if (mode64)
   15968             putIReg(rd, unop(Iop_1Uto64, binop(Iop_CmpLT64S, getIReg(rs),
   15969                                                getIReg(rt))));
   15970          else
   15971             putIReg(rd, unop(Iop_1Uto32, binop(Iop_CmpLT32S, getIReg(rs),
   15972                                                getIReg(rt))));
   15973          break;
   15974 
   15975       case 0x2B:  /* SLTU */
   15976          DIP("sltu r%u, r%u, r%u", rd, rs, rt);
   15977          if (mode64)
   15978             putIReg(rd, unop(Iop_1Uto64, binop(Iop_CmpLT64U, getIReg(rs),
   15979                                          getIReg(rt))));
   15980          else
   15981             putIReg(rd, unop(Iop_1Uto32, binop(Iop_CmpLT32U, getIReg(rs),
   15982                                          getIReg(rt))));
   15983          break;
   15984 
   15985       case 0x00: {  /* SLL */
   15986          DIP("sll r%u, r%u, %u", rd, rt, sa);
   15987          IRTemp tmpRt32 = newTemp(Ity_I32);
   15988          IRTemp tmpSh32 = newTemp(Ity_I32);
   15989          IRTemp tmpRd = newTemp(Ity_I64);
   15990          if (mode64) {
   15991             assign(tmpRt32, mkNarrowTo32(ty, getIReg(rt)));
   15992             assign(tmpSh32, binop(Iop_Shl32, mkexpr(tmpRt32), mkU8(sa)));
   15993             assign(tmpRd, mkWidenFrom32(ty, mkexpr(tmpSh32), True));
   15994             putIReg(rd, mkexpr(tmpRd));
   15995          } else
   15996             SXX_PATTERN(Iop_Shl32);
   15997          break;
   15998       }
   15999 
   16000       case 0x04: {  /* SLLV */
   16001          DIP("sllv r%u, r%u, r%u", rd, rt, rs);
   16002          if (mode64) {
   16003             IRTemp tmpRs8 = newTemp(Ity_I8);
   16004             IRTemp tmpRt32 = newTemp(Ity_I32);
   16005             IRTemp tmpSh32 = newTemp(Ity_I32);
   16006             IRTemp tmp = newTemp(ty);
   16007             assign(tmp, binop(mkSzOp(ty, Iop_And8), getIReg(rs),
   16008                               mkSzImm(ty, 31)));
   16009             assign(tmpRs8, mkNarrowTo8(ty, mkexpr(tmp)));
   16010             assign(tmpRt32, mkNarrowTo32(ty, getIReg(rt)));
   16011             assign(tmpSh32, binop(Iop_Shl32, mkexpr(tmpRt32), mkexpr(tmpRs8)));
   16012             putIReg(rd, mkWidenFrom32(ty, mkexpr(tmpSh32), True));
   16013          } else {
   16014             SXXV_PATTERN(Iop_Shl32);
   16015          }
   16016          break;
   16017       }
   16018 
   16019       case 0x03:  /* SRA */
   16020          DIP("sra r%u, r%u, %u", rd, rt, sa);
   16021          if (mode64) {
   16022             IRTemp tmpRt32 = newTemp(Ity_I32);
   16023             IRTemp tmpSh32 = newTemp(Ity_I32);
   16024 
   16025             t1 = newTemp(Ity_I64);
   16026             t2 = newTemp(Ity_I64);
   16027             t3 = newTemp(Ity_I64);
   16028 
   16029             assign(t1, binop(Iop_And64, getIReg(rt),  /* hi */
   16030                              mkU64(0xFFFFFFFF00000000ULL)));
   16031 
   16032             assign(t2, binop(Iop_Sar64, mkexpr(t1), mkU8(sa)));
   16033 
   16034             assign(tmpRt32, mkNarrowTo32(ty, getIReg(rt)));
   16035             assign(tmpSh32, binop(Iop_Sar32, mkexpr(tmpRt32), mkU8(sa)));
   16036 
   16037             putIReg(rd, mkWidenFrom32(ty, mkexpr(tmpSh32), True));
   16038          } else {
   16039             SXX_PATTERN(Iop_Sar32);
   16040          }
   16041          break;
   16042 
   16043       case 0x07:  /* SRAV */
   16044          DIP("srav r%u, r%u, r%u", rd, rt, rs);
   16045          if (mode64) {
   16046             IRTemp tmpRt32 = newTemp(Ity_I32);
   16047             IRTemp tmpSh32 = newTemp(Ity_I32);
   16048 
   16049             t1 = newTemp(Ity_I64);
   16050             t2 = newTemp(Ity_I64);
   16051             t3 = newTemp(Ity_I64);
   16052             t4 = newTemp(Ity_I8);
   16053 
   16054             assign(t4, unop(Iop_32to8, binop(Iop_And32,
   16055                        mkNarrowTo32(ty, getIReg(rs)), mkU32(0x0000001F))));
   16056 
   16057             assign(t1, binop(Iop_And64, getIReg(rt),  /* hi */
   16058                    mkU64(0xFFFFFFFF00000000ULL)));
   16059 
   16060             assign(t2, binop(Iop_Sar64, mkexpr(t1), mkexpr(t4)));
   16061 
   16062             assign(tmpRt32, mkNarrowTo32(ty, getIReg(rt)));
   16063             assign(tmpSh32, binop(Iop_Sar32, mkexpr(tmpRt32), mkexpr(t4)));
   16064 
   16065             putIReg(rd, mkWidenFrom32(ty, mkexpr(tmpSh32), True));
   16066          } else {
   16067             SXXV_PATTERN(Iop_Sar32);
   16068          }
   16069          break;
   16070 
   16071       case 0x02: {  /* SRL */
   16072          rot = get_rot(cins);
   16073          if (rot) {
   16074             DIP("rotr r%u, r%u, %u", rd, rt, sa);
   16075             putIReg(rd, mkWidenFrom32(ty, genROR32(mkNarrowTo32(ty,
   16076                         getIReg(rt)), sa), True));
   16077          } else {
   16078             DIP("srl r%u, r%u, %u", rd, rt, sa);
   16079             if (mode64) {
   16080                IRTemp tmpSh32 = newTemp(Ity_I32);
   16081                IRTemp tmpRt32 = newTemp(Ity_I32);
   16082 
   16083                assign(tmpRt32, mkNarrowTo32(ty, getIReg(rt)));
   16084                assign(tmpSh32, binop(Iop_Shr32, mkexpr(tmpRt32), mkU8(sa)));
   16085                putIReg(rd, mkWidenFrom32(ty, mkexpr(tmpSh32), True));
   16086             } else {
   16087                SXX_PATTERN(Iop_Shr32);
   16088             }
   16089          }
   16090       break;
   16091       }
   16092 
   16093       case 0x06: {
   16094          rot = get_rotv(cins);
   16095          if (rot) {
   16096             DIP("rotrv r%u, r%u, r%u", rd, rt, rs);
   16097             putIReg(rd, mkWidenFrom32(ty, genRORV32(mkNarrowTo32(ty,
   16098                         getIReg(rt)), mkNarrowTo32(ty, getIReg(rs))), True));
   16099             break;
   16100          } else {  /* SRLV */
   16101             DIP("srlv r%u, r%u, r%u", rd, rt, rs);
   16102             if (mode64) {
   16103                SXXV_PATTERN64(Iop_Shr32);
   16104             } else {
   16105                SXXV_PATTERN(Iop_Shr32);
   16106             }
   16107             break;
   16108          }
   16109       }
   16110 
   16111       case 0x0D:  /* BREAK */
   16112          DIP("break 0x%x", trap_code);
   16113          if (mode64)
   16114             jmp_lit64(&dres, Ijk_SigTRAP, (guest_PC_curr_instr + 4));
   16115          else
   16116             jmp_lit32(&dres, Ijk_SigTRAP, (guest_PC_curr_instr + 4));
   16117          vassert(dres.whatNext == Dis_StopHere);
   16118          break;
   16119 
   16120       case 0x30: {  /* TGE */
   16121          DIP("tge r%u, r%u %u", rs, rt, trap_code);
   16122          if (mode64) {
   16123             if (trap_code == 7)
   16124                stmt (IRStmt_Exit (unop (Iop_Not1,
   16125                                         binop (Iop_CmpLT64S,
   16126                                                getIReg (rs),
   16127                                                getIReg (rt))),
   16128                                 Ijk_SigFPE_IntDiv,
   16129                                 IRConst_U64(guest_PC_curr_instr + 4),
   16130                                 OFFB_PC));
   16131             else if (trap_code == 6)
   16132                stmt (IRStmt_Exit (unop (Iop_Not1,
   16133                                         binop (Iop_CmpLT64S,
   16134                                                getIReg (rs),
   16135                                                getIReg (rt))),
   16136                                 Ijk_SigFPE_IntOvf,
   16137                                 IRConst_U64(guest_PC_curr_instr + 4),
   16138                                 OFFB_PC));
   16139             else
   16140                stmt (IRStmt_Exit (unop (Iop_Not1,
   16141                                         binop (Iop_CmpLT64S,
   16142                                                getIReg (rs),
   16143                                                getIReg (rt))),
   16144                                 Ijk_SigTRAP,
   16145                                 IRConst_U64(guest_PC_curr_instr + 4),
   16146                                 OFFB_PC));
   16147          } else {
   16148             if (trap_code == 7)
   16149                stmt (IRStmt_Exit (unop (Iop_Not1,
   16150                                         binop (Iop_CmpLT32S,
   16151                                                getIReg (rs),
   16152                                                getIReg (rt))),
   16153                                   Ijk_SigFPE_IntDiv,
   16154                                   IRConst_U32(guest_PC_curr_instr + 4),
   16155                                   OFFB_PC));
   16156             else if (trap_code == 6)
   16157                stmt (IRStmt_Exit (unop (Iop_Not1,
   16158                                         binop (Iop_CmpLT32S,
   16159                                                getIReg (rs),
   16160                                                getIReg (rt))),
   16161                                   Ijk_SigFPE_IntOvf,
   16162                                   IRConst_U32(guest_PC_curr_instr + 4),
   16163                                   OFFB_PC));
   16164             else
   16165                stmt (IRStmt_Exit (unop (Iop_Not1,
   16166                                         binop (Iop_CmpLT32S,
   16167                                                getIReg (rs),
   16168                                                getIReg (rt))),
   16169                                   Ijk_SigTRAP,
   16170                                   IRConst_U32(guest_PC_curr_instr + 4),
   16171                                   OFFB_PC));
   16172          }
   16173          break;
   16174       }
   16175       case 0x31: {  /* TGEU */
   16176          DIP("tgeu r%u, r%u %u", rs, rt, trap_code);
   16177          if (mode64) {
   16178             if (trap_code == 7)
   16179                stmt (IRStmt_Exit (unop (Iop_Not1,
   16180                                         binop (Iop_CmpLT64U,
   16181                                                getIReg (rs),
   16182                                                getIReg (rt))),
   16183                                   Ijk_SigFPE_IntDiv,
   16184                                   IRConst_U64(guest_PC_curr_instr + 4),
   16185                                   OFFB_PC));
   16186             else if (trap_code == 6)
   16187                stmt (IRStmt_Exit (unop (Iop_Not1,
   16188                                         binop (Iop_CmpLT64U,
   16189                                                getIReg (rs),
   16190                                                getIReg (rt))),
   16191                                   Ijk_SigFPE_IntOvf,
   16192                                   IRConst_U64(guest_PC_curr_instr + 4),
   16193                                   OFFB_PC));
   16194             else
   16195                stmt (IRStmt_Exit (unop (Iop_Not1,
   16196                                         binop (Iop_CmpLT64U,
   16197                                                getIReg (rs),
   16198                                                getIReg (rt))),
   16199                                   Ijk_SigTRAP,
   16200                                   IRConst_U64(guest_PC_curr_instr + 4),
   16201                                   OFFB_PC));
   16202          } else {
   16203             if (trap_code == 7)
   16204                stmt (IRStmt_Exit (unop (Iop_Not1,
   16205                                         binop (Iop_CmpLT32U,
   16206                                                getIReg (rs),
   16207                                                getIReg (rt))),
   16208                                   Ijk_SigFPE_IntDiv,
   16209                                   IRConst_U32(guest_PC_curr_instr + 4),
   16210                                   OFFB_PC));
   16211             else if (trap_code == 6)
   16212                stmt (IRStmt_Exit (unop (Iop_Not1,
   16213                                         binop (Iop_CmpLT32U,
   16214                                                getIReg (rs),
   16215                                                getIReg (rt))),
   16216                                   Ijk_SigFPE_IntOvf,
   16217                                   IRConst_U32(guest_PC_curr_instr + 4),
   16218                                   OFFB_PC));
   16219             else
   16220                stmt (IRStmt_Exit (unop (Iop_Not1,
   16221                                         binop (Iop_CmpLT32U,
   16222                                                getIReg (rs),
   16223                                                getIReg (rt))),
   16224                                   Ijk_SigTRAP,
   16225                                   IRConst_U32(guest_PC_curr_instr + 4),
   16226                                   OFFB_PC));
   16227          }
   16228          break;
   16229       }
   16230       case 0x32: {  /* TLT */
   16231          DIP("tlt r%u, r%u %u", rs, rt, trap_code);
   16232          if (mode64) {
   16233             if (trap_code == 7)
   16234                stmt(IRStmt_Exit(binop(Iop_CmpLT64S, getIReg(rs),
   16235                                       getIReg(rt)), Ijk_SigFPE_IntDiv,
   16236                                 IRConst_U64(guest_PC_curr_instr + 4),
   16237                                 OFFB_PC));
   16238             else if (trap_code == 6)
   16239                stmt(IRStmt_Exit(binop(Iop_CmpLT64S, getIReg(rs),
   16240                                       getIReg(rt)), Ijk_SigFPE_IntOvf,
   16241                                 IRConst_U64(guest_PC_curr_instr + 4),
   16242                                 OFFB_PC));
   16243             else
   16244                stmt(IRStmt_Exit(binop(Iop_CmpLT64S, getIReg(rs),
   16245                                       getIReg(rt)), Ijk_SigTRAP,
   16246                                 IRConst_U64(guest_PC_curr_instr + 4),
   16247                                 OFFB_PC));
   16248          } else {
   16249             if (trap_code == 7)
   16250                stmt(IRStmt_Exit(binop(Iop_CmpLT32S, getIReg(rs),
   16251                                       getIReg(rt)), Ijk_SigFPE_IntDiv,
   16252                                 IRConst_U32(guest_PC_curr_instr + 4),
   16253                                 OFFB_PC));
   16254             else if (trap_code == 6)
   16255                stmt(IRStmt_Exit(binop(Iop_CmpLT32S, getIReg(rs),
   16256                                       getIReg(rt)), Ijk_SigFPE_IntOvf,
   16257                                 IRConst_U32(guest_PC_curr_instr + 4),
   16258                                 OFFB_PC));
   16259             else
   16260                stmt(IRStmt_Exit(binop(Iop_CmpLT32S, getIReg(rs),
   16261                                       getIReg(rt)), Ijk_SigTRAP,
   16262                                 IRConst_U32(guest_PC_curr_instr + 4),
   16263                                 OFFB_PC));
   16264          }
   16265          break;
   16266       }
   16267       case 0x33: {  /* TLTU */
   16268          DIP("tltu r%u, r%u %u", rs, rt, trap_code);
   16269          if (mode64) {
   16270             if (trap_code == 7)
   16271                stmt(IRStmt_Exit(binop(Iop_CmpLT64U, getIReg(rs),
   16272                                       getIReg(rt)), Ijk_SigFPE_IntDiv,
   16273                                 IRConst_U64(guest_PC_curr_instr + 4),
   16274                                 OFFB_PC));
   16275             else if (trap_code == 6)
   16276                stmt(IRStmt_Exit(binop(Iop_CmpLT64U, getIReg(rs),
   16277                                       getIReg(rt)), Ijk_SigFPE_IntOvf,
   16278                                 IRConst_U64(guest_PC_curr_instr + 4),
   16279                                 OFFB_PC));
   16280             else
   16281                stmt(IRStmt_Exit(binop(Iop_CmpLT64U, getIReg(rs),
   16282                                       getIReg(rt)), Ijk_SigTRAP,
   16283                                 IRConst_U64(guest_PC_curr_instr + 4),
   16284                                 OFFB_PC));
   16285          } else {
   16286             if (trap_code == 7)
   16287                stmt(IRStmt_Exit(binop(Iop_CmpLT32U, getIReg(rs),
   16288                                       getIReg(rt)), Ijk_SigFPE_IntDiv,
   16289                                 IRConst_U32(guest_PC_curr_instr + 4),
   16290                                 OFFB_PC));
   16291             else if (trap_code == 6)
   16292                stmt(IRStmt_Exit(binop(Iop_CmpLT32U, getIReg(rs),
   16293                                       getIReg(rt)), Ijk_SigFPE_IntOvf,
   16294                                 IRConst_U32(guest_PC_curr_instr + 4),
   16295                                 OFFB_PC));
   16296             else
   16297                stmt(IRStmt_Exit(binop(Iop_CmpLT32U, getIReg(rs),
   16298                                       getIReg (rt)), Ijk_SigTRAP,
   16299                                 IRConst_U32(guest_PC_curr_instr + 4),
   16300                                 OFFB_PC));
   16301          }
   16302          break;
   16303       }
   16304       case 0x34: {  /* TEQ */
   16305          DIP("teq r%u, r%u, %u", rs, rt, trap_code);
   16306          if (mode64) {
   16307             if (trap_code == 7)
   16308                stmt(IRStmt_Exit(binop(Iop_CmpEQ64, getIReg(rs),
   16309                                       getIReg(rt)), Ijk_SigFPE_IntDiv,
   16310                                 IRConst_U64(guest_PC_curr_instr + 4),
   16311                                 OFFB_PC));
   16312             else if (trap_code == 6)
   16313                stmt(IRStmt_Exit(binop(Iop_CmpEQ64, getIReg(rs),
   16314                                       getIReg(rt)), Ijk_SigFPE_IntOvf,
   16315                                 IRConst_U64(guest_PC_curr_instr + 4),
   16316                                 OFFB_PC));
   16317             else
   16318                stmt(IRStmt_Exit(binop(Iop_CmpEQ64, getIReg(rs),
   16319                                       getIReg(rt)), Ijk_SigTRAP,
   16320                                 IRConst_U64(guest_PC_curr_instr + 4),
   16321                                 OFFB_PC));
   16322          } else {
   16323             if (trap_code == 7)
   16324                stmt(IRStmt_Exit(binop(Iop_CmpEQ32, getIReg(rs),
   16325                                       getIReg(rt)), Ijk_SigFPE_IntDiv,
   16326                                 IRConst_U32(guest_PC_curr_instr + 4),
   16327                                 OFFB_PC));
   16328             else if (trap_code == 6)
   16329                stmt(IRStmt_Exit(binop(Iop_CmpEQ32, getIReg(rs),
   16330                                       getIReg(rt)), Ijk_SigFPE_IntOvf,
   16331                                 IRConst_U32(guest_PC_curr_instr + 4),
   16332                                 OFFB_PC));
   16333             else
   16334                stmt(IRStmt_Exit(binop(Iop_CmpEQ32, getIReg(rs),
   16335                                       getIReg(rt)), Ijk_SigTRAP,
   16336                                 IRConst_U32(guest_PC_curr_instr + 4),
   16337                                 OFFB_PC));
   16338          }
   16339          break;
   16340       }
   16341       case 0x36: {  /* TNE */
   16342          DIP("tne r%u, r%u %u", rs, rt, trap_code);
   16343          if (mode64) {
   16344             if (trap_code == 7)
   16345                stmt(IRStmt_Exit(binop(Iop_CmpNE64, getIReg(rs),
   16346                                       getIReg(rt)), Ijk_SigFPE_IntDiv,
   16347                                 IRConst_U64(guest_PC_curr_instr + 4),
   16348                                 OFFB_PC));
   16349             else if (trap_code == 6)
   16350                stmt(IRStmt_Exit(binop(Iop_CmpNE64, getIReg(rs),
   16351                                       getIReg(rt)), Ijk_SigFPE_IntOvf,
   16352                                 IRConst_U64(guest_PC_curr_instr + 4),
   16353                                 OFFB_PC));
   16354             else
   16355                stmt(IRStmt_Exit(binop(Iop_CmpNE64, getIReg(rs),
   16356                                       getIReg(rt)), Ijk_SigTRAP,
   16357                                 IRConst_U64(guest_PC_curr_instr + 4),
   16358                                 OFFB_PC));
   16359          } else {
   16360             if (trap_code == 7)
   16361                stmt(IRStmt_Exit(binop(Iop_CmpNE32, getIReg(rs),
   16362                                       getIReg(rt)), Ijk_SigFPE_IntDiv,
   16363                                 IRConst_U32(guest_PC_curr_instr + 4),
   16364                                 OFFB_PC));
   16365             else if (trap_code == 6)
   16366                stmt(IRStmt_Exit(binop(Iop_CmpNE32, getIReg(rs),
   16367                                       getIReg(rt)), Ijk_SigFPE_IntOvf,
   16368                                 IRConst_U32(guest_PC_curr_instr + 4),
   16369                                 OFFB_PC));
   16370             else
   16371                stmt(IRStmt_Exit(binop(Iop_CmpNE32, getIReg(rs),
   16372                                       getIReg(rt)), Ijk_SigTRAP,
   16373                                 IRConst_U32(guest_PC_curr_instr + 4),
   16374                                 OFFB_PC));
   16375          }
   16376          break;
   16377       }
   16378       case 0x14:
   16379       case 0x16:
   16380       case 0x17:  /* DSLLV, DROTRV:DSRLV, DSRAV */
   16381       case 0x38:
   16382       case 0x3A:
   16383       case 0x3B:  /* DSLL, DROTL:DSRL, DSRA  */
   16384       case 0x3C:
   16385       case 0x3E:
   16386       case 0x3F:  /* DSLL32, DROTR32:DSRL32, DSRA32 */
   16387          if (dis_instr_shrt(cins))
   16388             break;
   16389          goto decode_failure;
   16390 
   16391       case 0x0F:  /* SYNC */
   16392          DIP("sync 0x%x", sel);
   16393          /* Just ignore it. */
   16394          break;
   16395 
   16396       case 0x2C: {  /* Doubleword Add - DADD; MIPS64 */
   16397          DIP("dadd r%u, r%u, r%u", rd, rs, rt);
   16398          IRTemp tmpRs64 = newTemp(Ity_I64);
   16399          IRTemp tmpRt64 = newTemp(Ity_I64);
   16400 
   16401          assign(tmpRs64, getIReg(rs));
   16402          assign(tmpRt64, getIReg(rt));
   16403 
   16404          t0 = newTemp(Ity_I64);
   16405          t1 = newTemp(Ity_I64);
   16406          t2 = newTemp(Ity_I64);
   16407          t3 = newTemp(Ity_I64);
   16408          t4 = newTemp(Ity_I64);
   16409          /* dst = src0 + src1
   16410             if(sign(src0 ) != sign(src1 ))
   16411             goto no overflow;
   16412             if(sign(dst) == sign(src0 ))
   16413             goto no overflow;
   16414             we have overflow! */
   16415 
   16416          assign(t0, binop(Iop_Add64, mkexpr(tmpRs64), mkexpr(tmpRt64)));
   16417          assign(t1, binop(Iop_Xor64, mkexpr(tmpRs64), mkexpr(tmpRt64)));
   16418          assign(t2, unop(Iop_1Uto64,
   16419                          binop(Iop_CmpEQ64,
   16420                                binop(Iop_And64, mkexpr(t1),
   16421                                      mkU64(0x8000000000000000ULL)),
   16422                                mkU64(0x8000000000000000ULL))));
   16423 
   16424          assign(t3, binop(Iop_Xor64, mkexpr(t0), mkexpr(tmpRs64)));
   16425          assign(t4, unop(Iop_1Uto64,
   16426                          binop(Iop_CmpNE64,
   16427                                binop(Iop_And64, mkexpr(t3),
   16428                                      mkU64(0x8000000000000000ULL)),
   16429                                mkU64(0x8000000000000000ULL))));
   16430 
   16431          stmt(IRStmt_Exit(binop(Iop_CmpEQ64,
   16432                                 binop(Iop_Or64, mkexpr(t2), mkexpr(t4)),
   16433                                 mkU64(0)),
   16434                           Ijk_SigFPE_IntOvf,
   16435                           IRConst_U64(guest_PC_curr_instr + 4),
   16436                           OFFB_PC));
   16437 
   16438          putIReg(rd,  mkexpr(t0));
   16439          break;
   16440       }
   16441 
   16442       case 0x2D:  /* Doubleword Add Unsigned - DADDU; MIPS64 */
   16443          DIP("daddu r%u, r%u, r%u", rd, rs, rt);
   16444          ALU_PATTERN(Iop_Add64);
   16445          break;
   16446 
   16447       case 0x2E: {  /* Doubleword Subtract - DSUB; MIPS64 */
   16448          DIP("dsub r%u, r%u, r%u", rd, rs, rt);
   16449          IRTemp tmpRs64 = newTemp(Ity_I64);
   16450          IRTemp tmpRt64 = newTemp(Ity_I64);
   16451 
   16452          assign(tmpRs64, getIReg(rs));
   16453          assign(tmpRt64, getIReg(rt));
   16454          t0 = newTemp(Ity_I64);
   16455          t1 = newTemp(Ity_I64);
   16456          t2 = newTemp(Ity_I64);
   16457          t3 = newTemp(Ity_I64);
   16458          t4 = newTemp(Ity_I64);
   16459          t5 = newTemp(Ity_I64);
   16460          /* dst = src0 + (-1 * src1)
   16461             if(sign(src0 ) != sign((-1 * src1) ))
   16462             goto no overflow;
   16463             if(sign(dst) == sign(src0 ))
   16464             goto no overflow;
   16465             we have overflow! */
   16466 
   16467          assign(t5, binop(Iop_Mul64,
   16468                           mkexpr(tmpRt64),
   16469                           mkU64(0xffffffffffffffffULL)));
   16470          assign(t0, binop(Iop_Add64, mkexpr(tmpRs64), mkexpr(t5)));
   16471          assign(t1, binop(Iop_Xor64, mkexpr(tmpRs64), mkexpr(t5)));
   16472          assign(t2, unop(Iop_1Sto64,
   16473                          binop(Iop_CmpEQ64,
   16474                                binop(Iop_And64,
   16475                                      mkexpr(t1),
   16476                                      mkU64(0x8000000000000000ULL)),
   16477                                mkU64(0x8000000000000000ULL))));
   16478 
   16479          assign(t3, binop(Iop_Xor64, mkexpr(t0), mkexpr(tmpRs64)));
   16480          assign(t4, unop(Iop_1Sto64,
   16481                          binop(Iop_CmpNE64,
   16482                                binop(Iop_And64,
   16483                                      mkexpr(t3),
   16484                                      mkU64(0x8000000000000000ULL)),
   16485                                mkU64(0x8000000000000000ULL))));
   16486 
   16487          stmt(IRStmt_Exit(binop(Iop_CmpEQ64, binop(Iop_Or64, mkexpr(t2),
   16488                                 mkexpr(t4)), mkU64(0)), Ijk_SigFPE_IntOvf,
   16489                           IRConst_U64(guest_PC_curr_instr + 4),
   16490                           OFFB_PC));
   16491 
   16492          putIReg(rd, binop(Iop_Sub64, getIReg(rs), getIReg(rt)));
   16493          break;
   16494       }
   16495 
   16496       case 0x2F:  /* Doubleword Subtract Unsigned - DSUBU; MIPS64 */
   16497          DIP("dsub r%u, r%u,r%u", rd, rt, rt);
   16498          ALU_PATTERN(Iop_Sub64);
   16499          break;
   16500 
   16501       default:
   16502          goto decode_failure;
   16503       }
   16504       break;
   16505 
   16506    case 0x01:  /* Regimm */
   16507 
   16508       switch (rt) {
   16509       case 0x00:  /* BLTZ */
   16510          DIP("bltz r%u, %u", rs, imm);
   16511          if (mode64) {
   16512             if (!dis_instr_branch(cins, &dres, resteerOkFn,
   16513                         callback_opaque, &bstmt))
   16514                goto decode_failure;
   16515          } else
   16516             dis_branch(False, binop(Iop_CmpEQ32, binop(Iop_And32, getIReg(rs),
   16517                        mkU32(0x80000000)), mkU32(0x80000000)), imm, &bstmt);
   16518          break;
   16519 
   16520       case 0x01:  /* BGEZ */
   16521          DIP("bgez r%u, %u", rs, imm);
   16522          if (mode64) {
   16523             if (!dis_instr_branch(cins, &dres, resteerOkFn,
   16524                                   callback_opaque, &bstmt))
   16525                goto decode_failure;
   16526          } else
   16527             dis_branch(False, binop(Iop_CmpEQ32, binop(Iop_And32, getIReg(rs),
   16528                               mkU32(0x80000000)), mkU32(0x0)), imm, &bstmt);
   16529          break;
   16530 
   16531       case 0x02:  /* BLTZL */
   16532          DIP("bltzl r%u, %u", rs, imm);
   16533          lastn = dis_branch_likely(binop(mode64 ? Iop_CmpNE64 : Iop_CmpNE32,
   16534                      binop(mode64 ? Iop_And64 : Iop_And32, getIReg(rs),
   16535                      mode64 ? mkU64(0x8000000000000000ULL) : mkU32(0x80000000)),
   16536                      mode64 ? mkU64(0x8000000000000000ULL) : mkU32(0x80000000)),
   16537                      imm);
   16538          break;
   16539 
   16540       case 0x03:  /* BGEZL */
   16541          DIP("bgezl r%u, %u", rs, imm);
   16542          lastn = dis_branch_likely(binop(mode64 ? Iop_CmpNE64 : Iop_CmpNE32,
   16543                      binop(mode64 ? Iop_And64 : Iop_And32, getIReg(rs),
   16544                      mode64 ? mkU64(0x8000000000000000ULL) : mkU32(0x80000000)),
   16545                      mode64 ? mkU64(0x0) : mkU32(0x0)), imm);
   16546          break;
   16547 
   16548       case 0x10:  /* BLTZAL */
   16549          DIP("bltzal r%u, %u", rs, imm);
   16550          if (mode64) {
   16551             if (!dis_instr_branch(cins, &dres, resteerOkFn,
   16552                         callback_opaque, &bstmt))
   16553                goto decode_failure;
   16554          } else
   16555             dis_branch(True, binop(Iop_CmpEQ32, binop(Iop_And32, getIReg(rs),
   16556                        mkU32(0x80000000)), mkU32(0x80000000)), imm, &bstmt);
   16557          break;
   16558 
   16559       case 0x12:  /* BLTZALL */
   16560          DIP("bltzall r%u, %u", rs, imm);
   16561          putIReg(31, mode64 ? mkU64(guest_PC_curr_instr + 8) :
   16562                               mkU32(guest_PC_curr_instr + 8));
   16563          lastn = dis_branch_likely(binop(mode64 ? Iop_CmpNE64 : Iop_CmpNE32,
   16564                      binop(mode64 ? Iop_And64 : Iop_And32, getIReg(rs),
   16565                      mode64 ? mkU64(0x8000000000000000ULL) : mkU32(0x80000000)),
   16566                      mode64 ? mkU64(0x8000000000000000ULL) : mkU32(0x80000000)),
   16567                      imm);
   16568          break;
   16569 
   16570       case 0x11:  /* BGEZAL */
   16571          DIP("bgezal r%u, %u", rs, imm);
   16572          if (mode64) {
   16573             if (!dis_instr_branch(cins, &dres, resteerOkFn,
   16574                         callback_opaque, &bstmt))
   16575                goto decode_failure;
   16576          } else
   16577             dis_branch(True, binop(Iop_CmpEQ32, binop(Iop_And32, getIReg(rs),
   16578                        mkU32(0x80000000)), mkU32(0x0)), imm, &bstmt);
   16579          break;
   16580 
   16581       case 0x13:  /* BGEZALL */
   16582          DIP("bgezall r%u, %u", rs, imm);
   16583          if (mode64) {
   16584             putIReg(31, mkU64(guest_PC_curr_instr + 8));
   16585             lastn = dis_branch_likely(binop(Iop_CmpNE64,
   16586                                             binop(Iop_And64,
   16587                                                   getIReg(rs),
   16588                                                   mkU64(0x8000000000000000ULL)),
   16589                                             mkU64(0x0)),
   16590                                       imm);
   16591          } else {
   16592             putIReg(31, mkU32(guest_PC_curr_instr + 8));
   16593             lastn = dis_branch_likely(binop(Iop_CmpNE32, binop(Iop_And32,
   16594                                       getIReg(rs), mkU32(0x80000000)),
   16595                                       mkU32(0x0)), imm);
   16596          }
   16597          break;
   16598 
   16599       case 0x08:  /* TGEI */
   16600          DIP("tgei r%u, %u %u", rs, imm, trap_code);
   16601          if (mode64) {
   16602             stmt (IRStmt_Exit (unop (Iop_Not1,
   16603                                      binop (Iop_CmpLT64S,
   16604                                             getIReg (rs),
   16605                                             mkU64 (extend_s_16to64 (imm)))),
   16606                              Ijk_SigTRAP,
   16607                              IRConst_U64(guest_PC_curr_instr + 4),
   16608                              OFFB_PC));
   16609          } else {
   16610             stmt (IRStmt_Exit (unop (Iop_Not1,
   16611                                      binop (Iop_CmpLT32S,
   16612                                      getIReg (rs),
   16613                                      mkU32 (extend_s_16to32 (imm)))),
   16614                              Ijk_SigTRAP,
   16615                              IRConst_U32(guest_PC_curr_instr + 4),
   16616                              OFFB_PC));
   16617          }
   16618          break;
   16619 
   16620       case 0x09: {  /* TGEIU */
   16621          DIP("tgeiu r%u, %u %u", rs, imm, trap_code);
   16622          if (mode64) {
   16623             stmt (IRStmt_Exit (unop (Iop_Not1,
   16624                                      binop (Iop_CmpLT64U,
   16625                                             getIReg (rs),
   16626                                             mkU64 (extend_s_16to64 (imm)))),
   16627                              Ijk_SigTRAP,
   16628                              IRConst_U64(guest_PC_curr_instr + 4),
   16629                              OFFB_PC));
   16630          } else {
   16631             stmt (IRStmt_Exit (unop (Iop_Not1,
   16632                                      binop (Iop_CmpLT32U,
   16633                                             getIReg (rs),
   16634                                             mkU32 (extend_s_16to32 (imm)))),
   16635                                Ijk_SigTRAP,
   16636                                IRConst_U32(guest_PC_curr_instr + 4),
   16637                                OFFB_PC));
   16638          }
   16639          break;
   16640       }
   16641       case 0x0A: {  /* TLTI */
   16642          DIP("tlti r%u, %u %u", rs, imm, trap_code);
   16643          if (mode64) {
   16644             stmt (IRStmt_Exit (binop (Iop_CmpLT64S, getIReg (rs),
   16645                                       mkU64 (extend_s_16to64 (imm))),
   16646                              Ijk_SigTRAP,
   16647                              IRConst_U64(guest_PC_curr_instr + 4),
   16648                              OFFB_PC));
   16649          } else {
   16650             stmt (IRStmt_Exit (binop (Iop_CmpLT32S, getIReg (rs),
   16651                                       mkU32 (extend_s_16to32 (imm))),
   16652                                Ijk_SigTRAP,
   16653                                IRConst_U32(guest_PC_curr_instr + 4),
   16654                                OFFB_PC));
   16655          }
   16656          break;
   16657       }
   16658       case 0x0B: {  /* TLTIU */
   16659          DIP("tltiu r%u, %u %u", rs, imm, trap_code);
   16660          if (mode64) {
   16661             stmt (IRStmt_Exit (binop (Iop_CmpLT64U, getIReg (rs),
   16662                                       mkU64 (extend_s_16to64 (imm))),
   16663                              Ijk_SigTRAP,
   16664                              IRConst_U64(guest_PC_curr_instr + 4),
   16665                              OFFB_PC));
   16666          } else {
   16667             stmt (IRStmt_Exit (binop (Iop_CmpLT32U, getIReg (rs),
   16668                                       mkU32 (extend_s_16to32 (imm))),
   16669                                Ijk_SigTRAP,
   16670                                IRConst_U32(guest_PC_curr_instr + 4),
   16671                                OFFB_PC));
   16672          }
   16673          break;
   16674       }
   16675       case 0x0C: {  /* TEQI */
   16676           DIP("teqi r%u, %u %u", rs, imm, trap_code);
   16677          if (mode64) {
   16678             stmt (IRStmt_Exit (binop (Iop_CmpEQ64, getIReg (rs),
   16679                                       mkU64 (extend_s_16to64 (imm))),
   16680                                Ijk_SigTRAP,
   16681                                IRConst_U64(guest_PC_curr_instr + 4),
   16682                                OFFB_PC));
   16683          } else {
   16684             stmt (IRStmt_Exit (binop (Iop_CmpEQ32, getIReg (rs),
   16685                                       mkU32 (extend_s_16to32 (imm))),
   16686                                Ijk_SigTRAP,
   16687                                IRConst_U32(guest_PC_curr_instr + 4),
   16688                                OFFB_PC));
   16689          }
   16690          break;
   16691       }
   16692       case 0x0E: {  /* TNEI */
   16693          DIP("tnei r%u, %u %u", rs, imm, trap_code);
   16694          if (mode64) {
   16695             stmt (IRStmt_Exit (binop (Iop_CmpNE64, getIReg (rs),
   16696                                       mkU64 (extend_s_16to64 (imm))),
   16697                                Ijk_SigTRAP,
   16698                                IRConst_U64(guest_PC_curr_instr + 4),
   16699                                OFFB_PC));
   16700          } else {
   16701             stmt (IRStmt_Exit (binop (Iop_CmpNE32, getIReg (rs),
   16702                                       mkU32 (extend_s_16to32 (imm))),
   16703                                Ijk_SigTRAP,
   16704                                IRConst_U32(guest_PC_curr_instr + 4),
   16705                                OFFB_PC));
   16706          }
   16707          break;
   16708       }
   16709       case 0x1C: {  /* BPOSGE32 */
   16710          DIP("bposge32 %u", imm);
   16711          vassert(!mode64);
   16712          t0 = newTemp(Ity_I32);
   16713          /* Get pos field from DSPControl register. */
   16714          assign(t0, binop(Iop_And32, getDSPControl(), mkU32(0x3f)));
   16715          dis_branch(False, unop(Iop_Not1, binop(Iop_CmpLT32U, mkexpr(t0),
   16716                                 mkU32(32))), imm, &bstmt);
   16717       }
   16718       case 0x1F:
   16719          /* SYNCI */
   16720          /* Just ignore it */
   16721          break;
   16722 
   16723       default:
   16724          goto decode_failure;
   16725       }
   16726       break;
   16727 
   16728    case 0x04:
   16729       DIP("beq r%u, r%u, %u", rs, rt, imm);
   16730       if (mode64)
   16731          dis_branch(False, binop(Iop_CmpEQ64, getIReg(rs), getIReg(rt)),
   16732                                  imm, &bstmt);
   16733       else
   16734          dis_branch(False, binop(Iop_CmpEQ32, getIReg(rs), getIReg(rt)),
   16735                                  imm, &bstmt);
   16736       break;
   16737 
   16738    case 0x14:
   16739       DIP("beql r%u, r%u, %u", rs, rt, imm);
   16740       lastn = dis_branch_likely(binop(mode64 ? Iop_CmpNE64 : Iop_CmpNE32,
   16741                                 getIReg(rs), getIReg(rt)), imm);
   16742       break;
   16743 
   16744    case 0x05:
   16745       DIP("bne r%u, r%u, %u", rs, rt, imm);
   16746       if (mode64)
   16747          dis_branch(False, binop(Iop_CmpNE64, getIReg(rs), getIReg(rt)),
   16748                                  imm, &bstmt);
   16749       else
   16750          dis_branch(False, binop(Iop_CmpNE32, getIReg(rs), getIReg(rt)),
   16751                                  imm, &bstmt);
   16752       break;
   16753 
   16754    case 0x15:
   16755       DIP("bnel r%u, r%u, %u", rs, rt, imm);
   16756       lastn = dis_branch_likely(binop(mode64 ? Iop_CmpEQ64 : Iop_CmpEQ32,
   16757                                       getIReg(rs), getIReg(rt)), imm);
   16758       break;
   16759 
   16760    case 0x07:  /* BGTZ */
   16761       DIP("bgtz r%u, %u", rs, imm);
   16762       if (mode64)
   16763          dis_branch(False, unop(Iop_Not1, binop(Iop_CmpLE64S, getIReg(rs),
   16764                                 mkU64(0x00))), imm, &bstmt);
   16765       else
   16766          dis_branch(False, unop(Iop_Not1, binop(Iop_CmpLE32S, getIReg(rs),
   16767                                 mkU32(0x00))), imm, &bstmt);
   16768       break;
   16769 
   16770    case 0x17:  /* BGTZL */
   16771       DIP("bgtzl r%u, %u", rs, imm);
   16772       if (mode64)
   16773          lastn = dis_branch_likely(binop(Iop_CmpLE64S, getIReg(rs),
   16774                                          mkU64(0x00)), imm);
   16775       else
   16776          lastn = dis_branch_likely(binop(Iop_CmpLE32S, getIReg(rs),
   16777                                          mkU32(0x00)), imm);
   16778       break;
   16779 
   16780    case 0x06:  /* BLEZ */
   16781       DIP("blez r%u, %u", rs, imm);
   16782       if (mode64)
   16783          dis_branch(False, binop(Iop_CmpLE64S, getIReg(rs), mkU64(0x0)),
   16784                                 imm, &bstmt);
   16785       else
   16786          dis_branch(False,binop(Iop_CmpLE32S, getIReg(rs), mkU32(0x0)), imm,
   16787                                 &bstmt);
   16788       break;
   16789 
   16790    case 0x16:  /* BLEZL */
   16791       DIP("blezl r%u, %u", rs, imm);
   16792       lastn = dis_branch_likely(unop(Iop_Not1, (binop(mode64 ? Iop_CmpLE64S :
   16793                                      Iop_CmpLE32S, getIReg(rs), mode64 ?
   16794                                      mkU64(0x0) : mkU32(0x0)))), imm);
   16795       break;
   16796 
   16797    case 0x08: {  /* ADDI */
   16798       DIP("addi r%u, r%u, %u", rt, rs, imm);
   16799       IRTemp tmpRs32 = newTemp(Ity_I32);
   16800       assign(tmpRs32, mkNarrowTo32(ty, getIReg(rs)));
   16801 
   16802       t0 = newTemp(Ity_I32);
   16803       t1 = newTemp(Ity_I32);
   16804       t2 = newTemp(Ity_I32);
   16805       t3 = newTemp(Ity_I32);
   16806       t4 = newTemp(Ity_I32);
   16807       /* dst = src0 + sign(imm)
   16808          if(sign(src0 ) != sign(imm ))
   16809          goto no overflow;
   16810          if(sign(dst) == sign(src0 ))
   16811          goto no overflow;
   16812          we have overflow! */
   16813 
   16814       assign(t0, binop(Iop_Add32, mkexpr(tmpRs32),
   16815                        mkU32(extend_s_16to32(imm))));
   16816       assign(t1, binop(Iop_Xor32, mkexpr(tmpRs32),
   16817                        mkU32(extend_s_16to32(imm))));
   16818       assign(t2, unop(Iop_1Sto32, binop(Iop_CmpEQ32, binop(Iop_And32,
   16819                       mkexpr(t1), mkU32(0x80000000)), mkU32(0x80000000))));
   16820 
   16821       assign(t3, binop(Iop_Xor32, mkexpr(t0), mkexpr(tmpRs32)));
   16822       assign(t4, unop(Iop_1Sto32, binop(Iop_CmpNE32, binop(Iop_And32,
   16823                       mkexpr(t3), mkU32(0x80000000)), mkU32(0x80000000))));
   16824 
   16825       stmt(IRStmt_Exit(binop(Iop_CmpEQ32, binop(Iop_Or32, mkexpr(t2),
   16826                              mkexpr(t4)), mkU32(0)), Ijk_SigFPE_IntOvf,
   16827                        mode64 ? IRConst_U64(guest_PC_curr_instr + 4) :
   16828                                 IRConst_U32(guest_PC_curr_instr + 4),
   16829                        OFFB_PC));
   16830 
   16831       putIReg(rt,  mkWidenFrom32(ty, mkexpr(t0), True));
   16832       break;
   16833    }
   16834    case 0x09:  /* ADDIU */
   16835       DIP("addiu r%u, r%u, %u", rt, rs, imm);
   16836       if (mode64) {
   16837          putIReg(rt, mkWidenFrom32(ty, binop(Iop_Add32,
   16838                      mkNarrowTo32(ty, getIReg(rs)),mkU32(extend_s_16to32(imm))),
   16839                      True));
   16840       } else
   16841          putIReg(rt, binop(Iop_Add32, getIReg(rs),mkU32(extend_s_16to32(imm))));
   16842       break;
   16843 
   16844    case 0x0C:  /* ANDI */
   16845       DIP("andi r%u, r%u, %u", rt, rs, imm);
   16846       if (mode64) {
   16847          ALUI_PATTERN64(Iop_And64);
   16848       } else {
   16849          ALUI_PATTERN(Iop_And32);
   16850       }
   16851       break;
   16852 
   16853    case 0x0E:  /* XORI */
   16854       DIP("xori r%u, r%u, %u", rt, rs, imm);
   16855       if (mode64) {
   16856          ALUI_PATTERN64(Iop_Xor64);
   16857       } else {
   16858          ALUI_PATTERN(Iop_Xor32);
   16859       }
   16860       break;
   16861 
   16862    case 0x0D:  /* ORI */
   16863       DIP("ori r%u, r%u, %u", rt, rs, imm);
   16864       if (mode64) {
   16865          ALUI_PATTERN64(Iop_Or64);
   16866       } else {
   16867          ALUI_PATTERN(Iop_Or32);
   16868       }
   16869       break;
   16870 
   16871    case 0x0A:  /* SLTI */
   16872       DIP("slti r%u, r%u, %u", rt, rs, imm);
   16873       if (mode64)
   16874          putIReg(rt, unop(Iop_1Uto64, binop(Iop_CmpLT64S, getIReg(rs),
   16875                                             mkU64(extend_s_16to64(imm)))));
   16876       else
   16877          putIReg(rt, unop(Iop_1Uto32, binop(Iop_CmpLT32S, getIReg(rs),
   16878                                             mkU32(extend_s_16to32(imm)))));
   16879       break;
   16880 
   16881    case 0x0B:  /* SLTIU */
   16882       DIP("sltiu r%u, r%u, %u", rt, rs, imm);
   16883       if (mode64)
   16884          putIReg(rt, unop(Iop_1Uto64, binop(Iop_CmpLT64U, getIReg(rs),
   16885                                             mkU64(extend_s_16to64(imm)))));
   16886       else
   16887          putIReg(rt, unop(Iop_1Uto32, binop(Iop_CmpLT32U, getIReg(rs),
   16888                                             mkU32(extend_s_16to32(imm)))));
   16889       break;
   16890 
   16891    case 0x18: {  /* Doubleword Add Immidiate - DADD; MIPS64 */
   16892       DIP("daddi r%u, r%u, %u", rt, rs, imm);
   16893       IRTemp tmpRs64 = newTemp(Ity_I64);
   16894       assign(tmpRs64, getIReg(rs));
   16895 
   16896       t0 = newTemp(Ity_I64);
   16897       t1 = newTemp(Ity_I64);
   16898       t2 = newTemp(Ity_I64);
   16899       t3 = newTemp(Ity_I64);
   16900       t4 = newTemp(Ity_I64);
   16901       /* dst = src0 + sign(imm)
   16902          if(sign(src0 ) != sign(imm ))
   16903          goto no overflow;
   16904          if(sign(dst) == sign(src0 ))
   16905          goto no overflow;
   16906          we have overflow! */
   16907 
   16908       assign(t0, binop(Iop_Add64, mkexpr(tmpRs64),
   16909                        mkU64(extend_s_16to64(imm))));
   16910       assign(t1, binop(Iop_Xor64, mkexpr(tmpRs64),
   16911                        mkU64(extend_s_16to64(imm))));
   16912       assign(t2, unop(Iop_1Sto64, binop(Iop_CmpEQ64, binop(Iop_And64,
   16913                       mkexpr(t1), mkU64(0x8000000000000000ULL)),
   16914                                         mkU64(0x8000000000000000ULL))));
   16915 
   16916       assign(t3, binop(Iop_Xor64, mkexpr(t0), mkexpr(tmpRs64)));
   16917       assign(t4, unop(Iop_1Sto64, binop(Iop_CmpNE64, binop(Iop_And64,
   16918                       mkexpr(t3), mkU64(0x8000000000000000ULL)),
   16919                                         mkU64(0x8000000000000000ULL))));
   16920 
   16921       stmt(IRStmt_Exit(binop(Iop_CmpEQ64, binop(Iop_Or64, mkexpr(t2),
   16922                              mkexpr(t4)), mkU64(0)), Ijk_SigFPE_IntOvf,
   16923                        IRConst_U64(guest_PC_curr_instr + 4),
   16924                        OFFB_PC));
   16925 
   16926       putIReg(rt,  mkexpr(t0));
   16927       break;
   16928    }
   16929 
   16930    case 0x19:  /* Doubleword Add Immidiate Unsigned - DADDIU; MIPS64 */
   16931       DIP("daddiu r%u, r%u, %u", rt, rs, imm);
   16932       putIReg(rt, binop(Iop_Add64, getIReg(rs), mkU64(extend_s_16to64(imm))));
   16933       break;
   16934 
   16935    case 0x1A: {
   16936       /* Load Doubleword Left - LDL; MIPS64 */
   16937       vassert(mode64);
   16938       DIP("ldl r%u, %u(r%u)", rt, imm, rs);
   16939       /* t1 = addr */
   16940 #if defined (_MIPSEL)
   16941       t1 = newTemp(Ity_I64);
   16942       assign(t1, binop(Iop_Add64, getIReg(rs), mkU64(extend_s_16to64(imm))));
   16943 #elif defined (_MIPSEB)
   16944       t1 = newTemp(Ity_I64);
   16945       assign(t1, binop(Iop_Xor64, mkU64(0x7), binop(Iop_Add64, getIReg(rs),
   16946                                   mkU64(extend_s_16to64(imm)))));
   16947 #endif
   16948       /* t2 = word addr */
   16949       /* t4 = addr mod 8 */
   16950       LWX_SWX_PATTERN64_1;
   16951 
   16952       /* t3 = word content - shifted */
   16953       t3 = newTemp(Ity_I64);
   16954       assign(t3, binop(Iop_Shl64, load(Ity_I64, mkexpr(t2)),
   16955                  narrowTo(Ity_I8, binop(Iop_Shl64, binop(Iop_Sub64, mkU64(0x07),
   16956                  mkexpr(t4)), mkU8(3)))));
   16957 
   16958       /* rt content  - adjusted */
   16959       t5 = newTemp(Ity_I64);
   16960       t6 = newTemp(Ity_I64);
   16961       t7 = newTemp(Ity_I64);
   16962 
   16963       assign(t5, binop(Iop_Mul64, mkexpr(t4), mkU64(0x8)));
   16964 
   16965       assign(t6, binop(Iop_Shr64, mkU64(0x00FFFFFFFFFFFFFFULL),
   16966                        narrowTo(Ity_I8, mkexpr(t5))));
   16967 
   16968       assign(t7, binop(Iop_And64, getIReg(rt), mkexpr(t6)));
   16969 
   16970       putIReg(rt, binop(Iop_Or64, mkexpr(t7), mkexpr(t3)));
   16971       break;
   16972    }
   16973 
   16974    case 0x1B: {
   16975       /* Load Doubleword Right - LDR; MIPS64 */
   16976       vassert(mode64);
   16977       DIP("ldr r%u,%u(r%u)", rt, imm, rs);
   16978       /* t1 = addr */
   16979 #if defined (_MIPSEL)
   16980       t1 = newTemp(Ity_I64);
   16981       assign(t1, binop(Iop_Add64, getIReg(rs), mkU64(extend_s_16to64(imm))));
   16982 #elif defined (_MIPSEB)
   16983       t1 = newTemp(Ity_I64);
   16984       assign(t1, binop(Iop_Xor64, mkU64(0x7), binop(Iop_Add64, getIReg(rs),
   16985                                   mkU64(extend_s_16to64(imm)))));
   16986 #endif
   16987       /* t2 = word addr */
   16988       /* t4 = addr mod 8 */
   16989       LWX_SWX_PATTERN64_1;
   16990 
   16991       /* t3 = word content - shifted */
   16992       t3 = newTemp(Ity_I64);
   16993       assign(t3, binop(Iop_Shr64, load(Ity_I64, mkexpr(t2)),
   16994                  narrowTo(Ity_I8, binop(Iop_Shl64, mkexpr(t4), mkU8(3)))));
   16995 
   16996       /* rt content  - adjusted */
   16997       t5 = newTemp(Ity_I64);
   16998       assign(t5, binop(Iop_And64, getIReg(rt), unop(Iop_Not64,
   16999                  binop(Iop_Shr64, mkU64(0xFFFFFFFFFFFFFFFFULL),
   17000                  narrowTo(Ity_I8, binop(Iop_Shl64, mkexpr(t4), mkU8(0x3)))))));
   17001 
   17002       putIReg(rt, binop(Iop_Or64, mkexpr(t5), mkexpr(t3)));
   17003       break;
   17004    }
   17005 
   17006    case 0x27:  /* Load Word unsigned - LWU; MIPS64 */
   17007       DIP("lwu r%u,%u(r%u)", rt, imm, rs);
   17008       LOAD_STORE_PATTERN;
   17009 
   17010       putIReg(rt, mkWidenFrom32(ty, load(Ity_I32, mkexpr(t1)), False));
   17011       break;
   17012 
   17013    case 0x30:  /* LL / LWC0 */
   17014       DIP("ll r%u, %u(r%u)", rt, imm, rs);
   17015       LOAD_STORE_PATTERN;
   17016 
   17017       t2 = newTemp(Ity_I32);
   17018 #if defined (_MIPSEL)
   17019       stmt(IRStmt_LLSC(Iend_LE, t2, mkexpr(t1), NULL /* this is a load */ ));
   17020 #elif defined (_MIPSEB)
   17021       stmt(IRStmt_LLSC(Iend_BE, t2, mkexpr(t1), NULL /* this is a load */ ));
   17022 #endif
   17023       if (mode64)
   17024          putIReg(rt, unop(Iop_32Sto64, mkexpr(t2)));
   17025       else
   17026          putIReg(rt, mkexpr(t2));
   17027       break;
   17028 
   17029    case 0x34:  /* Load Linked Doubleword - LLD; MIPS64 */
   17030       DIP("lld r%u, %u(r%u)", rt, imm, rs);
   17031       LOAD_STORE_PATTERN;
   17032 
   17033       t2 = newTemp(Ity_I64);
   17034 #if defined (_MIPSEL)
   17035       stmt(IRStmt_LLSC
   17036            (Iend_LE, t2, mkexpr(t1), NULL /* this is a load */ ));
   17037 #elif defined (_MIPSEB)
   17038       stmt(IRStmt_LLSC
   17039            (Iend_BE, t2, mkexpr(t1), NULL /* this is a load */ ));
   17040 #endif
   17041 
   17042       putIReg(rt, mkexpr(t2));
   17043       break;
   17044 
   17045    case 0x38:  /* SC / SWC0 */
   17046       DIP("sc r%u, %u(r%u)", rt, imm, rs);
   17047       LOAD_STORE_PATTERN;
   17048 
   17049       t2 = newTemp(Ity_I1);
   17050 #if defined (_MIPSEL)
   17051       stmt(IRStmt_LLSC(Iend_LE, t2, mkexpr(t1), mkNarrowTo32(ty, getIReg(rt))));
   17052 #elif defined (_MIPSEB)
   17053       stmt(IRStmt_LLSC(Iend_BE, t2, mkexpr(t1), mkNarrowTo32(ty, getIReg(rt))));
   17054 #endif
   17055 
   17056       putIReg(rt, unop(mode64 ? Iop_1Uto64 : Iop_1Uto32, mkexpr(t2)));
   17057       break;
   17058 
   17059    case 0x3C:  /* Store Conditional Doubleword - SCD; MIPS64 */
   17060       DIP("sdc r%u, %u(r%u)", rt, imm, rs);
   17061       LOAD_STORE_PATTERN;
   17062 
   17063       t2 = newTemp(Ity_I1);
   17064 #if defined (_MIPSEL)
   17065       stmt(IRStmt_LLSC(Iend_LE, t2, mkexpr(t1), getIReg(rt)));
   17066 #elif defined (_MIPSEB)
   17067       stmt(IRStmt_LLSC(Iend_BE, t2, mkexpr(t1), getIReg(rt)));
   17068 #endif
   17069 
   17070       putIReg(rt, unop(Iop_1Uto64, mkexpr(t2)));
   17071       break;
   17072 
   17073    case 0x37:  /* Load Doubleword - LD; MIPS64 */
   17074       DIP("ld r%u, %u(r%u)", rt, imm, rs);
   17075       LOAD_STORE_PATTERN;
   17076       putIReg(rt, load(Ity_I64, mkexpr(t1)));
   17077       break;
   17078 
   17079    case 0x3F:  /* Store Doubleword - SD; MIPS64 */
   17080       DIP("sd r%u, %u(r%u)", rt, imm, rs);
   17081       LOAD_STORE_PATTERN;
   17082       store(mkexpr(t1), getIReg(rt));
   17083       break;
   17084 
   17085    case 0x32:  /* Branch on Bit Clear - BBIT0; Cavium OCTEON */
   17086       /* Cavium Specific instructions. */
   17087       if (VEX_MIPS_COMP_ID(archinfo->hwcaps) == VEX_PRID_COMP_CAVIUM) {
   17088          DIP("bbit0 r%u, 0x%x, %x", rs, rt, imm);
   17089          t0 = newTemp(Ity_I32);
   17090          t1 = newTemp(Ity_I32);
   17091          assign(t0, mkU32(0x1));
   17092          assign(t1, binop(Iop_Shl32, mkexpr(t0), mkU8(rt)));
   17093          dis_branch(False, binop(Iop_CmpEQ32,
   17094                                  binop(Iop_And32,
   17095                                        mkexpr(t1),
   17096                                        mkNarrowTo32(ty, getIReg(rs))),
   17097                                  mkU32(0x0)),
   17098                     imm, &bstmt);
   17099          break;
   17100       } else {
   17101          goto decode_failure;
   17102       }
   17103 
   17104    case 0x36:  /* Branch on Bit Clear Plus 32 - BBIT032; Cavium OCTEON */
   17105       /* Cavium Specific instructions. */
   17106       if (VEX_MIPS_COMP_ID(archinfo->hwcaps) == VEX_PRID_COMP_CAVIUM) {
   17107          DIP("bbit032 r%u, 0x%x, %x", rs, rt, imm);
   17108          t0 = newTemp(Ity_I64);
   17109          t1 = newTemp(Ity_I8);  /* Shift. */
   17110          t2 = newTemp(Ity_I64);
   17111          assign(t0, mkU64(0x1));
   17112          assign(t1, binop(Iop_Add8, mkU8(rt), mkU8(32)));
   17113          assign(t2, binop(Iop_Shl64, mkexpr(t0), mkexpr(t1)));
   17114          dis_branch(False, binop(Iop_CmpEQ64,
   17115                                  binop(Iop_And64,
   17116                                        mkexpr(t2),
   17117                                        getIReg(rs)),
   17118                                  mkU64(0x0)),
   17119                     imm, &bstmt);
   17120          break;
   17121       } else {
   17122          goto decode_failure;
   17123       }
   17124 
   17125    case 0x3A:  /* Branch on Bit Set - BBIT1; Cavium OCTEON */
   17126       /* Cavium Specific instructions. */
   17127       if (VEX_MIPS_COMP_ID(archinfo->hwcaps) == VEX_PRID_COMP_CAVIUM) {
   17128          DIP("bbit1 r%u, 0x%x, %x", rs, rt, imm);
   17129          t0 = newTemp(Ity_I32);
   17130          t1 = newTemp(Ity_I32);
   17131          assign(t0, mkU32(0x1));
   17132          assign(t1, binop(Iop_Shl32, mkexpr(t0), mkU8(rt)));
   17133          dis_branch(False, binop(Iop_CmpNE32,
   17134                                  binop(Iop_And32,
   17135                                        mkexpr(t1),
   17136                                        mkNarrowTo32(ty, getIReg(rs))),
   17137                                  mkU32(0x0)),
   17138                     imm, &bstmt);
   17139          break;
   17140       } else {
   17141          goto decode_failure;
   17142       }
   17143 
   17144    case 0x3E:  /* Branch on Bit Set Plus 32 - BBIT132; Cavium OCTEON */
   17145       /* Cavium Specific instructions. */
   17146       if (VEX_MIPS_COMP_ID(archinfo->hwcaps) == VEX_PRID_COMP_CAVIUM) {
   17147          DIP("bbit132 r%u, 0x%x, %x", rs, rt, imm);
   17148          t0 = newTemp(Ity_I64);
   17149          t1 = newTemp(Ity_I8);  /* Shift. */
   17150          t2 = newTemp(Ity_I64);
   17151          assign(t0, mkU64(0x1));
   17152          assign(t1, binop(Iop_Add8, mkU8(rt), mkU8(32)));
   17153          assign(t2, binop(Iop_Shl64, mkexpr(t0), mkexpr(t1)));
   17154          dis_branch(False, binop(Iop_CmpNE64,
   17155                                  binop(Iop_And64,
   17156                                        mkexpr(t2),
   17157                                        getIReg(rs)),
   17158                                  mkU64(0x0)),
   17159                     imm, &bstmt);
   17160          break;
   17161       } else {
   17162          goto decode_failure;
   17163       }
   17164 
   17165    default:
   17166       goto decode_failure;
   17167 
   17168    decode_failure_dsp:
   17169       vex_printf("Error occured while trying to decode MIPS32 DSP "
   17170                  "instruction.\nYour platform probably doesn't support "
   17171                  "MIPS32 DSP ASE.\n");
   17172    decode_failure:
   17173       /* All decode failures end up here. */
   17174       if (sigill_diag)
   17175          vex_printf("vex mips->IR: unhandled instruction bytes: "
   17176                     "0x%x 0x%x 0x%x 0x%x\n",
   17177                     (UInt) getIByte(delta_start + 0),
   17178                     (UInt) getIByte(delta_start + 1),
   17179                     (UInt) getIByte(delta_start + 2),
   17180                     (UInt) getIByte(delta_start + 3));
   17181 
   17182       /* Tell the dispatcher that this insn cannot be decoded, and so has
   17183          not been executed, and (is currently) the next to be executed.
   17184          EIP should be up-to-date since it made so at the start bnezof each
   17185          insn, but nevertheless be paranoid and update it again right
   17186          now. */
   17187       if (mode64) {
   17188          stmt(IRStmt_Put(offsetof(VexGuestMIPS64State, guest_PC),
   17189               mkU64(guest_PC_curr_instr)));
   17190          jmp_lit64(&dres, Ijk_NoDecode, guest_PC_curr_instr);
   17191       } else {
   17192          stmt(IRStmt_Put(offsetof(VexGuestMIPS32State, guest_PC),
   17193               mkU32(guest_PC_curr_instr)));
   17194          jmp_lit32(&dres, Ijk_NoDecode, guest_PC_curr_instr);
   17195       }
   17196       dres.whatNext = Dis_StopHere;
   17197       dres.len = 0;
   17198       return dres;
   17199    }  /* switch (opc) for the main (primary) opcode switch. */
   17200 
   17201    /* All MIPS insn have 4 bytes */
   17202 
   17203    if (delay_slot_branch) {
   17204       delay_slot_branch = False;
   17205       stmt(bstmt);
   17206       bstmt = NULL;
   17207       if (mode64)
   17208          putPC(mkU64(guest_PC_curr_instr + 4));
   17209       else
   17210          putPC(mkU32(guest_PC_curr_instr + 4));
   17211       dres.jk_StopHere = is_Branch_or_Jump_and_Link(guest_code + delta - 4) ?
   17212                          Ijk_Call : Ijk_Boring;
   17213    }
   17214 
   17215    if (likely_delay_slot) {
   17216       dres.jk_StopHere = Ijk_Boring;
   17217       dres.whatNext = Dis_StopHere;
   17218       putPC(lastn);
   17219       lastn = NULL;
   17220    }
   17221    if (delay_slot_jump) {
   17222       putPC(lastn);
   17223       lastn = NULL;
   17224       dres.jk_StopHere = is_Branch_or_Jump_and_Link(guest_code + delta - 4) ?
   17225                          Ijk_Call : Ijk_Boring;
   17226    }
   17227 
   17228  decode_success:
   17229    /* All decode successes end up here. */
   17230    switch (dres.whatNext) {
   17231       case Dis_Continue:
   17232          if (mode64)
   17233             putPC(mkU64(guest_PC_curr_instr + 4));
   17234          else
   17235             putPC(mkU32(guest_PC_curr_instr + 4));
   17236          break;
   17237       case Dis_ResteerU:
   17238       case Dis_ResteerC:
   17239          putPC(mkU32(dres.continueAt));
   17240          break;
   17241       case Dis_StopHere:
   17242          break;
   17243       default:
   17244          vassert(0);
   17245          break;
   17246    }
   17247 
   17248    /* On MIPS we need to check if the last instruction in block is branch or
   17249       jump. */
   17250    if (((vex_control.guest_max_insns - 1) == (delta + 4) / 4)
   17251        &&  (dres.whatNext != Dis_StopHere))
   17252       if (branch_or_jump(guest_code + delta + 4)) {
   17253          dres.whatNext = Dis_StopHere;
   17254          dres.jk_StopHere = Ijk_Boring;
   17255          if (mode64)
   17256             putPC(mkU64(guest_PC_curr_instr + 4));
   17257          else
   17258             putPC(mkU32(guest_PC_curr_instr + 4));
   17259       }
   17260    dres.len = 4;
   17261 
   17262    DIP("\n");
   17263 
   17264    return dres;
   17265 
   17266 }
   17267 
   17268 /*------------------------------------------------------------*/
   17269 /*--- Top-level fn                                         ---*/
   17270 /*------------------------------------------------------------*/
   17271 
   17272 /* Disassemble a single instruction into IR.  The instruction
   17273    is located in host memory at &guest_code[delta]. */
   17274 DisResult disInstr_MIPS( IRSB*        irsb_IN,
   17275                          Bool         (*resteerOkFn) ( void *, Addr ),
   17276                          Bool         resteerCisOk,
   17277                          void*        callback_opaque,
   17278                          const UChar* guest_code_IN,
   17279                          Long         delta,
   17280                          Addr         guest_IP,
   17281                          VexArch      guest_arch,
   17282                          const VexArchInfo* archinfo,
   17283                          const VexAbiInfo*  abiinfo,
   17284                          VexEndness   host_endness_IN,
   17285                          Bool         sigill_diag_IN )
   17286 {
   17287    DisResult dres;
   17288    /* Set globals (see top of this file) */
   17289    vassert(guest_arch == VexArchMIPS32 || guest_arch == VexArchMIPS64);
   17290 
   17291    mode64 = guest_arch != VexArchMIPS32;
   17292 #if (__mips_fpr==64)
   17293    fp_mode64 = ((VEX_MIPS_REV(archinfo->hwcaps) == VEX_PRID_CPU_32FPR)
   17294                 || guest_arch == VexArchMIPS64);
   17295 #endif
   17296 
   17297    guest_code = guest_code_IN;
   17298    irsb = irsb_IN;
   17299    host_endness = host_endness_IN;
   17300 #if defined(VGP_mips32_linux)
   17301    guest_PC_curr_instr = (Addr32)guest_IP;
   17302 #elif defined(VGP_mips64_linux)
   17303    guest_PC_curr_instr = (Addr64)guest_IP;
   17304 #endif
   17305 
   17306    dres = disInstr_MIPS_WRK(resteerOkFn, resteerCisOk, callback_opaque,
   17307                             delta, archinfo, abiinfo, sigill_diag_IN);
   17308 
   17309    return dres;
   17310 }
   17311 
   17312 /*--------------------------------------------------------------------*/
   17313 /*--- end                                        guest_mips_toIR.c ---*/
   17314 /*--------------------------------------------------------------------*/
   17315