]> git.ipfire.org Git - thirdparty/valgrind.git/commitdiff
mips32: Add support for mips32 DSP instruction set.
authorDejan Jevtic <dejan.jevtic@valgrind.org>
Thu, 25 Jul 2013 09:08:03 +0000 (09:08 +0000)
committerDejan Jevtic <dejan.jevtic@valgrind.org>
Thu, 25 Jul 2013 09:08:03 +0000 (09:08 +0000)
Add support for mips32 DSP and DSP revision 2 ASE.
More details about the mips32 DSP(r2) ASE:
http://www.mips.com/media/files/MD00566-2B-MIPSDSP-QRC-01.00.pdf
Applied patch provided by Maja Gagic <maja.gagic@rt-rk.com>

git-svn-id: svn://svn.valgrind.org/vex/trunk@2732

VEX/priv/guest_mips_helpers.c
VEX/priv/guest_mips_toIR.c
VEX/priv/host_mips_defs.c
VEX/priv/host_mips_defs.h
VEX/priv/host_mips_isel.c
VEX/priv/main_main.c
VEX/pub/libvex.h
VEX/pub/libvex_guest_mips32.h

index f390389819891332cc850adff7c1014a2704ce89..80ee906e9441af4ed5c9eb0890d8815e11b58bf7 100644 (file)
@@ -164,6 +164,13 @@ void LibVEX_GuestMIPS32_initialise( /*OUT*/ VexGuestMIPS32State * vex_state)
    vex_state->guest_NRADDR = 0;
 
    vex_state->guest_COND = 0;
+
+   /* MIPS32 DSP ASE(r2) specific registers */
+   vex_state->guest_DSPControl = 0;   /* DSPControl register */
+   vex_state->guest_ac0 = 0;          /* Accumulator 0 */
+   vex_state->guest_ac1 = 0;          /* Accumulator 1 */
+   vex_state->guest_ac2 = 0;          /* Accumulator 2 */
+   vex_state->guest_ac3 = 0;          /* Accumulator 3 */
 }
 
 void LibVEX_GuestMIPS64_initialise ( /*OUT*/ VexGuestMIPS64State * vex_state )
@@ -274,11 +281,11 @@ void LibVEX_GuestMIPS64_initialise ( /*OUT*/ VexGuestMIPS64State * vex_state )
 
 /* Figure out if any part of the guest state contained in minoff
    .. maxoff requires precise memory exceptions.  If in doubt return
-   True (but this generates significantly slower code).  
+   True (but this generates significantly slower code).
 
    We enforce precise exns for guest SP, PC.
 
-   Only SP is needed in mode VexRegUpdSpAtMemAccess.   
+   Only SP is needed in mode VexRegUpdSpAtMemAccess.
 */
 Bool guest_mips32_state_requires_precise_mem_exns(Int minoff, Int maxoff)
 {
@@ -1057,7 +1064,7 @@ ULong mips64_dirtyhelper_dmfc0 ( UInt rd, UInt sel )
            break;
          }
        break;
+
      default:
        break;
      }
index 551faee06bb40f3d27b098041a5b6f95f801e84e..6db5b85fac3d0544e7d1c7993627ea0d283b32d1 100644 (file)
@@ -395,8 +395,31 @@ static UInt floatGuestRegOffset(UInt fregNo)
    return ret;
 }
 
-/* Do a endian load of a 32-bit word, regardless of the
-   endianness of the underlying host. */
+/* ---------------- MIPS32 DSP ASE(r2) accumulators ---------------- */
+
+static UInt accumulatorGuestRegOffset(UInt acNo)
+{
+   vassert(!mode64);
+   vassert(acNo <= 3);
+   UInt ret;
+   switch (acNo) {
+      case 0:
+         ret = offsetof(VexGuestMIPS32State, guest_ac0); break;
+      case 1:
+         ret = offsetof(VexGuestMIPS32State, guest_ac1); break;
+      case 2:
+         ret = offsetof(VexGuestMIPS32State, guest_ac2); break;
+      case 3:
+         ret = offsetof(VexGuestMIPS32State, guest_ac3); break;
+      default:
+         vassert(0);
+    break;
+   }
+   return ret;
+}
+
+/* Do a endian load of a 32-bit word, regardless of the endianness of the
+   underlying host. */
 static inline UInt getUInt(UChar * p)
 {
    UInt w = 0;
@@ -449,7 +472,7 @@ static inline UInt getUInt(UChar * p)
    t4 = newTemp(Ity_I32); \
    assign(t4, mkNarrowTo32( ty, binop(Iop_And64, \
                                       mkexpr(t1), mkU64(0x3))));
+
 #define LWX_SWX_PATTERN64_1 \
    t2 = newTemp(Ity_I64); \
    assign(t2, binop(Iop_And64, mkexpr(t1), mkU64(0xFFFFFFFFFFFFFFF8ULL))); \
@@ -641,6 +664,43 @@ static UInt get_sel(UInt mipsins)
    return (0x00000007 & mipsins);
 }
 
+/* Get acc number for all MIPS32 DSP ASE(r2) instructions that use them,
+   except for MFHI and MFLO. */
+static UInt get_acNo(UInt mipsins)
+{
+   return (0x00001800 & mipsins) >> 11;
+}
+
+/* Get accumulator number for MIPS32 DSP ASEr2 MFHI and MFLO instructions. */
+static UInt get_acNo_mfhilo(UInt mipsins)
+{
+   return (0x00600000 & mipsins) >> 21;
+}
+
+/* Get mask field (helper function for wrdsp instruction). */
+static UInt get_wrdspMask(UInt mipsins)
+{
+   return (0x001ff800 & mipsins) >> 11;
+}
+
+/* Get mask field (helper function for rddsp instruction). */
+static UInt get_rddspMask(UInt mipsins)
+{
+   return (0x03ff0000 & mipsins) >> 16;
+}
+
+/* Get shift field (helper function for DSP ASE instructions). */
+static UInt get_shift(UInt mipsins)
+{
+   return (0x03f00000 & mipsins) >> 20;
+}
+
+/* Get immediate field for DSP ASE instructions. */
+static UInt get_dspImm(UInt mipsins)
+{
+   return (0x03ff0000 & mipsins) >> 16;
+}
+
 static Bool branch_or_jump(UChar * addr)
 {
    UInt fmt;
@@ -651,7 +711,7 @@ static Bool branch_or_jump(UChar * addr)
    UInt function = get_function(cins);
 
    /* bgtz, blez, bne, beq, jal */
-   if (opcode == 0x07 || opcode == 0x06 || opcode == 0x05 || opcode == 0x04 
+   if (opcode == 0x07 || opcode == 0x06 || opcode == 0x05 || opcode == 0x04
        || opcode == 0x03 || opcode == 0x02) {
       return True;
    }
@@ -694,6 +754,11 @@ static Bool branch_or_jump(UChar * addr)
       }
    }
 
+   /* bposge32 */
+   if (opcode == 0x01 && rt == 0x1c) {
+      return True;
+   }
+
    return False;
 }
 
@@ -767,13 +832,19 @@ static IRExpr *mkU8(UInt i)
    return IRExpr_Const(IRConst_U8((UChar) i));
 }
 
-/* Create an expression node for a 32-bit integer constant */
+/* Create an expression node for a 16-bit integer constant. */
+static IRExpr *mkU16(UInt i)
+{
+   return IRExpr_Const(IRConst_U16(i));
+}
+
+/* Create an expression node for a 32-bit integer constant. */
 static IRExpr *mkU32(UInt i)
 {
    return IRExpr_Const(IRConst_U32(i));
 }
 
-/* Create an expression node for a 64-bit integer constant */
+/* Create an expression node for a 64-bit integer constant. */
 static IRExpr *mkU64(ULong i)
 {
    return IRExpr_Const(IRConst_U64(i));
@@ -864,6 +935,11 @@ static IRExpr *genRORV32(IRExpr * src, IRExpr * rs)
                           binop(Iop_Shr32, src, mkexpr(t0)));
 }
 
+static UShort extend_s_10to16(UInt x)
+{
+   return (UShort) ((((Int) x) << 22) >> 22);
+}
+
 static UInt extend_s_16to32(UInt x)
 {
    return (UInt) ((((Int) x) << 16) >> 16);
@@ -911,6 +987,34 @@ static void jmp_lit64 ( /*MOD*/ DisResult* dres, IRJumpKind kind, Addr64 d64 )
    stmt(IRStmt_Put(OFFB_PC, mkU64(d64)));
 }
 
+/* Get value from accumulator (helper function for MIPS32 DSP ASE instructions).
+   This function should be called before any other operation if widening
+   multiplications are used. */
+static IRExpr *getAcc(UInt acNo)
+{
+   vassert(!mode64);
+   vassert(acNo <= 3);
+   return IRExpr_Get(accumulatorGuestRegOffset(acNo), Ity_I64);
+}
+
+/* Get value from DSPControl register (helper function for MIPS32 DSP ASE
+   instructions). */
+static IRExpr *getDSPControl(void)
+{
+   vassert(!mode64);
+   return IRExpr_Get(offsetof(VexGuestMIPS32State, guest_DSPControl), Ity_I32);
+}
+
+/* Put value to DSPControl register. Expression e is written to DSPControl as
+   is. If only certain bits of DSPControl need to be changed, it should be done
+   before calling putDSPControl(). It could be done by reading DSPControl and
+   ORing it with appropriate mask. */
+static void putDSPControl(IRExpr * e)
+{
+   vassert(!mode64);
+   stmt(IRStmt_Put(offsetof(VexGuestMIPS32State, guest_DSPControl), e));
+}
+
 /* Fetch a byte from the guest insn stream. */
 static UChar getIByte(Int delta)
 {
@@ -993,18 +1097,53 @@ static void putIReg(UInt archreg, IRExpr * e)
 
 static void putLO(IRExpr * e)
 {
-   if (mode64)
+   if (mode64) {
       stmt(IRStmt_Put(offsetof(VexGuestMIPS64State, guest_LO), e));
-   else
+   } else {
       stmt(IRStmt_Put(offsetof(VexGuestMIPS32State, guest_LO), e));
+   /* Add value to lower 32 bits of ac0 to maintain compatibility between
+      regular MIPS32 instruction set and MIPS DSP ASE. Keep higher 32bits
+      unchanged. */
+      IRTemp t_lo = newTemp(Ity_I32);
+      IRTemp t_hi = newTemp(Ity_I32);
+      assign(t_lo, e);
+      assign(t_hi, unop(Iop_64HIto32, getAcc(0)));
+      stmt(IRStmt_Put(accumulatorGuestRegOffset(0),
+           binop(Iop_32HLto64, mkexpr(t_hi), mkexpr(t_lo))));
+   }
 }
 
 static void putHI(IRExpr * e)
 {
-   if (mode64)
+   if (mode64) {
       stmt(IRStmt_Put(offsetof(VexGuestMIPS64State, guest_HI), e));
-   else
+   } else {
       stmt(IRStmt_Put(offsetof(VexGuestMIPS32State, guest_HI), e));
+   /* Add value to higher 32 bits of ac0 to maintain compatibility between
+      regular MIPS32 instruction set and MIPS DSP ASE. Keep lower 32bits
+      unchanged. */
+      IRTemp t_lo = newTemp(Ity_I32);
+      IRTemp t_hi = newTemp(Ity_I32);
+      assign(t_hi, e);
+      assign(t_lo, unop(Iop_64to32, getAcc(0)));
+      stmt(IRStmt_Put(accumulatorGuestRegOffset(0),
+           binop(Iop_32HLto64, mkexpr(t_hi), mkexpr(t_lo))));
+   }
+}
+
+/* Put value to accumulator(helper function for MIPS32 DSP ASE instructions). */
+static void putAcc(UInt acNo, IRExpr * e)
+{
+   vassert(!mode64);
+   vassert(acNo <= 3);
+   vassert(typeOfIRExpr(irsb->tyenv, e) == Ity_I64);
+   stmt(IRStmt_Put(accumulatorGuestRegOffset(acNo), e));
+/* If acNo = 0, split value to HI and LO regs in order to maintain compatibility
+   between MIPS32 and MIPS DSP ASE insn sets. */
+   if (0 == acNo) {
+     putLO(unop(Iop_64to32, e));
+     putHI(unop(Iop_64HIto32, e));
+   }
 }
 
 static IRExpr *mkNarrowTo8 ( IRType ty, IRExpr * src )
@@ -1088,9 +1227,9 @@ static IRExpr *dis_branch_likely(IRExpr * guard, UInt imm)
    IRTemp t0;
 
    /* PC = PC + (SignExtend(signed_immed_24) << 2)
-      An 18-bit signed offset (the 16-bit offset field shifted left 2 bits) 
+      An 18-bit signed offset (the 16-bit offset field shifted left 2 bits)
       is added to the address of the instruction following
-      the branch (not the branch itself), in the branch delay slot, to form 
+      the branch (not the branch itself), in the branch delay slot, to form
       a PC-relative effective target address. */
    if (mode64)
       branch_offset = extend_s_18to64(imm << 2);
@@ -1104,7 +1243,7 @@ static IRExpr *dis_branch_likely(IRExpr * guard, UInt imm)
       stmt(IRStmt_Exit(mkexpr(t0), Ijk_Boring,
                        IRConst_U64(guest_PC_curr_instr + 8), OFFB_PC));
    else
-      stmt(IRStmt_Exit(mkexpr(t0), Ijk_Boring, 
+      stmt(IRStmt_Exit(mkexpr(t0), Ijk_Boring,
                        IRConst_U32(guest_PC_curr_instr + 8), OFFB_PC));
 
    irsb->jumpkind = Ijk_Boring;
@@ -1128,9 +1267,9 @@ static void dis_branch(Bool link, IRExpr * guard, UInt imm, IRStmt ** set)
    }
 
    /* PC = PC + (SignExtend(signed_immed_24) << 2)
-      An 18-bit signed offset (the 16-bit offset field shifted left 2 bits) 
+      An 18-bit signed offset (the 16-bit offset field shifted left 2 bits)
       is added to the address of the instruction following
-      the branch (not the branch itself), in the branch delay slot, to form 
+      the branch (not the branch itself), in the branch delay slot, to form
       a PC-relative effective target address. */
 
    if (mode64)
@@ -1221,7 +1360,7 @@ static void setFPUCondCode(IRExpr * e, UInt cc)
       putFCSR(binop(Iop_And32, getFCSR(), mkU32(0xFF7FFFFF)));
       putFCSR(binop(Iop_Or32, getFCSR(), binop(Iop_Shl32, e, mkU8(23))));
    } else {
-      putFCSR(binop(Iop_And32, getFCSR(), unop(Iop_Not32, 
+      putFCSR(binop(Iop_And32, getFCSR(), unop(Iop_Not32,
                                binop(Iop_Shl32, mkU32(0x01000000), mkU8(cc)))));
       putFCSR(binop(Iop_Or32, getFCSR(), binop(Iop_Shl32, e, mkU8(24 + cc))));
    }
@@ -1229,7 +1368,7 @@ static void setFPUCondCode(IRExpr * e, UInt cc)
 
 static IRExpr* get_IR_roundingmode ( void )
 {
-/* 
+/*
    rounding mode | MIPS | IR
    ------------------------
    to nearest    | 00  | 00
@@ -1270,7 +1409,7 @@ static IRConst *mkSzConst ( IRType ty, ULong imm64 )
 static Addr64 mkSzAddr ( IRType ty, Addr64 addr )
 {
    vassert(ty == Ity_I32 || ty == Ity_I64);
-   return (ty == Ity_I64 ? (Addr64) addr : 
+   return (ty == Ity_I64 ? (Addr64) addr :
                            (Addr64) extend_s_32to64(toUInt(addr)));
 }
 
@@ -1515,11 +1654,11 @@ static Bool dis_instr_CCondFmt ( UInt cins )
                 */
 
                /* ccMIPS = Shl(1, (~(ccIR>>5) & 2) | ((ccIR ^ (ccIR>>6)) & 1) */
-               assign(ccMIPS, binop(Iop_Shl32, mkU32(1), unop(Iop_32to8, 
+               assign(ccMIPS, binop(Iop_Shl32, mkU32(1), unop(Iop_32to8,
                               binop(Iop_Or32, binop(Iop_And32, unop(Iop_Not32,
                               binop(Iop_Shr32, mkexpr(ccIR),mkU8(5))),mkU32(2)),
                               binop(Iop_And32, binop(Iop_Xor32, mkexpr(ccIR),
-                              binop(Iop_Shr32, mkexpr(ccIR), mkU8(6))), 
+                              binop(Iop_Shr32, mkexpr(ccIR), mkU8(6))),
                               mkU32(1))))));
                putLO(mkWidenFrom32(Ity_I64, mkexpr(ccMIPS), True));
 
@@ -1589,7 +1728,7 @@ static Bool dis_instr_CCondFmt ( UInt cins )
                   case 0xF:
                      setFPUCondCode(mkexpr(t2), fpc_cc);
                      break;
-   
+
                   default:
                      return False;
                }
@@ -1612,12 +1751,12 @@ static Bool dis_instr_CCondFmt ( UInt cins )
                 */
 
                /* ccMIPS = Shl(1, (~(ccIR>>5) & 2) | ((ccIR ^ (ccIR>>6)) & 1) */
-               assign(ccMIPS, binop(Iop_Shl32, mkU32(1), unop(Iop_32to8, 
+               assign(ccMIPS, binop(Iop_Shl32, mkU32(1), unop(Iop_32to8,
                               binop(Iop_Or32, binop(Iop_And32, unop(Iop_Not32,
                               binop(Iop_Shr32, mkexpr(ccIR), mkU8(5))),
                                     mkU32(2)), binop(Iop_And32,
                               binop(Iop_Xor32, mkexpr(ccIR),
-                              binop(Iop_Shr32, mkexpr(ccIR), mkU8(6))), 
+                              binop(Iop_Shr32, mkexpr(ccIR), mkU8(6))),
                               mkU32(1))))));
                /* UN */
                assign(t0, binop(Iop_And32, mkexpr(ccMIPS), mkU32(0x1)));
@@ -1686,7 +1825,7 @@ static Bool dis_instr_CCondFmt ( UInt cins )
                   case 0xF:
                      setFPUCondCode(mkexpr(t2), fpc_cc);
                      break;
-   
+
                   default:
                      return False;
                }
@@ -1717,7 +1856,7 @@ static Bool dis_instr_CCondFmt ( UInt cins )
                            binop(Iop_And32, binop(Iop_Xor32, mkexpr(ccIR),
                            binop(Iop_Shr32, mkexpr(ccIR), mkU8(6))),
                            mkU32(1))))));
-            
+
             /* UN */
             assign(t0, binop(Iop_And32, mkexpr(ccMIPS), mkU32(0x1)));
             /* EQ */
@@ -1904,14 +2043,9079 @@ static Bool dis_instr_branch ( UInt theInstr, DisResult * dres,
                jmpKind = Ijk_Call;
                break;
             }
-
+
+         }
+         break;
+      default:
+         return False;
+      }
+   *set = IRStmt_Exit(eCond, jmpKind, mkSzConst(ty, addrTgt), OFFB_PC);
+   return True;
+}
+
+/*------------------------------------------------------------*/
+/*---       Disassemble a single DSP ASE instruction       ---*/
+/*------------------------------------------------------------*/
+
+static UInt disDSPInstr_MIPS_WRK ( UInt cins )
+{
+   IRTemp t0, t1 = 0, t2, t3, t4, t5, t6, t7, t8, t9, t10, t11, t12, t13, t14,
+          t15, t16, t17, t18;
+   UInt opcode, rs, rt, rd, sa, function, ac, ac_mfhilo, rddsp_mask,
+        wrdsp_mask, dsp_imm, shift;
+
+   opcode = get_opcode(cins);
+   rs = get_rs(cins);
+   rt = get_rt(cins);
+   rd = get_rd(cins);
+   sa = get_sa(cins);
+   function = get_function(cins);
+   ac = get_acNo(cins);
+   ac_mfhilo = get_acNo_mfhilo(cins);
+   rddsp_mask = get_rddspMask(cins);
+   wrdsp_mask = get_wrdspMask(cins);
+   dsp_imm = get_dspImm(cins);
+   shift = get_shift(cins);
+
+   switch (opcode) {
+      case 0x00: {  /* Special */
+         switch (function) {
+            case 0x10: {  /* MFHI */
+               DIP("mfhi ac%d r%d", ac_mfhilo, rd);
+               putIReg(rd, unop(Iop_64HIto32, getAcc(ac_mfhilo)));
+               break;
+            }
+
+            case 0x11: {  /* MTHI */
+               DIP("mthi ac%d r%d", ac, rs);
+               t1 = newTemp(Ity_I32);
+               assign(t1, unop(Iop_64to32, getAcc(ac)));
+               putAcc(ac, binop(Iop_32HLto64, getIReg(rs), mkexpr(t1)));
+               break;
+            }
+
+            case 0x12: {  /* MFLO */
+               DIP("mflo ac%d r%d", ac_mfhilo, rd);
+               putIReg(rd, unop(Iop_64to32, getAcc(ac_mfhilo)));
+               break;
+            }
+
+            case 0x13: {  /* MTLO */
+               DIP("mtlo ac%d r%d", ac, rs);
+               t1 = newTemp(Ity_I32);
+               assign(t1, unop(Iop_64HIto32, getAcc(ac)));
+               putAcc(ac, binop(Iop_32HLto64, mkexpr(t1), getIReg(rs)));
+               break;
+            }
+
+            case 0x18: {  /* MULT */
+               DIP("mult ac%d r%d, r%d", ac, rs, rt);
+               t1 = newTemp(Ity_I64);
+               assign(t1, binop(Iop_MullS32, mkNarrowTo32(Ity_I32, getIReg(rs)),
+                                mkNarrowTo32(Ity_I32, getIReg(rt))));
+               putAcc(ac, mkexpr(t1));
+               break;
+            }
+
+            case 0x19: {  /* MULTU */
+               DIP("multu ac%d r%d, r%d", ac, rs, rt);
+               t1 = newTemp(Ity_I64);
+               assign(t1, binop(Iop_MullU32, mkNarrowTo32(Ity_I32, getIReg(rs)),
+                                             mkNarrowTo32(Ity_I32,
+                                                          getIReg(rt))));
+               putAcc(ac, mkexpr(t1));
+            break;
+            }
+         }
+         break;
+      }
+      case 0x1C: {  /* Special2 */
+         switch (function) {
+            case 0x00: {  /* MADD */
+               DIP("madd ac%d, r%d, r%d", ac, rs, rt);
+               t1 = newTemp(Ity_I64);
+               t2 = newTemp(Ity_I64);
+               t3 = newTemp(Ity_I64);
+
+               assign(t1, getAcc(ac));
+               assign(t2, binop(Iop_MullS32, getIReg(rs), getIReg(rt)));
+               assign(t3, binop(Iop_Add64, mkexpr(t1), mkexpr(t2)));
+
+               putAcc(ac, mkexpr(t3));
+               break;
+            }
+            case 0x01: {  /* MADDU */
+               DIP("maddu ac%d r%d, r%d", ac, rs, rt);
+               t1 = newTemp(Ity_I64);
+               t2 = newTemp(Ity_I64);
+               t3 = newTemp(Ity_I64);
+
+               assign(t1, getAcc(ac));
+               assign(t2, binop(Iop_MullU32, getIReg(rs), getIReg(rt)));
+               assign(t3, binop(Iop_Add64, mkexpr(t2), mkexpr(t1)));
+
+               putAcc(ac, mkexpr(t3));
+               break;
+            }
+            case 0x04: {  /* MSUB */
+               DIP("msub ac%d r%d, r%d", ac, rs, rt);
+               t1 = newTemp(Ity_I64);
+               t2 = newTemp(Ity_I64);
+               t3 = newTemp(Ity_I64);
+
+               assign(t1, getAcc(ac));
+               assign(t2, binop(Iop_MullS32, getIReg(rs), getIReg(rt)));
+               assign(t3, binop(Iop_Sub64, mkexpr(t1), mkexpr(t2)));
+
+               putAcc(ac, mkexpr(t3));
+               break;
+            }
+            case 0x05: {  /* MSUBU */
+               DIP("msubu ac%d r%d, r%d", ac, rs, rt);
+               t1 = newTemp(Ity_I64);
+               t2 = newTemp(Ity_I64);
+               t3 = newTemp(Ity_I64);
+
+               assign(t1, getAcc(ac));
+               assign(t2, binop(Iop_MullU32, getIReg(rs), getIReg(rt)));
+               assign(t3, binop(Iop_Sub64, mkexpr(t1), mkexpr(t2)));
+
+               putAcc(ac, mkexpr(t3));
+               break;
+            }
+         }
+         break;
+      }
+      case 0x1F: {  /* Special3 */
+         switch (function) {
+            case 0x12: {  /* ABSQ_S.PH */
+               switch (sa) {
+                  case 0x1: {  /* ABSQ_S.QB */
+                     DIP("absq_s.qb r%d, r%d", rd, rt);
+                     vassert(!mode64);
+                     t0 = newTemp(Ity_I8);
+                     t1 = newTemp(Ity_I1);
+                     t2 = newTemp(Ity_I1);
+                     t3 = newTemp(Ity_I8);
+                     t4 = newTemp(Ity_I8);
+                     t5 = newTemp(Ity_I1);
+                     t6 = newTemp(Ity_I1);
+                     t7 = newTemp(Ity_I8);
+                     t8 = newTemp(Ity_I8);
+                     t9 = newTemp(Ity_I1);
+                     t10 = newTemp(Ity_I1);
+                     t11 = newTemp(Ity_I8);
+                     t12 = newTemp(Ity_I8);
+                     t13 = newTemp(Ity_I1);
+                     t14 = newTemp(Ity_I1);
+                     t15 = newTemp(Ity_I8);
+                     t16 = newTemp(Ity_I32);
+                     t17 = newTemp(Ity_I32);
+
+                     /* Absolute value of the rightmost byte (bits 7-0). */
+                     /* t0 - rightmost byte. */
+                     assign(t0, unop(Iop_16to8, unop(Iop_32to16, getIReg(rt))));
+                     /* t1 holds 1 if t0 is equal to 0x80, or 0 otherwise. */
+                     assign(t1, binop(Iop_CmpEQ32,
+                                      unop(Iop_8Uto32, mkexpr(t0)),
+                                      mkU32(0x00000080)));
+                     /* t2 holds 1 if value in t0 is negative, 0 otherwise. */
+                     assign(t2, unop(Iop_32to1,
+                                     binop(Iop_Shr32,
+                                           binop(Iop_And32,
+                                                 getIReg(rt),
+                                                 mkU32(0x00000080)),
+                                           mkU8(0x7))));
+                     /* t3 holds abs(t0). */
+                     assign(t3, IRExpr_ITE(mkexpr(t1),
+                                           mkU8(0x7F),
+                                           IRExpr_ITE(mkexpr(t2),
+                                                      binop(Iop_Add8,
+                                                            unop(Iop_Not8,
+                                                                 mkexpr(t0)),
+                                                            mkU8(0x1)),
+                                                      mkexpr(t0))));
+
+                     /* Absolute value of bits 15-8. */
+                     /* t4 - input byte. */
+                     assign(t4,
+                            unop(Iop_16HIto8, unop(Iop_32to16, getIReg(rt))));
+                     /* t5 holds 1 if t4 is equal to 0x80, or 0 otherwise. */
+                     assign(t5, binop(Iop_CmpEQ32,
+                                      unop(Iop_8Uto32, mkexpr(t4)),
+                                      mkU32(0x00000080)));
+                     /* t6 holds 1 if value in t4 is negative, 0 otherwise. */
+                     assign(t6, unop(Iop_32to1,
+                                     binop(Iop_Shr32,
+                                           binop(Iop_And32,
+                                                 getIReg(rt),
+                                                 mkU32(0x00008000)),
+                                           mkU8(15))));
+                     /* t3 holds abs(t4). */
+                     assign(t7, IRExpr_ITE(mkexpr(t5),
+                                           mkU8(0x7F),
+                                           IRExpr_ITE(mkexpr(t6),
+                                                      binop(Iop_Add8,
+                                                            unop(Iop_Not8,
+                                                                 mkexpr(t4)),
+                                                            mkU8(0x1)),
+                                                      mkexpr(t4))));
+
+                     /* Absolute value of bits 23-15. */
+                     /* t8 - input byte. */
+                     assign(t8,
+                            unop(Iop_16to8, unop(Iop_32HIto16, getIReg(rt))));
+                     /* t9 holds 1 if t8 is equal to 0x80, or 0 otherwise. */
+                     assign(t9, binop(Iop_CmpEQ32,
+                                      unop(Iop_8Uto32, mkexpr(t8)),
+                                      mkU32(0x00000080)));
+                     /* t6 holds 1 if value in t8 is negative, 0 otherwise. */
+                     assign(t10, unop(Iop_32to1,
+                                      binop(Iop_Shr32,
+                                            binop(Iop_And32,
+                                                  getIReg(rt),
+                                                  mkU32(0x00800000)),
+                                            mkU8(23))));
+                     /* t3 holds abs(t8). */
+                     assign(t11, IRExpr_ITE(mkexpr(t9),
+                                            mkU8(0x7F),
+                                            IRExpr_ITE(mkexpr(t10),
+                                                       binop(Iop_Add8,
+                                                             unop(Iop_Not8,
+                                                                  mkexpr(t8)),
+                                                             mkU8(0x1)),
+                                                       mkexpr(t8))));
+
+                     /* Absolute value of bits 31-24. */
+                     /* t12 - input byte. */
+                     assign(t12,
+                            unop(Iop_16HIto8, unop(Iop_32HIto16, getIReg(rt))));
+                     /* t13 holds 1 if t12 is equal to 0x80, or 0 otherwise. */
+                     assign(t13, binop(Iop_CmpEQ32,
+                                       unop(Iop_8Uto32, mkexpr(t12)),
+                                       mkU32(0x00000080)));
+                     /* t14 holds 1 if value in t12 is negative, 0 otherwise. */
+                     assign(t14, unop(Iop_32to1,
+                                      binop(Iop_Shr32,
+                                            binop(Iop_And32,
+                                                  getIReg(rt),
+                                                  mkU32(0x80000000)),
+                                            mkU8(31))));
+                     /* t15 holds abs(t12). */
+                     assign(t15, IRExpr_ITE(mkexpr(t13),
+                                            mkU8(0x7F),
+                                            IRExpr_ITE(mkexpr(t14),
+                                                       binop(Iop_Add8,
+                                                             unop(Iop_Not8,
+                                                                  mkexpr(t12)),
+                                                             mkU8(0x1)),
+                                                       mkexpr(t12))));
+
+                     /* t16 holds !0 if any of input bytes is 0x80 or 0
+                        otherwise. */
+                     assign(t16,
+                            binop(Iop_Or32,
+                                  binop(Iop_Or32,
+                                        binop(Iop_Or32,
+                                              unop(Iop_1Sto32, mkexpr(t13)),
+                                              unop(Iop_1Sto32, mkexpr(t9))),
+                                        unop(Iop_1Sto32, mkexpr(t5))),
+                                  unop(Iop_1Sto32, mkexpr(t1))));
+
+                     putDSPControl(IRExpr_ITE(binop(Iop_CmpEQ32,
+                                                    mkexpr(t16),
+                                                    mkU32(0x0)),
+                                              getDSPControl(),
+                                              binop(Iop_Or32,
+                                                    getDSPControl(),
+                                                    mkU32(0x00100000))));
+
+                     /* t17 = t15|t11|t7|t3 */
+                     assign(t17,
+                            binop(Iop_16HLto32,
+                                  binop(Iop_8HLto16, mkexpr(t15), mkexpr(t11)),
+                                  binop(Iop_8HLto16, mkexpr(t7), mkexpr(t3))));
+
+                     putIReg(rd, mkexpr(t17));
+                     break;
+                  }
+                  case 0x2: {  /* REPL.QB */
+                     DIP("repl.qb r%d, %d", rd, dsp_imm);
+                     vassert(!mode64);
+
+                     putIReg(rd, mkU32((dsp_imm << 24) | (dsp_imm << 16) |
+                                       (dsp_imm << 8) | (dsp_imm)));
+                     break;
+                  }
+                  case 0x3: {  /* REPLV.QB */
+                     DIP("replv.qb r%d, r%d", rd, rt);
+                     vassert(!mode64);
+                     t0 = newTemp(Ity_I8);
+
+                     assign(t0, unop(Iop_32to8,
+                                binop(Iop_And32, getIReg(rt), mkU32(0xff))));
+                     putIReg(rd,
+                             binop(Iop_16HLto32,
+                                   binop(Iop_8HLto16, mkexpr(t0), mkexpr(t0)),
+                                   binop(Iop_8HLto16, mkexpr(t0), mkexpr(t0))));
+                     break;
+                  }
+                  case 0x4: {  /* PRECEQU.PH.QBL */
+                     DIP("precequ.ph.qbl r%d, r%d", rd, rt);
+                     vassert(!mode64);
+
+                     putIReg(rd, binop(Iop_Or32,
+                                       binop(Iop_Shr32,
+                                             binop(Iop_And32,
+                                                   getIReg(rt),
+                                                   mkU32(0xff000000)),
+                                             mkU8(1)),
+                                       binop(Iop_Shr32,
+                                             binop(Iop_And32,
+                                                   getIReg(rt),
+                                                   mkU32(0x00ff0000)),
+                                             mkU8(9))));
+                     break;
+                  }
+                  case 0x5: {  /* PRECEQU.PH.QBR */
+                     DIP("precequ.ph.qbr r%d, r%d", rd, rt);
+                     vassert(!mode64);
+
+                     putIReg(rd, binop(Iop_Or32,
+                                       binop(Iop_Shl32,
+                                             binop(Iop_And32,
+                                                   getIReg(rt),
+                                                   mkU32(0x0000ff00)),
+                                             mkU8(15)),
+                                       binop(Iop_Shl32,
+                                             binop(Iop_And32,
+                                                   getIReg(rt),
+                                                   mkU32(0x000000ff)),
+                                             mkU8(7))));
+                     break;
+                  }
+                  case 0x6: {  /* PRECEQU.PH.QBLA */
+                     DIP("precequ.ph.qbla r%d, r%d", rd, rt);
+                     vassert(!mode64);
+
+                     putIReg(rd, binop(Iop_Or32,
+                                       binop(Iop_Shr32,
+                                             binop(Iop_And32,
+                                                   getIReg(rt),
+                                                   mkU32(0xff000000)),
+                                             mkU8(1)),
+                                       binop(Iop_Shr32,
+                                             binop(Iop_And32,
+                                                   getIReg(rt),
+                                                   mkU32(0x0000ff00)),
+                                             mkU8(1))));
+                     break;
+                  }
+                  case 0x7: {  /* PRECEQU.PH.QBRA */
+                     DIP("precequ.ph.qbra r%d, r%d", rd, rt);
+                     vassert(!mode64);
+
+                     putIReg(rd, binop(Iop_Or32,
+                                       binop(Iop_Shl32,
+                                             binop(Iop_And32,
+                                                   getIReg(rt),
+                                                   mkU32(0x00ff0000)),
+                                             mkU8(7)),
+                                       binop(Iop_Shl32,
+                                             binop(Iop_And32,
+                                                   getIReg(rt),
+                                                   mkU32(0x000000ff)),
+                                             mkU8(7))));
+                     break;
+                  }
+                  case 0x9: {  /* ABSQ_S.PH */
+                     DIP("absq_s.ph r%d, r%d", rd, rt);
+                     vassert(!mode64);
+                     t0 = newTemp(Ity_I16);
+                     t1 = newTemp(Ity_I1);
+                     t2 = newTemp(Ity_I1);
+                     t3 = newTemp(Ity_I16);
+                     t4 = newTemp(Ity_I16);
+                     t5 = newTemp(Ity_I1);
+                     t6 = newTemp(Ity_I1);
+                     t7 = newTemp(Ity_I16);
+                     t8 = newTemp(Ity_I32);
+                     t9 = newTemp(Ity_I32);
+
+                     /* t0 holds lower 16 bits of value in rt. */
+                     assign(t0, unop(Iop_32to16, getIReg(rt)));
+                     /* t1 holds 1 if t0 is equal to 0x8000. */
+                     assign(t1, binop(Iop_CmpEQ32,
+                                      unop(Iop_16Uto32, mkexpr(t0)),
+                                      mkU32(0x00008000)));
+                     /* t2 holds 1 if value in t0 is negative, 0 otherwise. */
+                     assign(t2, unop(Iop_32to1,
+                                     binop(Iop_Shr32,
+                                           binop(Iop_And32,
+                                                 getIReg(rt),
+                                                 mkU32(0x00008000)),
+                                           mkU8(15))));
+                     /* t3 holds abs(t0). */
+                     assign(t3, IRExpr_ITE(mkexpr(t1),
+                                           mkU16(0x7FFF),
+                                           IRExpr_ITE(mkexpr(t2),
+                                                      binop(Iop_Add16,
+                                                            unop(Iop_Not16,
+                                                                 mkexpr(t0)),
+                                                            mkU16(0x1)),
+                                                      mkexpr(t0))));
+
+                     /* t4 holds lower 16 bits of value in rt. */
+                     assign(t4, unop(Iop_32HIto16, getIReg(rt)));
+                     /* t5 holds 1 if t4 is equal to 0x8000. */
+                     assign(t5, binop(Iop_CmpEQ32,
+                                      unop(Iop_16Uto32, mkexpr(t4)),
+                                      mkU32(0x00008000)));
+                     /* t6 holds 1 if value in t4 is negative, 0 otherwise. */
+                     assign(t6, unop(Iop_32to1,
+                                     binop(Iop_Shr32,
+                                           binop(Iop_And32,
+                                                 getIReg(rt),
+                                                 mkU32(0x80000000)),
+                                           mkU8(31))));
+                     /* t7 holds abs(t4). */
+                     assign(t7, IRExpr_ITE(mkexpr(t5),
+                                           mkU16(0x7FFF),
+                                           IRExpr_ITE(mkexpr(t6),
+                                                      binop(Iop_Add16,
+                                                            unop(Iop_Not16,
+                                                                 mkexpr(t4)),
+                                                            mkU16(0x1)),
+                                                      mkexpr(t4))));
+                     /* If any of the two input halfwords is equal 0x8000,
+                        set bit 20 in DSPControl register. */
+                     assign(t8, binop(Iop_Or32,
+                                      unop(Iop_1Sto32, mkexpr(t5)),
+                                      unop(Iop_1Sto32, mkexpr(t1))));
+
+                     putDSPControl(IRExpr_ITE(binop(Iop_CmpEQ32,
+                                                    mkexpr(t8),
+                                                    mkU32(0x0)),
+                                              getDSPControl(),
+                                              binop(Iop_Or32,
+                                                    getDSPControl(),
+                                                    mkU32(0x00100000))));
+
+                     /* t9 = t7|t3 */
+                     assign(t9, binop(Iop_16HLto32, mkexpr(t7), mkexpr(t3)));
+
+                     putIReg(rd, mkexpr(t9));
+                     break;
+                  }
+                  case 0xA: {  /* REPL.PH */
+                     DIP("repl.ph r%d, %d", rd, dsp_imm);
+                     vassert(!mode64);
+                     UShort immediate = extend_s_10to16(dsp_imm);
+
+                     putIReg(rd, mkU32(immediate << 16 | immediate));
+                     break;
+                  }
+                  case 0xB: {  /* REPLV.PH */
+                     DIP("replv.ph r%d, r%d", rd, rt);
+                     vassert(!mode64);
+
+                     putIReg(rd, binop(Iop_16HLto32,
+                                       unop(Iop_32to16, getIReg(rt)),
+                                       unop(Iop_32to16, getIReg(rt))));
+                     break;
+                  }
+                  case 0xC: {  /* PRECEQ.W.PHL */
+                     DIP("preceq.w.phl r%d, r%d", rd, rt);
+                     vassert(!mode64);
+                     putIReg(rd, binop(Iop_And32,
+                                       getIReg(rt),
+                                       mkU32(0xffff0000)));
+                     break;
+                  }
+                  case 0xD: {  /* PRECEQ.W.PHR */
+                     DIP("preceq.w.phr r%d, r%d", rd, rt);
+                     vassert(!mode64);
+                     putIReg(rd, binop(Iop_16HLto32,
+                                       unop(Iop_32to16, getIReg(rt)),
+                                       mkU16(0x0)));
+                     break;
+                  }
+                  case 0x11: {  /* ABSQ_S.W */
+                     DIP("absq_s.w r%d, r%d", rd, rt);
+                     vassert(!mode64);
+                     t0 = newTemp(Ity_I1);
+                     t1 = newTemp(Ity_I1);
+                     t2 = newTemp(Ity_I32);
+
+                     assign(t0,
+                            binop(Iop_CmpEQ32, getIReg(rt), mkU32(0x80000000)));
+
+                     putDSPControl(IRExpr_ITE(mkexpr(t0),
+                                              binop(Iop_Or32,
+                                                    getDSPControl(),
+                                                    mkU32(0x00100000)),
+                                              getDSPControl()));
+
+                     assign(t1, binop(Iop_CmpLT32S, getIReg(rt), mkU32(0x0)));
+
+                     assign(t2, IRExpr_ITE(mkexpr(t0),
+                                           mkU32(0x7FFFFFFF),
+                                           IRExpr_ITE(mkexpr(t1),
+                                                      binop(Iop_Add32,
+                                                            unop(Iop_Not32,
+                                                                 getIReg(rt)),
+                                                            mkU32(0x1)),
+                                                      getIReg(rt))));
+                     putIReg(rd, mkexpr(t2));
+                     break;
+                  }
+                  case 0x1B: {  /* BITREV */
+                     DIP("bitrev r%d, r%d", rd, rt);
+                     vassert(!mode64);
+                     /* 32bit reversal as seen on Bit Twiddling Hacks site
+                        http://graphics.stanford.edu/~seander/bithacks.html
+                        section ReverseParallel */
+                     t1 = newTemp(Ity_I32);
+                     t2 = newTemp(Ity_I32);
+                     t3 = newTemp(Ity_I32);
+                     t4 = newTemp(Ity_I32);
+                     t5 = newTemp(Ity_I32);
+
+                     assign(t1, binop(Iop_Or32,
+                                      binop(Iop_Shr32,
+                                            binop(Iop_And32,
+                                                  getIReg(rt),
+                                                  mkU32(0xaaaaaaaa)),
+                                            mkU8(0x1)),
+                                      binop(Iop_Shl32,
+                                            binop(Iop_And32,
+                                                  getIReg(rt),
+                                                  mkU32(0x55555555)),
+                                            mkU8(0x1))));
+                     assign(t2, binop(Iop_Or32,
+                                      binop(Iop_Shr32,
+                                            binop(Iop_And32,
+                                                  mkexpr(t1),
+                                                  mkU32(0xcccccccc)),
+                                            mkU8(0x2)),
+                                      binop(Iop_Shl32,
+                                            binop(Iop_And32,
+                                                  mkexpr(t1),
+                                                  mkU32(0x33333333)),
+                                            mkU8(0x2))));
+                     assign(t3, binop(Iop_Or32,
+                                      binop(Iop_Shr32,
+                                            binop(Iop_And32,
+                                                  mkexpr(t2),
+                                                  mkU32(0xf0f0f0f0)),
+                                            mkU8(0x4)),
+                                      binop(Iop_Shl32,
+                                            binop(Iop_And32,
+                                                  mkexpr(t2),
+                                                  mkU32(0x0f0f0f0f)),
+                                            mkU8(0x4))));
+                     assign(t4, binop(Iop_Or32,
+                                      binop(Iop_Shr32,
+                                            binop(Iop_And32,
+                                                  mkexpr(t3),
+                                                  mkU32(0xff00ff00)),
+                                            mkU8(0x8)),
+                                      binop(Iop_Shl32,
+                                            binop(Iop_And32,
+                                                  mkexpr(t3),
+                                                  mkU32(0x00ff00ff)),
+                                            mkU8(0x8))));
+                     assign(t5, binop(Iop_Or32,
+                                      binop(Iop_Shr32,
+                                            mkexpr(t4),
+                                            mkU8(0x10)),
+                                      binop(Iop_Shl32,
+                                            mkexpr(t4),
+                                            mkU8(0x10))));
+                     putIReg(rd, binop(Iop_Shr32,
+                                       mkexpr(t5),
+                                       mkU8(16)));
+                     break;
+                  }
+                  case 0x1C: {  /* PRECEU.PH.QBL */
+                     DIP("preceu.ph.qbl r%d, r%d", rd, rt);
+                     vassert(!mode64);
+
+                     putIReg(rd, binop(Iop_Or32,
+                                       binop(Iop_Shr32,
+                                             binop(Iop_And32,
+                                                   getIReg(rt),
+                                                   mkU32(0xff000000)),
+                                             mkU8(8)),
+                                       binop(Iop_Shr32,
+                                             binop(Iop_And32,
+                                                   getIReg(rt),
+                                                   mkU32(0x00ff0000)),
+                                             mkU8(16))));
+                     break;
+                  }
+                  case 0x1E: {  /* PRECEU.PH.QBLA */
+                     DIP("preceu.ph.qbla r%d, r%d", rd, rt);
+                     vassert(!mode64);
+
+                     putIReg(rd, binop(Iop_Or32,
+                                       binop(Iop_Shr32,
+                                             binop(Iop_And32,
+                                                   getIReg(rt),
+                                                   mkU32(0xff000000)),
+                                             mkU8(8)),
+                                       binop(Iop_Shr32,
+                                             binop(Iop_And32,
+                                                   getIReg(rt),
+                                                   mkU32(0x0000ff00)),
+                                             mkU8(8))));
+                     break;
+                  }
+                  case 0x1D: {  /* PRECEU.PH.QBR */
+                     DIP("preceu.ph.qbr r%d, r%d", rd, rt);
+                     vassert(!mode64);
+
+                     putIReg(rd, binop(Iop_Or32,
+                                       binop(Iop_Shl32,
+                                             binop(Iop_And32,
+                                                   getIReg(rt),
+                                                   mkU32(0x0000ff00)),
+                                             mkU8(8)),
+                                       binop(Iop_And32,
+                                             getIReg(rt),
+                                             mkU32(0x000000ff))));
+                     break;
+                  }
+                  case 0x1F: {  /* PRECEU.PH.QBRA */
+                     DIP("preceu.ph.qbra r%d, r%d", rd, rt);
+                     vassert(!mode64);
+
+                     putIReg(rd, binop(Iop_Or32,
+                                       binop(Iop_And32,
+                                             getIReg(rt),
+                                             mkU32(0x00ff0000)),
+                                       binop(Iop_And32,
+                                             getIReg(rt),
+                                             mkU32(0x000000ff))));
+                     break;
+                  }
+                  default:
+                     return -1;
+               }
+               break;  /* end of ABSQ_S.PH */
+            }
+            case 0x38: {  /* EXTR.W */
+               switch(sa) {
+                  case 0x0: {  /* EXTR.W */
+                     DIP("extr.w r%d, ac%d, %d", rt, ac, rs);
+                     vassert(!mode64);
+                     t0 = newTemp(Ity_I64);
+                     t1 = newTemp(Ity_I64);
+                     t2 = newTemp(Ity_I32);
+                     t3 = newTemp(Ity_I32);
+                     t4 = newTemp(Ity_I32);
+
+                     assign(t0, getAcc(ac));
+                     assign(t1, binop(Iop_Sar64, mkexpr(t0), mkU8(rs)));
+                     putIReg(rt, unop(Iop_64to32, mkexpr(t1)));
+
+                     assign(t2, binop(Iop_Or32,
+                                      getDSPControl(), mkU32(0x00800000)));
+
+                     /* Check if signOut == signIn */
+                     assign(t3, IRExpr_ITE(binop(Iop_CmpEQ32,
+                                                 binop(Iop_And32,
+                                                       unop(Iop_64HIto32,
+                                                            mkexpr(t0)),
+                                                       mkU32(0x80000000)),
+                                                 binop(Iop_And32,
+                                                       getIReg(rt),
+                                                       mkU32(0x80000000))),
+                                           getDSPControl(),
+                                           mkexpr(t2)));
+
+                     assign(t4, IRExpr_ITE(binop(Iop_CmpNE32,
+                                                 unop(Iop_64HIto32,
+                                                      mkexpr(t1)),
+                                                 mkU32(0x0)),
+                                           IRExpr_ITE(binop(Iop_CmpNE32,
+                                                            unop(Iop_64HIto32,
+                                                                 mkexpr(t1)),
+                                                            mkU32(0xffffffff)),
+                                                      mkexpr(t2),
+                                                      mkexpr(t3)),
+                                           mkexpr(t3)));
+                     putDSPControl(mkexpr(t4));
+                     break;
+                  }
+                  case 0x1: {  /* EXTRV.W */
+                     DIP("extrv.w r%d, ac%d, r%d", rt, ac, rs);
+                     vassert(!mode64);
+                     t0 = newTemp(Ity_I64);
+                     t1 = newTemp(Ity_I64);
+                     t2 = newTemp(Ity_I32);
+                     t3 = newTemp(Ity_I32);
+                     t4 = newTemp(Ity_I1);
+
+                     assign(t0, getAcc(ac));
+                     assign(t1, binop(Iop_Sar64,
+                                      mkexpr(t0),
+                                      unop(Iop_32to8,
+                                           binop(Iop_And32,
+                                                 getIReg(rs),
+                                                 mkU32(0x1f)))));
+                     putIReg(rt, unop(Iop_64to32, mkexpr(t1)));
+
+                     assign(t2, binop(Iop_Or32,
+                                      getDSPControl(), mkU32(0x00800000)));
+
+                     /* Check if signOut == signIn */
+                     assign(t3, IRExpr_ITE(binop(Iop_CmpEQ32,
+                                                 binop(Iop_And32,
+                                                       unop(Iop_64HIto32,
+                                                            mkexpr(t0)),
+                                                       mkU32(0x80000000)),
+                                                 binop(Iop_And32,
+                                                       getIReg(rt),
+                                                       mkU32(0x80000000))),
+                                           getDSPControl(),
+                                           mkexpr(t2)));
+                     assign(t4, binop(Iop_CmpNE32,
+                                      unop(Iop_64HIto32, mkexpr(t1)),
+                                      mkU32(0xffffffff)));
+                     putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32,
+                                                    unop(Iop_64HIto32,
+                                                         mkexpr(t1)),
+                                                    mkU32(0x0)),
+                                              IRExpr_ITE(mkexpr(t4),
+                                                         mkexpr(t2),
+                                                         mkexpr(t3)),
+                                              mkexpr(t3)));
+                     break;
+                  }
+                  case 0x2: {  /* EXTP */
+                     DIP("extp r%d, ac%d, %d", rt, ac, rs);
+                     vassert(!mode64);
+                     t0 = newTemp(Ity_I64);
+                     t1 = newTemp(Ity_I32);
+                     t2 = newTemp(Ity_I1);
+                     t3 = newTemp(Ity_I1);
+                     t4 = newTemp(Ity_I8);
+                     t5 = newTemp(Ity_I64);
+                     t6 = newTemp(Ity_I64);
+                     t7 = newTemp(Ity_I32);
+
+                     assign(t0, getAcc(ac));
+                     /* Extract pos field of DSPControl register. */
+                     assign(t1, binop(Iop_And32, getDSPControl(), mkU32(0x3f)));
+
+                     /* Check if (pos - size) >= 0 [size <= pos]
+                        if (pos < size)
+                           put 1 to EFI field of DSPControl register
+                        else
+                           extract bits from acc and put 0 to EFI field of
+                           DSPCtrl */
+                     assign(t2, binop(Iop_CmpLT32U, mkexpr(t1), mkU32(rs)));
+
+                     putDSPControl(IRExpr_ITE(mkexpr(t2),
+                                              binop(Iop_Or32,
+                                                    binop(Iop_And32,
+                                                          getDSPControl(),
+                                                          mkU32(0xffffbfff)),
+                                                    mkU32(0x4000)),
+                                              binop(Iop_And32,
+                                                    getDSPControl(),
+                                                    mkU32(0xffffbfff))));
+
+                     /* If pos <= 31, shift right the value from the acc
+                        (pos-size) times and take (size+1) bits from the least
+                        significant positions. Otherwise, shift left the value
+                        (63-pos) times, take (size+1) bits from the most
+                        significant positions and shift right (31-size) times.*/
+                     assign(t3, binop(Iop_CmpLE32U, mkexpr(t1), mkU32(31)));
+
+                     assign(t4,
+                           IRExpr_ITE(mkexpr(t3),
+                                      unop(Iop_32to8,
+                                           binop(Iop_Sub32,
+                                                 mkexpr(t1), mkU32(rs))),
+                                      unop(Iop_32to8,
+                                           binop(Iop_Sub32,
+                                                 mkU32(63), mkexpr(t1)))));
+
+                     assign(t5, IRExpr_ITE(mkexpr(t3),
+                                           binop(Iop_Shr64,
+                                                 mkexpr(t0), mkexpr(t4)),
+                                           binop(Iop_Shl64,
+                                                 mkexpr(t0), mkexpr(t4))));
+
+                     /* t6 holds a mask for bit extraction */
+                     assign(t6,
+                            IRExpr_ITE(mkexpr(t3),
+                                       unop(Iop_Not64,
+                                            binop(Iop_Shl64,
+                                                  mkU64(0xffffffffffffffffULL),
+                                                  mkU8(rs+1))),
+                                       unop(Iop_Not64,
+                                            binop(Iop_Shr64,
+                                                  mkU64(0xffffffffffffffffULL),
+                                                  mkU8(rs+1)))));
+
+                     assign(t7, IRExpr_ITE(mkexpr(t3),
+                                           unop(Iop_64to32,
+                                                binop(Iop_And64,
+                                                      mkexpr(t5),
+                                                      mkexpr(t6))),
+                                           binop(Iop_Shr32,
+                                                 unop(Iop_64HIto32,
+                                                      binop(Iop_And64,
+                                                            mkexpr(t5),
+                                                            mkexpr(t6))),
+                                                 mkU8(31-rs))));
+
+                     putIReg(rt, mkexpr(t7));
+                     break;
+                  }
+                  case 0x3: {  /* EXTPV */
+                     DIP("extpv r%d, ac%d, r%d", rt, ac, rs);
+                     vassert(!mode64);
+                     t0 = newTemp(Ity_I64);
+                     t1 = newTemp(Ity_I32);
+                     t2 = newTemp(Ity_I1);
+                     t3 = newTemp(Ity_I1);
+                     t4 = newTemp(Ity_I8);
+                     t5 = newTemp(Ity_I64);
+                     t6 = newTemp(Ity_I64);
+                     t7 = newTemp(Ity_I32);
+                     t8 = newTemp(Ity_I32);
+
+                     assign(t8, binop(Iop_And32, getIReg(rs), mkU32(0x1f)));
+                     assign(t0, getAcc(ac));
+                     /* Extract pos field of DSPControl register. */
+                     assign(t1, binop(Iop_And32, getDSPControl(), mkU32(0x3f)));
+
+                     /* Check if (pos - size) >= 0 [size <= pos]
+                        if (pos < size)
+                           put 1 to EFI field of DSPControl register
+                        else
+                           extract bits from acc and put 0 to EFI field of
+                           DSPCtrl */
+                     assign(t2, binop(Iop_CmpLT32U, mkexpr(t1), mkexpr(t8)));
+
+                     putDSPControl(IRExpr_ITE(mkexpr(t2),
+                                              binop(Iop_Or32,
+                                                    binop(Iop_And32,
+                                                          getDSPControl(),
+                                                          mkU32(0xffffbfff)),
+                                                    mkU32(0x4000)),
+                                              binop(Iop_And32,
+                                                    getDSPControl(),
+                                                    mkU32(0xffffbfff))));
+
+                     /* If pos <= 31, shift right the value from the acc
+                        (pos-size) times and take (size+1) bits from the least
+                        significant positions. Otherwise, shift left the value
+                        (63-pos) times, take (size+1) bits from the most
+                        significant positions and shift right (31-size)
+                        times. */
+                     assign(t3, binop(Iop_CmpLE32U, mkexpr(t1), mkU32(31)));
+
+                     assign(t4,
+                           IRExpr_ITE(mkexpr(t3),
+                                      unop(Iop_32to8,
+                                           binop(Iop_Sub32,
+                                                 mkexpr(t1), mkexpr(t8))),
+                                      unop(Iop_32to8,
+                                           binop(Iop_Sub32,
+                                                 mkU32(63), mkexpr(t1)))));
+
+                     assign(t5, IRExpr_ITE(mkexpr(t3),
+                                           binop(Iop_Shr64,
+                                                 mkexpr(t0), mkexpr(t4)),
+                                           binop(Iop_Shl64,
+                                                 mkexpr(t0), mkexpr(t4))));
+
+                     /* t6 holds a mask for bit extraction. */
+                     assign(t6,
+                            IRExpr_ITE(mkexpr(t3),
+                                       unop(Iop_Not64,
+                                            binop(Iop_Shl64,
+                                                  mkU64(0xffffffffffffffffULL),
+                                                  unop(Iop_32to8,
+                                                       binop(Iop_Add32,
+                                                             mkexpr(t8),
+                                                             mkU32(1))))),
+                                       unop(Iop_Not64,
+                                            binop(Iop_Shr64,
+                                                  mkU64(0xffffffffffffffffULL),
+                                                  unop(Iop_32to8,
+                                                       binop(Iop_Add32,
+                                                             mkexpr(t8),
+                                                             mkU32(1)))))));
+
+                     assign(t7, IRExpr_ITE(mkexpr(t3),
+                                           unop(Iop_64to32,
+                                                binop(Iop_And64,
+                                                      mkexpr(t5),
+                                                      mkexpr(t6))),
+                                           binop(Iop_Shr32,
+                                                 unop(Iop_64HIto32,
+                                                      binop(Iop_And64,
+                                                            mkexpr(t5),
+                                                            mkexpr(t6))),
+                                                 unop(Iop_32to8,
+                                                      binop(Iop_Sub32,
+                                                            mkU32(31),
+                                                            mkexpr(t8))))));
+
+                     putIReg(rt, mkexpr(t7));
+                     break;
+                  }
+                  case 0x4: {  /* EXTR_R.W */
+                     DIP("extr_r.w r%d, ac%d, %d", rt, ac, rs);
+                     vassert(!mode64);
+                     t0 = newTemp(Ity_I64);
+                     t1 = newTemp(Ity_I64);
+                     t2 = newTemp(Ity_I32);
+                     t4 = newTemp(Ity_I32);
+                     t5 = newTemp(Ity_I64);
+                     t6 = newTemp(Ity_I64);
+
+                     assign(t0, getAcc(ac));
+                     if (0 == rs) {
+                        putIReg(rt, unop(Iop_64to32, mkexpr(t0)));
+                     } else {
+                        assign(t1, binop(Iop_Sar64, mkexpr(t0), mkU8(rs)));
+
+                        assign(t2, binop(Iop_Or32,
+                                         getDSPControl(), mkU32(0x800000)));
+
+                        putDSPControl(IRExpr_ITE(
+                                      binop(Iop_CmpNE32,
+                                            unop(Iop_64HIto32, mkexpr(t1)),
+                                            mkU32(0x0)),
+                                      IRExpr_ITE(binop(Iop_CmpNE32,
+                                                       unop(Iop_64HIto32,
+                                                            mkexpr(t1)),
+                                                       mkU32(0xffffffff)),
+                                                 mkexpr(t2),
+                                                 getDSPControl()),
+                                      getDSPControl()));
+
+                        assign(t4, binop(Iop_Or32,
+                                         getDSPControl(), mkU32(0x800000)));
+                        /* If the last discarded bit is 1, there would be carry
+                           when rounding, otherwise there wouldn't. We use that
+                           fact and just add the value of the last discarded bit
+                           to the least sifgnificant bit of the shifted value
+                           from acc. */
+                        assign(t5, binop(Iop_Shr64,
+                                         binop(Iop_And64,
+                                               mkexpr(t0),
+                                               binop(Iop_Shl64,
+                                                     mkU64(0x1ULL),
+                                                     mkU8(rs-1))),
+                                         mkU8(rs-1)));
+
+                        assign(t6, binop(Iop_Add64, mkexpr(t1), mkexpr(t5)));
+
+                        putDSPControl(IRExpr_ITE(
+                                      binop(Iop_CmpNE32,
+                                            unop(Iop_64HIto32, mkexpr(t6)),
+                                                 mkU32(0x0)),
+                                            IRExpr_ITE(binop(Iop_CmpNE32,
+                                                             unop(Iop_64HIto32,
+                                                                  mkexpr(t6)),
+                                                             mkU32(0xffffffff)),
+                                                       mkexpr(t4),
+                                                       getDSPControl()),
+                                            getDSPControl()));
+                        putIReg(rt, unop(Iop_64to32, mkexpr(t6)));
+                     }
+                     break;
+                  }
+                  case 0x5: {  /* EXTRV_R.W */
+                     DIP("extrv_r.w r%d, ac%d, r%d", rt, ac, rs);
+                     vassert(!mode64);
+                     t0 = newTemp(Ity_I64);
+                     t1 = newTemp(Ity_I64);
+                     t2 = newTemp(Ity_I32);
+                     t4 = newTemp(Ity_I32);
+                     t5 = newTemp(Ity_I64);
+                     t6 = newTemp(Ity_I64);
+
+                     assign(t0, getAcc(ac));
+
+                     assign(t1, binop(Iop_Sar64,
+                                      mkexpr(t0),
+                                      unop(Iop_32to8,
+                                           binop(Iop_And32,
+                                                 getIReg(rs),
+                                                 mkU32(0x1f)))));
+
+                     assign(t2, binop(Iop_Or32,
+                                      getDSPControl(), mkU32(0x00800000)));
+
+                     putDSPControl(IRExpr_ITE(
+                                   binop(Iop_CmpNE32,
+                                         unop(Iop_64HIto32, mkexpr(t1)),
+                                         mkU32(0x0)),
+                                   IRExpr_ITE(binop(Iop_CmpNE32,
+                                                    unop(Iop_64HIto32,
+                                                         mkexpr(t1)),
+                                                    mkU32(0xffffffff)),
+                                              mkexpr(t2),
+                                              getDSPControl()),
+                                   getDSPControl()));
+
+                     assign(t4, binop(Iop_Or32,
+                                      getDSPControl(), mkU32(0x00800000)));
+                     /* If the last discarded bit is 1, there would be carry
+                        when rounding, otherwise there wouldn't. We use that
+                        fact and just add the value of the last discarded bit to
+                        the least sifgnificant bit of the shifted value from
+                        acc. */
+                     assign(t5, binop(Iop_Shr64,
+                                      binop(Iop_And64,
+                                            mkexpr(t0),
+                                            binop(Iop_Shl64,
+                                                  mkU64(0x1ULL),
+                                                  unop(Iop_32to8,
+                                                       binop(Iop_Sub32,
+                                                             binop(Iop_And32,
+                                                                   getIReg(rs),
+                                                                   mkU32(0x1f)),
+                                                             mkU32(0x1))))),
+                                      unop(Iop_32to8,
+                                           binop(Iop_Sub32,
+                                                 binop(Iop_And32,
+                                                       getIReg(rs),
+                                                       mkU32(0x1f)),
+                                                 mkU32(0x1)))));
+
+                     assign(t6, binop(Iop_Add64, mkexpr(t1), mkexpr(t5)));
+
+                     putDSPControl(IRExpr_ITE(
+                                   binop(Iop_CmpNE32,
+                                         unop(Iop_64HIto32, mkexpr(t6)),
+                                         mkU32(0x0)),
+                                   IRExpr_ITE(binop(Iop_CmpNE32,
+                                                    unop(Iop_64HIto32,
+                                                         mkexpr(t6)),
+                                                    mkU32(0xffffffff)),
+                                              mkexpr(t4),
+                                              getDSPControl()),
+                                   getDSPControl()));
+                     putIReg(rt, IRExpr_ITE(binop(Iop_CmpEQ32,
+                                                  binop(Iop_And32,
+                                                        getIReg(rs),
+                                                        mkU32(0x1f)),
+                                                  mkU32(0x0)),
+                                            unop(Iop_64to32, mkexpr(t0)),
+                                            unop(Iop_64to32, mkexpr(t6))));
+                     break;
+                  }
+                  case 0x6: {  /* EXTR_RS.W */
+                     DIP("extr_rs.w r%d, ac%d, %d", rt, ac, rs);
+                     vassert(!mode64);
+                     t0 = newTemp(Ity_I64);
+                     t1 = newTemp(Ity_I64);
+                     t2 = newTemp(Ity_I64);
+                     t3 = newTemp(Ity_I32);
+                     t4 = newTemp(Ity_I32);
+                     t5 = newTemp(Ity_I32);
+                     t6 = newTemp(Ity_I32);
+
+                     if (0 != rs) {
+                        assign(t0, getAcc(ac));
+                        assign(t1, binop(Iop_Sar64, mkexpr(t0), mkU8(rs)));
+                        putDSPControl(IRExpr_ITE(
+                                      binop(Iop_CmpNE32,
+                                            unop(Iop_64HIto32, mkexpr(t1)),
+                                            mkU32(0x0)),
+                                      IRExpr_ITE(binop(Iop_CmpNE32,
+                                                       unop(Iop_64HIto32,
+                                                            mkexpr(t1)),
+                                                       mkU32(0xffffffff)),
+                                                 binop(Iop_Or32,
+                                                       getDSPControl(),
+                                                       mkU32(0x00800000)),
+                                                 getDSPControl()),
+                                      getDSPControl()));
+                        /* If the last discarded bit is 1, there would be carry
+                           when rounding, otherwise there wouldn't. We use that
+                           fact and just add the value of the last discarded bit
+                           to the least sifgnificant bit of the shifted value
+                           from acc. */
+                        assign(t2, binop(Iop_Add64,
+                                         mkexpr(t1),
+                                         binop(Iop_Shr64,
+                                               binop(Iop_And64,
+                                                     mkexpr(t0),
+                                                     binop(Iop_Shl64,
+                                                           mkU64(0x1ULL),
+                                                           unop(Iop_32to8,
+                                                                mkU32(rs-1)))),
+                                               unop(Iop_32to8, mkU32(rs-1)))));
+                        assign(t6, IRExpr_ITE(binop(Iop_CmpNE32,
+                                                    unop(Iop_64HIto32,
+                                                         mkexpr(t2)),
+                                                    mkU32(0xffffffff)),
+                                              binop(Iop_Or32,
+                                                    getDSPControl(),
+                                                    mkU32(0x00800000)),
+                                              getDSPControl()));
+                        putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32,
+                                                       unop(Iop_64HIto32,
+                                                            mkexpr(t2)),
+                                                       mkU32(0x0)),
+                                                 mkexpr(t6),
+                                                 getDSPControl()));
+                        assign(t3, IRExpr_ITE(binop(Iop_CmpEQ32,
+                                                    binop(Iop_And32,
+                                                          unop(Iop_64HIto32,
+                                                               mkexpr(t2)),
+                                                          mkU32(0x80000000)),
+                                                    mkU32(0x0)),
+                                              mkU32(0x7fffffff),
+                                              mkU32(0x80000000)));
+                        assign(t4, IRExpr_ITE(binop(Iop_CmpNE32,
+                                                    unop(Iop_64HIto32,
+                                                         mkexpr(t2)),
+                                                    mkU32(0xffffffff)),
+                                              mkexpr(t3),
+                                              unop(Iop_64to32, mkexpr(t2))));
+                        assign(t5, IRExpr_ITE(binop(Iop_CmpNE32,
+                                                    unop(Iop_64HIto32,
+                                                         mkexpr(t2)),
+                                                    mkU32(0x0)),
+                                              mkexpr(t4),
+                                              unop(Iop_64to32, mkexpr(t2))));
+                        putIReg(rt, mkexpr(t5));
+                     } else {
+                        putIReg(rt, unop(Iop_64to32, getAcc(ac)));
+                     }
+                     break;
+                  }
+                  case 0x7: {  /* EXTRV_RS.W */
+                     DIP("extrv_rs.w r%d, ac%d, r%d", rt, ac, rs);
+                     vassert(!mode64);
+                     t0 = newTemp(Ity_I64);
+                     t1 = newTemp(Ity_I64);
+                     t2 = newTemp(Ity_I32);
+                     t4 = newTemp(Ity_I32);
+                     t5 = newTemp(Ity_I64);
+                     t6 = newTemp(Ity_I64);
+                     t7 = newTemp(Ity_I32);
+                     t8 = newTemp(Ity_I32);
+                     t9 = newTemp(Ity_I32);
+                     t10 = newTemp(Ity_I32);
+
+                     assign(t0, getAcc(ac));
+
+                     assign(t1, binop(Iop_Sar64,
+                                      mkexpr(t0),
+                                      unop(Iop_32to8, binop(Iop_And32,
+                                                            getIReg(rs),
+                                                            mkU32(0x1f)))));
+
+                     assign(t2, binop(Iop_Or32,
+                                      getDSPControl(), mkU32(0x00800000)));
+
+                     assign(t10, IRExpr_ITE(binop(Iop_CmpNE32,
+                                                  unop(Iop_64HIto32,
+                                                       mkexpr(t1)),
+                                                  mkU32(0x0)),
+                                            IRExpr_ITE(binop(Iop_CmpNE32,
+                                                             unop(Iop_64HIto32,
+                                                                  mkexpr(t1)),
+                                                             mkU32(0xffffffff)),
+                                                       mkexpr(t2),
+                                                       getDSPControl()),
+                                            getDSPControl()));
+
+                     putDSPControl(mkexpr(t10));
+
+                     assign(t4, binop(Iop_Or32,
+                                      getDSPControl(), mkU32(0x00800000)));
+                     /* If the last discarded bit is 1, there would be carry
+                        when rounding, otherwise there wouldn't. We use that
+                        fact and just add the value of the last discarded bit to
+                        the least sifgnificant bit of the shifted value from
+                        acc. */
+                     assign(t5, binop(Iop_Shr64,
+                                      binop(Iop_And64,
+                                            mkexpr(t0),
+                                            binop(Iop_Shl64,
+                                                  mkU64(0x1ULL),
+                                                  unop(Iop_32to8,
+                                                       binop(Iop_Sub32,
+                                                             binop(Iop_And32,
+                                                                   getIReg(rs),
+                                                                   mkU32(0x1f)),
+                                                             mkU32(0x1))))),
+                                      unop(Iop_32to8,
+                                           binop(Iop_Sub32,
+                                                 binop(Iop_And32,
+                                                       getIReg(rs),
+                                                       mkU32(0x1f)),
+                                                 mkU32(0x1)))));
+
+                     assign(t6, binop(Iop_Add64, mkexpr(t1), mkexpr(t5)));
+
+                     assign(t8, IRExpr_ITE(binop(Iop_CmpNE32,
+                                                 unop(Iop_64HIto32,
+                                                      mkexpr(t6)),
+                                                 mkU32(0xffffffff)),
+                                           mkexpr(t4),
+                                           getDSPControl()));
+                     putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32,
+                                                    unop(Iop_64HIto32,
+                                                         mkexpr(t6)),
+                                                    mkU32(0x0)),
+                                              mkexpr(t8),
+                                              getDSPControl()));
+                     assign(t9, IRExpr_ITE(binop(Iop_CmpEQ32,
+                                                 binop(Iop_And32,
+                                                       unop(Iop_64HIto32,
+                                                            mkexpr(t6)),
+                                                       mkU32(0x80000000)),
+                                                 mkU32(0x0)),
+                                           mkU32(0x7fffffff),
+                                           mkU32(0x80000000)));
+                     assign(t7, IRExpr_ITE(binop(Iop_CmpNE32,
+                                                 unop(Iop_64HIto32, mkexpr(t6)),
+                                                 mkU32(0x0)),
+                                           IRExpr_ITE(binop(Iop_CmpNE32,
+                                                            unop(Iop_64HIto32,
+                                                                 mkexpr(t6)),
+                                                            mkU32(0xffffffff)),
+                                                      mkexpr(t9),
+                                                      unop(Iop_64to32,
+                                                           mkexpr(t6))),
+                                           unop(Iop_64to32, mkexpr(t6))));
+                     putIReg(rt, IRExpr_ITE(binop(Iop_CmpEQ32,
+                                                  binop(Iop_And32,
+                                                        getIReg(rs),
+                                                        mkU32(0x1f)),
+                                                  mkU32(0x0)),
+                                            unop(Iop_64to32, mkexpr(t0)),
+                                            mkexpr(t7)));
+                     break;
+                  }
+                  case 0xA: {  /* EXTPDP */
+                     DIP("extpdp r%d, ac%d, %d", rt, ac, rs);
+                     vassert(!mode64);
+                     t0 = newTemp(Ity_I64);
+                     t1 = newTemp(Ity_I32);
+                     t2 = newTemp(Ity_I1);
+                     t3 = newTemp(Ity_I1);
+                     t4 = newTemp(Ity_I8);
+                     t5 = newTemp(Ity_I64);
+                     t6 = newTemp(Ity_I64);
+                     t7 = newTemp(Ity_I32);
+                     t8 = newTemp(Ity_I32);
+
+                     assign(t0, getAcc(ac));
+                     /* Extract pos field of DSPControl register. */
+                     assign(t1, binop(Iop_And32, getDSPControl(), mkU32(0x3f)));
+
+                     /* Check if (pos - size) >= 0 [size <= pos]
+                        if (pos < size)
+                           put 1 to EFI field of DSPControl register
+                        else
+                           extract bits from acc and put 0 to EFI field of
+                           DSPCtrl */
+                     assign(t2, binop(Iop_CmpLT32U, mkexpr(t1), mkU32(rs)));
+
+                     assign(t8, binop(Iop_Or32,
+                                      binop(Iop_And32,
+                                            getDSPControl(),
+                                            mkU32(0xffffbfc0)),
+                                      binop(Iop_And32,
+                                            binop(Iop_Sub32,
+                                                  binop(Iop_And32,
+                                                        getDSPControl(),
+                                                        mkU32(0x3f)),
+                                                  mkU32(rs+1)),
+                                            mkU32(0x3f))));
+                     putDSPControl(IRExpr_ITE(mkexpr(t2),
+                                              binop(Iop_Or32,
+                                                     binop(Iop_And32,
+                                                           getDSPControl(),
+                                                           mkU32(0xffffbfff)),
+                                                     mkU32(0x4000)),
+                                              mkexpr(t8)));
+
+                     /* If pos <= 31, shift right the value from the acc
+                        (pos-size) times and take (size+1) bits from the least
+                        significant positions. Otherwise, shift left the value
+                        (63-pos) times, take (size+1) bits from the most
+                        significant positions and shift right (31-size) times.
+                     */
+                     assign(t3, binop(Iop_CmpLE32U, mkexpr(t1), mkU32(31)));
+
+                     assign(t4,
+                            IRExpr_ITE(mkexpr(t3),
+                                       unop(Iop_32to8,
+                                            binop(Iop_Sub32,
+                                                  mkexpr(t1), mkU32(rs))),
+                                       unop(Iop_32to8,
+                                            binop(Iop_Sub32,
+                                                  mkU32(63), mkexpr(t1)))));
+
+                     assign(t5, IRExpr_ITE(mkexpr(t3),
+                                           binop(Iop_Shr64,
+                                                 mkexpr(t0), mkexpr(t4)),
+                                           binop(Iop_Shl64,
+                                                 mkexpr(t0), mkexpr(t4))));
+
+                     /* t6 holds a mask for bit extraction. */
+                     assign(t6,
+                            IRExpr_ITE(mkexpr(t3),
+                                       unop(Iop_Not64,
+                                            binop(Iop_Shl64,
+                                                  mkU64(0xffffffffffffffffULL),
+                                                  mkU8(rs+1))),
+                                       unop(Iop_Not64,
+                                            binop(Iop_Shr64,
+                                                  mkU64(0xffffffffffffffffULL),
+                                                  mkU8(rs+1)))));
+
+                     assign(t7, IRExpr_ITE(mkexpr(t3),
+                                           unop(Iop_64to32,
+                                                binop(Iop_And64,
+                                                      mkexpr(t5),
+                                                      mkexpr(t6))),
+                                           binop(Iop_Shr32,
+                                                 unop(Iop_64HIto32,
+                                                      binop(Iop_And64,
+                                                            mkexpr(t5),
+                                                            mkexpr(t6))),
+                                                 mkU8(31-rs))));
+
+                     putIReg(rt, mkexpr(t7));
+                     break;
+                  }
+                  case 0xB: {  /* EXTPDPV */
+                     DIP("extpdpv r%d, ac%d, r%d", rt, ac, rs);
+                     vassert(!mode64);
+                     t0 = newTemp(Ity_I64);
+                     t1 = newTemp(Ity_I32);
+                     t2 = newTemp(Ity_I1);
+                     t3 = newTemp(Ity_I1);
+                     t4 = newTemp(Ity_I8);
+                     t5 = newTemp(Ity_I64);
+                     t6 = newTemp(Ity_I64);
+                     t7 = newTemp(Ity_I32);
+                     t8 = newTemp(Ity_I32);
+                     t9 = newTemp(Ity_I32);
+
+                     assign(t8, binop(Iop_And32, getIReg(rs), mkU32(0x1f)));
+                     assign(t0, getAcc(ac));
+                     /* Extract pos field of DSPControl register. */
+                     assign(t1, binop(Iop_And32, getDSPControl(), mkU32(0x3f)));
+
+                     /* Check if (pos - size) >= 0 [size <= pos]
+                        if (pos < size)
+                           put 1 to EFI field of DSPControl register
+                        else
+                           extract bits from acc and put 0 to EFI field of
+                           DSPCtrl */
+                     assign(t2, binop(Iop_CmpLT32U, mkexpr(t1), mkexpr(t8)));
+
+                     assign(t9, binop(Iop_Or32,
+                                      binop(Iop_And32,
+                                            getDSPControl(),
+                                            mkU32(0xffffbfc0)),
+                                      binop(Iop_And32,
+                                            binop(Iop_Sub32,
+                                                  binop(Iop_And32,
+                                                        getDSPControl(),
+                                                        mkU32(0x3f)),
+                                                  binop(Iop_Add32,
+                                                        mkexpr(t8),
+                                                        mkU32(0x1))),
+                                            mkU32(0x3f))));
+                     putDSPControl(IRExpr_ITE(mkexpr(t2),
+                                              binop(Iop_Or32,
+                                                    binop(Iop_And32,
+                                                          getDSPControl(),
+                                                          mkU32(0xffffbfff)),
+                                                    mkU32(0x4000)),
+                                              mkexpr(t9)));
+
+                     /* If pos <= 31, shift right the value from the acc
+                        (pos-size) times and take (size+1) bits from the least
+                        significant positions. Otherwise, shift left the value
+                        (63-pos) times, take (size+1) bits from the most
+                        significant positions and shift right (31-size) times.
+                     */
+                     assign(t3, binop(Iop_CmpLE32U, mkexpr(t1), mkU32(31)));
+
+                     assign(t4,
+                            IRExpr_ITE(mkexpr(t3),
+                                      unop(Iop_32to8,
+                                           binop(Iop_Sub32,
+                                                 mkexpr(t1), mkexpr(t8))),
+                                      unop(Iop_32to8,
+                                           binop(Iop_Sub32,
+                                                 mkU32(63), mkexpr(t1)))));
+
+                     assign(t5, IRExpr_ITE(mkexpr(t3),
+                                           binop(Iop_Shr64,
+                                                 mkexpr(t0), mkexpr(t4)),
+                                           binop(Iop_Shl64,
+                                                 mkexpr(t0), mkexpr(t4))));
+
+                     /* t6 holds a mask for bit extraction. */
+                     assign(t6,
+                            IRExpr_ITE(mkexpr(t3),
+                                       unop(Iop_Not64,
+                                            binop(Iop_Shl64,
+                                                  mkU64(0xffffffffffffffffULL),
+                                                  unop(Iop_32to8,
+                                                       binop(Iop_Add32,
+                                                             mkexpr(t8),
+                                                             mkU32(1))))),
+                                       unop(Iop_Not64,
+                                            binop(Iop_Shr64,
+                                                  mkU64(0xffffffffffffffffULL),
+                                                  unop(Iop_32to8,
+                                                       binop(Iop_Add32,
+                                                             mkexpr(t8),
+                                                             mkU32(1)))))));
+
+                     assign(t7, IRExpr_ITE(mkexpr(t3),
+                                           unop(Iop_64to32,
+                                                binop(Iop_And64,
+                                                      mkexpr(t5),
+                                                      mkexpr(t6))),
+                                           binop(Iop_Shr32,
+                                                 unop(Iop_64HIto32,
+                                                      binop(Iop_And64,
+                                                            mkexpr(t5),
+                                                            mkexpr(t6))),
+                                                 unop(Iop_32to8,
+                                                      binop(Iop_Sub32,
+                                                            mkU32(31),
+                                                            mkexpr(t8))))));
+
+                     putIReg(rt, mkexpr(t7));
+                     break;
+                  }
+                  case 0xE: {  /* EXTR_S.H */
+                     DIP("extr_s.h r%d, ac%d, %d", rt, ac, rs);
+                     vassert(!mode64);
+                     t0 = newTemp(Ity_I64);
+                     t1 = newTemp(Ity_I64);
+                     t2 = newTemp(Ity_I32);
+                     t3 = newTemp(Ity_I64);
+                     t4 = newTemp(Ity_I32);
+                     t5 = newTemp(Ity_I32);
+                     t6 = newTemp(Ity_I64);
+                     t7 = newTemp(Ity_I32);
+                     t8 = newTemp(Ity_I32);
+                     t9 = newTemp(Ity_I32);
+                     t10 = newTemp(Ity_I1);
+
+                     assign(t0, getAcc(ac));
+
+                     assign(t1, binop(Iop_Sar64, mkexpr(t0), mkU8(rs)));
+
+                     assign(t2, binop(Iop_Or32,
+                                      getDSPControl(), mkU32(0x00800000)));
+
+                     assign(t9, binop(Iop_Shl32,
+                                      binop(Iop_And32,
+                                            unop(Iop_64to32,
+                                                 mkexpr(t1)),
+                                            mkU32(0x00008000)),
+                                      mkU8(16)));
+                     putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32,
+                                                    mkexpr(t9),
+                                                    binop(Iop_And32,
+                                                          unop(Iop_64HIto32,
+                                                               mkexpr(t0)),
+                                                          mkU32(0x80000000))),
+                                              mkexpr(t2),
+                                              getDSPControl()));
+
+                     /* Check if t1 > 0x7fff ((t1 - 0x7fff) > 0)
+                        1. subtract 0x7fff from t1
+                        2. if the resulting number is positive (sign bit = 0)
+                           and any of the other bits is 1, the value is > 0. */
+                     assign(t3, binop(Iop_Sub64,
+                                      mkexpr(t1),
+                                      mkU64(0x0000000000007fffULL)));
+                     assign(t4, binop(Iop_Or32,
+                                      unop(Iop_1Uto32,
+                                           binop(Iop_CmpNE32,
+                                                 mkU32(0),
+                                                 binop(Iop_And32,
+                                                       unop(Iop_64HIto32,
+                                                            mkexpr(t3)),
+                                                       mkU32(0x7fffffff)))),
+                                      unop(Iop_1Uto32,
+                                           binop(Iop_CmpNE32,
+                                                 mkU32(0),
+                                                 binop(Iop_And32,
+                                                       unop(Iop_64to32,
+                                                            mkexpr(t3)),
+                                                       mkU32(0xffffffff))))));
+
+                     assign(t5, IRExpr_ITE(unop(Iop_32to1,
+                                                binop(Iop_Shr32,
+                                                      binop(Iop_And32,
+                                                            unop(Iop_64HIto32,
+                                                                 mkexpr(t3)),
+                                                            mkU32(0x80000000)),
+                                                      mkU8(31))),
+                                           unop(Iop_64to32, mkexpr(t1)),
+                                           IRExpr_ITE(binop(Iop_CmpNE32,
+                                                            mkexpr(t4),
+                                                            mkU32(0x0)),
+                                                      mkU32(0x7fff),
+                                                      unop(Iop_64to32,
+                                                           mkexpr(t1)))));
+
+                     assign(t10, unop(Iop_32to1,
+                                      binop(Iop_Shr32,
+                                            binop(Iop_And32,
+                                                  unop(Iop_64HIto32,
+                                                       mkexpr(t3)),
+                                                   mkU32(0x80000000)),
+                                            mkU8(31))));
+                     putDSPControl(IRExpr_ITE(mkexpr(t10),
+                                             getDSPControl(),
+                                             IRExpr_ITE(binop(Iop_CmpNE32,
+                                                              mkexpr(t4),
+                                                              mkU32(0x0)),
+                                                        binop(Iop_Or32,
+                                                             getDSPControl(),
+                                                             mkU32(0x00800000)),
+                                                        getDSPControl())));
+
+                     /* Check if t1<0xffffffffffff8000 (0xffffffffffff8000-t1)>0
+                        1. subtract t1 from 0x7fff
+                        2. if the resulting number is positive (sign bit = 0)
+                            and any of the other bits is 1, the value is > 0 */
+                     assign(t6, binop(Iop_Sub64,
+                                       mkU64(0xffffffffffff8000ULL),
+                                       mkexpr(t1)));
+
+                     assign(t7, binop(Iop_Or32,
+                                      unop(Iop_1Uto32,
+                                           binop(Iop_CmpNE32,
+                                                 mkU32(0),
+                                                 binop(Iop_And32,
+                                                       unop(Iop_64HIto32,
+                                                            mkexpr(t6)),
+                                                       mkU32(0x7fffffff)))),
+                                      unop(Iop_1Uto32,
+                                           binop(Iop_CmpNE32,
+                                                 mkU32(0),
+                                                 binop(Iop_And32,
+                                                       unop(Iop_64to32,
+                                                            mkexpr(t6)),
+                                                       mkU32(0xffffffff))))));
+
+                     assign(t8, IRExpr_ITE(unop(Iop_32to1,
+                                                binop(Iop_Shr32,
+                                                      binop(Iop_And32,
+                                                            unop(Iop_64HIto32,
+                                                                 mkexpr(t6)),
+                                                            mkU32(0x80000000)),
+                                                      mkU8(31))),
+                                           unop(Iop_64to32, mkexpr(t1)),
+                                           IRExpr_ITE(binop(Iop_CmpNE32,
+                                                            mkexpr(t7),
+                                                            mkU32(0x0)),
+                                                      mkU32(0xffff8000),
+                                                      unop(Iop_64to32,
+                                                           mkexpr(t1)))));
+                     putDSPControl(IRExpr_ITE(unop(Iop_32to1,
+                                                   binop(Iop_Shr32,
+                                                         binop(Iop_And32,
+                                                             unop(Iop_64HIto32,
+                                                                   mkexpr(t6)),
+                                                             mkU32(0x80000000)),
+                                                         mkU8(31))),
+                                              getDSPControl(),
+                                              IRExpr_ITE(binop(Iop_CmpNE32,
+                                                               mkexpr(t7),
+                                                               mkU32(0x0)),
+                                                         binop(Iop_Or32,
+                                                             getDSPControl(),
+                                                             mkU32(0x00800000)),
+                                                         getDSPControl())));
+
+                     /* If the shifted value is positive, it can only be >0x7fff
+                        and the final result is the value stored in t5,
+                        otherwise, the final result is in t8. */
+                     putIReg(rt, IRExpr_ITE(unop(Iop_32to1,
+                                                 binop(Iop_Shr32,
+                                                       binop(Iop_And32,
+                                                             unop(Iop_64HIto32,
+                                                                  mkexpr(t1)),
+                                                             mkU32(0x80000000)),
+                                                       mkU8(31))),
+                                            mkexpr(t8),
+                                            mkexpr(t5)));
+                     break;
+                  }
+                  case 0xF: {  /* EXTRV_S.H */
+                     DIP("extrv_s.h r%d, ac%d, %d", rt, ac, rs);
+                     vassert(!mode64);
+                     t0 = newTemp(Ity_I64);
+                     t1 = newTemp(Ity_I64);
+                     t2 = newTemp(Ity_I32);
+                     t3 = newTemp(Ity_I64);
+                     t4 = newTemp(Ity_I32);
+                     t5 = newTemp(Ity_I32);
+                     t6 = newTemp(Ity_I64);
+                     t7 = newTemp(Ity_I32);
+                     t8 = newTemp(Ity_I32);
+                     t9 = newTemp(Ity_I32);
+                     t10 = newTemp(Ity_I32);
+                     t11 = newTemp(Ity_I32);
+
+                     assign(t0, getAcc(ac));
+
+                     assign(t1, binop(Iop_Sar64,
+                                      mkexpr(t0),
+                                      unop(Iop_32to8,
+                                           binop(Iop_And32,
+                                                 getIReg(rs),
+                                                 mkU32(0x1f)))));
+
+                     assign(t2, binop(Iop_Or32,
+                                      getDSPControl(), mkU32(0x00800000)));
+
+                     assign(t9, binop(Iop_Shl32,
+                                      binop(Iop_And32,
+                                            unop(Iop_64to32,
+                                                 mkexpr(t1)),
+                                            mkU32(0x00008000)),
+                                      mkU8(16)));
+                     putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32,
+                                                    mkexpr(t9),
+                                                    binop(Iop_And32,
+                                                          unop(Iop_64HIto32,
+                                                               mkexpr(t0)),
+                                                          mkU32(0x80000000))),
+                                              mkexpr(t2),
+                                              getDSPControl()));
+
+                     /* Check if t1 > 0x7fff ((t1 - 0x7fff) > 0)
+                        1. subtract 0x7fff from t1
+                        2. if the resulting number is positive (sign bit = 0)
+                            and any of the other bits is 1, the value is > 0 */
+                     assign(t3, binop(Iop_Sub64,
+                                      mkexpr(t1),
+                                      mkU64(0x0000000000007fffULL)));
+                     assign(t4, binop(Iop_Or32,
+                                      unop(Iop_1Uto32,
+                                           binop(Iop_CmpNE32,
+                                                 mkU32(0),
+                                                 binop(Iop_And32,
+                                                       unop(Iop_64HIto32,
+                                                            mkexpr(t3)),
+                                                       mkU32(0x7fffffff)))),
+                                      unop(Iop_1Uto32,
+                                           binop(Iop_CmpNE32,
+                                                 mkU32(0),
+                                                 binop(Iop_And32,
+                                                       unop(Iop_64to32,
+                                                            mkexpr(t3)),
+                                                       mkU32(0xffffffff))))));
+
+                     assign(t5, IRExpr_ITE(unop(Iop_32to1,
+                                                binop(Iop_Shr32,
+                                                      binop(Iop_And32,
+                                                            unop(Iop_64HIto32,
+                                                                 mkexpr(t3)),
+                                                            mkU32(0x80000000)),
+                                                      mkU8(31))),
+                                           unop(Iop_64to32, mkexpr(t1)),
+                                           IRExpr_ITE(binop(Iop_CmpNE32,
+                                                            mkexpr(t4),
+                                                            mkU32(0x0)),
+                                                      mkU32(0x7fff),
+                                                      unop(Iop_64to32,
+                                                           mkexpr(t1)))));
+
+                     assign(t10, binop(Iop_Shr32,
+                                       binop(Iop_And32,
+                                             unop(Iop_64HIto32,
+                                                  mkexpr(t3)),
+                                             mkU32(0x80000000)),
+                                       mkU8(31)));
+                     assign(t11, IRExpr_ITE(binop(Iop_CmpNE32,
+                                                  mkexpr(t4),
+                                                  mkU32(0x0)),
+                                            binop(Iop_Or32,
+                                                  getDSPControl(),
+                                                  mkU32(0x00800000)),
+                                            getDSPControl()));
+                     putDSPControl(IRExpr_ITE(unop(Iop_32to1,
+                                                   mkexpr(t10)),
+                                              getDSPControl(),
+                                              mkexpr(t11)));
+
+                     /* Check if t1<0xffffffffffff8000
+                        1. subtract t1 from 0x7fff
+                        2. if the resulting number is positive (sign bit == 0)
+                            and any of the other bits is 1, the value is > 0 */
+                     assign(t6, binop(Iop_Sub64,
+                                      mkU64(0xffffffffffff8000ULL),
+                                      mkexpr(t1)));
+
+                     assign(t7, binop(Iop_Or32,
+                                      unop(Iop_1Uto32,
+                                           binop(Iop_CmpNE32,
+                                                 mkU32(0),
+                                                 binop(Iop_And32,
+                                                       unop(Iop_64HIto32,
+                                                            mkexpr(t6)),
+                                                       mkU32(0x7fffffff)))),
+                                      unop(Iop_1Uto32,
+                                           binop(Iop_CmpNE32,
+                                                 mkU32(0),
+                                                 binop(Iop_And32,
+                                                       unop(Iop_64to32,
+                                                            mkexpr(t6)),
+                                                       mkU32(0xffffffff))))));
+
+                     assign(t8, IRExpr_ITE(unop(Iop_32to1,
+                                                binop(Iop_Shr32,
+                                                      binop(Iop_And32,
+                                                            unop(Iop_64HIto32,
+                                                                 mkexpr(t6)),
+                                                            mkU32(0x80000000)),
+                                                      mkU8(31))),
+                                           unop(Iop_64to32, mkexpr(t1)),
+                                           IRExpr_ITE(binop(Iop_CmpNE32,
+                                                            mkexpr(t7),
+                                                            mkU32(0x0)),
+                                                      mkU32(0xffff8000),
+                                                      unop(Iop_64to32,
+                                                           mkexpr(t1)))));
+                     putDSPControl(IRExpr_ITE(unop(Iop_32to1,
+                                                  binop(Iop_Shr32,
+                                                        binop(Iop_And32,
+                                                              unop(Iop_64HIto32,
+                                                                   mkexpr(t6)),
+                                                              mkU32(0x80000000)
+                                                             ),
+                                                        mkU8(31))),
+                                              getDSPControl(),
+                                              IRExpr_ITE(binop(Iop_CmpNE32,
+                                                               mkexpr(t7),
+                                                               mkU32(0x0)),
+                                                         binop(Iop_Or32,
+                                                               getDSPControl(),
+                                                               mkU32(0x00800000)
+                                                              ),
+                                                         getDSPControl())));
+
+                     /* If the shifted value is positive, it can only be >0x7fff
+                        and the final result is the value stored in t5,
+                        otherwise, the final result is in t8. */
+                     putIReg(rt, IRExpr_ITE(unop(Iop_32to1,
+                                                 binop(Iop_Shr32,
+                                                       binop(Iop_And32,
+                                                             unop(Iop_64HIto32,
+                                                                  mkexpr(t1)),
+                                                             mkU32(0x80000000)),
+                                                       mkU8(31))),
+                                            mkexpr(t8),
+                                            mkexpr(t5)));
+                     break;
+                  }
+                  case 0x12: {  /* RDDSP*/
+                     DIP("rddsp r%d, mask 0x%x", rd, rddsp_mask);
+                     vassert(!mode64);
+
+                     putIReg(rd, mkU32(0x0));
+
+                     if ((rddsp_mask & 0b000001) == 0b000001) {
+                        /* Read pos field (bits 5-0) of DSPControl register. */
+                        putIReg(rd, binop(Iop_Or32,
+                                          getIReg(rd),
+                                          binop(Iop_And32,
+                                                getDSPControl(),
+                                                mkU32(0x0000003F))));
+                     }
+
+                     if ((rddsp_mask & 0b000010) == 0b000010) {
+                        /* Read scount field (bits 12-7) of DSPControl
+                           register. */
+                        putIReg(rd, binop(Iop_Or32,
+                                          getIReg(rd),
+                                          binop(Iop_And32,
+                                                getDSPControl(),
+                                                mkU32(0x00001F80))));
+                     }
+
+                     if ((rddsp_mask & 0b000100) == 0b000100) {
+                        /* Read C field (bit 13) of DSPControl register. */
+                        putIReg(rd, binop(Iop_Or32,
+                                          getIReg(rd),
+                                          binop(Iop_And32,
+                                                getDSPControl(),
+                                                mkU32(0x00002000))));
+                     }
+
+                     if ((rddsp_mask & 0b001000) == 0b001000) {
+                        /* Read outflag field (bit s 23-16) of DSPControl
+                           register. */
+                        putIReg(rd, binop(Iop_Or32,
+                                          getIReg(rd),
+                                          binop(Iop_And32,
+                                                getDSPControl(),
+                                                mkU32(0x00FF0000))));
+                     }
+
+                     if ((rddsp_mask & 0b010000) == 0b010000) {
+                        /* Read ccond field (bits 31-24) of DSPControl
+                           register. */
+                        putIReg(rd, binop(Iop_Or32,
+                                          getIReg(rd),
+                                          binop(Iop_And32,
+                                                getDSPControl(),
+                                                mkU32(0xFF000000))));
+                     }
+
+                     if ((rddsp_mask & 0b100000) == 0b100000) {
+                        /* Read EFI field (bit 14) of DSPControl register. */
+                        putIReg(rd, binop(Iop_Or32,
+                                          getIReg(rd),
+                                          binop(Iop_And32,
+                                                getDSPControl(),
+                                                mkU32(0x00004000))));
+                     }
+
+                     if ((rddsp_mask & 0b111111) == 0b111111) {
+                        /* Read all fields of DSPControl register. */
+                        putIReg(rd, getDSPControl());
+                     }
+                     break;
+                  }
+                  case 0x13: {  /* WRDSP */
+                     DIP("wrdsp r%d, mask 0x%x", rs, wrdsp_mask);
+                     vassert(!mode64);
+
+                     if ((wrdsp_mask & 0b111111) == 0b111111) {
+                        /* If mips64 put all fields of rs, except bit 15 and bit
+                           6, to DSPControl register, otherwise put all except
+                           bits 15, 6 and bits 31..28. */
+                        putDSPControl(mode64 ?
+                                      binop(Iop_And32,
+                                            getIReg(rs),
+                                            mkU32(0xffff7fbf)) :
+                                      binop(Iop_And32,
+                                            getIReg(rs),
+                                            mkU32(0x0fff7fbf)));
+                     } else {
+                        if ((wrdsp_mask & 0b000001) == 0b000001) {
+                           /* Put bits 5-0 of rs to DSPControl register pos
+                              field. */
+                           putDSPControl(binop(Iop_Or32,
+                                               binop(Iop_And32,
+                                                     getDSPControl(),
+                                                     mkU32(0xFFFF7F40)),
+                                               binop(Iop_And32,
+                                                     getIReg(rs),
+                                                     mkU32(0x0000003F))));
+                        }
+
+                        if ((wrdsp_mask & 0b000010) == 0b000010) {
+                           /* Put bits 12-7 of rs to DSPControl scount field. */
+                           putDSPControl(binop(Iop_Or32,
+                                               binop(Iop_And32,
+                                                     getDSPControl(),
+                                                     mkU32(0xFFFFE03F)),
+                                               binop(Iop_And32,
+                                                     getIReg(rs),
+                                                     mkU32(0x00001F80))));
+                        }
+
+                        if ((wrdsp_mask & 0b000100) == 0b000100) {
+                           /* Put bit 13 of rs to DSPControl register C
+                              field. */
+                           putDSPControl(binop(Iop_Or32,
+                                               binop(Iop_And32,
+                                                     getDSPControl(),
+                                                     mkU32(0xFFFF5FBF)),
+                                               binop(Iop_And32,
+                                                     getIReg(rs),
+                                                     mkU32(0x00002000))));
+                        }
+
+                        if ((wrdsp_mask & 0b001000) == 0b001000) {
+                           /* Put bits 23-16 of rs to DSPControl reg outflag
+                              field. */
+                           putDSPControl(binop(Iop_Or32,
+                                               binop(Iop_And32,
+                                                     getDSPControl(),
+                                                     mkU32(0xFF007FBF)),
+                                               binop(Iop_And32,
+                                                     getIReg(rs),
+                                                     mkU32(0x00FF0000))));
+                        }
+
+                        if ((wrdsp_mask & 0b010000) == 0b010000) {
+                           /* Put bits 31-24 of rs to DSPControl reg ccond
+                              field. */
+                           putDSPControl(binop(Iop_Or32,
+                                               binop(Iop_And32,
+                                                     getDSPControl(),
+                                                     mkU32(0x00FF7FBF)),
+                                               binop(Iop_And32,
+                                                     getIReg(rs),
+                                                     mode64 ? mkU32(0xFF000000)
+                                                            : mkU32(0x0F000000))
+                                               )
+                                        );
+                        }
+
+                        if ((wrdsp_mask & 0b100000) == 0b100000) {
+                           /* Put bit 14 of rs to DSPControl register EFI
+                              field. */
+                           putDSPControl(binop(Iop_Or32,
+                                               binop(Iop_And32,
+                                                     getDSPControl(),
+                                                     mkU32(0xFFFF3FBF)),
+                                               binop(Iop_And32,
+                                                     getIReg(rs),
+                                                     mkU32(0x00004000))));
+                        }
+                     }
+                     break;
+                  }
+                  case 0x1A: {  /* SHILO */
+                     DIP("shilo ac%d, %d", ac, shift);
+                     vassert(!mode64);
+                     t0 = newTemp(Ity_I64);
+                     t1 = newTemp(Ity_I64);
+
+                     assign(t0, getAcc(ac));
+
+                     putAcc(ac, mkexpr(t0));
+
+                     if (0b100000 == (shift & 0x3f)) {
+                        putAcc(ac, binop(Iop_32HLto64,
+                                         unop(Iop_64to32, mkexpr(t0)),
+                                         mkU32(0x0)));
+                     } else if (0b100000 == (shift & 0x20)) {
+                        assign(t1, binop(Iop_Shl64,
+                                         mkexpr(t0),
+                                         unop(Iop_32to8,
+                                              binop(Iop_Add32,
+                                                    unop(Iop_Not32,
+                                                         mkU32(shift)),
+                                                    mkU32(0x1)))));
+
+                        putAcc(ac, mkexpr(t1));
+                     } else {
+                        assign(t1, binop(Iop_Shr64, mkexpr(t0), mkU8(shift)));
+
+                        putAcc(ac, mkexpr(t1));
+                     }
+                     break;
+                  }
+                  case 0x1B: {  /* SHILOV */
+                     DIP("shilov ac%d, r%d", ac, rs);
+                     vassert(!mode64);
+                     t0 = newTemp(Ity_I64);
+                     t1 = newTemp(Ity_I64);
+                     t2 = newTemp(Ity_I32);
+                     t3 = newTemp(Ity_I1);
+                     t4 = newTemp(Ity_I64);
+                     t5 = newTemp(Ity_I64);
+
+                     assign(t0, getAcc(ac));
+                     assign(t2, binop(Iop_And32, getIReg(rs), mkU32(0x3f)));
+                     assign(t3, binop(Iop_CmpEQ32, mkexpr(t2), mkU32(0x20)));
+
+                     assign(t4, binop(Iop_Shl64,
+                                      mkexpr(t0),
+                                      unop(Iop_32to8,
+                                           binop(Iop_Add32,
+                                                 unop(Iop_Not32,
+                                                      mkexpr(t2)),
+                                                 mkU32(0x1)))));
+                     assign(t5, binop(Iop_Shr64,
+                                      mkexpr(t0),
+                                      unop(Iop_32to8,
+                                           mkexpr(t2))));
+                     putAcc(ac, IRExpr_ITE(mkexpr(t3),
+                                           binop(Iop_32HLto64,
+                                                 unop(Iop_64to32, mkexpr(t0)),
+                                                 mkU32(0x0)),
+                                           IRExpr_ITE(binop(Iop_CmpEQ32,
+                                                            binop(Iop_And32,
+                                                                  mkexpr(t2),
+                                                                  mkU32(0x20)),
+                                                            mkU32(0x20)),
+                                                      mkexpr(t4),
+                                                      mkexpr(t5))));
+                     break;
+                  }
+                  case 0x1F: {  /* MTHLIP */
+                     DIP("mthlip r%d, ac%d", rs, ac);
+                     vassert(!mode64);
+                     t0 = newTemp(Ity_I64);
+                     t1 = newTemp(Ity_I32);
+                     t2 = newTemp(Ity_I32);
+                     t3 = newTemp(Ity_I1);
+
+                     assign(t0, getAcc(ac));
+                     putAcc(ac, binop(Iop_32HLto64,
+                                      unop(Iop_64to32, mkexpr(t0)),
+                                      getIReg(rs)));
+                     assign(t1, binop(Iop_And32, getDSPControl(), mkU32(0x3f)));
+                     putDSPControl(IRExpr_ITE(binop(Iop_CmpLE32U,
+                                                    mkU32(32),
+                                                    mkexpr(t1)),
+                                              binop(Iop_Or32,
+                                                    binop(Iop_Sub32,
+                                                          mkexpr(t1),
+                                                          mkU32(32)),
+                                                   binop(Iop_And32,
+                                                         getDSPControl(),
+                                                         mkU32(0xffffffc0))),
+                                              binop(Iop_Or32,
+                                                    binop(Iop_Add32,
+                                                          mkexpr(t1),
+                                                          mkU32(32)),
+                                                    binop(Iop_And32,
+                                                          getDSPControl(),
+                                                          mkU32(0xffffffc0)))));
+                     break;
+                  }
+                  default:
+                     return -1;
+               }
+               break;  /* end of EXTR.W */
+            }
+            case 0xA: {  /* LX */
+               switch(sa) {
+                  case 0x0: {  /* LWX */
+                     DIP("lwx r%d, r%d(r%d)", rd, rt, rs);
+                     vassert(!mode64);
+                     t0 = newTemp(Ity_I32);
+
+                     assign(t0, binop(Iop_Add32, getIReg(rt), getIReg(rs)));
+
+                     putIReg(rd, load(Ity_I32, mkexpr(t0)));
+                     break;
+                  }
+                  case 0x4: {  /* LHX */
+                     DIP("lhx r%d, r%d(r%d)", rd, rt, rs);
+                     vassert(!mode64);
+                     t0 = newTemp(Ity_I32);
+
+                     assign(t0, binop(Iop_Add32, getIReg(rt), getIReg(rs)));
+
+                     putIReg(rd, unop(Iop_16Sto32, load(Ity_I16, mkexpr(t0))));
+                     break;
+                  }
+                  case 0x6: {  /* LBUX */
+                     DIP("lbux r%d, r%d(r%d)", rd, rt, rs);
+                     vassert(!mode64);
+                     t0 = newTemp(Ity_I32);
+
+                     assign(t0, binop(Iop_Add32, getIReg(rt), getIReg(rs)));
+
+                     putIReg(rd, unop(Iop_8Uto32, load(Ity_I8, mkexpr(t0))));
+                     break;
+                  }
+                  default:
+                     return -1;
+               }
+               break;  /* end of LX */
+            }
+            case 0xC: {  /* INSV */
+               switch(sa) {
+                  case 0x0: {  /* INSV */
+                     DIP("insv r%d, r%d", rt, rs);
+                     vassert(!mode64);
+
+                     t0 = newTemp(Ity_I32);
+                     t1 = newTemp(Ity_I32);
+                     t2 = newTemp(Ity_I8);
+                     t3 = newTemp(Ity_I8);
+                     t4 = newTemp(Ity_I32);
+                     t5 = newTemp(Ity_I1);
+                     t6 = newTemp(Ity_I32);
+                     t7 = newTemp(Ity_I32);
+                     t8 = newTemp(Ity_I32);
+                     t9 = newTemp(Ity_I32);
+
+                     /* t0 <- pos field of DSPControl register. */
+                     assign(t0, binop(Iop_And32, getDSPControl(), mkU32(0x3f)));
+                     /* t1 <- scount field of DSPControl register. */
+                     assign(t1, binop(Iop_Shr32,
+                                      binop(Iop_And32,
+                                            getDSPControl(),
+                                            mkU32(0x1f80)),
+                                      mkU8(7)));
+
+                     assign(t2, unop(Iop_32to8,
+                                     binop(Iop_Add32,
+                                           mkexpr(t1),
+                                           mkexpr(t0))));
+
+                     /* 32-(pos+size) most significant bits of rt. */
+                     assign(t6, binop(Iop_Shl32,
+                                      binop(Iop_Shr32,
+                                            getIReg(rt),
+                                            mkexpr(t2)),
+                                      mkexpr(t2)));
+
+                     assign(t3, unop(Iop_32to8,
+                                     binop(Iop_Sub32,
+                                           mkU32(32),
+                                           mkexpr(t0))));
+                     /* Pos least significant bits of rt. */
+                     assign(t7, binop(Iop_Shr32,
+                                      binop(Iop_Shl32,
+                                            getIReg(rt),
+                                            mkexpr(t3)),
+                                      mkexpr(t3)));
+
+                     /* Size least significant bits of rs,
+                        shifted to appropriate position. */
+                     assign(t8, binop(Iop_Shl32,
+                                      binop(Iop_And32,
+                                            getIReg(rs),
+                                            unop(Iop_Not32,
+                                                 binop(Iop_Shl32,
+                                                       mkU32(0xffffffff),
+                                                       unop(Iop_32to8,
+                                                            mkexpr(t1))))),
+                                      unop(Iop_32to8,
+                                           mkexpr(t0))));
+
+                     putIReg(rt, IRExpr_ITE(binop(Iop_CmpEQ32,
+                                                  mkexpr(t0),
+                                                  mkU32(0)),
+                                            IRExpr_ITE(binop(Iop_CmpEQ32,
+                                                             mkexpr(t1),
+                                                             mkU32(32)),
+                                                       getIReg(rs),
+                                                       binop(Iop_Or32,
+                                                             mkexpr(t6),
+                                                             mkexpr(t8))),
+                                            IRExpr_ITE(binop(Iop_CmpEQ32,
+                                                             unop(Iop_8Uto32,
+                                                                  mkexpr(t2)),
+                                                             mkU32(32)),
+                                                       binop(Iop_Or32,
+                                                             mkexpr(t7),
+                                                             mkexpr(t8)),
+                                                       binop(Iop_Or32,
+                                                             binop(Iop_Or32,
+                                                                   mkexpr(t6),
+                                                                   mkexpr(t7)),
+                                                             mkexpr(t8)))));
+                     break;
+                  }
+                  default:
+                     return -1;
+               }
+               break;  /* enf of INSV */
+            }
+            case 0x10: {  /* ADDU.QB */
+               switch(sa) {
+                  case 0x00: {  /* ADDU.QB */
+                     DIP("addu.qb r%d, r%d, r%d", rd, rs, rt);
+                     vassert(!mode64);
+                     t0 = newTemp(Ity_I32);
+                     t1 = newTemp(Ity_I1);
+                     t2 = newTemp(Ity_I32);
+                     t3 = newTemp(Ity_I1);
+                     t4 = newTemp(Ity_I32);
+                     t5 = newTemp(Ity_I1);
+                     t6 = newTemp(Ity_I32);
+                     t7 = newTemp(Ity_I1);
+                     t8 = newTemp(Ity_I32);
+
+                     /* Add rightmost bytes of rs and rt. */
+                     assign(t0,
+                            binop(Iop_Add32,
+                                  unop(Iop_8Uto32,
+                                       unop(Iop_16to8,
+                                            unop(Iop_32to16, getIReg(rs)))),
+                                  unop(Iop_8Uto32,
+                                       unop(Iop_16to8,
+                                            unop(Iop_32to16, getIReg(rt))))));
+                     /* t1 will be 1 if there is overflow, 0 otherwise. */
+                     assign(t1, binop(Iop_CmpEQ32,
+                                      binop(Iop_And32,
+                                            mkexpr(t0),
+                                            mkU32(0x00000100)),
+                                      mkU32(0x00000100)));
+
+                     /* Add bits 15-8 of rs and rt. */
+                     assign(t2,
+                            binop(Iop_Add32,
+                                  unop(Iop_8Uto32,
+                                       unop(Iop_16HIto8,
+                                            unop(Iop_32to16, getIReg(rs)))),
+                                  unop(Iop_8Uto32,
+                                       unop(Iop_16HIto8,
+                                            unop(Iop_32to16, getIReg(rt))))));
+                     /* t3 will be 1 if there is overflow, 0 otherwise. */
+                     assign(t3, binop(Iop_CmpEQ32,
+                                      binop(Iop_And32,
+                                            mkexpr(t2),
+                                            mkU32(0x00000100)),
+                                      mkU32(0x00000100)));
+
+                     /* Add bits 15-8 of rs and rt. */
+                     assign(t4,
+                            binop(Iop_Add32,
+                                  unop(Iop_8Uto32,
+                                       unop(Iop_16to8,
+                                            unop(Iop_32HIto16, getIReg(rs)))),
+                                  unop(Iop_8Uto32,
+                                       unop(Iop_16to8,
+                                            unop(Iop_32HIto16, getIReg(rt))))));
+                     /* t5 will be 1 if there is overflow, 0 otherwise. */
+                     assign(t5, binop(Iop_CmpEQ32,
+                                      binop(Iop_And32,
+                                            mkexpr(t4),
+                                            mkU32(0x00000100)),
+                                      mkU32(0x00000100)));
+
+                     /* Add bits 15-8 of rs and rt. */
+                     assign(t6,
+                            binop(Iop_Add32,
+                                  unop(Iop_8Uto32,
+                                       unop(Iop_16HIto8,
+                                            unop(Iop_32HIto16, getIReg(rs)))),
+                                  unop(Iop_8Uto32,
+                                       unop(Iop_16HIto8,
+                                            unop(Iop_32HIto16, getIReg(rt))))));
+                     /* t7 will be 1 if there is overflow, 0 otherwise. */
+                     assign(t7, binop(Iop_CmpEQ32,
+                                      binop(Iop_And32,
+                                            mkexpr(t6),
+                                            mkU32(0x00000100)),
+                                      mkU32(0x00000100)));
+
+                     assign(t8,
+                            binop(Iop_Or32,
+                                  binop(Iop_Or32,
+                                        binop(Iop_Or32,
+                                              unop(Iop_1Sto32, mkexpr(t7)),
+                                              unop(Iop_1Sto32,  mkexpr(t5))),
+                                        unop(Iop_1Sto32, mkexpr(t3))),
+                                  unop(Iop_1Sto32, mkexpr(t1))));
+
+                     putDSPControl(IRExpr_ITE(binop(Iop_CmpEQ32,
+                                                    mkexpr(t8),
+                                                    mkU32(0x0)),
+                                              getDSPControl(),
+                                              binop(Iop_Or32,
+                                                    getDSPControl(),
+                                                    mkU32(0x00100000))));
+
+                     putIReg(rd, binop(Iop_16HLto32,
+                                       binop(Iop_8HLto16,
+                                             unop(Iop_32to8, mkexpr(t6)),
+                                             unop(Iop_32to8, mkexpr(t4))),
+                                       binop(Iop_8HLto16,
+                                             unop(Iop_32to8, mkexpr(t2)),
+                                             unop(Iop_32to8, mkexpr(t0)))));
+                     break;
+                  }
+                  case 0x1: {  /* SUBU.QB */
+                     DIP("subu.qb r%d, r%d, r%d", rd, rs, rt);
+                     vassert(!mode64);
+                     t0 = newTemp(Ity_I32);
+                     t1 = newTemp(Ity_I1);
+                     t2 = newTemp(Ity_I32);
+                     t3 = newTemp(Ity_I1);
+                     t4 = newTemp(Ity_I32);
+                     t5 = newTemp(Ity_I1);
+                     t6 = newTemp(Ity_I32);
+                     t7 = newTemp(Ity_I1);
+                     t8 = newTemp(Ity_I32);
+
+                     /* Subtract rightmost bytes of rs and rt. */
+                     assign(t0,
+                            binop(Iop_Sub32,
+                                  unop(Iop_8Uto32,
+                                       unop(Iop_16to8,
+                                            unop(Iop_32to16, getIReg(rs)))),
+                                  unop(Iop_8Uto32,
+                                       unop(Iop_16to8,
+                                            unop(Iop_32to16, getIReg(rt))))));
+                     /* t1 will be 1 if there is overflow, 0 otherwise. */
+                     assign(t1, binop(Iop_CmpEQ32,
+                                      binop(Iop_And32,
+                                            mkexpr(t0),
+                                            mkU32(0x00000100)),
+                                      mkU32(0x00000100)));
+
+                     /* Subtract bits 15-8 of rs and rt. */
+                     assign(t2,
+                            binop(Iop_Sub32,
+                                  unop(Iop_8Uto32,
+                                       unop(Iop_16HIto8,
+                                            unop(Iop_32to16, getIReg(rs)))),
+                                  unop(Iop_8Uto32,
+                                       unop(Iop_16HIto8,
+                                            unop(Iop_32to16, getIReg(rt))))));
+                     /* t3 will be 1 if there is overflow, 0 otherwise. */
+                     assign(t3, binop(Iop_CmpEQ32,
+                                      binop(Iop_And32,
+                                            mkexpr(t2),
+                                            mkU32(0x00000100)),
+                                      mkU32(0x00000100)));
+
+                     /* Subtract bits 15-8 of rs and rt. */
+                     assign(t4,
+                            binop(Iop_Sub32,
+                                  unop(Iop_8Uto32,
+                                       unop(Iop_16to8,
+                                            unop(Iop_32HIto16, getIReg(rs)))),
+                                  unop(Iop_8Uto32,
+                                       unop(Iop_16to8,
+                                            unop(Iop_32HIto16, getIReg(rt))))));
+                     /* t5 will be 1 if there is overflow, 0 otherwise. */
+                     assign(t5, binop(Iop_CmpEQ32,
+                                      binop(Iop_And32,
+                                            mkexpr(t4),
+                                            mkU32(0x00000100)),
+                                      mkU32(0x00000100)));
+
+                     /* Subtract bits 15-8 of rs and rt. */
+                     assign(t6,
+                            binop(Iop_Sub32,
+                                  unop(Iop_8Uto32,
+                                       unop(Iop_16HIto8,
+                                            unop(Iop_32HIto16, getIReg(rs)))),
+                                  unop(Iop_8Uto32,
+                                       unop(Iop_16HIto8,
+                                            unop(Iop_32HIto16, getIReg(rt))))));
+                     /* t7 will be 1 if there is overflow, 0 otherwise. */
+                     assign(t7, binop(Iop_CmpEQ32,
+                                      binop(Iop_And32,
+                                            mkexpr(t6),
+                                            mkU32(0x00000100)),
+                                      mkU32(0x00000100)));
+
+                     assign(t8, binop(Iop_Or32,
+                                      binop(Iop_Or32,
+                                            binop(Iop_Or32,
+                                                  unop(Iop_1Sto32, mkexpr(t7)),
+                                                  unop(Iop_1Sto32, mkexpr(t5))),
+                                            unop(Iop_1Sto32, mkexpr(t3))),
+                                      unop(Iop_1Sto32, mkexpr(t1))));
+
+                     putDSPControl(IRExpr_ITE(binop(Iop_CmpEQ32,
+                                                     mkexpr(t8),
+                                                     mkU32(0x0)),
+                                              getDSPControl(),
+                                              binop(Iop_Or32,
+                                                    getDSPControl(),
+                                                    mkU32(0x00100000))));
+
+                     putIReg(rd, binop(Iop_16HLto32,
+                                       binop(Iop_8HLto16,
+                                             unop(Iop_32to8, mkexpr(t6)),
+                                             unop(Iop_32to8, mkexpr(t4))),
+                                       binop(Iop_8HLto16,
+                                             unop(Iop_32to8, mkexpr(t2)),
+                                             unop(Iop_32to8, mkexpr(t0)))));
+                     break;
+                  }
+                  case 0x04: {  /* ADDU_S.QB */
+                     DIP("addu_s.qb r%d, r%d, r%d", rd, rs, rt);
+                     vassert(!mode64);
+                     t0 = newTemp(Ity_I32);
+                     t1 = newTemp(Ity_I1);
+                     t2 = newTemp(Ity_I8);
+                     t3 = newTemp(Ity_I32);
+                     t4 = newTemp(Ity_I1);
+                     t5 = newTemp(Ity_I8);
+                     t6 = newTemp(Ity_I32);
+                     t7 = newTemp(Ity_I1);
+                     t8 = newTemp(Ity_I8);
+                     t9 = newTemp(Ity_I32);
+                     t10 = newTemp(Ity_I1);
+                     t11 = newTemp(Ity_I8);
+                     t12 = newTemp(Ity_I32);
+
+                     /* Add rightmost bytes of rs and rt. */
+                     assign(t0,
+                            binop(Iop_Add32,
+                                  unop(Iop_8Uto32,
+                                       unop(Iop_16to8,
+                                            unop(Iop_32to16, getIReg(rs)))),
+                                  unop(Iop_8Uto32,
+                                       unop(Iop_16to8,
+                                            unop(Iop_32to16, getIReg(rt))))));
+                     /* t1 will be 1 if there is overflow, 0 otherwise. */
+                     assign(t1, binop(Iop_CmpEQ32,
+                                      binop(Iop_And32,
+                                            mkexpr(t0),
+                                            mkU32(0x00000100)),
+                                      mkU32(0x00000100)));
+                     /* Saturate if necessary. */
+                     assign(t2, IRExpr_ITE(mkexpr(t1),
+                                           mkU8(0xff),
+                                           unop(Iop_32to8, mkexpr(t0))));
+
+                     /* Add bits 15-8 of rs and rt. */
+                     assign(t3,
+                            binop(Iop_Add32,
+                                  unop(Iop_8Uto32,
+                                       unop(Iop_16HIto8,
+                                            unop(Iop_32to16, getIReg(rs)))),
+                                  unop(Iop_8Uto32,
+                                       unop(Iop_16HIto8,
+                                            unop(Iop_32to16, getIReg(rt))))));
+                     /* t4 will be 1 if there is overflow, 0 otherwise. */
+                     assign(t4, binop(Iop_CmpEQ32,
+                                      binop(Iop_And32,
+                                            mkexpr(t3),
+                                            mkU32(0x00000100)),
+                                      mkU32(0x00000100)));
+                     /* Saturate if necessary. */
+                     assign(t5, IRExpr_ITE(mkexpr(t4),
+                                           mkU8(0xff),
+                                           unop(Iop_32to8, mkexpr(t3))));
+
+                     /* Add bits 15-8 of rs and rt. */
+                     assign(t6,
+                            binop(Iop_Add32,
+                                  unop(Iop_8Uto32,
+                                       unop(Iop_16to8,
+                                            unop(Iop_32HIto16, getIReg(rs)))),
+                                  unop(Iop_8Uto32,
+                                       unop(Iop_16to8,
+                                            unop(Iop_32HIto16, getIReg(rt))))));
+                     /* t7 will be 1 if there is overflow, 0 otherwise. */
+                     assign(t7, binop(Iop_CmpEQ32,
+                                      binop(Iop_And32,
+                                            mkexpr(t6),
+                                            mkU32(0x00000100)),
+                                      mkU32(0x00000100)));
+                     /* Saturate if necessary. */
+                     assign(t8, IRExpr_ITE(mkexpr(t7),
+                                           mkU8(0xff),
+                                           unop(Iop_32to8, mkexpr(t6))));
+
+                     /* Add bits 15-8 of rs and rt. */
+                     assign(t9,
+                            binop(Iop_Add32,
+                                  unop(Iop_8Uto32,
+                                       unop(Iop_16HIto8,
+                                            unop(Iop_32HIto16, getIReg(rs)))),
+                                  unop(Iop_8Uto32,
+                                       unop(Iop_16HIto8,
+                                            unop(Iop_32HIto16, getIReg(rt))))));
+                     /* t10 will be 1 if there is overflow, 0 otherwise. */
+                     assign(t10, binop(Iop_CmpEQ32,
+                                       binop(Iop_And32,
+                                             mkexpr(t9),
+                                             mkU32(0x00000100)),
+                                       mkU32(0x00000100)));
+                     /* Saturate if necessary. */
+                     assign(t11, IRExpr_ITE(mkexpr(t10),
+                                            mkU8(0xff),
+                                            unop(Iop_32to8, mkexpr(t9))));
+
+                     assign(t12,
+                            binop(Iop_Or32,
+                                  binop(Iop_Or32,
+                                        binop(Iop_Or32,
+                                              unop(Iop_1Sto32, mkexpr(t10)),
+                                              unop(Iop_1Sto32, mkexpr(t7))),
+                                        unop(Iop_1Sto32, mkexpr(t4))),
+                                  unop(Iop_1Sto32, mkexpr(t1))));
+
+                     putDSPControl(IRExpr_ITE(binop(Iop_CmpEQ32,
+                                                    mkexpr(t12),
+                                                    mkU32(0x0)),
+                                              getDSPControl(),
+                                              binop(Iop_Or32,
+                                                    getDSPControl(),
+                                                    mkU32(0x00100000))));
+
+                     putIReg(rd,
+                             binop(Iop_16HLto32,
+                                   binop(Iop_8HLto16, mkexpr(t11), mkexpr(t8)),
+                                   binop(Iop_8HLto16, mkexpr(t5), mkexpr(t2))));
+                     break;
+                  }
+                  case 0x05: {  /* SUBU_S.QB */
+                     DIP("subu_s.qb r%d, r%d, r%d", rd, rs, rt);
+                     vassert(!mode64);
+                     t1 = newTemp(Ity_I32);
+                     t2 = newTemp(Ity_I1);
+                     t3 = newTemp(Ity_I1);
+                     t4 = newTemp(Ity_I1);
+                     t5 = newTemp(Ity_I1);
+                     t6 = newTemp(Ity_I32);
+                     t7 = newTemp(Ity_I32);
+                     t8 = newTemp(Ity_I32);
+                     t9 = newTemp(Ity_I32);
+
+                     /* Use C function to easily calculate the result
+                        and write it in the register more conveniently
+                        Underflow is checked using step by step subtraction. */
+                     assign(t1, binop(Iop_QSub8Ux4, getIReg(rs), getIReg(rt)));
+
+                     /* Subtract each byte of rs and rt. */
+                     assign(t6,
+                            binop(Iop_Sub32,
+                                  unop(Iop_8Uto32,
+                                       unop(Iop_16to8,
+                                            unop(Iop_32to16, getIReg(rs)))),
+                                  unop(Iop_8Uto32,
+                                       unop(Iop_16to8,
+                                            unop(Iop_32to16, getIReg(rt))))));
+                     assign(t7,
+                            binop(Iop_Sub32,
+                                  unop(Iop_8Uto32,
+                                       unop(Iop_16HIto8,
+                                            unop(Iop_32to16, getIReg(rs)))),
+                                  unop(Iop_8Uto32,
+                                       unop(Iop_16HIto8,
+                                            unop(Iop_32to16, getIReg(rt))))));
+                     assign(t8,
+                            binop(Iop_Sub32,
+                                  unop(Iop_8Uto32,
+                                       unop(Iop_16to8,
+                                            unop(Iop_32HIto16, getIReg(rs)))),
+                                  unop(Iop_8Uto32,
+                                       unop(Iop_16to8,
+                                            unop(Iop_32HIto16, getIReg(rt))))));
+                     assign(t9,
+                            binop(Iop_Sub32,
+                                  unop(Iop_8Uto32,
+                                       unop(Iop_16HIto8,
+                                            unop(Iop_32HIto16, getIReg(rs)))),
+                                  unop(Iop_8Uto32,
+                                       unop(Iop_16HIto8,
+                                            unop(Iop_32HIto16, getIReg(rt))))));
+
+                     /* Put 1 to bit 20 in DSPControl if there is underflow
+                        in either byte. */
+                     assign(t2, binop(Iop_CmpEQ32,
+                                      binop(Iop_And32,
+                                            mkexpr(t6),
+                                            mkU32(0x00000100)),
+                                      mkU32(0x00000100)));
+                     putDSPControl(IRExpr_ITE(mkexpr(t2),
+                                              binop(Iop_Or32,
+                                                    getDSPControl(),
+                                                    mkU32(0x00100000)),
+                                              getDSPControl()));
+                     assign(t3, binop(Iop_CmpEQ32,
+                                      binop(Iop_And32,
+                                            mkexpr(t7),
+                                            mkU32(0x00000100)),
+                                      mkU32(0x00000100)));
+                     putDSPControl(IRExpr_ITE(mkexpr(t3),
+                                              binop(Iop_Or32,
+                                                    getDSPControl(),
+                                                    mkU32(0x00100000)),
+                                              getDSPControl()));
+                     assign(t4, binop(Iop_CmpEQ32,
+                                      binop(Iop_And32,
+                                            mkexpr(t8),
+                                            mkU32(0x00000100)),
+                                      mkU32(0x00000100)));
+                     putDSPControl(IRExpr_ITE(mkexpr(t4),
+                                              binop(Iop_Or32,
+                                                    getDSPControl(),
+                                                    mkU32(0x00100000)),
+                                              getDSPControl()));
+                     assign(t5, binop(Iop_CmpEQ32,
+                                      binop(Iop_And32,
+                                            mkexpr(t9),
+                                            mkU32(0x00000100)),
+                                      mkU32(0x00000100)));
+                     putDSPControl(IRExpr_ITE(mkexpr(t5),
+                                              binop(Iop_Or32,
+                                                    getDSPControl(),
+                                                    mkU32(0x00100000)),
+                                              getDSPControl()));
+                     putIReg(rd, mkexpr(t1));
+                     break;
+                  }
+                  case 0x6: {  /* MULEU_S.PH.QBL */
+                     DIP("muleu_s.ph.qbl r%d, r%d, r%d", rd, rs, rt);
+                     vassert(!mode64);
+                     t0 = newTemp(Ity_I32);
+                     t1 = newTemp(Ity_I32);
+                     t2 = newTemp(Ity_I1);
+                     t3 = newTemp(Ity_I1);
+
+                     assign(t0,
+                            unop(Iop_64to32,
+                                 binop(Iop_MullU32,
+                                       unop(Iop_8Uto32,
+                                            unop(Iop_16HIto8,
+                                                 unop(Iop_32HIto16,
+                                                      getIReg(rs)))),
+                                       unop(Iop_16Uto32,
+                                            unop(Iop_32HIto16, getIReg(rt))))));
+                     assign(t1,
+                            unop(Iop_64to32,
+                                 binop(Iop_MullU32,
+                                       unop(Iop_8Uto32,
+                                            unop(Iop_16to8,
+                                                 unop(Iop_32HIto16,
+                                                      getIReg(rs)))),
+                                       unop(Iop_16Uto32,
+                                            unop(Iop_32to16, getIReg(rt))))));
+
+                     assign(t2, binop(Iop_CmpNE32,
+                                      mkU32(0x0),
+                                      binop(Iop_And32,
+                                            mkexpr(t0),
+                                            mkU32(0x03ff0000))));
+                     assign(t3, binop(Iop_CmpNE32,
+                                      mkU32(0x0),
+                                      binop(Iop_And32,
+                                            mkexpr(t1),
+                                            mkU32(0x03ff0000))));
+                     putDSPControl(IRExpr_ITE(mkexpr(t2),
+                                              binop(Iop_Or32,
+                                                    getDSPControl(),
+                                                    mkU32(0x200000)),
+                                              IRExpr_ITE(mkexpr(t3),
+                                                         binop(Iop_Or32,
+                                                               getDSPControl(),
+                                                               mkU32(0x200000)),
+                                                         getDSPControl())));
+                     putIReg(rd,
+                             binop(Iop_16HLto32,
+                                   IRExpr_ITE(mkexpr(t2),
+                                              mkU16(0xffff),
+                                              unop(Iop_32to16, mkexpr(t0))),
+                                   IRExpr_ITE(mkexpr(t3),
+                                              mkU16(0xffff),
+                                              unop(Iop_32to16, mkexpr(t1)))));
+                     break;
+                  }
+                  case 0x7: {  /* MULEU_S.PH.QBR */
+                     DIP("muleu_s.ph.qbr r%d, r%d, r%d", rd, rs, rt);
+                     vassert(!mode64);
+                     t0 = newTemp(Ity_I32);
+                     t1 = newTemp(Ity_I32);
+                     t2 = newTemp(Ity_I1);
+                     t3 = newTemp(Ity_I1);
+
+                     assign(t0, unop(Iop_64to32,
+                                     binop(Iop_MullU32,
+                                           unop(Iop_8Uto32,
+                                                unop(Iop_16HIto8,
+                                                     unop(Iop_32to16,
+                                                          getIReg(rs)))),
+                                           unop(Iop_16Uto32,
+                                                unop(Iop_32HIto16,
+                                                     getIReg(rt))))));
+                     assign(t1, unop(Iop_64to32,
+                                     binop(Iop_MullU32,
+                                           unop(Iop_8Uto32,
+                                                unop(Iop_16to8,
+                                                     unop(Iop_32to16,
+                                                          getIReg(rs)))),
+                                           unop(Iop_16Uto32,
+                                                unop(Iop_32to16,
+                                                     getIReg(rt))))));
+
+                     assign(t2, binop(Iop_CmpNE32,
+                                      mkU32(0x0),
+                                      binop(Iop_And32,
+                                            mkexpr(t0),
+                                            mkU32(0x03ff0000))));
+                     assign(t3, binop(Iop_CmpNE32,
+                                      mkU32(0x0),
+                                      binop(Iop_And32,
+                                            mkexpr(t1),
+                                            mkU32(0x03ff0000))));
+                     putDSPControl(IRExpr_ITE(mkexpr(t2),
+                                              binop(Iop_Or32,
+                                                    getDSPControl(),
+                                                    mkU32(0x200000)),
+                                              IRExpr_ITE(mkexpr(t3),
+                                                         binop(Iop_Or32,
+                                                               getDSPControl(),
+                                                               mkU32(0x200000)),
+                                                         getDSPControl())));
+                     putIReg(rd, binop(Iop_16HLto32,
+                                       IRExpr_ITE(mkexpr(t2),
+                                                  mkU16(0xffff),
+                                                  unop(Iop_32to16,
+                                                       mkexpr(t0))),
+                                       IRExpr_ITE(mkexpr(t3),
+                                                  mkU16(0xffff),
+                                                  unop(Iop_32to16,
+                                                       mkexpr(t1)))));
+                     break;
+                  }
+                  case 0x08: {  /* ADDU.PH */
+                     DIP("addu.ph r%d, r%d, r%d", rd, rs, rt);
+                     vassert(!mode64);
+                     t0 = newTemp(Ity_I32);
+                     t1 = newTemp(Ity_I1);
+                     t2 = newTemp(Ity_I32);
+                     t3 = newTemp(Ity_I1);
+
+                     /* Add lower halves. */
+                     assign(t0, binop(Iop_Add32,
+                                      unop(Iop_16Uto32,
+                                           unop(Iop_32to16, getIReg(rs))),
+                                      unop(Iop_16Uto32,
+                                           unop(Iop_32to16, getIReg(rt)))));
+
+                     /* Detect overflow. */
+                     assign(t1, binop(Iop_CmpLT32U,
+                                      unop(Iop_16Uto32,
+                                           unop(Iop_32to16, mkexpr(t0))),
+                                      unop(Iop_16Uto32,
+                                           unop(Iop_32to16, getIReg(rs)))));
+
+                     putDSPControl(IRExpr_ITE(mkexpr(t1),
+                                              binop(Iop_Or32,
+                                                    getDSPControl(),
+                                                    mkU32(0x00100000)),
+                                              getDSPControl()));
+
+                     /* Add higher halves. */
+                     assign(t2, binop(Iop_Add32,
+                                      unop(Iop_16Uto32,
+                                           unop(Iop_32HIto16, getIReg(rs))),
+                                      unop(Iop_16Uto32,
+                                           unop(Iop_32HIto16, getIReg(rt)))));
+
+                     /* Detect overflow. */
+                     assign(t3, binop(Iop_CmpLT32U,
+                                      unop(Iop_16Uto32,
+                                           unop(Iop_32to16, mkexpr(t2))),
+                                      unop(Iop_16Uto32,
+                                           unop(Iop_32HIto16,
+                                                getIReg(rs)))));
+
+                     putDSPControl(IRExpr_ITE(mkexpr(t3),
+                                              binop(Iop_Or32,
+                                                    getDSPControl(),
+                                                    mkU32(0x00100000)),
+                                              getDSPControl()));
+
+                     putIReg(rd, binop(Iop_16HLto32,
+                                       unop(Iop_32to16, mkexpr(t2)),
+                                       unop(Iop_32to16, mkexpr(t0))));
+                     break;
+                  }
+                  case 0x9: {  /* SUBU.PH */
+                     DIP("subu.ph r%d, r%d, r%d", rd, rs, rt);
+                     vassert(!mode64);
+                     t0 = newTemp(Ity_I32);
+                     t1 = newTemp(Ity_I1);
+                     t2 = newTemp(Ity_I32);
+                     t3 = newTemp(Ity_I1);
+
+                     /* Substract lower halves. */
+                     assign(t0, binop(Iop_Sub32,
+                                      unop(Iop_16Uto32,
+                                           unop(Iop_32to16, getIReg(rs))),
+                                      unop(Iop_16Uto32,
+                                           unop(Iop_32to16, getIReg(rt)))));
+
+                     /* Detect underflow. */
+                     assign(t1, binop(Iop_CmpNE32,
+                                      binop(Iop_And32,
+                                            mkexpr(t0),
+                                            mkU32(0x00010000)),
+                                      mkU32(0x0)));
+
+                     putDSPControl(IRExpr_ITE(mkexpr(t1),
+                                              binop(Iop_Or32,
+                                                    getDSPControl(),
+                                                    mkU32(0x00100000)),
+                                              getDSPControl()));
+
+                     /* Subtract higher halves. */
+                     assign(t2, binop(Iop_Sub32,
+                                      unop(Iop_16Uto32,
+                                           unop(Iop_32HIto16, getIReg(rs))),
+                                      unop(Iop_16Uto32,
+                                           unop(Iop_32HIto16, getIReg(rt)))));
+
+                     /* Detect underflow. */
+                     assign(t3, binop(Iop_CmpNE32,
+                                      binop(Iop_And32,
+                                            mkexpr(t2),
+                                            mkU32(0x00010000)),
+                                      mkU32(0x0)));
+
+                     putDSPControl(IRExpr_ITE(mkexpr(t3),
+                                              binop(Iop_Or32,
+                                                    getDSPControl(),
+                                                    mkU32(0x00100000)),
+                                              getDSPControl()));
+
+                     putIReg(rd, binop(Iop_16HLto32,
+                                       unop(Iop_32to16, mkexpr(t2)),
+                                       unop(Iop_32to16, mkexpr(t0))));
+                     break;
+                  }
+                  case 0xA: {  /* ADDQ.PH */
+                     DIP("addq.ph r%d, r%d, r%d", rd, rs, rt);
+                     vassert(!mode64);
+                     t0 = newTemp(Ity_I32);
+                     t1 = newTemp(Ity_I1);
+                     t2 = newTemp(Ity_I32);
+                     t3 = newTemp(Ity_I1);
+                     t6 = newTemp(Ity_I32);
+                     t7 = newTemp(Ity_I32);
+
+                     /* Add lower halves. */
+                     assign(t0, binop(Iop_Add32,
+                                      unop(Iop_16Sto32,
+                                           unop(Iop_32to16, getIReg(rs))),
+                                      unop(Iop_16Sto32,
+                                           unop(Iop_32to16, getIReg(rt)))));
+
+                     /* Bit 16 of the result. */
+                     assign(t6, binop(Iop_And32,
+                                      unop(Iop_16Uto32,
+                                           unop(Iop_32HIto16, mkexpr(t0))),
+                                      mkU32(0x1)));
+                     /* Detect overflow. */
+                     assign(t1, binop(Iop_CmpNE32,
+                                      binop(Iop_Shr32,
+                                            binop(Iop_And32,
+                                                  mkexpr(t0),
+                                                  mkU32(0x8000)),
+                                            mkU8(15)),
+                                      mkexpr(t6)));
+
+                     putDSPControl(IRExpr_ITE(mkexpr(t1),
+                                              binop(Iop_Or32,
+                                                    getDSPControl(),
+                                                    mkU32(0x00100000)),
+                                              getDSPControl()));
+
+                     /* Add higher halves. */
+                     assign(t2, binop(Iop_Add32,
+                                      unop(Iop_16Sto32,
+                                           unop(Iop_32HIto16, getIReg(rs))),
+                                      unop(Iop_16Sto32,
+                                           unop(Iop_32HIto16, getIReg(rt)))));
+
+                     /* Bit 16 of the result. */
+                     assign(t7, binop(Iop_And32,
+                                      unop(Iop_16Uto32,
+                                           unop(Iop_32HIto16, mkexpr(t2))),
+                                      mkU32(0x1)));
+                     /* Detect overflow. */
+                     assign(t3, binop(Iop_CmpNE32,
+                                      binop(Iop_Shr32,
+                                            binop(Iop_And32,
+                                                  mkexpr(t2),
+                                                  mkU32(0x00008000)),
+                                            mkU8(15)),
+                                      mkexpr(t7)));
+
+                     putDSPControl(IRExpr_ITE(mkexpr(t3),
+                                              binop(Iop_Or32,
+                                                    getDSPControl(),
+                                                    mkU32(0x00100000)),
+                                              getDSPControl()));
+
+                     putIReg(rd, binop(Iop_16HLto32,
+                                       unop(Iop_32to16, mkexpr(t2)),
+                                       unop(Iop_32to16, mkexpr(t0))));
+                     break;
+                  }
+                  case 0xB: {  /* SUBQ.PH */
+                     DIP("subq.ph r%d, r%d, r%d", rd, rs, rt);
+                     vassert(!mode64);
+                     t0 = newTemp(Ity_I32);
+                     t1 = newTemp(Ity_I1);
+                     t2 = newTemp(Ity_I32);
+                     t3 = newTemp(Ity_I1);
+                     t6 = newTemp(Ity_I32);
+                     t7 = newTemp(Ity_I32);
+
+                     /* Subtract lower halves. */
+                     assign(t0, binop(Iop_Sub32,
+                                      unop(Iop_16Sto32,
+                                           unop(Iop_32to16, getIReg(rs))),
+                                      unop(Iop_16Sto32,
+                                           unop(Iop_32to16, getIReg(rt)))));
+
+                     /* Bit 16 of the result. */
+                     assign(t6, binop(Iop_And32,
+                                      unop(Iop_16Uto32,
+                                           unop(Iop_32HIto16, mkexpr(t0))),
+                                      mkU32(0x1)));
+                     /* Compare the signs of input value and the result. */
+                     assign(t1, binop(Iop_CmpNE32,
+                                      binop(Iop_Shr32,
+                                            binop(Iop_And32,
+                                                  mkexpr(t0),
+                                                  mkU32(0x8000)),
+                                            mkU8(15)),
+                                      mkexpr(t6)));
+
+                     putDSPControl(IRExpr_ITE(mkexpr(t1),
+                                              binop(Iop_Or32,
+                                                    getDSPControl(),
+                                                    mkU32(0x00100000)),
+                                              getDSPControl()));
+
+                     /* Subtract higher halves. */
+                     assign(t2, binop(Iop_Sub32,
+                                      unop(Iop_16Sto32,
+                                           unop(Iop_32HIto16, getIReg(rs))),
+                                      unop(Iop_16Sto32,
+                                           unop(Iop_32HIto16, getIReg(rt)))));
+
+                     /* Bit 16 of the result. */
+                     assign(t7, binop(Iop_And32,
+                                      unop(Iop_16Uto32,
+                                           unop(Iop_32HIto16, mkexpr(t2))),
+                                      mkU32(0x1)));
+                     /* Compare the signs of input value and the result. */
+                     assign(t3, binop(Iop_CmpNE32,
+                                      binop(Iop_Shr32,
+                                            binop(Iop_And32,
+                                                  mkexpr(t2),
+                                                  mkU32(0x00008000)),
+                                            mkU8(15)),
+                                      mkexpr(t7)));
+
+                     putDSPControl(IRExpr_ITE(mkexpr(t3),
+                                              binop(Iop_Or32,
+                                                    getDSPControl(),
+                                                    mkU32(0x00100000)),
+                                              getDSPControl()));
+
+                     putIReg(rd, binop(Iop_16HLto32,
+                                       unop(Iop_32to16, mkexpr(t2)),
+                                       unop(Iop_32to16, mkexpr(t0))));
+                     break;
+                  }
+                  case 0xC: {  /* ADDU_S.PH */
+                     DIP("addu_s.ph r%d, r%d, r%d", rd, rs, rt);
+                     vassert(!mode64);
+                     t0 = newTemp(Ity_I32);
+                     t1 = newTemp(Ity_I1);
+                     t2 = newTemp(Ity_I32);
+                     t3 = newTemp(Ity_I1);
+
+                     /* Add lower halves. */
+                     assign(t0, binop(Iop_Add32,
+                                      unop(Iop_16Uto32,
+                                           unop(Iop_32to16, getIReg(rs))),
+                                      unop(Iop_16Uto32,
+                                           unop(Iop_32to16, getIReg(rt)))));
+
+                     /* Detect overflow. */
+                     assign(t1, binop(Iop_CmpLT32U,
+                                      unop(Iop_16Uto32,
+                                           unop(Iop_32to16, mkexpr(t0))),
+                                      unop(Iop_16Uto32,
+                                           unop(Iop_32to16, getIReg(rs)))));
+
+                     putDSPControl(IRExpr_ITE(mkexpr(t1),
+                                              binop(Iop_Or32,
+                                                    getDSPControl(),
+                                                    mkU32(0x00100000)),
+                                              getDSPControl()));
+
+                     /* Add higher halves. */
+                     assign(t2, binop(Iop_Add32,
+                                      unop(Iop_16Uto32,
+                                           unop(Iop_32HIto16, getIReg(rs))),
+                                      unop(Iop_16Uto32,
+                                           unop(Iop_32HIto16, getIReg(rt)))));
+
+                     /* Detect overflow. */
+                     assign(t3, binop(Iop_CmpLT32U,
+                                      unop(Iop_16Uto32,
+                                           unop(Iop_32to16, mkexpr(t2))),
+                                      unop(Iop_16Uto32,
+                                           unop(Iop_32HIto16, getIReg(rs)))));
+
+                     putDSPControl(IRExpr_ITE(mkexpr(t3),
+                                              binop(Iop_Or32,
+                                                    getDSPControl(),
+                                                    mkU32(0x00100000)),
+                                              getDSPControl()));
+
+                     putIReg(rd, binop(Iop_16HLto32,
+                                       IRExpr_ITE(mkexpr(t3),
+                                                  mkU16(0xffff),
+                                                  unop(Iop_32to16,
+                                                       mkexpr(t2))),
+                                       IRExpr_ITE(mkexpr(t1),
+                                                  mkU16(0xffff),
+                                                  unop(Iop_32to16,
+                                                       mkexpr(t0)))));
+                     break;
+                  }
+                  case 0xD: {  /* SUBU_S.PH */
+                     DIP("subu_s.ph r%d, r%d, r%d", rd, rs, rt);
+                     vassert(!mode64);
+                     t0 = newTemp(Ity_I32);
+                     t1 = newTemp(Ity_I1);
+                     t2 = newTemp(Ity_I32);
+                     t3 = newTemp(Ity_I1);
+
+                     /* Subtract lower halves. */
+                     assign(t0, binop(Iop_Sub32,
+                                      unop(Iop_16Uto32,
+                                           unop(Iop_32to16, getIReg(rs))),
+                                      unop(Iop_16Uto32,
+                                           unop(Iop_32to16, getIReg(rt)))));
+
+                     /* Detect underflow. */
+                     assign(t1, binop(Iop_CmpNE32,
+                                      binop(Iop_And32,
+                                            mkexpr(t0), mkU32(0x00010000)),
+                                      mkU32(0x0)));
+
+                     putDSPControl(IRExpr_ITE(mkexpr(t1),
+                                              binop(Iop_Or32,
+                                                    getDSPControl(),
+                                                    mkU32(0x00100000)),
+                                              getDSPControl()));
+
+                     /* Subtract higher halves. */
+                     assign(t2, binop(Iop_Sub32,
+                                      unop(Iop_16Uto32,
+                                           unop(Iop_32HIto16, getIReg(rs))),
+                                      unop(Iop_16Uto32,
+                                           unop(Iop_32HIto16, getIReg(rt)))));
+
+                     /* Detect underflow. */
+                     assign(t3, binop(Iop_CmpNE32,
+                                      binop(Iop_And32,
+                                            mkexpr(t2), mkU32(0x00010000)),
+                                      mkU32(0x0)));
+
+                     putDSPControl(IRExpr_ITE(mkexpr(t3),
+                                              binop(Iop_Or32,
+                                                    getDSPControl(),
+                                                    mkU32(0x00100000)),
+                                              getDSPControl()));
+
+                     putIReg(rd,
+                             binop(Iop_16HLto32,
+                                   IRExpr_ITE(mkexpr(t3),
+                                              mkU16(0x0000),
+                                              unop(Iop_32to16, mkexpr(t2))),
+                                   IRExpr_ITE(mkexpr(t1),
+                                              mkU16(0x0000),
+                                              unop(Iop_32to16, mkexpr(t0)))));
+                     break;
+                  }
+                  case 0xE: {  /* ADDQ_S.PH */
+                     DIP("addq_s.ph r%d r%d, r%d", rd, rs, rt);
+                     vassert(!mode64);
+                     t0 = newTemp(Ity_I32);
+                     t1 = newTemp(Ity_I1);
+                     t2 = newTemp(Ity_I32);
+                     t3 = newTemp(Ity_I1);
+                     t4 = newTemp(Ity_I16);
+                     t5 = newTemp(Ity_I16);
+                     t6 = newTemp(Ity_I32);
+                     t7 = newTemp(Ity_I32);
+
+                     /* Add lower halves. */
+                     assign(t0, binop(Iop_Add32,
+                                      unop(Iop_16Sto32,
+                                           unop(Iop_32to16, getIReg(rs))),
+                                      unop(Iop_16Sto32,
+                                           unop(Iop_32to16, getIReg(rt)))));
+
+                     /* Bit 16 of the result. */
+                     assign(t6, binop(Iop_And32,
+                                      unop(Iop_16Uto32,
+                                           unop(Iop_32HIto16, mkexpr(t0))),
+                                      mkU32(0x1)));
+                     /* Detect overflow. */
+                     assign(t1, binop(Iop_CmpNE32,
+                                      binop(Iop_Shr32,
+                                            binop(Iop_And32,
+                                                  mkexpr(t0),
+                                                  mkU32(0x8000)),
+                                            mkU8(15)),
+                                      mkexpr(t6)));
+
+                     putDSPControl(IRExpr_ITE(mkexpr(t1),
+                                              binop(Iop_Or32,
+                                                    getDSPControl(),
+                                                    mkU32(0x00100000)),
+                                              getDSPControl()));
+                     /* Saturate if needed. */
+                     assign(t4, IRExpr_ITE(mkexpr(t1),
+                                           IRExpr_ITE(binop(Iop_CmpEQ32,
+                                                            mkexpr(t6),
+                                                            mkU32(0x0)),
+                                                      mkU16(0x7fff),
+                                                      mkU16(0x8000)),
+                                           unop(Iop_32to16, mkexpr(t0))));
+
+                     /* Add higher halves. */
+                     assign(t2, binop(Iop_Add32,
+                                      unop(Iop_16Sto32,
+                                           unop(Iop_32HIto16, getIReg(rs))),
+                                      unop(Iop_16Sto32,
+                                           unop(Iop_32HIto16, getIReg(rt)))));
+
+                     /* Bit 16 of the result. */
+                     assign(t7, binop(Iop_And32,
+                                      unop(Iop_16Uto32,
+                                           unop(Iop_32HIto16, mkexpr(t2))),
+                                      mkU32(0x1)));
+                     /* Detect overflow. */
+                     assign(t3, binop(Iop_CmpNE32,
+                                      binop(Iop_Shr32,
+                                            binop(Iop_And32,
+                                                  mkexpr(t2),
+                                                  mkU32(0x00008000)),
+                                            mkU8(15)),
+                                      mkexpr(t7)));
+
+                     putDSPControl(IRExpr_ITE(mkexpr(t3),
+                                              binop(Iop_Or32,
+                                                    getDSPControl(),
+                                                    mkU32(0x00100000)),
+                                              getDSPControl()));
+                     /* Saturate if needed. */
+                     assign(t5, IRExpr_ITE(mkexpr(t3),
+                                           IRExpr_ITE(binop(Iop_CmpEQ32,
+                                                            mkexpr(t7),
+                                                            mkU32(0x0)),
+                                                      mkU16(0x7fff),
+                                                      mkU16(0x8000)),
+                                           unop(Iop_32to16, mkexpr(t2))));
+
+                     putIReg(rd, binop(Iop_16HLto32, mkexpr(t5), mkexpr(t4)));
+                     break;
+                  }
+                  case 0xF: {  /* SUBQ_S.PH */
+                     DIP("subq_s.ph r%d r%d, r%d", rd, rs, rt);
+                     vassert(!mode64);
+                     t0 = newTemp(Ity_I32);
+                     t1 = newTemp(Ity_I1);
+                     t2 = newTemp(Ity_I32);
+                     t3 = newTemp(Ity_I1);
+                     t4 = newTemp(Ity_I16);
+                     t5 = newTemp(Ity_I16);
+                     t6 = newTemp(Ity_I32);
+                     t7 = newTemp(Ity_I32);
+
+                     /* Subtract lower halves. */
+                     assign(t0, binop(Iop_Sub32,
+                                      unop(Iop_16Sto32,
+                                           unop(Iop_32to16, getIReg(rs))),
+                                      unop(Iop_16Sto32,
+                                           unop(Iop_32to16, getIReg(rt)))));
+
+                     /* Bit 16 of the result. */
+                     assign(t6, binop(Iop_And32,
+                                      unop(Iop_16Uto32,
+                                           unop(Iop_32HIto16, mkexpr(t0))),
+                                      mkU32(0x1)));
+                     /* Detect overflow or underflow. */
+                     assign(t1, binop(Iop_CmpNE32,
+                                      binop(Iop_Shr32,
+                                            binop(Iop_And32,
+                                                  mkexpr(t0),
+                                                  mkU32(0x8000)),
+                                            mkU8(15)),
+                                      mkexpr(t6)));
+
+                     putDSPControl(IRExpr_ITE(mkexpr(t1),
+                                              binop(Iop_Or32,
+                                                    getDSPControl(),
+                                                    mkU32(0x00100000)),
+                                              getDSPControl()));
+                     /* Saturate if needed. */
+                     assign(t4, IRExpr_ITE(mkexpr(t1),
+                                           IRExpr_ITE(binop(Iop_CmpEQ32,
+                                                            mkexpr(t6),
+                                                            mkU32(0x0)),
+                                                      mkU16(0x7fff),
+                                                      mkU16(0x8000)),
+                                           unop(Iop_32to16, mkexpr(t0))));
+
+                     /* Subtract higher halves. */
+                     assign(t2, binop(Iop_Sub32,
+                                      unop(Iop_16Sto32,
+                                           unop(Iop_32HIto16, getIReg(rs))),
+                                      unop(Iop_16Sto32,
+                                           unop(Iop_32HIto16, getIReg(rt)))));
+
+                     /* Bit 16 of the result. */
+                     assign(t7, binop(Iop_And32,
+                                      unop(Iop_16Uto32,
+                                           unop(Iop_32HIto16, mkexpr(t2))),
+                                      mkU32(0x1)));
+                     /* Detect overflow or underflow. */
+                     assign(t3, binop(Iop_CmpNE32,
+                                      binop(Iop_Shr32,
+                                            binop(Iop_And32,
+                                                  mkexpr(t2),
+                                                  mkU32(0x00008000)),
+                                            mkU8(15)),
+                                      mkexpr(t7)));
+
+                     putDSPControl(IRExpr_ITE(mkexpr(t3),
+                                              binop(Iop_Or32,
+                                                    getDSPControl(),
+                                                    mkU32(0x00100000)),
+                                              getDSPControl()));
+                     /* Saturate if needed. */
+                     assign(t5, IRExpr_ITE(mkexpr(t3),
+                                           IRExpr_ITE(binop(Iop_CmpEQ32,
+                                                            mkexpr(t7),
+                                                            mkU32(0x0)),
+                                                      mkU16(0x7fff),
+                                                      mkU16(0x8000)),
+                                           unop(Iop_32to16, mkexpr(t2))));
+
+                     putIReg(rd, binop(Iop_16HLto32, mkexpr(t5), mkexpr(t4)));
+                     break;
+                  }
+                  case 0x10: {  /* ADDSC */
+                     DIP("addsc r%d, r%d, r%d", rd, rs, rt);
+                     vassert(!mode64);
+                     t0 = newTemp(Ity_I64);
+                     t1 = newTemp(Ity_I1);
+
+                     /* The carry bit result out of the addition operation is
+                        written to bit 13(the c field) of the DSPControl reg. */
+                     assign(t0, binop(Iop_Add64,
+                                      unop(Iop_32Uto64, getIReg(rs)),
+                                      unop(Iop_32Uto64, getIReg(rt))));
+
+                     assign(t1, binop(Iop_CmpEQ32,
+                                      binop(Iop_And32,
+                                            unop(Iop_64HIto32, mkexpr(t0)),
+                                            mkU32(0x1)),
+                                      mkU32(0x1)));
+                     putDSPControl(IRExpr_ITE(mkexpr(t1),
+                                              binop(Iop_Or32,
+                                                    getDSPControl(),
+                                                    mkU32(0x2000)),
+                                              binop(Iop_And32,
+                                                    getDSPControl(),
+                                                    mkU32(0xffffdfff))));
+
+                     putIReg(rd, unop(Iop_64to32, mkexpr(t0)));
+                     break;
+                  }
+                  case 0x11: {  /* ADDWC */
+                     DIP("addwc r%d, r%d, r%d", rd, rs, rt);
+                     vassert(!mode64);
+                     t0 = newTemp(Ity_I32);
+                     t1 = newTemp(Ity_I64);
+                     t2 = newTemp(Ity_I32);
+                     t3 = newTemp(Ity_I32);
+                     t4 = newTemp(Ity_I1);
+
+                     /* Get carry bit from DSPControl register. */
+                     assign(t0, binop(Iop_Shr32,
+                                       binop(Iop_And32,
+                                             getDSPControl(),
+                                             mkU32(0x2000)),
+                                       mkU8(0xd)));
+                     assign(t1, binop(Iop_Add64,
+                                      unop(Iop_32Sto64, getIReg(rs)),
+                                      unop(Iop_32Sto64,
+                                           binop(Iop_Add32,
+                                                 getIReg(rt),
+                                                 mkexpr(t0)))));
+
+                     /* Extract bits 32 and 31. */
+                     assign(t2, binop(Iop_And32,
+                                      unop(Iop_64HIto32, mkexpr(t1)),
+                                      mkU32(0x1)));
+                     assign(t3, binop(Iop_Shr32,
+                                      binop(Iop_And32,
+                                            unop(Iop_64to32, mkexpr(t1)),
+                                            mkU32(0x80000000)),
+                                      mkU8(31)));
+                     assign(t4, binop(Iop_CmpNE32, mkexpr(t2), mkexpr(t3)));
+
+                     putDSPControl(IRExpr_ITE(mkexpr(t4),
+                                              binop(Iop_Or32,
+                                                    getDSPControl(),
+                                                    mkU32(0x00100000)),
+                                              getDSPControl()));
+                     putIReg(rd, unop(Iop_64to32, mkexpr(t1)));
+                     break;
+                  }
+                  case 0x12: {  /* MODSUB */
+                     DIP("modsub r%d, r%d, r%d", rd, rs, rt);
+                     vassert(!mode64);
+                     t0 = newTemp(Ity_I32);
+                     t1 = newTemp(Ity_I32);
+                     t2 = newTemp(Ity_I32);
+
+                     /* decr_7..0 */
+                     assign(t0,
+                            unop(Iop_8Uto32,
+                                 unop(Iop_16to8,
+                                      unop(Iop_32to16, getIReg(rt)))));
+
+                     /* lastindex_15..0 */
+                     assign(t1,
+                            unop(Iop_16Uto32,
+                                 binop(Iop_8HLto16,
+                                       unop(Iop_16to8,
+                                            unop(Iop_32HIto16, getIReg(rt))),
+                                       unop(Iop_16HIto8,
+                                            unop(Iop_32to16, getIReg(rt))))));
+                     /* temp_15..0 */
+                     assign(t2,
+                            IRExpr_ITE(binop(Iop_CmpEQ32,
+                                             getIReg(rs),
+                                             mkU32(0x00000000)),
+                                       mkexpr(t1),
+                                       binop(Iop_Sub32,
+                                             getIReg(rs), mkexpr(t0))));
+                     putIReg(rd, mkexpr(t2));
+                     break;
+                  }
+                  case 0x14: {  /* RADDU.W.QB */
+                     DIP("raddu.w.qb r%d, r%d", rd, rs);
+                     vassert(!mode64);
+                     putIReg(rd, binop(Iop_Add32,
+                                       binop(Iop_Add32,
+                                             unop(Iop_8Uto32,
+                                                  unop(Iop_16to8,
+                                                       unop(Iop_32to16,
+                                                            getIReg(rs)))),
+                                             unop(Iop_8Uto32,
+                                                  unop(Iop_16HIto8,
+                                                       unop(Iop_32to16,
+                                                            getIReg(rs))))),
+                                       binop(Iop_Add32,
+                                             unop(Iop_8Uto32,
+                                                  unop(Iop_16to8,
+                                                       unop(Iop_32HIto16,
+                                                            getIReg(rs)))),
+                                             unop(Iop_8Uto32,
+                                                  unop(Iop_16HIto8,
+                                                       unop(Iop_32HIto16,
+                                                            getIReg(rs)))))));
+                     break;
+                  }
+                  case 0x16: {  /* ADDQ_S.W */
+                     DIP("addq_s.w r%d, r%d, r%d", rd, rs, rt);
+                     vassert(!mode64);
+                     t0 = newTemp(Ity_I64);
+                     t1 = newTemp(Ity_I1);
+                     t2 = newTemp(Ity_I32);
+                     t3 = newTemp(Ity_I32);
+
+                     assign(t0, binop(Iop_Add64,
+                                      unop(Iop_32Sto64, getIReg(rs)),
+                                      unop(Iop_32Sto64, getIReg(rt))));
+
+                     assign(t3, binop(Iop_And32,
+                                      unop(Iop_64HIto32, mkexpr(t0)),
+                                      mkU32(0x1)));
+                     assign(t1, binop(Iop_CmpNE32,
+                                      binop(Iop_Shr32,
+                                            binop(Iop_And32,
+                                                  unop(Iop_64to32, mkexpr(t0)),
+                                                  mkU32(0x80000000)),
+                                            mkU8(31)),
+                                      mkexpr(t3)));
+
+                     putDSPControl(IRExpr_ITE(mkexpr(t1),
+                                              binop(Iop_Or32,
+                                                    getDSPControl(),
+                                                    mkU32(0x00100000)),
+                                              getDSPControl()));
+
+                     putIReg(rd, IRExpr_ITE(mkexpr(t1),
+                                            IRExpr_ITE(binop(Iop_CmpEQ32,
+                                                             mkexpr(t3),
+                                                             mkU32(0x0)),
+                                                       mkU32(0x7fffffff),
+                                                       mkU32(0x80000000)),
+                                            unop(Iop_64to32, mkexpr(t0))));
+                     break;
+                  }
+                  case 0x17: {  /* SUBQ_S.W */
+                     DIP("subq_s.w r%d, r%d, r%d", rd, rs, rt);
+                     vassert(!mode64);
+                     t0 = newTemp(Ity_I64);
+                     t1 = newTemp(Ity_I1);
+                     t2 = newTemp(Ity_I32);
+                     t3 = newTemp(Ity_I32);
+
+                     assign(t0, binop(Iop_Sub64,
+                                      unop(Iop_32Sto64, getIReg(rs)),
+                                      unop(Iop_32Sto64, getIReg(rt))));
+
+                     assign(t3, binop(Iop_And32,
+                                      unop(Iop_64HIto32, mkexpr(t0)),
+                                      mkU32(0x1)));
+                     assign(t1, binop(Iop_CmpNE32,
+                                      binop(Iop_Shr32,
+                                            binop(Iop_And32,
+                                                  unop(Iop_64to32, mkexpr(t0)),
+                                                  mkU32(0x80000000)),
+                                            mkU8(31)),
+                                      mkexpr(t3)));
+
+                     putDSPControl(IRExpr_ITE(mkexpr(t1),
+                                              binop(Iop_Or32,
+                                                    getDSPControl(),
+                                                    mkU32(0x00100000)),
+                                              getDSPControl()));
+
+                     putIReg(rd, IRExpr_ITE(mkexpr(t1),
+                                            IRExpr_ITE(binop(Iop_CmpEQ32,
+                                                             mkexpr(t3),
+                                                             mkU32(0x0)),
+                                                       mkU32(0x7fffffff),
+                                                       mkU32(0x80000000)),
+                                            unop(Iop_64to32, mkexpr(t0))));
+                     break;
+                  }
+                  case 0x1C: {  /* MULEQ_S.W.PHL */
+                     DIP("muleq_s.w.phl r%d, r%d, r%d", rd, rs, rt);
+                     vassert(!mode64);
+                     t0 = newTemp(Ity_I32);
+                     t1 = newTemp(Ity_I1);
+                     t2 = newTemp(Ity_I1);
+                     t3 = newTemp(Ity_I32);
+
+                     assign(t0,
+                            binop(Iop_Shl32,
+                                  binop(Iop_Mul32,
+                                        unop(Iop_16Sto32,
+                                             unop(Iop_32HIto16, getIReg(rt))),
+                                        unop(Iop_16Sto32,
+                                             unop(Iop_32HIto16, getIReg(rs)))),
+                                  mkU8(0x1)));
+                     assign(t1, binop(Iop_CmpEQ32,
+                                      binop(Iop_And32,
+                                            getIReg(rt),
+                                            mkU32(0xffff0000)),
+                                      mkU32(0x80000000)));
+                     assign(t2, binop(Iop_CmpEQ32,
+                                      binop(Iop_And32,
+                                            getIReg(rs),
+                                            mkU32(0xffff0000)),
+                                      mkU32(0x80000000)));
+                     assign(t3, IRExpr_ITE(mkexpr(t1),
+                                           IRExpr_ITE(mkexpr(t2),
+                                                      binop(Iop_Or32,
+                                                            getDSPControl(),
+                                                            mkU32(0x00200000)),
+                                                      getDSPControl()),
+                                           getDSPControl()));
+                     putDSPControl(mkexpr(t3));
+
+                     putIReg(rd, IRExpr_ITE(mkexpr(t1),
+                                            IRExpr_ITE(mkexpr(t2),
+                                                       mkU32(0x7fffffff),
+                                                       mkexpr(t0)),
+                                            mkexpr(t0)));
+                     break;
+                  }
+                  case 0x1D: {  /* MULEQ_S.W.PHR */
+                     DIP("muleq_s.w.phr r%d, r%d, r%d", rd, rs, rt);
+                     vassert(!mode64);
+                     t0 = newTemp(Ity_I32);
+                     t1 = newTemp(Ity_I1);
+                     t2 = newTemp(Ity_I1);
+
+                     assign(t0,
+                            binop(Iop_Shl32,
+                                  binop(Iop_Mul32,
+                                        unop(Iop_16Sto32,
+                                             unop(Iop_32to16, getIReg(rt))),
+                                        unop(Iop_16Sto32,
+                                             unop(Iop_32to16, getIReg(rs)))),
+                                  mkU8(0x1)));
+                     assign(t1, binop(Iop_CmpEQ32,
+                                      binop(Iop_And32,
+                                            getIReg(rt),
+                                            mkU32(0xffff)),
+                                      mkU32(0x8000)));
+                     assign(t2, binop(Iop_CmpEQ32,
+                                      binop(Iop_And32,
+                                            getIReg(rs),
+                                            mkU32(0xffff)),
+                                      mkU32(0x8000)));
+                     putDSPControl(IRExpr_ITE(mkexpr(t1),
+                                              IRExpr_ITE(mkexpr(t2),
+                                                         binop(Iop_Or32,
+                                                               getDSPControl(),
+                                                               mkU32(0x00200000)
+                                                              ),
+                                                         getDSPControl()),
+                                              getDSPControl()));
+                     putIReg(rd, IRExpr_ITE(mkexpr(t1),
+                                            IRExpr_ITE(mkexpr(t2),
+                                                       mkU32(0x7fffffff),
+                                                       mkexpr(t0)),
+                                            mkexpr(t0)));
+                     break;
+                  }
+                  case 0x1E: {  /* MULQ_S.PH */
+                     DIP("mulq_s.ph r%d, r%d, r%d", rd, rs, rt);
+                     vassert(!mode64);
+                     t0 = newTemp(Ity_I32);
+                     t1 = newTemp(Ity_I32);
+                     t2 = newTemp(Ity_I16);
+                     t3 = newTemp(Ity_I16);
+                     t5 = newTemp(Ity_I32);
+                     t6 = newTemp(Ity_I32);
+                     t7 = newTemp(Ity_I32);
+                     t8 = newTemp(Ity_I32);
+
+                     assign(t5,
+                            unop(Iop_16Sto32, unop(Iop_32to16, getIReg(rs))));
+                     assign(t6,
+                            unop(Iop_16Sto32, unop(Iop_32to16, getIReg(rt))));
+
+                     assign(t7,
+                            unop(Iop_16Sto32, unop(Iop_32HIto16, getIReg(rs))));
+                     assign(t8,
+                            unop(Iop_16Sto32, unop(Iop_32HIto16, getIReg(rt))));
+
+                     assign(t0, binop(Iop_And32,
+                                      unop(Iop_1Sto32,
+                                           binop(Iop_CmpEQ32,
+                                                 binop(Iop_And32,
+                                                       mkexpr(t5),
+                                                       mkU32(0xffff)),
+                                                 mkU32(0x8000))),
+                                      unop(Iop_1Sto32,
+                                           binop(Iop_CmpEQ32,
+                                                 binop(Iop_And32,
+                                                       mkexpr(t6),
+                                                       mkU32(0xffff)),
+                                                 mkU32(0x8000)))));
+                     assign(t1, binop(Iop_And32,
+                                      unop(Iop_1Sto32,
+                                           binop(Iop_CmpEQ32,
+                                                 binop(Iop_And32,
+                                                       mkexpr(t7),
+                                                       mkU32(0xffff)),
+                                                 mkU32(0x8000))),
+                                      unop(Iop_1Sto32,
+                                           binop(Iop_CmpEQ32,
+                                                 binop(Iop_And32,
+                                                       mkexpr(t8),
+                                                       mkU32(0xffff)),
+                                                 mkU32(0x8000)))));
+
+                     putDSPControl(IRExpr_ITE(binop(Iop_CmpEQ32,
+                                                    binop(Iop_Or32,
+                                                          mkexpr(t0),
+                                                          mkexpr(t1)),
+                                                    mkU32(0x0)),
+                                              getDSPControl(),
+                                              binop(Iop_Or32,
+                                                    getDSPControl(),
+                                                    mkU32(0x200000))));
+
+                     assign(t2, unop(Iop_32HIto16,
+                                     binop(Iop_Shl32,
+                                           unop(Iop_64to32,
+                                                binop(Iop_MullS32,
+                                                      mkexpr(t7),
+                                                      mkexpr(t8))),
+                                           mkU8(0x1))));
+                     assign(t3, unop(Iop_32HIto16,
+                                     binop(Iop_Shl32,
+                                           unop(Iop_64to32,
+                                                binop(Iop_MullS32,
+                                                      mkexpr(t5),
+                                                      mkexpr(t6))),
+                                           mkU8(0x1))));
+                     putIReg(rd, binop(Iop_16HLto32,
+                                       IRExpr_ITE(binop(Iop_CmpEQ32,
+                                                        mkexpr(t1),
+                                                        mkU32(0x0)),
+                                                  mkexpr(t2),
+                                                  mkU16(0x7fff)),
+                                       IRExpr_ITE(binop(Iop_CmpEQ32,
+                                                        mkexpr(t0),
+                                                        mkU32(0x0)),
+                                                  mkexpr(t3),
+                                                  mkU16(0x7fff))));
+                     break;
+                  }
+                  case 0x1F: {  /* MULQ_RS.PH */
+                     DIP("mulq_rs.ph r%d, r%d, r%d", rd, rs, rt);
+                     vassert(!mode64);
+                     t0 = newTemp(Ity_I32);
+                     t1 = newTemp(Ity_I1);
+                     t2 = newTemp(Ity_I1);
+                     t3 = newTemp(Ity_I16);
+                     t4 = newTemp(Ity_I32);
+                     t5 = newTemp(Ity_I1);
+                     t6 = newTemp(Ity_I1);
+                     t7 = newTemp(Ity_I16);
+
+                     /* Multiply and round lower halfwords. */
+                     assign(t0, binop(Iop_Add32,
+                                      binop(Iop_Shl32,
+                                            binop(Iop_Mul32,
+                                                  unop(Iop_16Sto32,
+                                                       unop(Iop_32to16,
+                                                            getIReg(rt))),
+                                                  unop(Iop_16Sto32,
+                                                       unop(Iop_32to16,
+                                                            getIReg(rs)))),
+                                            mkU8(0x1)),
+                                      mkU32(0x00008000)));
+                     assign(t1, binop(Iop_CmpEQ32,
+                                      binop(Iop_And32,
+                                            getIReg(rt), mkU32(0xffff)),
+                                      mkU32(0x8000)));
+                     assign(t2, binop(Iop_CmpEQ32,
+                                      binop(Iop_And32,
+                                            getIReg(rs), mkU32(0xffff)),
+                                      mkU32(0x8000)));
+                     putDSPControl(IRExpr_ITE(mkexpr(t1),
+                                              IRExpr_ITE(mkexpr(t2),
+                                                         binop(Iop_Or32,
+                                                               getDSPControl(),
+                                                               mkU32(0x00200000)
+                                                              ),
+                                                         getDSPControl()),
+                                              getDSPControl()));
+                     assign(t3, IRExpr_ITE(mkexpr(t1),
+                                           IRExpr_ITE(mkexpr(t2),
+                                                      mkU16(0x7fff),
+                                                      unop(Iop_32HIto16,
+                                                           mkexpr(t0))),
+                                           unop(Iop_32HIto16, mkexpr(t0))));
+
+                     /* Multiply and round higher halfwords. */
+                     assign(t4, binop(Iop_Add32,
+                                      binop(Iop_Shl32,
+                                            binop(Iop_Mul32,
+                                                  unop(Iop_16Sto32,
+                                                       unop(Iop_32HIto16,
+                                                            getIReg(rt))),
+                                                  unop(Iop_16Sto32,
+                                                       unop(Iop_32HIto16,
+                                                            getIReg(rs)))),
+                                            mkU8(0x1)),
+                                      mkU32(0x00008000)));
+                     assign(t5, binop(Iop_CmpEQ32,
+                                      binop(Iop_And32,
+                                            getIReg(rt),
+                                            mkU32(0xffff0000)),
+                                      mkU32(0x80000000)));
+                     assign(t6, binop(Iop_CmpEQ32,
+                                      binop(Iop_And32,
+                                            getIReg(rs),
+                                            mkU32(0xffff0000)),
+                                      mkU32(0x80000000)));
+                     putDSPControl(IRExpr_ITE(mkexpr(t5),
+                                             IRExpr_ITE(mkexpr(t6),
+                                                        binop(Iop_Or32,
+                                                             getDSPControl(),
+                                                             mkU32(0x00200000)),
+                                                        getDSPControl()),
+                                             getDSPControl()));
+                     assign(t7, IRExpr_ITE(mkexpr(t5),
+                                           IRExpr_ITE(mkexpr(t6),
+                                                      mkU16(0x7fff),
+                                                      unop(Iop_32HIto16,
+                                                           mkexpr(t4))),
+                                           unop(Iop_32HIto16, mkexpr(t4))));
+
+                     putIReg(rd, binop(Iop_16HLto32, mkexpr(t7), mkexpr(t3)));
+                     break;
+                  }
+                  default:
+                     return -1;
+               }
+               break;  /* end of ADDU.QB */
+            }
+            case 0x11: {  /* CMPU.EQ.QB */
+               switch(sa) {
+                  case 0x0: {  /* CMPU.EQ.QB */
+                     DIP("cmpu.eq.qb r%d, r%d", rs, rt);
+                     vassert(!mode64);
+                     t1 = newTemp(Ity_I1);
+                     t2 = newTemp(Ity_I1);
+                     t3 = newTemp(Ity_I1);
+                     t4 = newTemp(Ity_I1);
+
+                     assign(t1,
+                            binop(Iop_CmpEQ32,
+                                  binop(Iop_And32, getIReg(rs), mkU32(0xff)),
+                                  binop(Iop_And32, getIReg(rt), mkU32(0xff))));
+                     putDSPControl(IRExpr_ITE(mkexpr(t1),
+                                              binop(Iop_Or32,
+                                                    getDSPControl(),
+                                                    mkU32(0x01000000)),
+                                              binop(Iop_And32,
+                                                    getDSPControl(),
+                                                    mkU32(0xfeffffff))));
+
+                     assign(t2, binop(Iop_CmpEQ32,
+                                      unop(Iop_8Uto32,
+                                           unop(Iop_16HIto8,
+                                                unop(Iop_32to16,
+                                                     getIReg(rs)))),
+                                      unop(Iop_8Uto32,
+                                           unop(Iop_16HIto8,
+                                                unop(Iop_32to16,
+                                                     getIReg(rt))))));
+                     putDSPControl(IRExpr_ITE(mkexpr(t2),
+                                              binop(Iop_Or32,
+                                                    getDSPControl(),
+                                                    mkU32(0x02000000)),
+                                              binop(Iop_And32,
+                                                    getDSPControl(),
+                                                    mkU32(0xfdffffff))));
+
+                     assign(t3, binop(Iop_CmpEQ32,
+                                      unop(Iop_8Uto32,
+                                           unop(Iop_16to8,
+                                                unop(Iop_32HIto16,
+                                                     getIReg(rs)))),
+                                      unop(Iop_8Uto32,
+                                           unop(Iop_16to8,
+                                                unop(Iop_32HIto16,
+                                                     getIReg(rt))))));
+                     putDSPControl(IRExpr_ITE(mkexpr(t3),
+                                              binop(Iop_Or32,
+                                                    getDSPControl(),
+                                                    mkU32(0x04000000)),
+                                              binop(Iop_And32,
+                                                    getDSPControl(),
+                                                    mkU32(0xfbffffff))));
+
+                     assign(t4, binop(Iop_CmpEQ32,
+                                      unop(Iop_8Uto32,
+                                           unop(Iop_16HIto8,
+                                                unop(Iop_32HIto16,
+                                                     getIReg(rs)))),
+                                      unop(Iop_8Uto32,
+                                           unop(Iop_16HIto8,
+                                                unop(Iop_32HIto16,
+                                                     getIReg(rt))))));
+                     putDSPControl(IRExpr_ITE(mkexpr(t4),
+                                              binop(Iop_Or32,
+                                                    getDSPControl(),
+                                                    mkU32(0x08000000)),
+                                              binop(Iop_And32,
+                                                    getDSPControl(),
+                                                    mkU32(0xf7ffffff))));
+                     break;
+                  }
+                  case 0x1: {  /* CMPU.LT.QB */
+                     DIP("cmpu.lt.qb r%d, r%d", rs, rt);
+                     vassert(!mode64);
+                     t1 = newTemp(Ity_I1);
+                     t2 = newTemp(Ity_I1);
+                     t3 = newTemp(Ity_I1);
+                     t4 = newTemp(Ity_I1);
+
+                     assign(t1, binop(Iop_CmpLT32U,
+                                      unop(Iop_8Uto32,
+                                           unop(Iop_16to8,
+                                                unop(Iop_32to16,
+                                                     getIReg(rs)))),
+                                      unop(Iop_8Uto32,
+                                           unop(Iop_16to8,
+                                                unop(Iop_32to16,
+                                                     getIReg(rt))))));
+                     putDSPControl(IRExpr_ITE(mkexpr(t1),
+                                              binop(Iop_Or32,
+                                                    getDSPControl(),
+                                                    mkU32(0x01000000)),
+                                              binop(Iop_And32,
+                                                    getDSPControl(),
+                                                    mkU32(0xfeffffff))));
+
+                     assign(t2, binop(Iop_CmpLT32U,
+                                      unop(Iop_8Uto32,
+                                           unop(Iop_16HIto8,
+                                                unop(Iop_32to16,
+                                                     getIReg(rs)))),
+                                      unop(Iop_8Uto32,
+                                           unop(Iop_16HIto8,
+                                                unop(Iop_32to16,
+                                                     getIReg(rt))))));
+                     putDSPControl(IRExpr_ITE(mkexpr(t2),
+                                              binop(Iop_Or32,
+                                                    getDSPControl(),
+                                                    mkU32(0x02000000)),
+                                              binop(Iop_And32,
+                                                    getDSPControl(),
+                                                    mkU32(0xfdffffff))));
+
+                     assign(t3, binop(Iop_CmpLT32U,
+                                      unop(Iop_8Uto32,
+                                           unop(Iop_16to8,
+                                                unop(Iop_32HIto16,
+                                                     getIReg(rs)))),
+                                      unop(Iop_8Uto32,
+                                           unop(Iop_16to8,
+                                                unop(Iop_32HIto16,
+                                                     getIReg(rt))))));
+                     putDSPControl(IRExpr_ITE(mkexpr(t3),
+                                              binop(Iop_Or32,
+                                                    getDSPControl(),
+                                                    mkU32(0x04000000)),
+                                              binop(Iop_And32,
+                                                    getDSPControl(),
+                                                    mkU32(0xfbffffff))));
+
+                     assign(t4, binop(Iop_CmpLT32U,
+                                      unop(Iop_8Uto32,
+                                           unop(Iop_16HIto8,
+                                                unop(Iop_32HIto16,
+                                                     getIReg(rs)))),
+                                      unop(Iop_8Uto32,
+                                           unop(Iop_16HIto8,
+                                                unop(Iop_32HIto16,
+                                                     getIReg(rt))))));
+                     putDSPControl(IRExpr_ITE(mkexpr(t4),
+                                              binop(Iop_Or32,
+                                                    getDSPControl(),
+                                                    mkU32(0x08000000)),
+                                              binop(Iop_And32,
+                                                    getDSPControl(),
+                                                    mkU32(0xf7ffffff))));
+                     break;
+                  }
+                  case 0x2: {  /* CMPU.LE.QB */
+                     DIP("cmpu.le.qb r%d, r%d", rs, rt);
+                     vassert(!mode64);
+                     t1 = newTemp(Ity_I1);
+                     t2 = newTemp(Ity_I1);
+                     t3 = newTemp(Ity_I1);
+                     t4 = newTemp(Ity_I1);
+
+                     assign(t1, binop(Iop_CmpLE32U,
+                                      unop(Iop_8Uto32,
+                                           unop(Iop_16to8,
+                                                unop(Iop_32to16,
+                                                     getIReg(rs)))),
+                                      unop(Iop_8Uto32,
+                                           unop(Iop_16to8,
+                                                unop(Iop_32to16,
+                                                     getIReg(rt))))));
+                     putDSPControl(IRExpr_ITE(mkexpr(t1),
+                                              binop(Iop_Or32,
+                                                    getDSPControl(),
+                                                    mkU32(0x01000000)),
+                                              binop(Iop_And32,
+                                                    getDSPControl(),
+                                                    mkU32(0xfeffffff))));
+
+                     assign(t2, binop(Iop_CmpLE32U,
+                                      unop(Iop_8Uto32,
+                                           unop(Iop_16HIto8,
+                                                unop(Iop_32to16,
+                                                     getIReg(rs)))),
+                                      unop(Iop_8Uto32,
+                                           unop(Iop_16HIto8,
+                                                unop(Iop_32to16,
+                                                     getIReg(rt))))));
+                     putDSPControl(IRExpr_ITE(mkexpr(t2),
+                                              binop(Iop_Or32,
+                                                    getDSPControl(),
+                                                    mkU32(0x02000000)),
+                                              binop(Iop_And32,
+                                                    getDSPControl(),
+                                                    mkU32(0xfdffffff))));
+
+                     assign(t3, binop(Iop_CmpLE32U,
+                                      unop(Iop_8Uto32,
+                                           unop(Iop_16to8,
+                                                unop(Iop_32HIto16,
+                                                     getIReg(rs)))),
+                                      unop(Iop_8Uto32,
+                                           unop(Iop_16to8,
+                                                unop(Iop_32HIto16,
+                                                     getIReg(rt))))));
+                     putDSPControl(IRExpr_ITE(mkexpr(t3),
+                                              binop(Iop_Or32,
+                                                    getDSPControl(),
+                                                    mkU32(0x04000000)),
+                                              binop(Iop_And32,
+                                                    getDSPControl(),
+                                                    mkU32(0xfbffffff))));
+
+                     assign(t4, binop(Iop_CmpLE32U,
+                                      unop(Iop_8Uto32,
+                                           unop(Iop_16HIto8,
+                                                unop(Iop_32HIto16,
+                                                     getIReg(rs)))),
+                                      unop(Iop_8Uto32,
+                                           unop(Iop_16HIto8,
+                                                unop(Iop_32HIto16,
+                                                     getIReg(rt))))));
+                     putDSPControl(IRExpr_ITE(mkexpr(t4),
+                                              binop(Iop_Or32,
+                                                    getDSPControl(),
+                                                    mkU32(0x08000000)),
+                                              binop(Iop_And32,
+                                                    getDSPControl(),
+                                                    mkU32(0xf7ffffff))));
+                     break;
+                  }
+                  case 0x3: {  /* PICK.QB */
+                     DIP("pick.qb r%d, r%d, r%d", rd, rs, rt);
+                     vassert(!mode64);
+                     t0 = newTemp(Ity_I32);
+                     t1 = newTemp(Ity_I8);
+                     t2 = newTemp(Ity_I8);
+                     t3 = newTemp(Ity_I8);
+                     t4 = newTemp(Ity_I8);
+
+                     assign(t0, getDSPControl());
+                     assign(t1, IRExpr_ITE(binop(Iop_CmpNE32,
+                                                 binop(Iop_And32,
+                                                       mkexpr(t0),
+                                                       mkU32(0x01000000)),
+                                                 mkU32(0x0)),
+                                           unop(Iop_16to8,
+                                                 unop(Iop_32to16,
+                                                      getIReg(rs))),
+                                           unop(Iop_16to8,
+                                                unop(Iop_32to16,
+                                                     getIReg(rt)))));
+                     assign(t2, IRExpr_ITE(binop(Iop_CmpNE32,
+                                                 binop(Iop_And32,
+                                                       mkexpr(t0),
+                                                       mkU32(0x02000000)),
+                                                 mkU32(0x0)),
+                                           unop(Iop_16HIto8,
+                                                unop(Iop_32to16, getIReg(rs))),
+                                           unop(Iop_16HIto8,
+                                                unop(Iop_32to16,
+                                                     getIReg(rt)))));
+                     assign(t3, IRExpr_ITE(binop(Iop_CmpNE32,
+                                                 binop(Iop_And32,
+                                                       mkexpr(t0),
+                                                       mkU32(0x04000000)),
+                                                 mkU32(0x0)),
+                                           unop(Iop_16to8,
+                                                unop(Iop_32HIto16,
+                                                     getIReg(rs))),
+                                           unop(Iop_16to8,
+                                                unop(Iop_32HIto16,
+                                                     getIReg(rt)))));
+                     assign(t4, IRExpr_ITE(binop(Iop_CmpNE32,
+                                                 binop(Iop_And32,
+                                                       mkexpr(t0),
+                                                       mkU32(0x08000000)),
+                                                 mkU32(0x0)),
+                                           unop(Iop_16HIto8,
+                                                unop(Iop_32HIto16,
+                                                     getIReg(rs))),
+                                           unop(Iop_16HIto8,
+                                                unop(Iop_32HIto16,
+                                                     getIReg(rt)))));
+                     putIReg(rd,
+                             binop(Iop_16HLto32,
+                                   binop(Iop_8HLto16, mkexpr(t4), mkexpr(t3)),
+                                   binop(Iop_8HLto16, mkexpr(t2), mkexpr(t1))));
+                     break;
+                  }
+                  case 0x4: {  /* CMPGU.EQ.QB */
+                     DIP("cmpgu.eq.qb r%d, r%d, r%d", rd, rs, rt);
+                     vassert(!mode64);
+                     t1 = newTemp(Ity_I1);
+                     t2 = newTemp(Ity_I1);
+                     t3 = newTemp(Ity_I1);
+                     t4 = newTemp(Ity_I1);
+                     t5 = newTemp(Ity_I32);
+                     t6 = newTemp(Ity_I32);
+                     t7 = newTemp(Ity_I32);
+                     t8 = newTemp(Ity_I32);
+
+                     assign(t1, binop(Iop_CmpEQ32,
+                                      unop(Iop_8Uto32,
+                                           unop(Iop_16to8,
+                                                unop(Iop_32to16, getIReg(rs)))),
+                                      unop(Iop_8Uto32,
+                                           unop(Iop_16to8,
+                                                unop(Iop_32to16,
+                                                     getIReg(rt))))));
+                     assign(t5, IRExpr_ITE(mkexpr(t1),
+                                           mkU32(0x00000001), mkU32(0)));
+
+                     assign(t2, binop(Iop_CmpEQ32,
+                                      unop(Iop_8Uto32,
+                                           unop(Iop_16HIto8,
+                                                unop(Iop_32to16, getIReg(rs)))),
+                                      unop(Iop_8Uto32,
+                                           unop(Iop_16HIto8,
+                                                unop(Iop_32to16,
+                                                     getIReg(rt))))));
+                     assign(t6, IRExpr_ITE(mkexpr(t2),
+                                           mkU32(0x00000002), mkU32(0)));
+
+                     assign(t3, binop(Iop_CmpEQ32,
+                                      unop(Iop_8Uto32,
+                                           unop(Iop_16to8,
+                                                unop(Iop_32HIto16,
+                                                     getIReg(rs)))),
+                                      unop(Iop_8Uto32,
+                                           unop(Iop_16to8,
+                                                unop(Iop_32HIto16,
+                                                     getIReg(rt))))));
+                     assign(t7, IRExpr_ITE(mkexpr(t3),
+                                           mkU32(0x00000004), mkU32(0)));
+
+                     assign(t4, binop(Iop_CmpEQ32,
+                                      unop(Iop_8Uto32,
+                                           unop(Iop_16HIto8,
+                                                unop(Iop_32HIto16,
+                                                     getIReg(rs)))),
+                                      unop(Iop_8Uto32,
+                                           unop(Iop_16HIto8,
+                                                unop(Iop_32HIto16,
+                                                     getIReg(rt))))));
+                     assign(t8, IRExpr_ITE(mkexpr(t4),
+                                           mkU32(0x00000008), mkU32(0)));
+
+                     putIReg(rd, binop(Iop_Or32,
+                                       binop(Iop_Or32,
+                                             binop(Iop_Or32,
+                                                   mkexpr(t5), mkexpr(t6)),
+                                             mkexpr(t7)),
+                                       mkexpr(t8)));
+                     break;
+                  }
+                  case 0x5: {  /* CMPGU.LT.QB */
+                     DIP("cmpgu.lt.qb r%d, r%d, r%d", rd, rs, rt);
+                     vassert(!mode64);
+                     t1 = newTemp(Ity_I1);
+                     t2 = newTemp(Ity_I1);
+                     t3 = newTemp(Ity_I1);
+                     t4 = newTemp(Ity_I1);
+                     t5 = newTemp(Ity_I32);
+                     t6 = newTemp(Ity_I32);
+                     t7 = newTemp(Ity_I32);
+                     t8 = newTemp(Ity_I32);
+
+                     assign(t1, binop(Iop_CmpLT32U,
+                                      unop(Iop_8Uto32,
+                                           unop(Iop_16to8,
+                                                unop(Iop_32to16, getIReg(rs)))),
+                                      unop(Iop_8Uto32,
+                                           unop(Iop_16to8,
+                                                unop(Iop_32to16,
+                                                     getIReg(rt))))));
+                     assign(t5, IRExpr_ITE(mkexpr(t1),
+                                           mkU32(0x00000001), mkU32(0)));
+
+                     assign(t2, binop(Iop_CmpLT32U,
+                                      unop(Iop_8Uto32,
+                                           unop(Iop_16HIto8,
+                                                unop(Iop_32to16, getIReg(rs)))),
+                                      unop(Iop_8Uto32,
+                                           unop(Iop_16HIto8,
+                                                unop(Iop_32to16,
+                                                     getIReg(rt))))));
+                     assign(t6, IRExpr_ITE(mkexpr(t2),
+                                           mkU32(0x00000002), mkU32(0)));
+
+                     assign(t3, binop(Iop_CmpLT32U,
+                                      unop(Iop_8Uto32,
+                                           unop(Iop_16to8,
+                                                unop(Iop_32HIto16,
+                                                     getIReg(rs)))),
+                                      unop(Iop_8Uto32,
+                                           unop(Iop_16to8,
+                                                unop(Iop_32HIto16,
+                                                     getIReg(rt))))));
+                     assign(t7, IRExpr_ITE(mkexpr(t3),
+                                           mkU32(0x00000004), mkU32(0)));
+
+                     assign(t4, binop(Iop_CmpLT32U,
+                                      unop(Iop_8Uto32,
+                                           unop(Iop_16HIto8,
+                                                unop(Iop_32HIto16,
+                                                     getIReg(rs)))),
+                                      unop(Iop_8Uto32,
+                                           unop(Iop_16HIto8,
+                                                unop(Iop_32HIto16,
+                                                     getIReg(rt))))));
+                     assign(t8, IRExpr_ITE(mkexpr(t4),
+                                           mkU32(0x00000008), mkU32(0)));
+                     putIReg(rd, binop(Iop_Or32,
+                                       binop(Iop_Or32,
+                                             binop(Iop_Or32,
+                                                   mkexpr(t5), mkexpr(t6)),
+                                             mkexpr(t7)),
+                                       mkexpr(t8)));
+                     break;
+                  }
+                  case 0x6: {  /* CMPGU.LE.QB */
+                     DIP("cmpgu.le.qb r%d, r%d, r%d", rd, rs, rt);
+                     vassert(!mode64);
+                     t1 = newTemp(Ity_I1);
+                     t2 = newTemp(Ity_I1);
+                     t3 = newTemp(Ity_I1);
+                     t4 = newTemp(Ity_I1);
+                     t5 = newTemp(Ity_I32);
+                     t6 = newTemp(Ity_I32);
+                     t7 = newTemp(Ity_I32);
+                     t8 = newTemp(Ity_I32);
+
+                     assign(t1, binop(Iop_CmpLE32U,
+                                      unop(Iop_8Uto32,
+                                           unop(Iop_16to8,
+                                                unop(Iop_32to16, getIReg(rs)))),
+                                      unop(Iop_8Uto32,
+                                           unop(Iop_16to8,
+                                                unop(Iop_32to16,
+                                                     getIReg(rt))))));
+                     assign(t5, IRExpr_ITE(mkexpr(t1),
+                                           mkU32(0x00000001), mkU32(0)));
+
+                     assign(t2, binop(Iop_CmpLE32U,
+                                      unop(Iop_8Uto32,
+                                           unop(Iop_16HIto8,
+                                                unop(Iop_32to16, getIReg(rs)))),
+                                      unop(Iop_8Uto32,
+                                           unop(Iop_16HIto8,
+                                                unop(Iop_32to16,
+                                                     getIReg(rt))))));
+                     assign(t6, IRExpr_ITE(mkexpr(t2),
+                                           mkU32(0x00000002), mkU32(0)));
+
+                     assign(t3, binop(Iop_CmpLE32U,
+                                      unop(Iop_8Uto32,
+                                           unop(Iop_16to8,
+                                                unop(Iop_32HIto16,
+                                                     getIReg(rs)))),
+                                      unop(Iop_8Uto32,
+                                           unop(Iop_16to8,
+                                                unop(Iop_32HIto16,
+                                                     getIReg(rt))))));
+                     assign(t7, IRExpr_ITE(mkexpr(t3),
+                                           mkU32(0x00000004), mkU32(0)));
+
+                     assign(t4, binop(Iop_CmpLE32U,
+                                      unop(Iop_8Uto32,
+                                           unop(Iop_16HIto8,
+                                                unop(Iop_32HIto16,
+                                                     getIReg(rs)))),
+                                      unop(Iop_8Uto32,
+                                           unop(Iop_16HIto8,
+                                                unop(Iop_32HIto16,
+                                                     getIReg(rt))))));
+                     assign(t8, IRExpr_ITE(mkexpr(t4),
+                                           mkU32(0x00000008), mkU32(0)));
+                     putIReg(rd, binop(Iop_Or32,
+                                       binop(Iop_Or32,
+                                             binop(Iop_Or32,
+                                                   mkexpr(t5), mkexpr(t6)),
+                                             mkexpr(t7)),
+                                       mkexpr(t8)));
+                     break;
+                  }
+                  case 0x8: {  /* CMP.EQ.PH */
+                     DIP("cmp.eq.ph r%d, r%d", rs, rt);
+                     vassert(!mode64);
+                     t1 = newTemp(Ity_I1);
+                     t2 = newTemp(Ity_I1);
+
+                     assign(t1, binop(Iop_CmpEQ16,
+                                      unop(Iop_32to16, getIReg(rs)),
+                                      unop(Iop_32to16, getIReg(rt))));
+                     putDSPControl(IRExpr_ITE(mkexpr(t1),
+                                              binop(Iop_Or32,
+                                                    getDSPControl(),
+                                                    mkU32(0x01000000)),
+                                              binop(Iop_And32,
+                                                    getDSPControl(),
+                                                    mkU32(0xfeffffff))));
+                     assign(t2, binop(Iop_CmpEQ16,
+                                      unop(Iop_32HIto16, getIReg(rs)),
+                                      unop(Iop_32HIto16, getIReg(rt))));
+                     putDSPControl(IRExpr_ITE(mkexpr(t2),
+                                              binop(Iop_Or32,
+                                                    getDSPControl(),
+                                                    mkU32(0x02000000)),
+                                              binop(Iop_And32,
+                                                    getDSPControl(),
+                                                    mkU32(0xfdffffff))));
+                     break;
+                  }
+                  case 0x9: {  /* CMP.LT.PH */
+                     DIP("cmp.lt.ph r%d, r%d", rs, rt);
+                     vassert(!mode64);
+                     t1 = newTemp(Ity_I1);
+                     t2 = newTemp(Ity_I1);
+
+                     assign(t1, binop(Iop_CmpLT32S,
+                                      unop(Iop_16Sto32,
+                                           unop(Iop_32to16, getIReg(rs))),
+                                      unop(Iop_16Sto32,
+                                           unop(Iop_32to16, getIReg(rt)))));
+                     putDSPControl(IRExpr_ITE(mkexpr(t1),
+                                              binop(Iop_Or32,
+                                                    getDSPControl(),
+                                                    mkU32(0x01000000)),
+                                              binop(Iop_And32,
+                                                    getDSPControl(),
+                                                    mkU32(0xfeffffff))));
+
+                     assign(t2, binop(Iop_CmpLT32S,
+                                      unop(Iop_16Sto32,
+                                           unop(Iop_32HIto16, getIReg(rs))),
+                                      unop(Iop_16Sto32,
+                                           unop(Iop_32HIto16, getIReg(rt)))));
+                     putDSPControl(IRExpr_ITE(mkexpr(t2),
+                                              binop(Iop_Or32,
+                                                    getDSPControl(),
+                                                    mkU32(0x02000000)),
+                                              binop(Iop_And32,
+                                                    getDSPControl(),
+                                                    mkU32(0xfdffffff))));
+                     break;
+                  }
+                  case 0xA: {  /* CMP.LE.PH */
+                     DIP("cmp.le.ph r%d, r%d", rs, rt);
+                     vassert(!mode64);
+                     t1 = newTemp(Ity_I1);
+                     t2 = newTemp(Ity_I1);
+
+                     assign(t1, binop(Iop_CmpLE32S,
+                                      unop(Iop_16Sto32,
+                                           unop(Iop_32to16, getIReg(rs))),
+                                      unop(Iop_16Sto32,
+                                           unop(Iop_32to16, getIReg(rt)))));
+                     putDSPControl(IRExpr_ITE(mkexpr(t1),
+                                              binop(Iop_Or32,
+                                                    getDSPControl(),
+                                                    mkU32(0x01000000)),
+                                              binop(Iop_And32,
+                                                    getDSPControl(),
+                                                    mkU32(0xfeffffff))));
+
+                     assign(t2, binop(Iop_CmpLE32S,
+                                      unop(Iop_16Sto32,
+                                           unop(Iop_32HIto16, getIReg(rs))),
+                                      unop(Iop_16Sto32,
+                                           unop(Iop_32HIto16, getIReg(rt)))));
+                     putDSPControl(IRExpr_ITE(mkexpr(t2),
+                                              binop(Iop_Or32,
+                                                    getDSPControl(),
+                                                    mkU32(0x02000000)),
+                                              binop(Iop_And32,
+                                                    getDSPControl(),
+                                                    mkU32(0xfdffffff))));
+                     break;
+                  }
+                  case 0xB: {  /* PICK.PH */
+                     DIP("pick.qb r%d, r%d, r%d", rd, rs, rt);
+                     vassert(!mode64);
+                     t0 = newTemp(Ity_I32);
+                     t1 = newTemp(Ity_I16);
+                     t2 = newTemp(Ity_I16);
+
+                     assign(t0, getDSPControl());
+
+                     assign(t1, IRExpr_ITE(binop(Iop_CmpNE32,
+                                                 binop(Iop_And32,
+                                                       mkexpr(t0),
+                                                       mkU32(0x01000000)),
+                                                 mkU32(0x0)),
+                                           unop(Iop_32to16, getIReg(rs)),
+                                           unop(Iop_32to16, getIReg(rt))));
+
+                     assign(t2, IRExpr_ITE(binop(Iop_CmpNE32,
+                                                 binop(Iop_And32,
+                                                       mkexpr(t0),
+                                                       mkU32(0x02000000)),
+                                                 mkU32(0x0)),
+                                           unop(Iop_32HIto16, getIReg(rs)),
+                                           unop(Iop_32HIto16, getIReg(rt))));
+
+                     putIReg(rd, binop(Iop_16HLto32, mkexpr(t2), mkexpr(t1)));
+                     break;
+                  }
+                  case 0xC: {  /* PRECRQ.QB.PH */
+                     DIP("precrq.qb.ph r%d, r%d, %d", rd, rs, rt);
+                     vassert(!mode64);
+                     putIReg(rd,
+                             binop(Iop_16HLto32,
+                                   binop(Iop_8HLto16,
+                                         unop(Iop_16HIto8,
+                                              unop(Iop_32HIto16, getIReg(rs))),
+                                         unop(Iop_16HIto8,
+                                              unop(Iop_32to16, getIReg(rs)))),
+                                   binop(Iop_8HLto16,
+                                         unop(Iop_16HIto8,
+                                              unop(Iop_32HIto16, getIReg(rt))),
+                                         unop(Iop_16HIto8,
+                                              unop(Iop_32to16, getIReg(rt))))));
+                     break;
+                  }
+                  case 0xD: {  /* PRECR.QB.PH */
+                     DIP("precr.qb.ph r%d, r%d, r%d", rd, rs, rt);
+                     vassert(!mode64);
+
+                     putIReg(rd,
+                             binop(Iop_16HLto32,
+                                   binop(Iop_8HLto16,
+                                         unop(Iop_16to8,
+                                              unop(Iop_32HIto16, getIReg(rs))),
+                                         unop(Iop_16to8,
+                                              unop(Iop_32to16, getIReg(rs)))),
+                                   binop(Iop_8HLto16,
+                                         unop(Iop_16to8,
+                                              unop(Iop_32HIto16, getIReg(rt))),
+                                         unop(Iop_16to8,
+                                              unop(Iop_32to16, getIReg(rt))))));
+                     break;
+                  }
+                  case 0xF: {  /* PRECRQU_S.QB.PH */
+                     DIP("precrqu_s.qb.ph r%d, r%d, %d", rd, rs, rt);
+                     vassert(!mode64);
+                     t0 = newTemp(Ity_I8);
+                     t1 = newTemp(Ity_I8);
+                     t2 = newTemp(Ity_I8);
+                     t3 = newTemp(Ity_I8);
+                     t4 = newTemp(Ity_I8);
+                     t5 = newTemp(Ity_I32);
+                     t6 = newTemp(Ity_I1);
+                     t7 = newTemp(Ity_I8);
+                     t8 = newTemp(Ity_I1);
+                     t9 = newTemp(Ity_I32);
+                     t10 = newTemp(Ity_I8);
+                     t11 = newTemp(Ity_I1);
+                     t12 = newTemp(Ity_I32);
+                     t13 = newTemp(Ity_I8);
+                     t14 = newTemp(Ity_I1);
+                     t15 = newTemp(Ity_I32);
+
+                     assign(t4, IRExpr_ITE(binop(Iop_CmpLT32U,
+                                                 mkU32(0x7f80),
+                                                 binop(Iop_And32,
+                                                       unop(Iop_16Uto32,
+                                                            unop(Iop_32to16,
+                                                            getIReg(rs))),
+                                                       mkU32(0x7fff))),
+                                           mkU8(0xff),
+                                           unop(Iop_16HIto8,
+                                                unop(Iop_32to16,
+                                                     binop(Iop_Shl32,
+                                                           getIReg(rs),
+                                                           mkU8(1))))));
+                     assign(t0, IRExpr_ITE(binop(Iop_CmpEQ32,
+                                                 binop(Iop_And32,
+                                                       unop(Iop_16Uto32,
+                                                            unop(Iop_32to16,
+                                                                 getIReg(rs))),
+                                                       mkU32(0x00008000)),
+                                                 mkU32(0x0)),
+                                           mkexpr(t4),
+                                           mkU8(0x0)));
+                     assign(t5, binop(Iop_And32,
+                                      unop(Iop_16Uto32,
+                                            unop(Iop_32to16,
+                                                 getIReg(rs))),
+                                      mkU32(0x00008000)));
+                     assign(t6, binop(Iop_CmpLT32U,
+                                      mkU32(0x7f80),
+                                      binop(Iop_And32,
+                                            unop(Iop_16Uto32,
+                                                 unop(Iop_32to16,
+                                                 getIReg(rs))),
+                                            mkU32(0x7fff))));
+                     putDSPControl(IRExpr_ITE(binop(Iop_CmpEQ32,
+                                                    mkexpr(t5),
+                                                    mkU32(0x0)),
+                                              IRExpr_ITE(mkexpr(t6),
+                                                         binop(Iop_Or32,
+                                                               getDSPControl(),
+                                                               mkU32(0x00400000)
+                                                              ),
+                                                         getDSPControl()),
+                                              binop(Iop_Or32,
+                                                    getDSPControl(),
+                                                    mkU32(0x00400000))));
+
+                     assign(t7, IRExpr_ITE(binop(Iop_CmpLT32U,
+                                                 mkU32(0x7f80),
+                                                 binop(Iop_And32,
+                                                       unop(Iop_16Uto32,
+                                                            unop(Iop_32HIto16,
+                                                                 getIReg(rs))),
+                                                       mkU32(0x7fff))),
+                                           mkU8(0xff),
+                                           unop(Iop_16HIto8,
+                                                unop(Iop_32HIto16,
+                                                     binop(Iop_Shl32,
+                                                           getIReg(rs),
+                                                           mkU8(1))))));
+                     assign(t1, IRExpr_ITE(binop(Iop_CmpEQ32,
+                                                 binop(Iop_And32,
+                                                       unop(Iop_16Uto32,
+                                                            unop(Iop_32HIto16,
+                                                                 getIReg(rs))),
+                                                       mkU32(0x00008000)),
+                                                 mkU32(0x0)),
+                                           mkexpr(t7),
+                                           mkU8(0x0)));
+                     assign(t8, binop(Iop_CmpEQ32,
+                                      binop(Iop_And32,
+                                            unop(Iop_16Uto32,
+                                                 unop(Iop_32HIto16,
+                                                      getIReg(rs))),
+                                            mkU32(0x00008000)),
+                                      mkU32(0x0)));
+                     assign(t9, IRExpr_ITE(binop(Iop_CmpLT32U,
+                                                 mkU32(0x7f80),
+                                                 binop(Iop_And32,
+                                                       unop(Iop_16Uto32,
+                                                            unop(Iop_32HIto16,
+                                                                 getIReg(rs))),
+                                                       mkU32(0x7fff))),
+                                           binop(Iop_Or32,
+                                                 getDSPControl(),
+                                                 mkU32(0x00400000)),
+                                           getDSPControl()));
+                     putDSPControl(IRExpr_ITE(mkexpr(t8),
+                                              mkexpr(t9),
+                                              binop(Iop_Or32,
+                                                    getDSPControl(),
+                                                    mkU32(0x00400000))));
+
+                     assign(t10, IRExpr_ITE(binop(Iop_CmpLT32U,
+                                                  mkU32(0x7f80),
+                                                  binop(Iop_And32,
+                                                        unop(Iop_16Uto32,
+                                                             unop(Iop_32to16,
+                                                             getIReg(rt))),
+                                                        mkU32(0x7fff))),
+                                            mkU8(0xff),
+                                            unop(Iop_16HIto8,
+                                                 unop(Iop_32to16,
+                                                      binop(Iop_Shl32,
+                                                            getIReg(rt),
+                                                            mkU8(1))))));
+                     assign(t2, IRExpr_ITE(binop(Iop_CmpEQ32,
+                                                 binop(Iop_And32,
+                                                       unop(Iop_16Uto32,
+                                                            unop(Iop_32to16,
+                                                                 getIReg(rt))),
+                                                       mkU32(0x00008000)),
+                                                 mkU32(0x0)),
+                                           mkexpr(t10),
+                                           mkU8(0x0)));
+                     assign(t11, binop(Iop_CmpEQ32,
+                                       binop(Iop_And32,
+                                             unop(Iop_16Uto32,
+                                                  unop(Iop_32to16,
+                                                       getIReg(rt))),
+                                             mkU32(0x00008000)),
+                                       mkU32(0x0)));
+                     assign(t12, IRExpr_ITE(binop(Iop_CmpLT32U,
+                                                  mkU32(0x7f80),
+                                                  binop(Iop_And32,
+                                                        unop(Iop_16Uto32,
+                                                             unop(Iop_32to16,
+                                                             getIReg(rt))),
+                                                        mkU32(0x7fff))),
+                                            binop(Iop_Or32,
+                                                  getDSPControl(),
+                                                  mkU32(0x00400000)),
+                                            getDSPControl()));
+                     putDSPControl(IRExpr_ITE(mkexpr(t11),
+                                              mkexpr(t12),
+                                              binop(Iop_Or32,
+                                                    getDSPControl(),
+                                                    mkU32(0x00400000))));
+
+                     assign(t13, IRExpr_ITE(binop(Iop_CmpLT32U,
+                                                  mkU32(0x7f80),
+                                                  binop(Iop_And32,
+                                                        unop(Iop_16Uto32,
+                                                             unop(Iop_32HIto16,
+                                                                  getIReg(rt))),
+                                                        mkU32(0x7fff))),
+                                            mkU8(0xff),
+                                            unop(Iop_16HIto8,
+                                                 unop(Iop_32HIto16,
+                                                      binop(Iop_Shl32,
+                                                            getIReg(rt),
+                                                            mkU8(1))))));
+                     assign(t3, IRExpr_ITE(binop(Iop_CmpEQ32,
+                                                 binop(Iop_And32,
+                                                       unop(Iop_16Uto32,
+                                                            unop(Iop_32HIto16,
+                                                                 getIReg(rt))),
+                                                       mkU32(0x00008000)),
+                                                 mkU32(0x0)),
+                                           mkexpr(t13),
+                                           mkU8(0x0)));
+                     assign(t14, binop(Iop_CmpEQ32,
+                                       binop(Iop_And32,
+                                             unop(Iop_16Uto32,
+                                                  unop(Iop_32HIto16,
+                                                       getIReg(rt))),
+                                             mkU32(0x00008000)),
+                                       mkU32(0x0)));
+                     assign(t15, IRExpr_ITE(binop(Iop_CmpLT32U,
+                                                  mkU32(0x7f80),
+                                                  binop(Iop_And32,
+                                                        unop(Iop_16Uto32,
+                                                             unop(Iop_32HIto16,
+                                                                  getIReg(rt))),
+                                                        mkU32(0x7fff))),
+                                            binop(Iop_Or32,
+                                                  getDSPControl(),
+                                                  mkU32(0x00400000)),
+                                            getDSPControl()));
+                     putDSPControl(IRExpr_ITE(mkexpr(t14),
+                                              mkexpr(t15),
+                                              binop(Iop_Or32,
+                                                    getDSPControl(),
+                                                    mkU32(0x00400000))));
+
+                     putIReg(rd, binop(Iop_16HLto32,
+                                       binop(Iop_8HLto16,
+                                             mkexpr(t1), mkexpr(t0)),
+                                       binop(Iop_8HLto16,
+                                             mkexpr(t3), mkexpr(t2))));
+                     break;
+                  }
+                  case 0x14: {  /* PRECRQ.PH.W */
+                     DIP("precrq.ph.w r%d, r%d, %d", rd, rs, rt);
+                     vassert(!mode64);
+                     putIReg(rd, binop(Iop_16HLto32,
+                                       unop(Iop_32HIto16, getIReg(rs)),
+                                       unop(Iop_32HIto16, getIReg(rt))));
+                     break;
+                  }
+                  case 0x15: {  /* PRECRQ_RS.PH.W */
+                     DIP("precrq_rs.ph.w r%d, r%d, %d", rd, rs, rt);
+                     vassert(!mode64);
+                     t0 = newTemp(Ity_I64);
+                     t1 = newTemp(Ity_I1);
+                     t2 = newTemp(Ity_I32);
+                     t3 = newTemp(Ity_I64);
+                     t4 = newTemp(Ity_I1);
+                     t5 = newTemp(Ity_I32);
+
+                     assign(t0, binop(Iop_Add64,
+                                      binop(Iop_32HLto64,
+                                            binop(Iop_Shr32,
+                                                  binop(Iop_And32,
+                                                        getIReg(rs),
+                                                        mkU32(0x80000000)),
+                                                  mkU8(31)),
+                                            getIReg(rs)),
+                                      mkU64(0x0000000000008000ULL)));
+                     assign(t1, binop(Iop_CmpNE32,
+                                      binop(Iop_And32,
+                                            unop(Iop_64HIto32, mkexpr(t0)),
+                                            mkU32(0x1)),
+                                      binop(Iop_And32,
+                                            binop(Iop_Shr32,
+                                                  unop(Iop_64to32, mkexpr(t0)),
+                                                  mkU8(31)),
+                                            mkU32(0x1))));
+                     assign(t2, IRExpr_ITE(mkexpr(t1),
+                                           mkU32(0x7fffffff),
+                                           unop(Iop_64to32, mkexpr(t0))));
+                     putDSPControl(IRExpr_ITE(mkexpr(t1),
+                                              binop(Iop_Or32,
+                                                    getDSPControl(),
+                                                    mkU32(0x400000)),
+                                              getDSPControl()));
+                     assign(t3, binop(Iop_Add64,
+                                      binop(Iop_32HLto64,
+                                            binop(Iop_Shr32,
+                                                  binop(Iop_And32,
+                                                        getIReg(rt),
+                                                        mkU32(0x80000000)),
+                                                  mkU8(31)),
+                                            getIReg(rt)),
+                                      mkU64(0x0000000000008000ULL)));
+                     assign(t4, binop(Iop_CmpNE32,
+                                      binop(Iop_And32,
+                                            unop(Iop_64HIto32, mkexpr(t3)),
+                                            mkU32(0x1)),
+                                      binop(Iop_And32,
+                                            binop(Iop_Shr32,
+                                                  unop(Iop_64to32, mkexpr(t3)),
+                                                  mkU8(31)),
+                                            mkU32(0x1))));
+                     assign(t5, IRExpr_ITE(mkexpr(t4),
+                                           mkU32(0x7fffffff),
+                                           unop(Iop_64to32, mkexpr(t3))));
+                     putDSPControl(IRExpr_ITE(mkexpr(t4),
+                                              binop(Iop_Or32,
+                                                    getDSPControl(),
+                                                    mkU32(0x400000)),
+                                              getDSPControl()));
+                     putIReg(rd, binop(Iop_16HLto32,
+                                       unop(Iop_32HIto16, mkexpr(t2)),
+                                       unop(Iop_32HIto16, mkexpr(t5))));
+                     break;
+                  }
+                  case 0x1E: {  /* PRECR_SRA.PH.W */
+                     DIP("precr_sra.ph.w r%d, r%d, %d", rt, rs, rd);
+                     vassert(!mode64);
+
+                     if (0 == rd) {
+                        putIReg(rt, binop(Iop_16HLto32,
+                                          unop(Iop_32to16, getIReg(rt)),
+                                          unop(Iop_32to16, getIReg(rs))));
+                     } else {
+                        putIReg(rt, binop(Iop_16HLto32,
+                                          unop(Iop_32to16, binop(Iop_Sar32,
+                                                                 getIReg(rt),
+                                                                 mkU8(rd))),
+                                          unop(Iop_32to16, binop(Iop_Sar32,
+                                                                 getIReg(rs),
+                                                                 mkU8(rd)))));
+                     }
+                     break;
+                  }
+                  case 0x1F: {  /* PRECR_SRA_R.PH.W */
+                     DIP("precr_sra_r.ph.w r%d, r%d, %d", rt, rs, rd);
+                     vassert(!mode64);
+
+                     t0 = newTemp(Ity_I32);
+                     t1 = newTemp(Ity_I32);
+
+                     if (0 == rd) {
+                        putIReg(rt, binop(Iop_16HLto32,
+                                          unop(Iop_32to16, getIReg(rt)),
+                                          unop(Iop_32to16, getIReg(rs))));
+                     } else {
+                        assign(t0, binop(Iop_Shr32,
+                                         binop(Iop_Add32,
+                                               binop(Iop_Sar32,
+                                                     getIReg(rt),
+                                                     mkU8(rd-1)),
+                                               mkU32(0x1)),
+                                         mkU8(0x1)));
+                        assign(t1, binop(Iop_Shr32,
+                                         binop(Iop_Add32,
+                                               binop(Iop_Sar32,
+                                                     getIReg(rs),
+                                                     mkU8(rd-1)),
+                                               mkU32(0x1)),
+                                         mkU8(0x1)));
+                        putIReg(rt, binop(Iop_16HLto32,
+                                          unop(Iop_32to16, mkexpr(t0)),
+                                          unop(Iop_32to16, mkexpr(t1))));
+                     };
+                     break;
+                  }
+                  case 0xE: {  /* PACKRL.PH */
+                     DIP("packrl.ph r%d, r%d, r%d", rd, rs, rt);
+                     vassert(!mode64);
+
+                     putIReg(rd, binop(Iop_16HLto32,
+                                       unop(Iop_32to16, getIReg(rs)),
+                                       unop(Iop_32HIto16, getIReg(rt))));
+                     break;
+                  }
+                  case 0x18: {  /* CMPGDU.EQ.QB */
+                     DIP("cmpgdu.eq.qb r%d, r%d, r%d", rd, rs, rt);
+                     vassert(!mode64);
+                     t1 = newTemp(Ity_I1);
+                     t2 = newTemp(Ity_I1);
+                     t3 = newTemp(Ity_I1);
+                     t4 = newTemp(Ity_I1);
+                     t5 = newTemp(Ity_I32);
+                     t6 = newTemp(Ity_I32);
+                     t7 = newTemp(Ity_I32);
+                     t8 = newTemp(Ity_I32);
+
+                     assign(t1,
+                            binop(Iop_CmpEQ32,
+                                  unop(Iop_8Uto32,
+                                       unop(Iop_16to8,
+                                            unop(Iop_32to16, getIReg(rs)))),
+                                  unop(Iop_8Uto32,
+                                       unop(Iop_16to8,
+                                            unop(Iop_32to16, getIReg(rt))))));
+                     assign(t5, IRExpr_ITE(mkexpr(t1),
+                                           mkU32(0x00000001), mkU32(0)));
+                     putDSPControl(IRExpr_ITE(mkexpr(t1),
+                                              binop(Iop_Or32,
+                                                    getDSPControl(),
+                                                    mkU32(0x01000000)),
+                                              binop(Iop_And32,
+                                                    getDSPControl(),
+                                                    mkU32(0xfeffffff))));
+
+                     assign(t2, binop(Iop_CmpEQ32,
+                                      unop(Iop_8Uto32,
+                                           unop(Iop_16HIto8,
+                                                unop(Iop_32to16, getIReg(rs)))),
+                                      unop(Iop_8Uto32,
+                                           unop(Iop_16HIto8,
+                                                unop(Iop_32to16,
+                                                     getIReg(rt))))));
+                     assign(t6, IRExpr_ITE(mkexpr(t2),
+                                           mkU32(0x00000002), mkU32(0)));
+                     putDSPControl(IRExpr_ITE(mkexpr(t2),
+                                              binop(Iop_Or32,
+                                                    getDSPControl(),
+                                                    mkU32(0x02000000)),
+                                              binop(Iop_And32,
+                                                    getDSPControl(),
+                                                    mkU32(0xfdffffff))));
+
+                     assign(t3, binop(Iop_CmpEQ32,
+                                      unop(Iop_8Uto32,
+                                           unop(Iop_16to8,
+                                                unop(Iop_32HIto16,
+                                                     getIReg(rs)))),
+                                      unop(Iop_8Uto32,
+                                           unop(Iop_16to8,
+                                                unop(Iop_32HIto16,
+                                                     getIReg(rt))))));
+                     assign(t7, IRExpr_ITE(mkexpr(t3),
+                                           mkU32(0x00000004), mkU32(0)));
+                     putDSPControl(IRExpr_ITE(mkexpr(t3),
+                                              binop(Iop_Or32,
+                                                    getDSPControl(),
+                                                    mkU32(0x04000000)),
+                                              binop(Iop_And32,
+                                                    getDSPControl(),
+                                                    mkU32(0xfbffffff))));
+
+                     assign(t4, binop(Iop_CmpEQ32,
+                                      unop(Iop_8Uto32,
+                                           unop(Iop_16HIto8,
+                                                unop(Iop_32HIto16,
+                                                     getIReg(rs)))),
+                                      unop(Iop_8Uto32,
+                                           unop(Iop_16HIto8,
+                                                unop(Iop_32HIto16,
+                                                     getIReg(rt))))));
+                     assign(t8, IRExpr_ITE(mkexpr(t4),
+                                           mkU32(0x00000008), mkU32(0)));
+                     putDSPControl(IRExpr_ITE(mkexpr(t4),
+                                              binop(Iop_Or32,
+                                                    getDSPControl(),
+                                                    mkU32(0x08000000)),
+                                              binop(Iop_And32,
+                                                    getDSPControl(),
+                                                    mkU32(0xf7ffffff))));
+
+                     putIReg(rd, binop(Iop_Or32,
+                                       binop(Iop_Or32,
+                                             binop(Iop_Or32,
+                                                   mkexpr(t5), mkexpr(t6)),
+                                             mkexpr(t7)),
+                                       mkexpr(t8)));
+                     break;
+                  }
+                  case 0x19: {  /* CMPGDU.LT.QB */
+                     DIP("cmpgdu.lt.qb r%d, r%d, r%d", rd, rs, rt);
+                     vassert(!mode64);
+                     t1 = newTemp(Ity_I1);
+                     t2 = newTemp(Ity_I1);
+                     t3 = newTemp(Ity_I1);
+                     t4 = newTemp(Ity_I1);
+                     t5 = newTemp(Ity_I32);
+                     t6 = newTemp(Ity_I32);
+                     t7 = newTemp(Ity_I32);
+                     t8 = newTemp(Ity_I32);
+
+                     assign(t1, binop(Iop_CmpLT32U,
+                                      unop(Iop_8Uto32,
+                                           unop(Iop_16to8,
+                                                unop(Iop_32to16, getIReg(rs)))),
+                                      unop(Iop_8Uto32,
+                                           unop(Iop_16to8,
+                                                unop(Iop_32to16,
+                                                     getIReg(rt))))));
+                     assign(t5, IRExpr_ITE(mkexpr(t1),
+                                           mkU32(0x00000001), mkU32(0)));
+                     putDSPControl(IRExpr_ITE(mkexpr(t1),
+                                              binop(Iop_Or32,
+                                                    getDSPControl(),
+                                                    mkU32(0x01000000)),
+                                              binop(Iop_And32,
+                                                    getDSPControl(),
+                                                    mkU32(0xfeffffff))));
+
+                     assign(t2, binop(Iop_CmpLT32U,
+                                      unop(Iop_8Uto32,
+                                           unop(Iop_16HIto8,
+                                                unop(Iop_32to16, getIReg(rs)))),
+                                      unop(Iop_8Uto32,
+                                           unop(Iop_16HIto8,
+                                                unop(Iop_32to16,
+                                                     getIReg(rt))))));
+                     assign(t6, IRExpr_ITE(mkexpr(t2),
+                                           mkU32(0x00000002), mkU32(0)));
+                     putDSPControl(IRExpr_ITE(mkexpr(t2),
+                                              binop(Iop_Or32,
+                                                    getDSPControl(),
+                                                    mkU32(0x02000000)),
+                                              binop(Iop_And32,
+                                                    getDSPControl(),
+                                                    mkU32(0xfdffffff))));
+
+                     assign(t3, binop(Iop_CmpLT32U,
+                                      unop(Iop_8Uto32,
+                                           unop(Iop_16to8,
+                                                unop(Iop_32HIto16,
+                                                     getIReg(rs)))),
+                                      unop(Iop_8Uto32,
+                                           unop(Iop_16to8,
+                                                unop(Iop_32HIto16,
+                                                     getIReg(rt))))));
+                     assign(t7, IRExpr_ITE(mkexpr(t3),
+                                           mkU32(0x00000004), mkU32(0)));
+                     putDSPControl(IRExpr_ITE(mkexpr(t3),
+                                              binop(Iop_Or32,
+                                                    getDSPControl(),
+                                                    mkU32(0x04000000)),
+                                              binop(Iop_And32,
+                                                    getDSPControl(),
+                                                    mkU32(0xfbffffff))));
+
+                     assign(t4, binop(Iop_CmpLT32U,
+                                      unop(Iop_8Uto32,
+                                           unop(Iop_16HIto8,
+                                                unop(Iop_32HIto16,
+                                                     getIReg(rs)))),
+                                      unop(Iop_8Uto32,
+                                           unop(Iop_16HIto8,
+                                                unop(Iop_32HIto16,
+                                                     getIReg(rt))))));
+                     assign(t8, IRExpr_ITE(mkexpr(t4),
+                                           mkU32(0x00000008), mkU32(0)));
+                     putDSPControl(IRExpr_ITE(mkexpr(t4),
+                                              binop(Iop_Or32,
+                                                    getDSPControl(),
+                                                    mkU32(0x08000000)),
+                                              binop(Iop_And32,
+                                                    getDSPControl(),
+                                                    mkU32(0xf7ffffff))));
+
+                     putIReg(rd, binop(Iop_Or32,
+                                       binop(Iop_Or32,
+                                             binop(Iop_Or32,
+                                                   mkexpr(t5), mkexpr(t6)),
+                                             mkexpr(t7)),
+                                       mkexpr(t8)));
+                     break;
+                  }
+                  case 0x1A: {  /* CMPGDU.LE.QB */
+                     DIP("cmpgdu.le.qb r%d, r%d, r%d", rd, rs, rt);
+                     vassert(!mode64);
+                     t1 = newTemp(Ity_I1);
+                     t2 = newTemp(Ity_I1);
+                     t3 = newTemp(Ity_I1);
+                     t4 = newTemp(Ity_I1);
+                     t5 = newTemp(Ity_I32);
+                     t6 = newTemp(Ity_I32);
+                     t7 = newTemp(Ity_I32);
+                     t8 = newTemp(Ity_I32);
+
+                     assign(t1, binop(Iop_CmpLE32U,
+                                      unop(Iop_8Uto32,
+                                           unop(Iop_16to8,
+                                                unop(Iop_32to16, getIReg(rs)))),
+                                      unop(Iop_8Uto32,
+                                           unop(Iop_16to8,
+                                                unop(Iop_32to16,
+                                                     getIReg(rt))))));
+                     assign(t5, IRExpr_ITE(mkexpr(t1),
+                                           mkU32(0x00000001),
+                                           mkU32(0)));
+                     putDSPControl(IRExpr_ITE(mkexpr(t1),
+                                              binop(Iop_Or32,
+                                                    getDSPControl(),
+                                                    mkU32(0x01000000)),
+                                              binop(Iop_And32,
+                                                    getDSPControl(),
+                                                    mkU32(0xfeffffff))));
+
+                     assign(t2, binop(Iop_CmpLE32U,
+                                      unop(Iop_8Uto32,
+                                           unop(Iop_16HIto8,
+                                                unop(Iop_32to16, getIReg(rs)))),
+                                      unop(Iop_8Uto32,
+                                           unop(Iop_16HIto8,
+                                                unop(Iop_32to16,
+                                                     getIReg(rt))))));
+                     assign(t6, IRExpr_ITE(mkexpr(t2),
+                                           mkU32(0x00000002), mkU32(0)));
+                     putDSPControl(IRExpr_ITE(mkexpr(t2),
+                                              binop(Iop_Or32,
+                                                    getDSPControl(),
+                                                    mkU32(0x02000000)),
+                                              binop(Iop_And32,
+                                                    getDSPControl(),
+                                                    mkU32(0xfdffffff))));
+
+                     assign(t3, binop(Iop_CmpLE32U,
+                                      unop(Iop_8Uto32,
+                                           unop(Iop_16to8,
+                                                unop(Iop_32HIto16,
+                                                     getIReg(rs)))),
+                                      unop(Iop_8Uto32,
+                                           unop(Iop_16to8,
+                                                unop(Iop_32HIto16,
+                                                     getIReg(rt))))));
+                     assign(t7, IRExpr_ITE(mkexpr(t3),
+                                           mkU32(0x00000004), mkU32(0)));
+                     putDSPControl(IRExpr_ITE(mkexpr(t3),
+                                              binop(Iop_Or32,
+                                                    getDSPControl(),
+                                                    mkU32(0x04000000)),
+                                              binop(Iop_And32,
+                                                    getDSPControl(),
+                                                    mkU32(0xfbffffff))));
+
+                     assign(t4, binop(Iop_CmpLE32U,
+                                      unop(Iop_8Uto32,
+                                           unop(Iop_16HIto8,
+                                                unop(Iop_32HIto16,
+                                                     getIReg(rs)))),
+                                      unop(Iop_8Uto32,
+                                           unop(Iop_16HIto8,
+                                                unop(Iop_32HIto16,
+                                                     getIReg(rt))))));
+                     assign(t8, IRExpr_ITE(mkexpr(t4),
+                                           mkU32(0x00000008), mkU32(0)));
+                     putDSPControl(IRExpr_ITE(mkexpr(t4),
+                                              binop(Iop_Or32,
+                                                    getDSPControl(),
+                                                    mkU32(0x08000000)),
+                                              binop(Iop_And32,
+                                                    getDSPControl(),
+                                                    mkU32(0xf7ffffff))));
+
+                     putIReg(rd, binop(Iop_Or32,
+                                       binop(Iop_Or32,
+                                             binop(Iop_Or32,
+                                                   mkexpr(t5), mkexpr(t6)),
+                                             mkexpr(t7)),
+                                       mkexpr(t8)));
+                     break;
+                  }
+                  default:
+                     return -1;
+               }
+               break;  /* end of CMPU.EQ.QB */
+            }
+            case 0x13: {  /* SHLL.QB */
+               switch(sa) {
+                  case 0x0: {  /* SHLL.QB */
+                     DIP("shll.qb r%d, r%d, %d", rd, rt, rs);
+                     vassert(!mode64);
+                     t0 = newTemp(Ity_I32);
+                     t1 = newTemp(Ity_I1);
+                     t2 = newTemp(Ity_I1);
+                     t3 = newTemp(Ity_I1);
+                     t4 = newTemp(Ity_I32);
+                     t5 = newTemp(Ity_I32);
+                     t6 = newTemp(Ity_I1);
+                     t7 = newTemp(Ity_I1);
+                     t8 = newTemp(Ity_I1);
+                     t9 = newTemp(Ity_I32);
+                     t10 = newTemp(Ity_I32);
+                     t11 = newTemp(Ity_I1);
+                     t12 = newTemp(Ity_I1);
+                     t13 = newTemp(Ity_I1);
+                     t14 = newTemp(Ity_I32);
+                     t15 = newTemp(Ity_I32);
+                     t16 = newTemp(Ity_I1);
+                     t17 = newTemp(Ity_I1);
+                     t18 = newTemp(Ity_I32);
+
+                     if (0 == rs) {
+                        putIReg(rd, getIReg(rt));
+                     } else {
+                        /* Shift bits 7..0. */
+                        assign(t0, binop(Iop_Shl32,
+                                         unop(Iop_8Uto32,
+                                              unop(Iop_32to8, getIReg(rt))),
+                                         unop(Iop_32to8,
+                                              binop(Iop_And32,
+                                                    mkU32(rs),
+                                                    mkU32(0x7)))));
+                        /* Check if discard isn't 0x0 and 0xffffffff. */
+                        assign(t1, binop(Iop_CmpNE32,
+                                         unop(Iop_8Uto32,
+                                              unop(Iop_16HIto8,
+                                                   unop(Iop_32to16,
+                                                        mkexpr(t0)))),
+                                         mkU32(0x00000000)));
+                        assign(t2, binop(Iop_CmpNE32,
+                                         unop(Iop_8Uto32,
+                                              unop(Iop_16HIto8,
+                                                   unop(Iop_32to16,
+                                                        mkexpr(t0)))),
+                                         mkU32(0x000000ff)));
+                        assign(t4, binop(Iop_Or32,
+                                         getDSPControl(), mkU32(0x400000)));
+                        putDSPControl(IRExpr_ITE(mkexpr(t1),
+                                                 IRExpr_ITE(mkexpr(t2),
+                                                            mkexpr(t4),
+                                                            getDSPControl()),
+                                                 getDSPControl()));
+
+                        /* Shift bits 15..8. */
+                        assign(t5, binop(Iop_Shl32,
+                                         unop(Iop_8Uto32,
+                                              unop(Iop_16HIto8,
+                                                   unop(Iop_32to16,
+                                                        getIReg(rt)))),
+                                         unop(Iop_32to8,
+                                              binop(Iop_And32,
+                                                    mkU32(rs),
+                                                    mkU32(0x7)))));
+                        /* Check if discard isn't 0x0 and 0xffffffff. */
+                        assign(t6, binop(Iop_CmpNE32,
+                                         unop(Iop_8Uto32,
+                                              unop(Iop_16HIto8,
+                                                   unop(Iop_32to16,
+                                                        mkexpr(t5)))),
+                                         mkU32(0x00000000)));
+                        assign(t7, binop(Iop_CmpNE32,
+                                         unop(Iop_8Uto32,
+                                              unop(Iop_16HIto8,
+                                                   unop(Iop_32to16,
+                                                        mkexpr(t5)))),
+                                         mkU32(0x000000ff)));
+                        assign(t9, binop(Iop_Or32,
+                                         getDSPControl(),
+                                         mkU32(0x400000)));
+                        putDSPControl(IRExpr_ITE(mkexpr(t6),
+                                                 IRExpr_ITE(mkexpr(t7),
+                                                            mkexpr(t9),
+                                                            getDSPControl()),
+                                                 getDSPControl()));
+
+                        /* Shift bits 23..16. */
+                        assign(t10, binop(Iop_Shl32,
+                                          unop(Iop_8Uto32,
+                                               unop(Iop_16to8,
+                                                    unop(Iop_32HIto16,
+                                                         getIReg(rt)))),
+                                          unop(Iop_32to8,
+                                               binop(Iop_And32,
+                                                     mkU32(rs),
+                                                     mkU32(0x7)))));
+                        /* Check if discard isn't 0x0 and 0xffffffff. */
+                        assign(t11, binop(Iop_CmpNE32,
+                                          unop(Iop_8Uto32,
+                                               unop(Iop_16HIto8,
+                                                    unop(Iop_32to16,
+                                                         mkexpr(t10)))),
+                                          mkU32(0x00000000)));
+                        assign(t12, binop(Iop_CmpNE32,
+                                          unop(Iop_8Uto32,
+                                               unop(Iop_16HIto8,
+                                                    unop(Iop_32to16,
+                                                         mkexpr(t10)))),
+                                          mkU32(0x000000ff)));
+
+                        assign(t14, binop(Iop_Or32,
+                                          getDSPControl(),
+                                          mkU32(0x400000)));
+                        putDSPControl(IRExpr_ITE(mkexpr(t11),
+                                                 IRExpr_ITE(mkexpr(t12),
+                                                            mkexpr(t14),
+                                                            getDSPControl()),
+                                                 getDSPControl()));
+
+                        /* Shift bits 31..24. */
+                        assign(t15, binop(Iop_Shl32,
+                                          unop(Iop_8Uto32,
+                                               unop(Iop_16HIto8,
+                                                    unop(Iop_32HIto16,
+                                                         getIReg(rt)))),
+                                          unop(Iop_32to8,
+                                               binop(Iop_And32,
+                                                     mkU32(rs),
+                                                     mkU32(0x7)))));
+                        /* Check if discard isn't 0x0 and 0xffffffff. */
+                        assign(t16, binop(Iop_CmpNE32,
+                                          unop(Iop_8Uto32,
+                                               unop(Iop_16HIto8,
+                                                    unop(Iop_32to16,
+                                                         mkexpr(t15)))),
+                                          mkU32(0x00000000)));
+                        assign(t17, binop(Iop_CmpNE32,
+                                          unop(Iop_8Uto32,
+                                               unop(Iop_16HIto8,
+                                                    unop(Iop_32to16,
+                                                         mkexpr(t15)))),
+                                          mkU32(0x000000ff)));
+
+                        assign(t18, binop(Iop_Or32,
+                                          getDSPControl(),
+                                          mkU32(0x400000)));
+                        putDSPControl(IRExpr_ITE(mkexpr(t16),
+                                                 IRExpr_ITE(mkexpr(t17),
+                                                            mkexpr(t18),
+                                                            getDSPControl()),
+                                                 getDSPControl()));
+
+                        putIReg(rd, binop(Iop_16HLto32,
+                                          binop(Iop_8HLto16,
+                                                unop(Iop_32to8, mkexpr(t15)),
+                                                unop(Iop_32to8, mkexpr(t10))),
+                                          binop(Iop_8HLto16,
+                                                unop(Iop_32to8, mkexpr(t5)),
+                                                unop(Iop_32to8, mkexpr(t0)))));
+                     }
+                     break;
+                  }
+                  case 0x3: {  /* SHRL.QB */
+                     DIP("shrl.qb r%d, r%d, %d", rd, rt, rs);
+                     vassert(!mode64);
+                     t0 = newTemp(Ity_I32);
+                     t1 = newTemp(Ity_I8);
+                     t2 = newTemp(Ity_I32);
+                     t3 = newTemp(Ity_I8);
+                     t4 = newTemp(Ity_I32);
+                     t5 = newTemp(Ity_I8);
+                     t6 = newTemp(Ity_I32);
+                     t7 = newTemp(Ity_I8);
+                     t9 = newTemp(Ity_I32);
+
+                     assign(t9, binop(Iop_And32, getIReg(rs), mkU32(0x7)));
+                     assign(t0, unop(Iop_8Uto32,
+                                     unop(Iop_16to8,
+                                          unop(Iop_32to16, getIReg(rt)))));
+                     assign(t1, unop(Iop_32to8,
+                                     binop(Iop_Shr32,
+                                           mkexpr(t0),
+                                           unop(Iop_32to8, mkexpr(t9)))));
+
+                     assign(t2, unop(Iop_8Uto32,
+                                     unop(Iop_16HIto8,
+                                          unop(Iop_32to16, getIReg(rt)))));
+                     assign(t3, unop(Iop_32to8,
+                                     binop(Iop_Shr32,
+                                           mkexpr(t2),
+                                           unop(Iop_32to8, mkexpr(t9)))));
+
+                     assign(t4, unop(Iop_8Uto32,
+                                     unop(Iop_16to8,
+                                          unop(Iop_32HIto16, getIReg(rt)))));
+                     assign(t5, unop(Iop_32to8,
+                                     binop(Iop_Shr32,
+                                           mkexpr(t4),
+                                           unop(Iop_32to8, mkexpr(t9)))));
+
+                     assign(t6, unop(Iop_8Uto32,
+                                     unop(Iop_16HIto8,
+                                          unop(Iop_32HIto16, getIReg(rt)))));
+                     assign(t7, unop(Iop_32to8,
+                                     binop(Iop_Shr32,
+                                           mkexpr(t6),
+                                           unop(Iop_32to8, mkexpr(t9)))));
+                     putIReg(rd, IRExpr_ITE(binop(Iop_CmpEQ32,
+                                                  mkexpr(t9),
+                                                  mkU32(0x0)),
+                                            getIReg(rt),
+                                            binop(Iop_16HLto32,
+                                                  binop(Iop_8HLto16,
+                                                        mkexpr(t7),
+                                                        mkexpr(t5)),
+                                                  binop(Iop_8HLto16,
+                                                        mkexpr(t3),
+                                                        mkexpr(t1)))));
+                     break;
+                  }
+                  case 0x2: {  /* SHLLV.QB */
+                     DIP("shllv.qb r%d, r%d, r%d", rd, rt, rs);
+                     vassert(!mode64);
+                     t0 = newTemp(Ity_I32);
+                     t1 = newTemp(Ity_I1);
+                     t2 = newTemp(Ity_I1);
+                     t3 = newTemp(Ity_I1);
+                     t4 = newTemp(Ity_I32);
+                     t5 = newTemp(Ity_I32);
+                     t6 = newTemp(Ity_I1);
+                     t7 = newTemp(Ity_I1);
+                     t8 = newTemp(Ity_I1);
+                     t9 = newTemp(Ity_I32);
+                     t10 = newTemp(Ity_I32);
+                     t11 = newTemp(Ity_I1);
+                     t12 = newTemp(Ity_I1);
+                     t13 = newTemp(Ity_I1);
+                     t14 = newTemp(Ity_I32);
+                     t15 = newTemp(Ity_I32);
+                     t16 = newTemp(Ity_I1);
+                     t17 = newTemp(Ity_I1);
+                     t18 = newTemp(Ity_I32);
+
+                     /* Shift bits 7..0. */
+                     assign(t0, binop(Iop_Shl32,
+                                      unop(Iop_8Uto32,
+                                           unop(Iop_32to8, getIReg(rt))),
+                                      unop(Iop_32to8,
+                                           binop(Iop_And32,
+                                                 getIReg(rs),
+                                                 mkU32(0x7)))));
+                     /* Check if discard isn't 0x0 and 0xffffffff. */
+                     assign(t1, binop(Iop_CmpNE32,
+                                      unop(Iop_8Uto32,
+                                           unop(Iop_16HIto8,
+                                                unop(Iop_32to16, mkexpr(t0)))),
+                                      mkU32(0x00000000)));
+                     assign(t2, binop(Iop_CmpNE32,
+                                      unop(Iop_8Uto32,
+                                           unop(Iop_16HIto8,
+                                                unop(Iop_32to16, mkexpr(t0)))),
+                                      mkU32(0x000000ff)));
+
+                     assign(t4, binop(Iop_Or32,
+                                      getDSPControl(),
+                                      mkU32(0x400000)));
+                     putDSPControl(IRExpr_ITE(mkexpr(t1),
+                                              IRExpr_ITE(mkexpr(t2),
+                                                         mkexpr(t4),
+                                                         getDSPControl()),
+                                              getDSPControl()));
+
+                     /* Shift bits 15..8. */
+                     assign(t5, binop(Iop_Shl32,
+                                      unop(Iop_8Uto32,
+                                           unop(Iop_16HIto8,
+                                                unop(Iop_32to16, getIReg(rt)))),
+                                      unop(Iop_32to8,
+                                           binop(Iop_And32,
+                                                 getIReg(rs),
+                                                 mkU32(0x7)))));
+                     /* Check if discard isn't 0x0 and 0xffffffff. */
+                     assign(t6, binop(Iop_CmpNE32,
+                                      unop(Iop_8Uto32,
+                                           unop(Iop_16HIto8,
+                                                unop(Iop_32to16, mkexpr(t5)))),
+                                       mkU32(0x00000000)));
+                     assign(t7, binop(Iop_CmpNE32,
+                                      unop(Iop_8Uto32,
+                                           unop(Iop_16HIto8,
+                                                unop(Iop_32to16, mkexpr(t5)))),
+                                      mkU32(0x000000ff)));
+
+                     assign(t9, binop(Iop_Or32,
+                                      getDSPControl(),
+                                      mkU32(0x400000)));
+                     putDSPControl(IRExpr_ITE(mkexpr(t6),
+                                              IRExpr_ITE(mkexpr(t7),
+                                                         mkexpr(t9),
+                                                         getDSPControl()),
+                                              getDSPControl()));
+
+                     /* Shift bits 23..16. */
+                     assign(t10, binop(Iop_Shl32,
+                                       unop(Iop_8Uto32,
+                                            unop(Iop_16to8,
+                                                 unop(Iop_32HIto16,
+                                                      getIReg(rt)))),
+                                       unop(Iop_32to8,
+                                            binop(Iop_And32,
+                                                  getIReg(rs),
+                                                  mkU32(0x7)))));
+                     /* Check if discard isn't 0x0 and 0xffffffff. */
+                     assign(t11, binop(Iop_CmpNE32,
+                                       unop(Iop_8Uto32,
+                                            unop(Iop_16HIto8,
+                                                 unop(Iop_32to16,
+                                                      mkexpr(t10)))),
+                                       mkU32(0x00000000)));
+                     assign(t12, binop(Iop_CmpNE32,
+                                       unop(Iop_8Uto32,
+                                            unop(Iop_16HIto8,
+                                                 unop(Iop_32to16,
+                                                      mkexpr(t10)))),
+                                       mkU32(0x000000ff)));
+
+                     assign(t14, binop(Iop_Or32,
+                                       getDSPControl(),
+                                       mkU32(0x400000)));
+                     putDSPControl(IRExpr_ITE(mkexpr(t11),
+                                              IRExpr_ITE(mkexpr(t12),
+                                                         mkexpr(t14),
+                                                         getDSPControl()),
+                                              getDSPControl()));
+
+                     /* Shift bits 31..24. */
+                     assign(t15, binop(Iop_Shl32,
+                                       unop(Iop_8Uto32,
+                                            unop(Iop_16HIto8,
+                                                 unop(Iop_32HIto16,
+                                                      getIReg(rt)))),
+                                       unop(Iop_32to8,
+                                            binop(Iop_And32,
+                                                  getIReg(rs),
+                                                  mkU32(0x7)))));
+                     /* Check if discard isn't 0x0 and 0xffffffff. */
+                     assign(t16, binop(Iop_CmpNE32,
+                                       unop(Iop_8Uto32,
+                                            unop(Iop_16HIto8,
+                                                 unop(Iop_32to16,
+                                                      mkexpr(t15)))),
+                                       mkU32(0x00000000)));
+                     assign(t17, binop(Iop_CmpNE32,
+                                       unop(Iop_8Uto32,
+                                            unop(Iop_16HIto8,
+                                                 unop(Iop_32to16,
+                                                      mkexpr(t15)))),
+                                       mkU32(0x000000ff)));
+
+                     assign(t18, binop(Iop_Or32,
+                                       getDSPControl(),
+                                       mkU32(0x400000)));
+                     putDSPControl(IRExpr_ITE(mkexpr(t16),
+                                              IRExpr_ITE(mkexpr(t17),
+                                                         mkexpr(t18),
+                                                         getDSPControl()),
+                                              getDSPControl()));
+
+                     putIReg(rd, IRExpr_ITE(binop(Iop_CmpEQ32,
+                                                  binop(Iop_And32,
+                                                        getIReg(rs),
+                                                        mkU32(0x7)),
+                                                  mkU32(0x0)),
+                                            getIReg(rt),
+                                            binop(Iop_16HLto32,
+                                                  binop(Iop_8HLto16,
+                                                        unop(Iop_32to8,
+                                                             mkexpr(t15)),
+                                                        unop(Iop_32to8,
+                                                             mkexpr(t10))),
+                                                  binop(Iop_8HLto16,
+                                                        unop(Iop_32to8,
+                                                             mkexpr(t5)),
+                                                        unop(Iop_32to8,
+                                                             mkexpr(t0))))));
+                     break;
+                  }
+                  case 0x1: {  /* SHRLV.QB */
+                     DIP("shrlv.qb r%d, r%d, r%d", rd, rt, rs);
+                     vassert(!mode64);
+                     t0 = newTemp(Ity_I8);
+                     t1 = newTemp(Ity_I8);
+                     t2 = newTemp(Ity_I8);
+                     t3 = newTemp(Ity_I8);
+
+                     assign(t0, unop(Iop_32to8,
+                                     binop(Iop_Shr32,
+                                           unop(Iop_8Uto32,
+                                                unop(Iop_32to8, getIReg(rt))),
+                                           mkU8(rs))));
+                     assign(t1, unop(Iop_32to8,
+                                     binop(Iop_Shr32,
+                                           unop(Iop_8Uto32,
+                                                unop(Iop_16HIto8,
+                                                     unop(Iop_32to16,
+                                                          getIReg(rt)))),
+                                           mkU8(rs))));
+                     assign(t2, unop(Iop_32to8,
+                                      binop(Iop_Shr32,
+                                            unop(Iop_8Uto32,
+                                                 unop(Iop_16to8,
+                                                      unop(Iop_32HIto16,
+                                                           getIReg(rt)))),
+                                            mkU8(rs))));
+                     assign(t3, unop(Iop_32to8,
+                                     binop(Iop_Shr32,
+                                           unop(Iop_8Uto32,
+                                                unop(Iop_16HIto8,
+                                                     unop(Iop_32HIto16,
+                                                          getIReg(rt)))),
+                                           mkU8(rs))));
+                     putIReg(rd,
+                             binop(Iop_16HLto32,
+                                   binop(Iop_8HLto16, mkexpr(t3), mkexpr(t2)),
+                                   binop(Iop_8HLto16, mkexpr(t1), mkexpr(t0))));
+                     break;
+                  }
+                  case 0x4: {  /* SHRA.QB */
+                     DIP("shra.qb r%d, r%d, %d", rd, rt, rs);
+                     vassert(!mode64);
+                     t0 = newTemp(Ity_I32);
+                     t1 = newTemp(Ity_I32);
+                     t2 = newTemp(Ity_I32);
+                     t3 = newTemp(Ity_I32);
+                     t4 = newTemp(Ity_I32);
+                     t5 = newTemp(Ity_I32);
+                     t6 = newTemp(Ity_I32);
+                     t7 = newTemp(Ity_I32);
+                     t8 = newTemp(Ity_I32);
+                     t9 = newTemp(Ity_I32);
+                     t10 = newTemp(Ity_I32);
+                     t11 = newTemp(Ity_I32);
+
+                     /* ========== GPR[rt]_31..24 ========== */
+                     assign(t1,
+                            unop(Iop_8Uto32,
+                                 unop(Iop_16HIto8,
+                                      unop(Iop_32HIto16, getIReg(rt)))));
+                     assign(t2,
+                            binop(Iop_Shr32, mkexpr(t1), mkU8(rs)));
+                     /* tempD_7..0 */
+                     assign(t0,
+                            binop(Iop_Or32,
+                                  mkexpr(t2),
+                                  binop(Iop_Shl32,
+                                        IRExpr_ITE(binop(Iop_CmpEQ32,
+                                                         binop(Iop_And32,
+                                                               mkexpr(t1),
+                                                               mkU32(0x00000080)
+                                                              ),
+                                                         mkU32(0x00000080)),
+                                                   mkU32(0xFFFFFFFF),
+                                                   mkU32(0x00000000)),
+                                        binop(Iop_Sub8, mkU8(0x8), mkU8(rs)))));
+
+                     /* ========== GPR[rt]_23..16 ========== */
+                     assign(t4,
+                            unop(Iop_8Uto32,
+                                 unop(Iop_16to8,
+                                      unop(Iop_32HIto16, getIReg(rt)))));
+                     assign(t5, binop(Iop_Shr32, mkexpr(t4), mkU8(rs)));
+                     /* tempC_7..0 */
+                     assign(t3,
+                            binop(Iop_Or32,
+                                  mkexpr(t5),
+                                  binop(Iop_Shl32,
+                                        IRExpr_ITE(binop(Iop_CmpEQ32,
+                                                         binop(Iop_And32,
+                                                               mkexpr(t4),
+                                                               mkU32(0x00000080)
+                                                              ),
+                                                         mkU32(0x00000080)),
+                                                   mkU32(0xFFFFFFFF),
+                                                   mkU32(0x00000000)),
+                                        binop(Iop_Sub8, mkU8(0x8), mkU8(rs)))));
+
+                     /* ========== GPR[rt]_15..8 ========== */
+                     assign(t7,
+                            unop(Iop_8Uto32,
+                                 unop(Iop_16HIto8,
+                                      unop(Iop_32to16, getIReg(rt)))));
+                     assign(t8, binop(Iop_Shr32, mkexpr(t7), mkU8(rs)));
+                     /* tempB_7..0 */
+                     assign(t6,
+                            binop(Iop_Or32,
+                                  mkexpr(t8),
+                                  binop(Iop_Shl32,
+                                        IRExpr_ITE(binop(Iop_CmpEQ32,
+                                                         binop(Iop_And32,
+                                                               mkexpr(t7),
+                                                               mkU32(0x00000080)
+                                                              ),
+                                                         mkU32(0x00000080)),
+                                                   mkU32(0xFFFFFFFF),
+                                                   mkU32(0x00000000)),
+                                        binop(Iop_Sub8, mkU8(0x8), mkU8(rs)))));
+
+                     /* ========== GPR[rt]_7..0 ========== */
+                     assign(t10,
+                            unop(Iop_8Uto32,
+                                 unop(Iop_16to8,
+                                      unop(Iop_32to16, getIReg(rt)))));
+                     assign(t11, binop(Iop_Shr32, mkexpr(t10), mkU8(rs)));
+                     /* tempB_7..0 */
+                     assign(t9,
+                            binop(Iop_Or32,
+                                  mkexpr(t11),
+                                  binop(Iop_Shl32,
+                                        IRExpr_ITE(binop(Iop_CmpEQ32,
+                                                         binop(Iop_And32,
+                                                               mkexpr(t10),
+                                                               mkU32(0x00000080)
+                                                              ),
+                                                         mkU32(0x00000080)),
+                                                   mkU32(0xFFFFFFFF),
+                                                   mkU32(0x00000000)),
+                                        binop(Iop_Sub8, mkU8(0x8), mkU8(rs)))));
+
+                     putIReg(rd,
+                             binop(Iop_16HLto32,
+                                   binop(Iop_8HLto16,
+                                         unop(Iop_32to8, mkexpr(t0)),
+                                         unop(Iop_32to8, mkexpr(t3))),
+                                   binop(Iop_8HLto16,
+                                         unop(Iop_32to8, mkexpr(t6)),
+                                         unop(Iop_32to8, mkexpr(t9)))));
+                     break;
+                  }
+                  case 0x5: {  /* SHRA_R.QB */
+                     DIP("shra_r.qb r%d, r%d, %d", rd, rt, rs);
+                     vassert(!mode64);
+                     t0 = newTemp(Ity_I32);
+                     t1 = newTemp(Ity_I8);
+                     t2 = newTemp(Ity_I32);
+                     t3 = newTemp(Ity_I8);
+                     t4 = newTemp(Ity_I32);
+                     t5 = newTemp(Ity_I8);
+                     t6 = newTemp(Ity_I32);
+                     t7 = newTemp(Ity_I8);
+
+                     if (0 == rs) {
+                        putIReg(rd, getIReg(rt));
+                     } else {
+                        assign(t0, unop(Iop_8Sto32,
+                                        unop(Iop_16to8,
+                                             unop(Iop_32to16, getIReg(rt)))));
+                        assign(t1, unop(Iop_32to8,
+                                        binop(Iop_Sar32,
+                                              binop(Iop_Add32,
+                                                    mkexpr(t0),
+                                                    binop(Iop_Shl32,
+                                                          mkU32(0x1),
+                                                          mkU8(rs-1))),
+                                              mkU8(rs))));
+
+                        assign(t2, unop(Iop_8Sto32,
+                                        unop(Iop_16HIto8,
+                                             unop(Iop_32to16, getIReg(rt)))));
+                        assign(t3, unop(Iop_32to8,
+                                        binop(Iop_Sar32,
+                                              binop(Iop_Add32,
+                                                    mkexpr(t2),
+                                                    binop(Iop_Shl32,
+                                                          mkU32(0x1),
+                                                          mkU8(rs-1))),
+                                              mkU8(rs))));
+
+                        assign(t4, unop(Iop_8Sto32,
+                                        unop(Iop_16to8,
+                                             unop(Iop_32HIto16, getIReg(rt)))));
+                        assign(t5, unop(Iop_32to8,
+                                        binop(Iop_Sar32,
+                                              binop(Iop_Add32,
+                                                    mkexpr(t4),
+                                                    binop(Iop_Shl32,
+                                                          mkU32(0x1),
+                                                          mkU8(rs-1))),
+                                              mkU8(rs))));
+
+                        assign(t6, unop(Iop_8Sto32,
+                                        unop(Iop_16HIto8,
+                                             unop(Iop_32HIto16, getIReg(rt)))));
+                        assign(t7, unop(Iop_32to8,
+                                        binop(Iop_Sar32,
+                                              binop(Iop_Add32,
+                                                    mkexpr(t6),
+                                                    binop(Iop_Shl32,
+                                                          mkU32(0x1),
+                                                          mkU8(rs-1))),
+                                              mkU8(rs))));
+                        putIReg(rd, binop(Iop_16HLto32,
+                                         binop(Iop_8HLto16,
+                                               mkexpr(t7), mkexpr(t5)),
+                                         binop(Iop_8HLto16,
+                                               mkexpr(t3), mkexpr(t1))));
+                     }
+                     break;
+                  }
+                  case 0x6: {  /* SHRAV.QB */
+                     DIP("shrav.qb r%d, r%d, %d", rd, rt, rs);
+                     vassert(!mode64);
+
+                     t0 = newTemp(Ity_I32);
+                     t1 = newTemp(Ity_I32);
+                     t2 = newTemp(Ity_I32);
+
+                     t3 = newTemp(Ity_I32);
+                     t4 = newTemp(Ity_I32);
+                     t5 = newTemp(Ity_I32);
+
+                     t6 = newTemp(Ity_I32);
+                     t7 = newTemp(Ity_I32);
+                     t8 = newTemp(Ity_I32);
+
+                     t9 = newTemp(Ity_I32);
+                     t10 = newTemp(Ity_I32);
+                     t11 = newTemp(Ity_I32);
+
+                     /* ========== GPR[rt]_31..24 ========== */
+                     assign(t1,
+                            unop(Iop_8Uto32,
+                                 unop(Iop_16HIto8,
+                                      unop(Iop_32HIto16, getIReg(rt)))));
+                     assign(t2,
+                            binop(Iop_Shr32,
+                                  mkexpr(t1),
+                                  unop(Iop_32to8, binop(Iop_And32,
+                                                        getIReg(rs),
+                                                        mkU32(0x7)))));
+                     /* tempD_7..0 */
+                     assign(t0,
+                            binop(Iop_Or32,
+                                  mkexpr(t2),
+                                  binop(Iop_Shl32,
+                                        IRExpr_ITE(binop(Iop_CmpEQ32,
+                                                         binop(Iop_And32,
+                                                               mkexpr(t1),
+                                                               mkU32(0x00000080)
+                                                              ),
+                                                         mkU32(0x00000080)),
+                                                   mkU32(0xFFFFFFFF),
+                                                   mkU32(0x00000000)),
+                                        binop(Iop_Sub8,
+                                              mkU8(0x8),
+                                              unop(Iop_32to8, binop(Iop_And32,
+                                                                    getIReg(rs),
+                                                                    mkU32(0x7)))
+                                              ))));
+
+                     /* ========== GPR[rt]_23..16 ========== */
+                     assign(t4,
+                            unop(Iop_8Uto32,
+                                 unop(Iop_16to8,
+                                      unop(Iop_32HIto16, getIReg(rt)))));
+                     assign(t5,
+                            binop(Iop_Shr32,
+                                  mkexpr(t4),
+                                  unop(Iop_32to8, binop(Iop_And32,
+                                                        getIReg(rs),
+                                                        mkU32(0x7)))));
+                     /* tempC_7..0 */
+                     assign(t3,
+                            binop(Iop_Or32,
+                                  mkexpr(t5),
+                                  binop(Iop_Shl32,
+                                        IRExpr_ITE(binop(Iop_CmpEQ32,
+                                                         binop(Iop_And32,
+                                                               mkexpr(t4),
+                                                               mkU32(0x00000080)
+                                                              ),
+                                                         mkU32(0x00000080)),
+                                                   mkU32(0xFFFFFFFF),
+                                                   mkU32(0x00000000)),
+                                        binop(Iop_Sub8,
+                                              mkU8(0x8),
+                                              unop(Iop_32to8, binop(Iop_And32,
+                                                                    getIReg(rs),
+                                                                    mkU32(0x7)))
+                                              ))));
+
+                     /* ========== GPR[rt]_15..8 ========== */
+                     assign(t7,
+                            unop(Iop_8Uto32,
+                                 unop(Iop_16HIto8,
+                                      unop(Iop_32to16, getIReg(rt)))));
+                     assign(t8,
+                            binop(Iop_Shr32,
+                                  mkexpr(t7),
+                                  unop(Iop_32to8, binop(Iop_And32,
+                                                        getIReg(rs),
+                                                        mkU32(0x7)))));
+                     /* tempB_7..0 */
+                     assign(t6,
+                            binop(Iop_Or32,
+                                  mkexpr(t8),
+                                  binop(Iop_Shl32,
+                                        IRExpr_ITE(binop(Iop_CmpEQ32,
+                                                         binop(Iop_And32,
+                                                               mkexpr(t7),
+                                                               mkU32(0x00000080)
+                                                              ),
+                                                         mkU32(0x00000080)),
+                                                   mkU32(0xFFFFFFFF),
+                                                   mkU32(0x00000000)),
+                                        binop(Iop_Sub8,
+                                              mkU8(0x8),
+                                              unop(Iop_32to8, binop(Iop_And32,
+                                                                    getIReg(rs),
+                                                                    mkU32(0x7)))
+                                              ))));
+
+                     /* ========== GPR[rt]_7..0 ========== */
+                     assign(t10,
+                            unop(Iop_8Uto32,
+                                 unop(Iop_16to8,
+                                      unop(Iop_32to16, getIReg(rt)))));
+                     assign(t11,
+                            binop(Iop_Shr32,
+                                  mkexpr(t10),
+                                  unop(Iop_32to8, binop(Iop_And32,
+                                                        getIReg(rs),
+                                                        mkU32(0x7)))));
+                     /* tempB_7..0 */
+                     assign(t9,
+                            binop(Iop_Or32,
+                                  mkexpr(t11),
+                                  binop(Iop_Shl32,
+                                        IRExpr_ITE(binop(Iop_CmpEQ32,
+                                                         binop(Iop_And32,
+                                                               mkexpr(t10),
+                                                               mkU32(0x00000080)
+                                                              ),
+                                                         mkU32(0x00000080)),
+                                                   mkU32(0xFFFFFFFF),
+                                                   mkU32(0x00000000)),
+                                        binop(Iop_Sub8,
+                                              mkU8(0x8),
+                                              unop(Iop_32to8, binop(Iop_And32,
+                                                                    getIReg(rs),
+                                                                    mkU32(0x7)))
+                                              ))));
+
+                     putIReg(rd,
+                             binop(Iop_16HLto32,
+                                   binop(Iop_8HLto16,
+                                         unop(Iop_32to8,
+                                              IRExpr_ITE(binop(Iop_CmpEQ32,
+                                                               binop(Iop_And32,
+                                                                     mkU32(rs),
+                                                                     mkU32(0x7)
+                                                                    ),
+                                                               mkU32(0x0)),
+                                                         mkexpr(t1),
+                                                         mkexpr(t0))),
+                                         unop(Iop_32to8,
+                                              IRExpr_ITE(binop(Iop_CmpEQ32,
+                                                               binop(Iop_And32,
+                                                                     mkU32(rs),
+                                                                     mkU32(0x7)
+                                                                    ),
+                                                               mkU32(0x0)),
+                                                         mkexpr(t2),
+                                                         mkexpr(t3)))),
+                                   binop(Iop_8HLto16,
+                                         unop(Iop_32to8,
+                                              IRExpr_ITE(binop(Iop_CmpEQ32,
+                                                               binop(Iop_And32,
+                                                                     mkU32(rs),
+                                                                     mkU32(0x7)
+                                                                    ),
+                                                               mkU32(0x0)),
+                                                         mkexpr(t5),
+                                                         mkexpr(t6))),
+                                         unop(Iop_32to8,
+                                              IRExpr_ITE(binop(Iop_CmpEQ32,
+                                                               binop(Iop_And32,
+                                                                     mkU32(rs),
+                                                                     mkU32(0x7)
+                                                                    ),
+                                                               mkU32(0x0)),
+                                                         mkexpr(t8),
+                                                         mkexpr(t9))))));
+                     break;
+                  }
+                  case 0x7: {  /* SHRAV_R.QB */
+                     DIP("shrav_r.qb r%d, r%d, r%d", rd, rt, rs);
+                     vassert(!mode64);
+                     t0 = newTemp(Ity_I32);
+                     t1 = newTemp(Ity_I8);
+                     t2 = newTemp(Ity_I32);
+                     t3 = newTemp(Ity_I8);
+                     t4 = newTemp(Ity_I32);
+                     t5 = newTemp(Ity_I8);
+                     t6 = newTemp(Ity_I32);
+                     t7 = newTemp(Ity_I8);
+                     t8 = newTemp(Ity_I8);
+                     t9 = newTemp(Ity_I32);
+
+                     assign(t9, binop(Iop_And32, getIReg(rs), mkU32(0x7)));
+                     assign(t8, unop(Iop_32to8,
+                                     binop(Iop_Sub32, mkexpr(t9), mkU32(0x1))));
+                     assign(t0, unop(Iop_8Sto32,
+                                     unop(Iop_16to8,
+                                          unop(Iop_32to16, getIReg(rt)))));
+                     assign(t1, unop(Iop_32to8,
+                                     binop(Iop_Sar32,
+                                           binop(Iop_Add32,
+                                                 mkexpr(t0),
+                                                 binop(Iop_Shl32,
+                                                       mkU32(0x1),
+                                                       mkexpr(t8))),
+                                           unop(Iop_32to8,
+                                                mkexpr(t9)))));
+
+                     assign(t2, unop(Iop_8Sto32,
+                                     unop(Iop_16HIto8,
+                                          unop(Iop_32to16, getIReg(rt)))));
+                     assign(t3, unop(Iop_32to8,
+                                     binop(Iop_Sar32,
+                                           binop(Iop_Add32,
+                                                 mkexpr(t2),
+                                                 binop(Iop_Shl32,
+                                                       mkU32(0x1),
+                                                       mkexpr(t8))),
+                                           unop(Iop_32to8, mkexpr(t9)))));
+
+                     assign(t4, unop(Iop_8Sto32,
+                                     unop(Iop_16to8,
+                                          unop(Iop_32HIto16, getIReg(rt)))));
+                     assign(t5, unop(Iop_32to8,
+                                     binop(Iop_Sar32,
+                                           binop(Iop_Add32,
+                                                 mkexpr(t4),
+                                                 binop(Iop_Shl32,
+                                                       mkU32(0x1),
+                                                       mkexpr(t8))),
+                                           unop(Iop_32to8, mkexpr(t9)))));
+
+                     assign(t6, unop(Iop_8Sto32,
+                                     unop(Iop_16HIto8,
+                                          unop(Iop_32HIto16, getIReg(rt)))));
+                     assign(t7, unop(Iop_32to8,
+                                     binop(Iop_Sar32,
+                                           binop(Iop_Add32,
+                                                 mkexpr(t6),
+                                                 binop(Iop_Shl32,
+                                                       mkU32(0x1),
+                                                       mkexpr(t8))),
+                                           unop(Iop_32to8, mkexpr(t9)))));
+                     putIReg(rd, IRExpr_ITE(binop(Iop_CmpEQ32,
+                                                  mkexpr(t9),
+                                                  mkU32(0x0)),
+                                            getIReg(rt),
+                                            binop(Iop_16HLto32,
+                                                  binop(Iop_8HLto16,
+                                                        mkexpr(t7),
+                                                        mkexpr(t5)),
+                                                  binop(Iop_8HLto16,
+                                                        mkexpr(t3),
+                                                        mkexpr(t1)))));
+                     break;
+                  }
+                  case 0x8: {  /* SHLL.PH */
+                     DIP("shll.ph r%d, r%d, %d", rd, rt, rs);
+                     vassert(!mode64);
+                     t0 = newTemp(Ity_I32);
+                     t1 = newTemp(Ity_I32);
+                     t2 = newTemp(Ity_I32);
+                     t3 = newTemp(Ity_I32);
+                     t4 = newTemp(Ity_I1);
+
+                     if (0 == rs) {
+                        putIReg(rd, getIReg(rt));
+                     } else {
+                        /* Shift lower 16 bits. */
+                        assign(t0, binop(Iop_Shl32,
+                                         unop(Iop_16Sto32,
+                                              unop(Iop_32to16, getIReg(rt))),
+                                         mkU8(rs)));
+
+                        assign(t2, IRExpr_ITE(binop(Iop_CmpNE32,
+                                                    unop(Iop_16Sto32,
+                                                         unop(Iop_32HIto16,
+                                                              mkexpr(t0))),
+                                                    mkU32(0xffffffff)),
+                                              binop(Iop_Or32,
+                                                    getDSPControl(),
+                                                    mkU32(0x400000)),
+                                              getDSPControl()));
+                        putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32,
+                                                       unop(Iop_16Sto32,
+                                                            unop(Iop_32HIto16,
+                                                                 mkexpr(t0))),
+                                                       mkU32(0x00000000)),
+                                                 mkexpr(t2),
+                                                 getDSPControl()));
+                        putDSPControl(IRExpr_ITE(binop(Iop_CmpEQ32,
+                                                       binop(Iop_And32,
+                                                             getIReg(rt),
+                                                             mkU32(0x00008000)),
+                                                       binop(Iop_And32,
+                                                             mkexpr(t0),
+                                                             mkU32(0x00008000))
+                                                      ),
+                                                 getDSPControl(),
+                                                 binop(Iop_Or32,
+                                                       getDSPControl(),
+                                                       mkU32(0x400000))));
+                        /* Shift higher 16 bits. */
+                        assign(t1, binop(Iop_Shl32,
+                                         unop(Iop_16Sto32,
+                                              unop(Iop_32HIto16, getIReg(rt))),
+                                         mkU8(rs)));
+
+                        assign(t3, IRExpr_ITE(binop(Iop_CmpNE32,
+                                                    unop(Iop_16Sto32,
+                                                         unop(Iop_32HIto16,
+                                                              mkexpr(t1))),
+                                                    mkU32(0xffffffff)),
+                                              binop(Iop_Or32,
+                                                    getDSPControl(),
+                                                    mkU32(0x400000)),
+                                              getDSPControl()));
+                        putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32,
+                                                     unop(Iop_16Sto32,
+                                                          unop(Iop_32HIto16,
+                                                               mkexpr(t1))),
+                                                     mkU32(0x00000000)),
+                                                mkexpr(t3),
+                                                getDSPControl()));
+                        assign(t4, binop(Iop_CmpEQ32,
+                                         binop(Iop_Shr32,
+                                               binop(Iop_And32,
+                                                     getIReg(rt),
+                                                     mkU32(0x80000000)),
+                                               mkU8(31)),
+                                         binop(Iop_Shr32,
+                                               binop(Iop_And32,
+                                                     mkexpr(t1),
+                                                     mkU32(0x00008000)),
+                                               mkU8(15))));
+                        putDSPControl(IRExpr_ITE(mkexpr(t4),
+                                                 getDSPControl(),
+                                                 binop(Iop_Or32,
+                                                       getDSPControl(),
+                                                       mkU32(0x400000))));
+
+                        putIReg(rd, binop(Iop_16HLto32,
+                                          unop(Iop_32to16, mkexpr(t1)),
+                                          unop(Iop_32to16, mkexpr(t0))));
+                     }
+                     break;
+                  }
+                  case 0x9: {  /* SHRA.PH */
+                     DIP("shra.ph r%d, r%d, %d", rd, rt, rs);
+                     vassert(!mode64);
+                     t0 = newTemp(Ity_I32);
+                     t1 = newTemp(Ity_I32);
+                     if (0 == rs) {
+                        putIReg(rd, getIReg(rt));
+                     } else {
+                        assign(t0, binop(Iop_Sar32,
+                                         unop(Iop_16Sto32,
+                                              unop(Iop_32to16, getIReg(rt))),
+                                         mkU8(rs)));
+                        assign(t1, binop(Iop_Sar32,
+                                         unop(Iop_16Sto32,
+                                              unop(Iop_32HIto16, getIReg(rt))),
+                                         mkU8(rs)));
+                        putIReg(rd, binop(Iop_16HLto32,
+                                          unop(Iop_32to16, mkexpr(t1)),
+                                          unop(Iop_32to16, mkexpr(t0))));
+                     }
+                     break;
+                  }
+                  case 0xA: {  /* SHLLV.PH */
+                     DIP("shllv.ph r%d, r%d, r%d", rd, rt, rs);
+                     vassert(!mode64);
+                     t0 = newTemp(Ity_I32);
+                     t2 = newTemp(Ity_I32);
+                     t3 = newTemp(Ity_I1);
+                     t4 = newTemp(Ity_I1);
+                     t5 = newTemp(Ity_I32);
+                     t6 = newTemp(Ity_I32);
+                     t7 = newTemp(Ity_I1);
+                     t8 = newTemp(Ity_I1);
+                     t9 = newTemp(Ity_I32);
+                     t10 = newTemp(Ity_I32);
+                     t11 = newTemp(Ity_I32);
+                     t12 = newTemp(Ity_I1);
+                     t13 = newTemp(Ity_I1);
+
+                     assign(t0, binop(Iop_And32, getIReg(rs), mkU32(0x0f)));
+
+                     /* Shift lower 16 bits. */
+                     assign(t2, binop(Iop_Shl32,
+                                      unop(Iop_16Sto32,
+                                           unop(Iop_32to16, getIReg(rt))),
+                                      unop(Iop_32to8, mkexpr(t0))));
+
+                     assign(t3, binop(Iop_CmpNE32,
+                                      unop(Iop_16Sto32,
+                                           unop(Iop_32HIto16, mkexpr(t2))),
+                                      mkU32(0x00000000)));
+                     assign(t4, binop(Iop_CmpNE32,
+                                      unop(Iop_16Sto32,
+                                           unop(Iop_32HIto16, mkexpr(t2))),
+                                      mkU32(0xffffffff)));
+                     assign(t10, binop(Iop_And32,
+                                       unop(Iop_1Sto32, mkexpr(t3)),
+                                       unop(Iop_1Sto32, mkexpr(t4))));
+                     assign(t5, binop(Iop_Shr32,
+                                      binop(Iop_And32,
+                                            getIReg(rt),
+                                            mkU32(0x00008000)),
+                                      mkU8(15)));
+                     assign(t12, binop(Iop_CmpEQ32,
+                                       mkexpr(t5),
+                                       binop(Iop_Shr32,
+                                             binop(Iop_And32,
+                                                   mkexpr(t2),
+                                                   mkU32(0x00008000)),
+                                             mkU8(15))));
+
+                     putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32,
+                                                    mkexpr(t10),
+                                                    mkU32(0x0)),
+                                              binop(Iop_Or32,
+                                                    getDSPControl(),
+                                                    mkU32(0x400000)),
+                                              IRExpr_ITE(mkexpr(t12),
+                                                         getDSPControl(),
+                                                         binop(Iop_Or32,
+                                                               getDSPControl(),
+                                                               mkU32(0x400000)))
+                                             ));
+                     /* Shift higher 16 bits. */
+                     assign(t6, binop(Iop_Shl32,
+                                      unop(Iop_16Sto32,
+                                           unop(Iop_32HIto16, getIReg(rt))),
+                                      unop(Iop_32to8, mkexpr(t0))));
+
+                     assign(t7, binop(Iop_CmpNE32,
+                                      unop(Iop_16Sto32,
+                                           unop(Iop_32HIto16, mkexpr(t6))),
+                                      mkU32(0x00000000)));
+                     assign(t8, binop(Iop_CmpNE32,
+                                      unop(Iop_16Sto32,
+                                           unop(Iop_32HIto16, mkexpr(t6))),
+                                      mkU32(0xffffffff)));
+                     assign(t11, binop(Iop_And32,
+                                       unop(Iop_1Sto32, mkexpr(t7)),
+                                       unop(Iop_1Sto32, mkexpr(t8))));
+
+                     assign(t9, binop(Iop_Shr32,
+                                      binop(Iop_And32,
+                                            getIReg(rt),
+                                            mkU32(0x80000000)),
+                                      mkU8(31)));
+                     assign(t13, binop(Iop_CmpEQ32,
+                                       mkexpr(t9),
+                                       binop(Iop_Shr32,
+                                             binop(Iop_And32,
+                                                   mkexpr(t6),
+                                                   mkU32(0x00008000)),
+                                             mkU8(15))));
+
+                     putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32,
+                                                    mkexpr(t11),
+                                                    mkU32(0x0)),
+                                              binop(Iop_Or32,
+                                                    getDSPControl(),
+                                                    mkU32(0x400000)),
+                                              IRExpr_ITE(mkexpr(t13),
+                                                         getDSPControl(),
+                                                         binop(Iop_Or32,
+                                                               getDSPControl(),
+                                                               mkU32(0x400000)))
+                                             ));
+
+                     putIReg(rd, binop(Iop_16HLto32,
+                                       unop(Iop_32to16, mkexpr(t6)),
+                                       unop(Iop_32to16, mkexpr(t2))));
+                     break;
+                  }
+                  case 0xB: {  /* SHRAV.PH */
+                     DIP("shrav.ph r%d, r%d, r%d", rd, rt, rs);
+                     vassert(!mode64);
+                     t0 = newTemp(Ity_I32);
+                     t1 = newTemp(Ity_I1);
+                     t2 = newTemp(Ity_I32);
+                     t3 = newTemp(Ity_I32);
+
+                     assign(t0, binop(Iop_And32, getIReg(rs), mkU32(0x0f)));
+                     assign(t1, binop(Iop_CmpEQ32, mkexpr(t0), mkU32(0x0)));
+                     assign(t2, binop(Iop_Sar32,
+                                      unop(Iop_16Sto32,
+                                           unop(Iop_32to16, getIReg(rt))),
+                                      unop(Iop_32to8, mkexpr(t0))));
+                     assign(t3, binop(Iop_Sar32,
+                                      unop(Iop_16Sto32,
+                                           unop(Iop_32HIto16, getIReg(rt))),
+                                      unop(Iop_32to8, mkexpr(t0))));
+                     putIReg(rd,
+                             binop(Iop_16HLto32,
+                                   IRExpr_ITE(mkexpr(t1),
+                                              unop(Iop_32HIto16, getIReg(rt)),
+                                              unop(Iop_32to16, mkexpr(t3))),
+                                   IRExpr_ITE(mkexpr(t1),
+                                              unop(Iop_32to16, getIReg(rt)),
+                                              unop(Iop_32to16, mkexpr(t2)))));
+                     break;
+                  }
+                  case 0xC: {  /* SHLL_S.PH */
+                     DIP("shll_s.ph r%d, r%d, %d", rd, rt, rs);
+                     vassert(!mode64);
+                     t0 = newTemp(Ity_I32);
+                     t1 = newTemp(Ity_I16);
+                     t2 = newTemp(Ity_I16);
+                     t3 = newTemp(Ity_I16);
+                     t4 = newTemp(Ity_I32);
+                     t5 = newTemp(Ity_I16);
+                     t6 = newTemp(Ity_I16);
+                     t7 = newTemp(Ity_I16);
+                     t8 = newTemp(Ity_I32);
+                     t9 = newTemp(Ity_I32);
+                     t10 = newTemp(Ity_I1);
+                     t11 = newTemp(Ity_I32);
+                     t12 = newTemp(Ity_I32);
+
+                     if (0 == rs) {
+                        putIReg(rd, getIReg(rt));
+                     } else {
+                        /* Shift lower 16 bits. */
+                        assign(t0, binop(Iop_Shl32,
+                                         unop(Iop_16Sto32,
+                                              unop(Iop_32to16, getIReg(rt))),
+                                         mkU8(rs)));
+
+                        assign(t1, IRExpr_ITE(binop(Iop_CmpEQ32,
+                                                    binop(Iop_And32,
+                                                          getIReg(rt),
+                                                          mkU32(0x00008000)),
+                                                    mkU32(0x0)),
+                                              mkU16(0x7fff),
+                                              mkU16(0x8000)));
+                        assign(t2,
+                               IRExpr_ITE(binop(Iop_CmpEQ32,
+                                                binop(Iop_Shr32,
+                                                      binop(Iop_And32,
+                                                            getIReg(rt),
+                                                            mkU32(0x00008000)),
+                                                      mkU8(15)),
+                                                binop(Iop_Shr32,
+                                                      binop(Iop_And32,
+                                                            mkexpr(t0),
+                                                            mkU32(0x00008000)),
+                                                      mkU8(15))),
+                                          unop(Iop_32to16, mkexpr(t0)),
+                                          mkexpr(t1)));
+                        assign(t11, IRExpr_ITE(binop(Iop_CmpNE32,
+                                                     unop(Iop_16Sto32,
+                                                          unop(Iop_32HIto16,
+                                                               mkexpr(t0))),
+                                                     mkU32(0xffffffff)),
+                                               mkexpr(t1),
+                                               mkexpr(t2)));
+                        assign(t3,
+                               IRExpr_ITE(binop(Iop_CmpNE32,
+                                                unop(Iop_16Sto32,
+                                                     unop(Iop_32HIto16,
+                                                          mkexpr(t0))),
+                                                mkU32(0x00000000)),
+                                          mkexpr(t11),
+                                          mkexpr(t2)));
+                        assign(t8, IRExpr_ITE(binop(Iop_CmpNE32,
+                                                    unop(Iop_16Sto32,
+                                                         unop(Iop_32HIto16,
+                                                              mkexpr(t0))),
+                                                    mkU32(0xffffffff)),
+                                              binop(Iop_Or32,
+                                                    getDSPControl(),
+                                                    mkU32(0x400000)),
+                                              getDSPControl()));
+                        putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32,
+                                                       unop(Iop_16Sto32,
+                                                            unop(Iop_32HIto16,
+                                                                 mkexpr(t0))),
+                                                       mkU32(0x00000000)),
+                                                mkexpr(t8),
+                                                getDSPControl()));
+                        putDSPControl(IRExpr_ITE(binop(Iop_CmpEQ32,
+                                                       binop(Iop_And32,
+                                                             getIReg(rt),
+                                                             mkU32(0x00008000)),
+                                                       binop(Iop_And32,
+                                                            mkexpr(t0),
+                                                            mkU32(0x00008000))),
+                                                 getDSPControl(),
+                                                 binop(Iop_Or32,
+                                                       getDSPControl(),
+                                                       mkU32(0x400000))));
+                        /* Shift higher 16 bits. */
+                        assign(t4, binop(Iop_Shl32,
+                                         unop(Iop_16Sto32,
+                                              unop(Iop_32HIto16, getIReg(rt))),
+                                         mkU8(rs)));
+
+                        assign(t5, IRExpr_ITE(binop(Iop_CmpEQ32,
+                                                    binop(Iop_And32,
+                                                          getIReg(rt),
+                                                          mkU32(0x80000000)),
+                                                    mkU32(0x0)),
+                                              mkU16(0x7fff),
+                                              mkU16(0x8000)));
+                        assign(t6,
+                               IRExpr_ITE(binop(Iop_CmpEQ32,
+                                                binop(Iop_Shr32,
+                                                      binop(Iop_And32,
+                                                            getIReg(rt),
+                                                            mkU32(0x80000000)),
+                                                      mkU8(31)),
+                                                binop(Iop_Shr32,
+                                                      binop(Iop_And32,
+                                                            mkexpr(t4),
+                                                            mkU32(0x00008000)),
+                                                      mkU8(15))),
+                                          unop(Iop_32to16, mkexpr(t4)),
+                                          mkexpr(t5)));
+                        assign(t12, IRExpr_ITE(binop(Iop_CmpNE32,
+                                                     unop(Iop_16Sto32,
+                                                          unop(Iop_32HIto16,
+                                                               mkexpr(t4))),
+                                                     mkU32(0xffffffff)),
+                                               mkexpr(t5),
+                                               mkexpr(t6)));
+                        assign(t7,
+                               IRExpr_ITE(binop(Iop_CmpNE32,
+                                                unop(Iop_16Sto32,
+                                                     unop(Iop_32HIto16,
+                                                          mkexpr(t4))),
+                                                mkU32(0x00000000)),
+                                          mkexpr(t12),
+                                          mkexpr(t6)));
+                        assign(t9, IRExpr_ITE(binop(Iop_CmpNE32,
+                                                    unop(Iop_16Sto32,
+                                                      unop(Iop_32HIto16,
+                                                           mkexpr(t4))),
+                                                    mkU32(0xffffffff)),
+                                              binop(Iop_Or32,
+                                                    getDSPControl(),
+                                                    mkU32(0x400000)),
+                                              getDSPControl()));
+                        putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32,
+                                                       unop(Iop_16Sto32,
+                                                            unop(Iop_32HIto16,
+                                                                 mkexpr(t4))),
+                                                       mkU32(0x00000000)),
+                                                 mkexpr(t9),
+                                                 getDSPControl()));
+                        assign(t10, binop(Iop_CmpEQ32,
+                                          binop(Iop_Shr32,
+                                                binop(Iop_And32,
+                                                      getIReg(rt),
+                                                      mkU32(0x80000000)),
+                                                mkU8(31)),
+                                          binop(Iop_Shr32,
+                                                binop(Iop_And32,
+                                                      mkexpr(t4),
+                                                      mkU32(0x00008000)),
+                                                mkU8(15))));
+                        putDSPControl(IRExpr_ITE(mkexpr(t10),
+                                                 getDSPControl(),
+                                                 binop(Iop_Or32,
+                                                       getDSPControl(),
+                                                       mkU32(0x400000))));
+
+                        putIReg(rd, binop(Iop_16HLto32,
+                                          mkexpr(t7), mkexpr(t3)));
+                     }
+                     break;
+                  }
+                  case 0xD: {  /* SHRA_R.PH */
+                     DIP("shra.ph r%d, r%d, %d", rd, rt, rs);
+                     vassert(!mode64);
+                     t0 = newTemp(Ity_I32);
+                     t1 = newTemp(Ity_I32);
+                     if (0 == rs) {
+                        putIReg(rd, getIReg(rt));
+                     } else {
+                        assign(t0, binop(Iop_Sar32,
+                                         binop(Iop_Add32,
+                                               unop(Iop_16Sto32,
+                                                    unop(Iop_32to16,
+                                                         getIReg(rt))),
+                                               binop(Iop_Shl32,
+                                                     mkU32(0x1),
+                                                     mkU8(rs-1))),
+                                         mkU8(rs)));
+                        assign(t1, binop(Iop_Sar32,
+                                         binop(Iop_Add32,
+                                               unop(Iop_16Sto32,
+                                                    unop(Iop_32HIto16,
+                                                         getIReg(rt))),
+                                               binop(Iop_Shl32,
+                                                     mkU32(0x1),
+                                                     mkU8(rs-1))),
+                                         mkU8(rs)));
+                        putIReg(rd, binop(Iop_16HLto32,
+                                          unop(Iop_32to16, mkexpr(t1)),
+                                          unop(Iop_32to16, mkexpr(t0))));
+                     }
+                     break;
+                  }
+                  case 0xE: {  /* SHLLV_S.PH */
+                     DIP("shllv_s.ph r%d, r%d, r%d", rd, rt, rs);
+                     vassert(!mode64);
+                     t0 = newTemp(Ity_I32);
+                     t2 = newTemp(Ity_I32);
+                     t3 = newTemp(Ity_I1);
+                     t4 = newTemp(Ity_I1);
+                     t5 = newTemp(Ity_I32);
+                     t6 = newTemp(Ity_I32);
+                     t7 = newTemp(Ity_I1);
+                     t8 = newTemp(Ity_I1);
+                     t9 = newTemp(Ity_I32);
+                     t10 = newTemp(Ity_I32);
+                     t11 = newTemp(Ity_I32);
+                     t12 = newTemp(Ity_I1);
+                     t13 = newTemp(Ity_I1);
+                     t14 = newTemp(Ity_I16);
+                     t15 = newTemp(Ity_I16);
+                     t16 = newTemp(Ity_I16);
+                     t17 = newTemp(Ity_I16);
+
+                     assign(t0, binop(Iop_And32, getIReg(rs), mkU32(0x0f)));
+
+                     /* Shift lower 16 bits. */
+                     assign(t2, binop(Iop_Shl32,
+                                      unop(Iop_16Sto32,
+                                           unop(Iop_32to16, getIReg(rt))),
+                                      unop(Iop_32to8, mkexpr(t0))));
+
+                     assign(t3, binop(Iop_CmpNE32,
+                                      unop(Iop_16Sto32,
+                                           unop(Iop_32HIto16, mkexpr(t2))),
+                                      mkU32(0x00000000)));
+                     assign(t4, binop(Iop_CmpNE32,
+                                      unop(Iop_16Sto32,
+                                           unop(Iop_32HIto16, mkexpr(t2))),
+                                      mkU32(0xffffffff)));
+                     assign(t10, binop(Iop_And32,
+                                       unop(Iop_1Sto32, mkexpr(t3)),
+                                       unop(Iop_1Sto32, mkexpr(t4))));
+                     assign(t5, binop(Iop_Shr32,
+                                       binop(Iop_And32,
+                                             getIReg(rt),
+                                             mkU32(0x00008000)),
+                                       mkU8(15)));
+                     assign(t12, binop(Iop_CmpEQ32,
+                                       mkexpr(t5),
+                                       binop(Iop_Shr32,
+                                             binop(Iop_And32,
+                                                   mkexpr(t2),
+                                                   mkU32(0x00008000)),
+                                             mkU8(15))));
+
+                     putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32,
+                                                    mkexpr(t10),
+                                                    mkU32(0x0)),
+                                              binop(Iop_Or32,
+                                                    getDSPControl(),
+                                                    mkU32(0x400000)),
+                                              IRExpr_ITE(mkexpr(t12),
+                                                         getDSPControl(),
+                                                         binop(Iop_Or32,
+                                                               getDSPControl(),
+                                                               mkU32(0x400000)))
+                                             ));
+                     assign(t14, IRExpr_ITE(binop(Iop_CmpNE32,
+                                                  mkexpr(t5),
+                                                  mkU32(0x0)),
+                                            mkU16(0x8000),
+                                            mkU16(0x7fff)));
+                     assign(t15, IRExpr_ITE(binop(Iop_CmpNE32,
+                                                  mkexpr(t10),
+                                                  mkU32(0x0)),
+                                            mkexpr(t14),
+                                            IRExpr_ITE(mkexpr(t12),
+                                                       unop(Iop_32to16,
+                                                            mkexpr(t2)),
+                                                       mkexpr(t14))));
+                     /* Shift higher 16 bits. */
+                     assign(t6, binop(Iop_Shl32,
+                                      unop(Iop_16Sto32,
+                                           unop(Iop_32HIto16, getIReg(rt))),
+                                      unop(Iop_32to8, mkexpr(t0))));
+
+                     assign(t7, binop(Iop_CmpNE32,
+                                      unop(Iop_16Sto32,
+                                           unop(Iop_32HIto16, mkexpr(t6))),
+                                      mkU32(0x00000000)));
+                     assign(t8, binop(Iop_CmpNE32,
+                                      unop(Iop_16Sto32,
+                                           unop(Iop_32HIto16, mkexpr(t6))),
+                                      mkU32(0xffffffff)));
+                     assign(t11, binop(Iop_And32,
+                                       unop(Iop_1Sto32, mkexpr(t7)),
+                                       unop(Iop_1Sto32, mkexpr(t8))));
+
+                     assign(t9, binop(Iop_Shr32,
+                                      binop(Iop_And32,
+                                            getIReg(rt),
+                                            mkU32(0x80000000)),
+                                      mkU8(31)));
+                     assign(t13, binop(Iop_CmpEQ32,
+                                       mkexpr(t9),
+                                       binop(Iop_Shr32,
+                                             binop(Iop_And32,
+                                                   mkexpr(t6),
+                                                   mkU32(0x00008000)),
+                                             mkU8(15))));
+
+                     putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32,
+                                                    mkexpr(t11),
+                                                    mkU32(0x0)),
+                                              binop(Iop_Or32,
+                                                    getDSPControl(),
+                                                    mkU32(0x400000)),
+                                              IRExpr_ITE(mkexpr(t13),
+                                                         getDSPControl(),
+                                                         binop(Iop_Or32,
+                                                               getDSPControl(),
+                                                               mkU32(0x400000)))
+                                             ));
+
+                     assign(t16, IRExpr_ITE(binop(Iop_CmpNE32,
+                                                  mkexpr(t9),
+                                                  mkU32(0x0)),
+                                            mkU16(0x8000),
+                                            mkU16(0x7fff)));
+                     assign(t17, IRExpr_ITE(binop(Iop_CmpNE32,
+                                                  mkexpr(t11),
+                                                  mkU32(0x0)),
+                                            mkexpr(t16),
+                                            IRExpr_ITE(mkexpr(t13),
+                                                       unop(Iop_32to16,
+                                                            mkexpr(t6)),
+                                                       mkexpr(t16))));
+
+                     putIReg(rd, binop(Iop_16HLto32, mkexpr(t17), mkexpr(t15)));
+                     break;
+                  }
+                  case 0xF: {  /* SHRAV_R.PH */
+                     DIP("shrav_r.ph r%d, r%d, r%d", rd, rt, rs);
+                     vassert(!mode64);
+                     t0 = newTemp(Ity_I32);
+                     t1 = newTemp(Ity_I1);
+                     t2 = newTemp(Ity_I8);
+                     t3 = newTemp(Ity_I32);
+                     t4 = newTemp(Ity_I32);
+
+                     assign(t0, binop(Iop_And32, getIReg(rs), mkU32(0x0f)));
+                     assign(t1, binop(Iop_CmpEQ32, mkexpr(t0), mkU32(0x0)));
+                     assign(t2, unop(Iop_32to8,
+                                     binop(Iop_Sub32, mkexpr(t0), mkU32(1))));
+
+                     assign(t3, binop(Iop_Sar32,
+                                      binop(Iop_Add32,
+                                            unop(Iop_16Sto32,
+                                                 unop(Iop_32to16, getIReg(rt))),
+                                            binop(Iop_Shl32,
+                                                  mkU32(0x1),
+                                                  mkexpr(t2))),
+                                      unop(Iop_32to8, mkexpr(t0))));
+                     assign(t4, binop(Iop_Sar32,
+                                      binop(Iop_Add32,
+                                            unop(Iop_16Sto32,
+                                                 unop(Iop_32HIto16,
+                                                      getIReg(rt))),
+                                            binop(Iop_Shl32,
+                                                  mkU32(0x1),
+                                                  mkexpr(t2))),
+                                      unop(Iop_32to8, mkexpr(t0))));
+
+                     putIReg(rd, binop(Iop_16HLto32,
+                                       IRExpr_ITE(mkexpr(t1),
+                                                  unop(Iop_32HIto16,
+                                                       getIReg(rt)),
+                                                  unop(Iop_32to16,
+                                                       mkexpr(t4))),
+                                       IRExpr_ITE(mkexpr(t1),
+                                                  unop(Iop_32to16, getIReg(rt)),
+                                                  unop(Iop_32to16,
+                                                       mkexpr(t3)))));
+                     break;
+                  }
+                  case 0x14: {  /* SHLL_S.W */
+                     DIP("shll_s.w r%d, r%d, %d", rd, rt, rs);
+                     vassert(!mode64);
+                     t0 = newTemp(Ity_I32);
+                     t1 = newTemp(Ity_I32);
+                     t2 = newTemp(Ity_I32);
+                     t3 = newTemp(Ity_I32);
+                     t4 = newTemp(Ity_I32);
+                     t5 = newTemp(Ity_I32);
+
+                     if (0 == rs) {
+                        putIReg(rd, getIReg(rt));
+                     } else {
+                        /* t0-bits that will be discarded, sign extended to
+                           32bits. */
+                        assign(t0, binop(Iop_Sar32,
+                                         binop(Iop_And32,
+                                               getIReg(rt),
+                                               binop(Iop_Sar32,
+                                                     mkU32(0x80000000),
+                                                     mkU8(rs-1))),
+                                         mkU8(32-rs)));
+
+                        assign(t1, IRExpr_ITE(binop(Iop_CmpEQ32,
+                                                    binop(Iop_And32,
+                                                          getIReg(rt),
+                                                          mkU32(0x80000000)),
+                                                    mkU32(0x0)),
+                                              mkU32(0x7fffffff),
+                                              mkU32(0x80000000)));
+
+                        assign(t2, binop(Iop_Shl32, getIReg(rt), mkU8(rs)));
+                        assign(t3, IRExpr_ITE(binop(Iop_CmpEQ32,
+                                                    binop(Iop_And32,
+                                                          getIReg(rt),
+                                                          mkU32(0x80000000)),
+                                                    binop(Iop_And32,
+                                                          mkexpr(t2),
+                                                          mkU32(0x80000000))),
+                                              mkexpr(t2),
+                                              mkexpr(t1)));
+
+                        assign(t4, IRExpr_ITE(binop(Iop_CmpNE32,
+                                                    mkexpr(t0),
+                                                    mkU32(0x0)),
+                                              IRExpr_ITE(binop(Iop_CmpNE32,
+                                                               mkexpr(t0),
+                                                               mkU32(0xffffffff)
+                                                              ),
+                                                         mkexpr(t1),
+                                                         mkexpr(t3)),
+                                              mkexpr(t3)));
+                        assign(t5, IRExpr_ITE(binop(Iop_CmpNE32,
+                                                    mkexpr(t0),
+                                                    mkU32(0xffffffff)),
+                                              binop(Iop_Or32,
+                                                    getDSPControl(),
+                                                    mkU32(0x400000)),
+                                              getDSPControl()));
+                        putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32,
+                                                       mkexpr(t0),
+                                                       mkU32(0x0)),
+                                                 mkexpr(t5),
+                                                 getDSPControl()));
+                        putDSPControl(IRExpr_ITE(binop(Iop_CmpEQ32,
+                                                       binop(Iop_And32,
+                                                             getIReg(rt),
+                                                             mkU32(0x80000000)),
+                                                       binop(Iop_And32,
+                                                             mkexpr(t2),
+                                                             mkU32(0x80000000))
+                                                            ),
+                                                 getDSPControl(),
+                                                 binop(Iop_Or32,
+                                                       getDSPControl(),
+                                                       mkU32(0x400000))));
+                        putIReg(rd, mkexpr(t4));
+                     }
+                     break;
+                  }
+                  case 0x15: {  /* SHRA_R.W */
+                     DIP("shra_r.w r%d, r%d, %d", rd, rt, rs);
+                     vassert(!mode64);
+                     if (0 == rs) {
+                        putIReg(rd, getIReg(rt));
+                     } else {
+                        putIReg(rd, binop(Iop_Add32,
+                                          binop(Iop_Sar32,
+                                                getIReg(rt), mkU8(rs)),
+                                          binop(Iop_Shr32,
+                                                binop(Iop_And32,
+                                                      getIReg(rt),
+                                                      binop(Iop_Shl32,
+                                                            mkU32(0x1),
+                                                            mkU8(rs-1))),
+                                                mkU8(rs-1))));
+                     }
+                     break;
+                  }
+                  case 0x16: {  /* SHLLV_S.W */
+                     DIP("shllv_s.w r%d, r%d, r%d", rd, rt, rs);
+                     vassert(!mode64);
+                     t0 = newTemp(Ity_I32);
+                     t1 = newTemp(Ity_I1);
+                     t2 = newTemp(Ity_I32);
+                     t3 = newTemp(Ity_I64);
+                     t4 = newTemp(Ity_I1);
+                     t5 = newTemp(Ity_I1);
+                     t6 = newTemp(Ity_I32);
+                     t7 = newTemp(Ity_I1);
+                     t8 = newTemp(Ity_I32);
+
+                     /* Check if shift amount is zero. */
+                     assign(t0, binop(Iop_And32, getIReg(rs), mkU32(0x1f)));
+                     assign(t1, binop(Iop_CmpEQ32, mkexpr(t0), mkU32(0x0)));
+
+                     /* t2 = sign of the input value. */
+                     assign(t2, binop(Iop_Shr32,
+                                      binop(Iop_And32,
+                                            getIReg(rt),
+                                            mkU32(0x80000000)),
+                                      mkU8(31)));
+                     /* Shift left input value and check for overflow. */
+                     assign(t3, binop(Iop_Shl64,
+                                      unop(Iop_32Sto64, getIReg(rt)),
+                                      unop(Iop_32to8, mkexpr(t0))));
+                     assign(t4, binop(Iop_CmpNE32,
+                                      unop(Iop_64HIto32, mkexpr(t3)),
+                                      mkU32(0x00000000)));
+                     assign(t5, binop(Iop_CmpNE32,
+                                      unop(Iop_64HIto32, mkexpr(t3)),
+                                      mkU32(0xffffffff)));
+                     assign(t6, binop(Iop_And32,
+                                      unop(Iop_1Uto32, mkexpr(t4)),
+                                      unop(Iop_1Uto32, mkexpr(t5))));
+                     assign(t7, binop(Iop_CmpEQ32,
+                                      binop(Iop_Shr32,
+                                            binop(Iop_And32,
+                                                  getIReg(rt),
+                                                  mkU32(0x80000000)),
+                                            mkU8(31)),
+                                      binop(Iop_Shr32,
+                                            binop(Iop_And32,
+                                                  unop(Iop_64to32, mkexpr(t3)),
+                                                  mkU32(0x80000000)),
+                                            mkU8(31))));
+
+                     putDSPControl(IRExpr_ITE(unop(Iop_32to1, mkexpr(t6)),
+                                                   binop(Iop_Or32,
+                                                         getDSPControl(),
+                                                         mkU32(0x400000)),
+                                              IRExpr_ITE(mkexpr(t7),
+                                                         getDSPControl(),
+                                                         binop(Iop_Or32,
+                                                               getDSPControl(),
+                                                               mkU32(0x400000)))
+                                             ));
+
+                     assign(t8, IRExpr_ITE(unop(Iop_32to1,
+                                                mkexpr(t2)),
+                                           mkU32(0x80000000),
+                                           mkU32(0x7fffffff)));
+                     putIReg(rd, IRExpr_ITE(unop(Iop_32to1, mkexpr(t6)),
+                                            IRExpr_ITE(unop(Iop_32to1,
+                                                            mkexpr(t2)),
+                                                       mkU32(0x80000000),
+                                                       mkU32(0x7fffffff)),
+                                            IRExpr_ITE(mkexpr(t7),
+                                                       unop(Iop_64to32,
+                                                            mkexpr(t3)),
+                                                       mkexpr(t8))));
+                     break;
+                  }
+                  case 0x17: {  /* SHRAV_R.W */
+                     DIP("shrav_r.w r%d, r%d, r%d", rd, rt, rs);
+                     vassert(!mode64);
+                     t0 = newTemp(Ity_I32);
+                     t1 = newTemp(Ity_I1);
+                     t2 = newTemp(Ity_I8);
+                     t3 = newTemp(Ity_I32);
+
+                     assign(t0, binop(Iop_And32, getIReg(rs), mkU32(0x1f)));
+                     assign(t1, binop(Iop_CmpEQ32, mkexpr(t0), mkU32(0x0)));
+                     assign(t2, unop(Iop_32to8,
+                                     binop(Iop_Sub32, mkexpr(t0), mkU32(1))));
+
+                     putIReg(rd, IRExpr_ITE(mkexpr(t1),
+                                            getIReg(rt),
+                                            binop(Iop_Sar32,
+                                                  binop(Iop_Add32,
+                                                        binop(Iop_Sar32,
+                                                              getIReg(rt),
+                                                              mkexpr(t2)),
+                                                        mkU32(0x1)),
+                                                  mkU8(1))));
+                     break;
+                  }
+                  case 0x19: {  /* SHRL.PH */
+                     DIP("shrl.ph r%d, r%d, %d", rd, rt, rs);
+                     vassert(!mode64);
+                     t0 = newTemp(Ity_I32);
+                     t1 = newTemp(Ity_I32);
+                     assign(t0, binop(Iop_Shr32,
+                                      unop(Iop_16Uto32,
+                                           unop(Iop_32to16, getIReg(rt))),
+                                      mkU8(rs)));
+                     assign(t1, binop(Iop_Shr32,
+                                      unop(Iop_16Uto32,
+                                           unop(Iop_32HIto16, getIReg(rt))),
+                                      mkU8(rs)));
+                     putIReg(rd, binop(Iop_16HLto32,
+                                       unop(Iop_32to16, mkexpr(t1)),
+                                       unop(Iop_32to16, mkexpr(t0))));
+                     break;
+                  }
+                  case 0x1B: {  /* SHRLV.PH */
+                     DIP("shrlv.ph r%d, r%d, r%d", rd, rt, rs);
+                     vassert(!mode64);
+                     t0 = newTemp(Ity_I32);
+                     t1 = newTemp(Ity_I1);
+                     t2 = newTemp(Ity_I32);
+                     t3 = newTemp(Ity_I32);
+                     t4 = newTemp(Ity_I16);
+                     t5 = newTemp(Ity_I16);
+
+                     /* Get shift amount from lower 5 bits of rs
+                        and check if it is zero. */
+                     assign(t0, binop(Iop_And32, getIReg(rs), mkU32(0x0f)));
+                     assign(t1, binop(Iop_CmpEQ32, mkexpr(t0), mkU32(0x0)));
+
+                     assign(t2, binop(Iop_Shr32,
+                                      unop(Iop_16Uto32,
+                                           unop(Iop_32to16, getIReg(rt))),
+                                      unop(Iop_32to8, mkexpr(t0))));
+                     assign(t3, binop(Iop_Shr32,
+                                      unop(Iop_16Uto32,
+                                           unop(Iop_32HIto16, getIReg(rt))),
+                                      unop(Iop_32to8, mkexpr(t0))));
+
+                     assign(t4, IRExpr_ITE(mkexpr(t1),
+                                           unop(Iop_32HIto16, getIReg(rt)),
+                                           unop(Iop_32to16, mkexpr(t3))));
+                     assign(t5, IRExpr_ITE(mkexpr(t1),
+                                           unop(Iop_32to16, getIReg(rt)),
+                                           unop(Iop_32to16, mkexpr(t2))));
+                     putIReg(rd, binop(Iop_16HLto32, mkexpr(t4), mkexpr(t5)));
+                     break;
+                  }
+                  default:
+                     return -1;
+               }
+               break;  /* end of SHLL.QB */
+            }
+            case 0x18: {  /* ADDUH.QB/MUL.PH */
+               switch(sa) {
+                  case 0x00: {  /* ADDUH.QB */
+                     DIP("adduh.qb r%d, r%d, r%d", rd, rs, rt);
+                     vassert(!mode64);
+                     t0 = newTemp(Ity_I32);
+
+                     assign(t0, binop(Iop_HAdd8Ux4, getIReg(rs), getIReg(rt)));
+
+                     putIReg(rd, mkexpr(t0));
+                     break;
+                  }
+                  case 0x1: {  /* SUBUH.QB */
+                     DIP("subuh.qb r%d, r%d, r%d", rd, rs, rt);
+                     vassert(!mode64);
+                     t0 = newTemp(Ity_I32);
+
+                     assign(t0, binop(Iop_HSub8Ux4, getIReg(rs), getIReg(rt)));
+
+                     putIReg(rd, mkexpr(t0));
+                     break;
+                  }
+                  case 0x02: {  /* ADDUH_R.QB */
+                     DIP("adduh_r.qb r%d, r%d, r%d", rd, rs, rt);
+                     vassert(!mode64);
+                     t0 = newTemp(Ity_I32);
+                     t1 = newTemp(Ity_I32);
+                     t2 = newTemp(Ity_I8);
+                     t3 = newTemp(Ity_I32);
+                     t4 = newTemp(Ity_I32);
+                     t5 = newTemp(Ity_I8);
+                     t6 = newTemp(Ity_I32);
+                     t7 = newTemp(Ity_I32);
+                     t8 = newTemp(Ity_I8);
+                     t9 = newTemp(Ity_I32);
+                     t10 = newTemp(Ity_I32);
+                     t11 = newTemp(Ity_I8);
+
+                     /* Extract input bytes, add values, add 1 and half the
+                        result. */
+                     assign(t0, unop(Iop_8Uto32,
+                                     unop(Iop_16to8,
+                                          unop(Iop_32to16, getIReg(rs)))));
+                     assign(t1, unop(Iop_8Uto32,
+                                     unop(Iop_16to8,
+                                          unop(Iop_32to16, getIReg(rt)))));
+                     assign(t2, unop(Iop_16to8,
+                                     unop(Iop_32to16,
+                                          binop(Iop_Shr32,
+                                                binop(Iop_Add32,
+                                                      binop(Iop_Add32,
+                                                            mkexpr(t0),
+                                                            mkexpr(t1)),
+                                                      mkU32(0x00000001)),
+                                                mkU8(0x01)))));
+
+                     assign(t3, unop(Iop_8Uto32,
+                                     unop(Iop_16HIto8,
+                                          unop(Iop_32to16, getIReg(rs)))));
+                     assign(t4, unop(Iop_8Uto32,
+                                     unop(Iop_16HIto8,
+                                          unop(Iop_32to16, getIReg(rt)))));
+                     assign(t5, unop(Iop_16to8,
+                                     unop(Iop_32to16,
+                                          binop(Iop_Shr32,
+                                                binop(Iop_Add32,
+                                                      binop(Iop_Add32,
+                                                            mkexpr(t3),
+                                                            mkexpr(t4)),
+                                                      mkU32(0x00000001)),
+                                                mkU8(0x01)))));
+
+                     assign(t6, unop(Iop_8Uto32,
+                                     unop(Iop_16to8,
+                                          unop(Iop_32HIto16, getIReg(rs)))));
+                     assign(t7, unop(Iop_8Uto32,
+                                     unop(Iop_16to8,
+                                          unop(Iop_32HIto16, getIReg(rt)))));
+                     assign(t8, unop(Iop_16to8,
+                                     unop(Iop_32to16,
+                                          binop(Iop_Shr32,
+                                                binop(Iop_Add32,
+                                                      binop(Iop_Add32,
+                                                            mkexpr(t7),
+                                                            mkexpr(t6)),
+                                                      mkU32(0x00000001)),
+                                                mkU8(0x01)))));
+
+                     assign(t9, unop(Iop_8Uto32,
+                                     unop(Iop_16HIto8,
+                                          unop(Iop_32HIto16, getIReg(rs)))));
+                     assign(t10, unop(Iop_8Uto32,
+                                      unop(Iop_16HIto8,
+                                           unop(Iop_32HIto16, getIReg(rt)))));
+                     assign(t11, unop(Iop_16to8,
+                                      unop(Iop_32to16,
+                                           binop(Iop_Shr32,
+                                                 binop(Iop_Add32,
+                                                       binop(Iop_Add32,
+                                                             mkexpr(t9),
+                                                             mkexpr(t10)),
+                                                       mkU32(0x00000001)),
+                                                 mkU8(0x01)))));
+
+                     putIReg(rd, binop(Iop_16HLto32,
+                                       binop(Iop_8HLto16,
+                                             mkexpr(t11), mkexpr(t8)),
+                                       binop(Iop_8HLto16,
+                                             mkexpr(t5), mkexpr(t2))));
+                     break;
+                  }
+                  case 0x3: {  /* SUBUH_R.QB */
+                     DIP("subuh_r.qb r%d, r%d, r%d", rd, rs, rt);
+                     vassert(!mode64);
+                     t1 = newTemp(Ity_I32);
+                     t2 = newTemp(Ity_I32);
+                     t3 = newTemp(Ity_I32);
+                     t4 = newTemp(Ity_I32);
+                     t5 = newTemp(Ity_I32);
+                     t6 = newTemp(Ity_I32);
+                     t7 = newTemp(Ity_I32);
+                     t8 = newTemp(Ity_I32);
+                     t9 = newTemp(Ity_I8);
+                     t10 = newTemp(Ity_I8);
+                     t11 = newTemp(Ity_I8);
+                     t12 = newTemp(Ity_I8);
+
+                     /* Extract each byte of rs and rt. */
+                     assign(t1, unop(Iop_8Uto32,
+                                     unop(Iop_16to8,
+                                          unop(Iop_32to16, getIReg(rs)))));
+                     assign(t2, unop(Iop_8Uto32,
+                                     unop(Iop_16HIto8,
+                                          unop(Iop_32to16, getIReg(rs)))));
+                     assign(t3, unop(Iop_8Uto32,
+                                     unop(Iop_16to8,
+                                          unop(Iop_32HIto16, getIReg(rs)))));
+                     assign(t4, unop(Iop_8Uto32,
+                                     unop(Iop_16HIto8,
+                                          unop(Iop_32HIto16, getIReg(rs)))));
+
+                     assign(t5, unop(Iop_8Uto32,
+                                     unop(Iop_16to8,
+                                          unop(Iop_32to16, getIReg(rt)))));
+                     assign(t6, unop(Iop_8Uto32,
+                                     unop(Iop_16HIto8,
+                                          unop(Iop_32to16, getIReg(rt)))));
+                     assign(t7, unop(Iop_8Uto32,
+                                     unop(Iop_16to8,
+                                          unop(Iop_32HIto16, getIReg(rt)))));
+                     assign(t8, unop(Iop_8Uto32,
+                                     unop(Iop_16HIto8,
+                                          unop(Iop_32HIto16, getIReg(rt)))));
+
+                     /* Add 1 to each resulting byte and half the results. */
+                     assign(t9, unop(Iop_16to8,
+                                     unop(Iop_32to16,
+                                          binop(Iop_Shr32,
+                                                binop(Iop_Add32,
+                                                      binop(Iop_Sub32,
+                                                            mkexpr(t1),
+                                                            mkexpr(t5)),
+                                                      mkU32(0x00000001)),
+                                                mkU8(0x01)))));
+                     assign(t10, unop(Iop_16to8,
+                                      unop(Iop_32to16,
+                                           binop(Iop_Shr32,
+                                                 binop(Iop_Add32,
+                                                       binop(Iop_Sub32,
+                                                             mkexpr(t2),
+                                                             mkexpr(t6)),
+                                                       mkU32(0x00000001)),
+                                                 mkU8(0x01)))));
+                     assign(t11, unop(Iop_16to8,
+                                      unop(Iop_32to16,
+                                            binop(Iop_Shr32,
+                                                  binop(Iop_Add32,
+                                                        binop(Iop_Sub32,
+                                                              mkexpr(t3),
+                                                              mkexpr(t7)),
+                                                        mkU32(0x00000001)),
+                                                  mkU8(0x01)))));
+                     assign(t12, unop(Iop_16to8,
+                                      unop(Iop_32to16,
+                                           binop(Iop_Shr32,
+                                                 binop(Iop_Add32,
+                                                       binop(Iop_Sub32,
+                                                             mkexpr(t4),
+                                                             mkexpr(t8)),
+                                                       mkU32(0x00000001)),
+                                                 mkU8(0x01)))));
+
+                     putIReg(rd, binop(Iop_16HLto32,
+                                       binop(Iop_8HLto16,
+                                             mkexpr(t12), mkexpr(t11)),
+                                       binop(Iop_8HLto16,
+                                             mkexpr(t10), mkexpr(t9))));
+                     break;
+                  }
+                  case 0x8: {  /* ADDQH.PH */
+                     DIP("addqh.ph r%d, r%d, r%d", rd, rs, rt);
+                     vassert(!mode64);
+                     t0 = newTemp(Ity_I32);
+                     t1 = newTemp(Ity_I16);
+                     t2 = newTemp(Ity_I32);
+                     t3 = newTemp(Ity_I16);
+
+                     /* Add lower halfs of rs and rt
+                        and right shift the result by 1. */
+                     assign(t0, binop(Iop_Add32,
+                                      unop(Iop_16Sto32,
+                                           unop(Iop_32to16, getIReg(rs))),
+                                      unop(Iop_16Sto32,
+                                           unop(Iop_32to16, getIReg(rt)))));
+                     assign(t1, unop(Iop_32to16,
+                                     binop(Iop_Shr32,
+                                           binop(Iop_And32,
+                                                 mkexpr(t0),
+                                                 mkU32(0x0001fffe)),
+                                           mkU8(0x1))));
+                     /* Add higher halfs of rs and rt
+                        and right shift the result by 1. */
+                     assign(t2, binop(Iop_Add32,
+                                      unop(Iop_16Sto32,
+                                           unop(Iop_32HIto16, getIReg(rs))),
+                                      unop(Iop_16Sto32,
+                                           unop(Iop_32HIto16, getIReg(rt)))));
+                     assign(t3, unop(Iop_32to16,
+                                     binop(Iop_Shr32,
+                                           binop(Iop_And32,
+                                                 mkexpr(t2),
+                                                 mkU32(0x0001fffe)),
+                                           mkU8(0x1))));
+                     putIReg(rd, binop(Iop_16HLto32, mkexpr(t3), mkexpr(t1)));
+                     break;
+                  }
+                  case 0x9: {  /* SUBQH.PH */
+                     DIP("subqh.ph r%d, r%d, r%d", rd, rs, rt);
+                     vassert(!mode64);
+
+                     putIReg(rd, binop(Iop_HSub16Sx2,
+                                       getIReg(rs), getIReg(rt)));
+                     break;
+                  }
+                  case 0xA: {/* ADDQH_R.PH */
+                     DIP("addqh_r.ph r%d, r%d, r%d", rd, rs, rt);
+                     vassert(!mode64);
+                     t0 = newTemp(Ity_I32);
+                     t1 = newTemp(Ity_I16);
+                     t2 = newTemp(Ity_I32);
+                     t3 = newTemp(Ity_I16);
+
+                     /* Add lower halfs of rs and rt, add 1
+                        and right shift the result by 1. */
+                     assign(t0, binop(Iop_Add32,
+                                      unop(Iop_16Sto32,
+                                           unop(Iop_32to16, getIReg(rs))),
+                                      unop(Iop_16Sto32,
+                                           unop(Iop_32to16, getIReg(rt)))));
+                     assign(t1, unop(Iop_32to16,
+                                     binop(Iop_Shr32,
+                                           binop(Iop_And32,
+                                                 binop(Iop_Add32,
+                                                       mkexpr(t0),
+                                                       mkU32(0x1)),
+                                                 mkU32(0x0001fffe)),
+                                           mkU8(0x1))));
+                     /* Add higher halfs of rs and rt, add 1
+                        and right shift the result by 1. */
+                     assign(t2, binop(Iop_Add32,
+                                      unop(Iop_16Sto32,
+                                           unop(Iop_32HIto16, getIReg(rs))),
+                                      unop(Iop_16Sto32,
+                                           unop(Iop_32HIto16, getIReg(rt)))));
+                     assign(t3, unop(Iop_32to16,
+                                     binop(Iop_Shr32,
+                                           binop(Iop_And32,
+                                                 binop(Iop_Add32,
+                                                       mkexpr(t2),
+                                                       mkU32(0x1)),
+                                                 mkU32(0x0001fffe)),
+                                           mkU8(0x1))));
+
+                     putIReg(rd, binop(Iop_16HLto32, mkexpr(t3), mkexpr(t1)));
+                     break;
+                  }
+                  case 0xB: {  /* SUBQH_R.PH */
+                     DIP("subqh_r.ph r%d, r%d, r%d", rd, rs, rt);
+                     vassert(!mode64);
+                     t0 = newTemp(Ity_I32);
+                     t1 = newTemp(Ity_I16);
+                     t2 = newTemp(Ity_I32);
+                     t3 = newTemp(Ity_I16);
+
+                     /* Sub lower halfs of rs and rt, add 1
+                        and right shift the result by 1. */
+                     assign(t0, binop(Iop_Sub32,
+                                      unop(Iop_16Sto32,
+                                           unop(Iop_32to16, getIReg(rs))),
+                                      unop(Iop_16Sto32,
+                                           unop(Iop_32to16, getIReg(rt)))));
+                     assign(t1, unop(Iop_32to16,
+                                     binop(Iop_Shr32,
+                                           binop(Iop_And32,
+                                                 binop(Iop_Add32,
+                                                       mkexpr(t0),
+                                                       mkU32(0x1)),
+                                                 mkU32(0x0001fffe)),
+                                           mkU8(0x1))));
+                     /* Sub higher halfs of rs and rt, add 1
+                        and right shift the result by 1. */
+                     assign(t2, binop(Iop_Sub32,
+                                      unop(Iop_16Sto32,
+                                           unop(Iop_32HIto16, getIReg(rs))),
+                                      unop(Iop_16Sto32,
+                                           unop(Iop_32HIto16, getIReg(rt)))));
+                     assign(t3, unop(Iop_32to16,
+                                     binop(Iop_Shr32,
+                                           binop(Iop_And32,
+                                                 binop(Iop_Add32,
+                                                       mkexpr(t2),
+                                                       mkU32(0x1)),
+                                                 mkU32(0x0001fffe)),
+                                           mkU8(0x1))));
+
+                     putIReg(rd, binop(Iop_16HLto32, mkexpr(t3), mkexpr(t1)));
+                     break;
+                  }
+                  case 0xC: {  /* MUL.PH */
+                     DIP("mul.ph r%d, r%d, r%d", rd, rs, rt);
+                     vassert(!mode64);
+                     t0 = newTemp(Ity_I32);
+                     t1 = newTemp(Ity_I32);
+                     t2 = newTemp(Ity_I32);
+
+                     assign(t0,
+                            binop(Iop_Mul32,
+                                  unop(Iop_16Sto32,
+                                       unop(Iop_32HIto16, getIReg(rs))),
+                                  unop(Iop_16Sto32,
+                                       unop(Iop_32HIto16, getIReg(rt)))));
+                     /* DSP Control flag. */
+                     putDSPControl(IRExpr_ITE(unop(Iop_Not1,
+                                                   binop(Iop_CmpLE32S,
+                                                         mkexpr(t0),
+                                                         mkU32(0x7FFF))),
+                                              binop(Iop_Or32,
+                                                    getDSPControl(),
+                                                    mkU32(0x00200000)),
+                                              IRExpr_ITE(binop(Iop_CmpLT32S,
+                                                               mkexpr(t0),
+                                                               mkU32(0xFFFF8000)
+                                                             ),
+                                                         binop(Iop_Or32,
+                                                               getDSPControl(),
+                                                               mkU32(0x00200000)
+                                                              ),
+                                                         getDSPControl())));
+
+                     assign(t1,
+                            binop(Iop_Mul32,
+                                  unop(Iop_16Sto32,
+                                       unop(Iop_32to16, getIReg(rs))),
+                                  unop(Iop_16Sto32,
+                                       unop(Iop_32to16, getIReg(rt)))));
+                     /* DSP Control flag. */
+                     putDSPControl(IRExpr_ITE(unop(Iop_Not1,
+                                                   binop(Iop_CmpLE32S,
+                                                         mkexpr(t1),
+                                                         mkU32(0x7FFF))),
+                                              binop(Iop_Or32,
+                                                    getDSPControl(),
+                                                    mkU32(0x00200000)),
+                                              IRExpr_ITE(binop(Iop_CmpLT32S,
+                                                               mkexpr(t1),
+                                                               mkU32(0xFFFF8000)
+                                                              ),
+                                                         binop(Iop_Or32,
+                                                               getDSPControl(),
+                                                               mkU32(0x00200000)
+                                                              ),
+                                                         getDSPControl())));
+
+                     assign(t2, binop(Iop_16HLto32,
+                                      unop(Iop_32to16, mkexpr(t0)),
+                                      unop(Iop_32to16, mkexpr(t1))));
+                     putIReg(rd, mkexpr(t2));
+                     break;
+                  }
+                  case 0xE: {  /* MUL_S.PH */
+                     DIP("mul_s.ph r%d r%d, r%d", rd, rs, rt);
+                     vassert(!mode64);
+
+                     t0 = newTemp(Ity_I32);
+                     t1 = newTemp(Ity_I32);
+                     t2 = newTemp(Ity_I32);
+                     t3 = newTemp(Ity_I32);
+                     t4 = newTemp(Ity_I32);
+
+                     /* t0 - signed intermediate result. */
+                     assign(t0,
+                           binop(Iop_Mul32,
+                                 unop(Iop_16Sto32,
+                                      unop(Iop_32HIto16, getIReg(rs))),
+                                 unop(Iop_16Sto32,
+                                      unop(Iop_32HIto16, getIReg(rt)))));
+
+                     assign(t1,
+                            IRExpr_ITE(unop(Iop_Not1,
+                                            binop(Iop_CmpLE32S,
+                                                  mkexpr(t0),
+                                                  mkU32(0x7FFF))),
+                                       mkU32(0x00007FFF),
+                                       IRExpr_ITE(binop(Iop_CmpLT32S,
+                                                        mkexpr(t0),
+                                                        mkU32(0xFFFF8000)),
+                                                  mkU32(0xFFFF8000),
+                                                  mkexpr(t0))));
+
+                     /* DSP Control flag. */
+                     putDSPControl(IRExpr_ITE(unop(Iop_Not1,
+                                                   binop(Iop_CmpLE32S,
+                                                         mkexpr(t0),
+                                                         mkU32(0x7FFF))),
+                                              binop(Iop_Or32,
+                                                    getDSPControl(),
+                                                    mkU32(0x00200000)),
+                                              IRExpr_ITE(binop(Iop_CmpLT32S,
+                                                               mkexpr(t0),
+                                                               mkU32(0xFFFF8000)
+                                                              ),
+                                                         binop(Iop_Or32,
+                                                               getDSPControl(),
+                                                               mkU32(0x00200000)
+                                                              ),
+                                                         getDSPControl())));
+
+                     /* t2 - signed intermediate result. */
+                     assign(t2, binop(Iop_Mul32,
+                                      unop(Iop_16Sto32,
+                                           unop(Iop_32to16, getIReg(rs))),
+                                      unop(Iop_16Sto32,
+                                           unop(Iop_32to16, getIReg(rt)))));
+
+                     assign(t3, IRExpr_ITE(unop(Iop_Not1,
+                                                binop(Iop_CmpLE32S,
+                                                      mkexpr(t2),
+                                                      mkU32(0x7FFF))),
+                                           mkU32(0x00007FFF),
+                                           IRExpr_ITE(binop(Iop_CmpLT32S,
+                                                            mkexpr(t2),
+                                                            mkU32(0xFFFF8000)),
+                                                      mkU32(0xFFFF8000),
+                                                      mkexpr(t2))));
+
+                     /* DSP Control flag. */
+                     putDSPControl(IRExpr_ITE(unop(Iop_Not1,
+                                                   binop(Iop_CmpLE32S,
+                                                         mkexpr(t2),
+                                                         mkU32(0x7FFF))),
+                                              binop(Iop_Or32,
+                                                    getDSPControl(),
+                                                    mkU32(0x00200000)),
+                                              IRExpr_ITE(binop(Iop_CmpLT32S,
+                                                               mkexpr(t2),
+                                                               mkU32(0xFFFF8000)
+                                                              ),
+                                                         binop(Iop_Or32,
+                                                               getDSPControl(),
+                                                               mkU32(0x00200000)
+                                                              ),
+                                                         getDSPControl())));
+
+                     assign(t4, binop(Iop_16HLto32,
+                                      unop(Iop_32to16, mkexpr(t1)),
+                                      unop(Iop_32to16, mkexpr(t3))));
+                     putIReg(rd, mkexpr(t4));
+                     break;
+                  }
+                  case 0x10: {  /* ADDQH.W */
+                     DIP("addqh.w r%d, r%d, r%d", rd, rs, rt);
+                     vassert(!mode64);
+                     t0 = newTemp(Ity_I64);
+                     t1 = newTemp(Ity_I64);
+
+                     assign(t0, binop(Iop_Add64,
+                                      unop(Iop_32Sto64, getIReg(rs)),
+                                      unop(Iop_32Sto64, getIReg(rt))));
+                     assign(t1, binop(Iop_And64,
+                                      mkexpr(t0),
+                                      mkU64(0x00000001fffffffeULL)));
+                     putIReg(rd, unop(Iop_64to32,
+                                      binop(Iop_Shr64, mkexpr(t1), mkU8(0x1))));
+                     break;
+                  }
+                  case 0x11: {  /* SUBQH.W */
+                     DIP("subqh.w r%d, r%d, r%d", rd, rs, rt);
+                     vassert(!mode64);
+                     t0 = newTemp(Ity_I64);
+                     t1 = newTemp(Ity_I64);
+
+                     assign(t0, binop(Iop_Sub64,
+                                      unop(Iop_32Sto64, getIReg(rs)),
+                                      unop(Iop_32Sto64, getIReg(rt))));
+                     assign(t1, binop(Iop_And64,
+                                      mkexpr(t0),
+                                      mkU64(0x00000001fffffffeULL)));
+                     putIReg(rd, unop(Iop_64to32,
+                                      binop(Iop_Shr64, mkexpr(t1), mkU8(0x1))));
+                     break;
+                  }
+                  case 0x12: {  /* ADDQH_R.W */
+                     DIP("addqh_r.w r%d, r%d, r%d", rd, rs, rt);
+                     vassert(!mode64);
+                     t0 = newTemp(Ity_I64);
+                     t1 = newTemp(Ity_I64);
+                     t2 = newTemp(Ity_I64);
+
+                     assign(t0, binop(Iop_Add64,
+                                      unop(Iop_32Sto64, getIReg(rs)),
+                                      unop(Iop_32Sto64, getIReg(rt))));
+                     assign(t1, binop(Iop_Add64,
+                                      mkexpr(t0),
+                                      mkU64(0x0000000000000001ULL)));
+                     assign(t2, binop(Iop_And64,
+                                      mkexpr(t1),
+                                      mkU64(0x00000001fffffffeULL)));
+                     putIReg(rd, unop(Iop_64to32,
+                                      binop(Iop_Shr64, mkexpr(t2), mkU8(0x1))));
+                     break;
+                  }
+                  case 0x13: {  /* SUBQH_R.W */
+                     DIP("subqh_r.w r%d, r%d, r%d", rd, rs, rt);
+                     vassert(!mode64);
+                     t0 = newTemp(Ity_I64);
+                     t1 = newTemp(Ity_I64);
+                     t2 = newTemp(Ity_I64);
+
+                     assign(t0, binop(Iop_Sub64,
+                                      unop(Iop_32Sto64, getIReg(rs)),
+                                      unop(Iop_32Sto64, getIReg(rt))));
+                     assign(t1, binop(Iop_Add64,
+                                      mkexpr(t0),
+                                      mkU64(0x0000000000000001ULL)));
+                     assign(t2, binop(Iop_And64,
+                                      mkexpr(t1),
+                                      mkU64(0x00000001fffffffeULL)));
+                     putIReg(rd, unop(Iop_64to32,
+                                      binop(Iop_Shr64, mkexpr(t2), mkU8(0x1))));
+                     break;
+                  }
+                  case 0x16: {  /* MULQ_S.W */
+                     DIP("mulq_s.w r%d, r%d, r%d", rd, rs, rt);
+                     vassert(!mode64);
+                     t0 = newTemp(Ity_I64);
+                     t1 = newTemp(Ity_I1);
+                     t2 = newTemp(Ity_I1);
+
+                     assign(t0, binop(Iop_Shl64,
+                                      binop(Iop_MullS32,
+                                            getIReg(rt), getIReg(rs)),
+                                      mkU8(0x1)));
+                     assign(t1, binop(Iop_CmpEQ32,
+                                      getIReg(rt), mkU32(0x80000000)));
+                     assign(t2, binop(Iop_CmpEQ32,
+                                      getIReg(rs), mkU32(0x80000000)));
+
+                     putDSPControl(IRExpr_ITE(mkexpr(t1),
+                                              IRExpr_ITE(mkexpr(t2),
+                                                         binop(Iop_Or32,
+                                                               getDSPControl(),
+                                                               mkU32(0x00200000)
+                                                              ),
+                                                         getDSPControl()),
+                                              getDSPControl()));
+                     putIReg(rd, IRExpr_ITE(mkexpr(t1),
+                                            IRExpr_ITE(mkexpr(t2),
+                                                       mkU32(0x7fffffff),
+                                                       unop(Iop_64HIto32,
+                                                            mkexpr(t0))),
+                                            unop(Iop_64HIto32, mkexpr(t0))));
+                     break;
+                  }
+                  case 0x17: {  /* MULQ_RS.W */
+                     DIP("mulq_rs.w r%d, r%d, r%d", rd, rs, rt);
+                     vassert(!mode64);
+                     t0 = newTemp(Ity_I64);
+                     t1 = newTemp(Ity_I1);
+                     t2 = newTemp(Ity_I1);
+
+                     assign(t0, binop(Iop_Add64,
+                                      binop(Iop_Shl64,
+                                            binop(Iop_MullS32,
+                                                  getIReg(rt),
+                                                  getIReg(rs)),
+                                            mkU8(0x1)),
+                                      mkU64(0x0000000080000000ULL)));
+                     assign(t1,
+                            binop(Iop_CmpEQ32, getIReg(rt), mkU32(0x80000000)));
+                     assign(t2,
+                            binop(Iop_CmpEQ32, getIReg(rs), mkU32(0x80000000)));
+                     putDSPControl(IRExpr_ITE(mkexpr(t1),
+                                              IRExpr_ITE(mkexpr(t2),
+                                                         binop(Iop_Or32,
+                                                               getDSPControl(),
+                                                               mkU32(0x00200000)
+                                                              ),
+                                                         getDSPControl()),
+                                              getDSPControl()));
+                     putIReg(rd, IRExpr_ITE(mkexpr(t1),
+                                            IRExpr_ITE(mkexpr(t2),
+                                                       mkU32(0x7fffffff),
+                                                       unop(Iop_64HIto32,
+                                                            mkexpr(t0))),
+                                            unop(Iop_64HIto32, mkexpr(t0))));
+                     break;
+                  }
+                  default:
+                     return -1;
+               }
+               break;  /* end of ADDUH.QB/MUL.PH */
+            }
+            case 0x30: {  /* DPAQ.W.PH */
+               switch(sa) {
+                  case 0x0: {  /* DPA.W.PH */
+                     DIP("dpa.w.ph ac%d, r%d, r%d", ac, rs, rt);
+                     vassert(!mode64);
+
+                     t0 = newTemp(Ity_I64);
+                     t1 = newTemp(Ity_I64);
+                     t2 = newTemp(Ity_I64);
+
+                     assign(t0,
+                            unop(Iop_32Sto64,
+                                 binop(Iop_Mul32,
+                                       unop(Iop_16Sto32,
+                                            unop(Iop_32HIto16, getIReg(rs))),
+                                       unop(Iop_16Sto32,
+                                            unop(Iop_32HIto16, getIReg(rt))))));
+                     assign(t1,
+                            unop(Iop_32Sto64,
+                                 binop(Iop_Mul32,
+                                       unop(Iop_16Sto32,
+                                            unop(Iop_32to16, getIReg(rs))),
+                                       unop(Iop_16Sto32,
+                                            unop(Iop_32to16, getIReg(rt))))));
+                     assign(t2,
+                            binop(Iop_Add64,
+                                  getAcc(ac),
+                                  binop(Iop_Add64, mkexpr(t0), mkexpr(t1))));
+                     putAcc(ac, mkexpr(t2));
+                     break;
+                  }
+                  case 0x1: {  /* DPS.W.PH */
+                     DIP("dps.w.ph ac%d, r%d, r%d", ac, rs, rt);
+                     vassert(!mode64);
+
+                     t0 = newTemp(Ity_I64);
+                     t1 = newTemp(Ity_I64);
+                     t2 = newTemp(Ity_I64);
+
+                     assign(t0,
+                            unop(Iop_32Sto64,
+                                 binop(Iop_Mul32,
+                                       unop(Iop_16Sto32,
+                                            unop(Iop_32HIto16, getIReg(rs))),
+                                       unop(Iop_16Sto32,
+                                            unop(Iop_32HIto16, getIReg(rt))))));
+                     assign(t1,
+                            unop(Iop_32Sto64,
+                                 binop(Iop_Mul32,
+                                       unop(Iop_16Sto32,
+                                            unop(Iop_32to16, getIReg(rs))),
+                                       unop(Iop_16Sto32,
+                                            unop(Iop_32to16, getIReg(rt))))));
+                     assign(t2,
+                            binop(Iop_Sub64,
+                                  getAcc(ac),
+                                  binop(Iop_Add64, mkexpr(t0), mkexpr(t1))));
+                     putAcc(ac, mkexpr(t2));
+                     break;
+                  }
+                  case 0x2: {  /* MULSA.W.PH */
+                     DIP("mulsa.w.ph ac%d, r%d, r%d", ac, rs, rt);
+                     vassert(!mode64);
+                     t0 = newTemp(Ity_I32);
+                     t1 = newTemp(Ity_I32);
+                     t2 = newTemp(Ity_I32);
+                     t3 = newTemp(Ity_I1);
+                     t4 = newTemp(Ity_I64);
+
+                     assign(t4, getAcc(ac));
+                     assign(t0, binop(Iop_Mul32,
+                                      unop(Iop_16Sto32,
+                                           unop(Iop_32to16, getIReg(rt))),
+                                      unop(Iop_16Sto32,
+                                           unop(Iop_32to16, getIReg(rs)))));
+                     assign(t1, binop(Iop_Mul32,
+                                      unop(Iop_16Sto32,
+                                           unop(Iop_32HIto16, getIReg(rt))),
+                                      unop(Iop_16Sto32,
+                                           unop(Iop_32HIto16, getIReg(rs)))));
+                     assign(t2, binop(Iop_Sub32, mkexpr(t1), mkexpr(t0)));
+                     putAcc(ac, binop(Iop_Add64,
+                                      mkexpr(t4),
+                                      unop(Iop_32Sto64, mkexpr(t2))));
+                     break;
+                  }
+                  case 0x3: {  /* DPAU.H.QBL */
+                     DIP("dpau.h.qbl ac%d, r%d, r%d", ac, rs, rt);
+                     vassert(!mode64);
+                     t0 = newTemp(Ity_I32);
+                     t1 = newTemp(Ity_I32);
+                     t2 = newTemp(Ity_I64);
+                     t3 = newTemp(Ity_I64);
+
+                     assign(t0,
+                            binop(Iop_Mul32,
+                                  unop(Iop_8Uto32,
+                                       unop(Iop_16HIto8,
+                                            unop(Iop_32HIto16, getIReg(rs)))),
+                                  unop(Iop_8Uto32,
+                                       unop(Iop_16HIto8,
+                                            unop(Iop_32HIto16, getIReg(rt))))));
+                     assign(t1,
+                            binop(Iop_Mul32,
+                                  unop(Iop_8Uto32,
+                                       unop(Iop_16to8,
+                                            unop(Iop_32HIto16, getIReg(rs)))),
+                                  unop(Iop_8Uto32,
+                                       unop(Iop_16to8,
+                                            unop(Iop_32HIto16, getIReg(rt))))));
+                     assign(t2,
+                            unop(Iop_32Uto64,
+                                 binop(Iop_Add32,
+                                       mkexpr(t0),
+                                       mkexpr(t1))));
+                     assign(t3,
+                            binop(Iop_Add64, getAcc(ac), mkexpr(t2)));
+                     putAcc(ac, mkexpr(t3));
+                     break;
+                  }
+                  case 0x4: {  /* DPAQ_S.W.PH */
+                     DIP("dpaq_s.w.ph ac%d, r%d, r%d", ac, rs, rt);
+                     vassert(!mode64);
+                     t0 = newTemp(Ity_I64);
+                     t1 = newTemp(Ity_I64);
+                     t2 = newTemp(Ity_I1);
+                     t3 = newTemp(Ity_I1);
+                     t4 = newTemp(Ity_I64);
+                     t5 = newTemp(Ity_I64);
+                     t6 = newTemp(Ity_I1);
+                     t7 = newTemp(Ity_I1);
+                     t8 = newTemp(Ity_I64);
+                     t9 = newTemp(Ity_I64);
+
+                     assign(t0, getAcc(ac));
+
+                     assign(t1, binop(Iop_Shl64,
+                                      binop(Iop_MullS32,
+                                            unop(Iop_16Sto32,
+                                                 unop(Iop_32HIto16,
+                                                      getIReg(rs))),
+                                            unop(Iop_16Sto32,
+                                                 unop(Iop_32HIto16,
+                                                      getIReg(rt)))),
+                                      mkU8(0x1)));
+                     assign(t2, binop(Iop_CmpEQ32,
+                                      unop(Iop_16Uto32,
+                                           unop(Iop_32HIto16, getIReg(rs))),
+                                      mkU32(0x00008000)));
+                     assign(t3, binop(Iop_CmpEQ32,
+                                      unop(Iop_16Uto32,
+                                           unop(Iop_32HIto16, getIReg(rt))),
+                                      mkU32(0x00008000)));
+                     assign(t4,
+                            IRExpr_ITE(mkexpr(t2),
+                                       IRExpr_ITE(mkexpr(t3),
+                                                  mkU64(0x000000007fffffffULL),
+                                                  mkexpr(t1)),
+                                       mkexpr(t1)));
+
+                     putDSPControl(IRExpr_ITE(mkexpr(t2),
+                                              IRExpr_ITE(mkexpr(t3),
+                                                         binop(Iop_Or32,
+                                                               getDSPControl(),
+                                                               binop(Iop_Shl32,
+                                                                     mkU32(0x1),
+                                                                     mkU8(ac+16)
+                                                                    )
+                                                              ),
+                                                         getDSPControl()),
+                                              getDSPControl()));
+
+                     assign(t5, binop(Iop_Shl64,
+                                      binop(Iop_MullS32,
+                                            unop(Iop_16Sto32,
+                                                 unop(Iop_32to16, getIReg(rs))),
+                                            unop(Iop_16Sto32,
+                                                 unop(Iop_32to16, getIReg(rt)))
+                                           ),
+                                      mkU8(0x1)));
+                     assign(t6, binop(Iop_CmpEQ32,
+                                      unop(Iop_16Uto32,
+                                           unop(Iop_32to16, getIReg(rs))),
+                                      mkU32(0x00008000)));
+                     assign(t7, binop(Iop_CmpEQ32,
+                                      unop(Iop_16Uto32,
+                                           unop(Iop_32to16, getIReg(rt))),
+                                      mkU32(0x00008000)));
+                     assign(t8,
+                            IRExpr_ITE(mkexpr(t6),
+                                       IRExpr_ITE(mkexpr(t7),
+                                                  mkU64(0x000000007fffffffULL),
+                                                  mkexpr(t5)),
+                                       mkexpr(t5)));
+
+                     putDSPControl(IRExpr_ITE(mkexpr(t6),
+                                              IRExpr_ITE(mkexpr(t7),
+                                                         binop(Iop_Or32,
+                                                               getDSPControl(),
+                                                               binop(Iop_Shl32,
+                                                                     mkU32(0x1),
+                                                                     mkU8(ac+16)
+                                                                    )
+                                                              ),
+                                                         getDSPControl()),
+                                              getDSPControl()));
+
+                     assign(t9, binop(Iop_Add64,
+                                      binop(Iop_Add64, mkexpr(t4), mkexpr(t8)),
+                                      mkexpr(t0)));
+                     putAcc(ac, mkexpr(t9));
+                     break;
+                  }
+                  case 0x5: {  /* DPSQ_S.W.PH */
+                     DIP("dpsq_s.w.ph ac%d r%d, r%d", ac, rs, rt);
+                     vassert(!mode64);
+                     t0 = newTemp(Ity_I64);
+                     t1 = newTemp(Ity_I64);
+                     t2 = newTemp(Ity_I1);
+                     t3 = newTemp(Ity_I1);
+                     t4 = newTemp(Ity_I64);
+                     t5 = newTemp(Ity_I64);
+                     t6 = newTemp(Ity_I1);
+                     t7 = newTemp(Ity_I1);
+                     t8 = newTemp(Ity_I64);
+                     t9 = newTemp(Ity_I64);
+
+                     assign(t0, getAcc(ac));
+
+                     assign(t1, binop(Iop_Shl64,
+                                      binop(Iop_MullS32,
+                                            unop(Iop_16Sto32,
+                                                 unop(Iop_32HIto16,
+                                                      getIReg(rs))),
+                                            unop(Iop_16Sto32,
+                                                 unop(Iop_32HIto16,
+                                                      getIReg(rt)))),
+                                      mkU8(0x1)));
+                     assign(t2, binop(Iop_CmpEQ32,
+                                      unop(Iop_16Uto32,
+                                           unop(Iop_32HIto16, getIReg(rs))),
+                                      mkU32(0x00008000)));
+                     assign(t3, binop(Iop_CmpEQ32,
+                                      unop(Iop_16Uto32,
+                                           unop(Iop_32HIto16, getIReg(rt))),
+                                      mkU32(0x00008000)));
+                     assign(t4,
+                            IRExpr_ITE(mkexpr(t2),
+                                       IRExpr_ITE(mkexpr(t3),
+                                                  mkU64(0x000000007fffffffULL),
+                                                  mkexpr(t1)),
+                                       mkexpr(t1)));
+
+                     putDSPControl(IRExpr_ITE(mkexpr(t2),
+                                              IRExpr_ITE(mkexpr(t3),
+                                                         binop(Iop_Or32,
+                                                               getDSPControl(),
+                                                               binop(Iop_Shl32,
+                                                                     mkU32(0x1),
+                                                                     mkU8(ac+16)
+                                                                    )
+                                                              ),
+                                                         getDSPControl()),
+                                              getDSPControl()));
+
+                     assign(t5,
+                            binop(Iop_Shl64,
+                                  binop(Iop_MullS32,
+                                        unop(Iop_16Sto32,
+                                             unop(Iop_32to16, getIReg(rs))),
+                                        unop(Iop_16Sto32,
+                                             unop(Iop_32to16, getIReg(rt)))),
+                                  mkU8(0x1)));
+                     assign(t6, binop(Iop_CmpEQ32,
+                                      unop(Iop_16Uto32,
+                                           unop(Iop_32to16, getIReg(rs))),
+                                      mkU32(0x00008000)));
+                     assign(t7, binop(Iop_CmpEQ32,
+                                      unop(Iop_16Uto32,
+                                           unop(Iop_32to16, getIReg(rt))),
+                                      mkU32(0x00008000)));
+                     assign(t8,
+                            IRExpr_ITE(mkexpr(t6),
+                                       IRExpr_ITE(mkexpr(t7),
+                                                  mkU64(0x000000007fffffffULL),
+                                                  mkexpr(t5)),
+                                       mkexpr(t5)));
+
+                     putDSPControl(IRExpr_ITE(mkexpr(t6),
+                                              IRExpr_ITE(mkexpr(t7),
+                                                         binop(Iop_Or32,
+                                                               getDSPControl(),
+                                                               binop(Iop_Shl32,
+                                                                     mkU32(0x1),
+                                                                     mkU8(ac+16)
+                                                                    )
+                                                              ),
+                                                         getDSPControl()),
+                                              getDSPControl()));
+
+                     assign(t9,
+                            binop(Iop_Sub64,
+                                  mkexpr(t0),
+                                  binop(Iop_Add64, mkexpr(t4), mkexpr(t8))));
+                     putAcc(ac, mkexpr(t9));
+                     break;
+                  }
+                  case 0x6: {  /* MULSAQ_S.W.PH */
+                     DIP("mulsaq_s.w.ph ac%d r%d, r%d", ac, rs, rt);
+                     vassert(!mode64);
+
+                     t0 = newTemp(Ity_I32);
+                     t1 = newTemp(Ity_I32);
+                     t2 = newTemp(Ity_I32);
+                     t3 = newTemp(Ity_I32);
+                     t4 = newTemp(Ity_I32);
+                     t5 = newTemp(Ity_I32);
+                     t6 = newTemp(Ity_I64);
+                     t7 = newTemp(Ity_I64);
+                     t8 = newTemp(Ity_I32);
+                     t9 = newTemp(Ity_I32);
+
+                     assign(t0, unop(Iop_16Sto32,
+                                     unop(Iop_32HIto16, getIReg(rs))));
+                     assign(t1, unop(Iop_16Sto32,
+                                     unop(Iop_32HIto16, getIReg(rt))));
+
+                     assign(t8, binop(Iop_And32,
+                                      unop(Iop_1Sto32,
+                                           binop(Iop_CmpEQ32,
+                                                 unop(Iop_16Uto32,
+                                                      unop(Iop_32HIto16,
+                                                           getIReg(rs))),
+                                                 mkU32(0x8000))),
+                                    unop(Iop_1Sto32,
+                                         binop(Iop_CmpEQ32,
+                                               unop(Iop_16Uto32,
+                                                    unop(Iop_32HIto16,
+                                                         getIReg(rt))),
+                                               mkU32(0x8000)))));
+                     /* DSPControl_outflag:16+acc <- 1 */
+                     putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32,
+                                                    mkexpr(t8),
+                                                    mkU32(0x0)),
+                                              binop(Iop_Or32,
+                                                    getDSPControl(),
+                                                    binop(Iop_Shl32,
+                                                          mkU32(0x00010000),
+                                                          mkU8(ac))),
+                                              getDSPControl()));
+
+                     /* tempB_31..0 */
+                     assign(t2,
+                            IRExpr_ITE(binop(Iop_CmpNE32,
+                                             mkexpr(t8), mkU32(0x0)),
+                                       mkU32(0x7FFFFFFF),
+                                       binop(Iop_Shl32,
+                                             binop(Iop_Mul32,
+                                                   mkexpr(t0), mkexpr(t1)),
+                                             mkU8(1))));
+
+                     assign(t3, unop(Iop_16Sto32,
+                                     unop(Iop_32to16, getIReg(rs))));
+                     assign(t4, unop(Iop_16Sto32,
+                                     unop(Iop_32to16, getIReg(rt))));
+
+                     assign(t9, binop(Iop_And32,
+                                      unop(Iop_1Sto32,
+                                           binop(Iop_CmpEQ32,
+                                                 unop(Iop_16Uto32,
+                                                      unop(Iop_32to16,
+                                                           getIReg(rs))),
+                                                 mkU32(0x8000))),
+                                      unop(Iop_1Sto32,
+                                           binop(Iop_CmpEQ32,
+                                                 unop(Iop_16Uto32,
+                                                      unop(Iop_32to16,
+                                                           getIReg(rt))),
+                                                 mkU32(0x8000)))));
+                     /* DSPControl_outflag:16+acc <- 1 */
+                     putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32,
+                                                    mkexpr(t9),
+                                                    mkU32(0x0)),
+                                              binop(Iop_Or32,
+                                                    getDSPControl(),
+                                                    binop(Iop_Shl32,
+                                                          mkU32(0x00010000),
+                                                          mkU8(ac))),
+                                              getDSPControl()));
+                     /* tempA_31..0 */
+                     assign(t5,
+                            IRExpr_ITE(binop(Iop_CmpNE32,
+                                             mkexpr(t9),
+                                             mkU32(0x0)),
+                                       mkU32(0x7FFFFFFF),
+                                       binop(Iop_Shl32,
+                                             binop(Iop_Mul32,
+                                                   mkexpr(t3),
+                                                   mkexpr(t4)),
+                                             mkU8(1))));
+                     /* dotp_63..0 */
+                     assign(t6,
+                            binop(Iop_Sub64,
+                                  unop(Iop_32Sto64, mkexpr(t2)),
+                                  unop(Iop_32Sto64, mkexpr(t5))));
+                     /* tempC_63..0 */
+                     assign(t7, binop(Iop_Add64, getAcc(ac), mkexpr(t6)));
+
+                     putAcc(ac, mkexpr(t7));
+                     break;
+                  }
+                  case 0x7: {  /* DPAU.H.QBR */
+                     DIP("dpau.h.qbr ac%d, r%d, r%d", ac, rs, rt);
+                     vassert(!mode64);
+                     t0 = newTemp(Ity_I32);
+                     t1 = newTemp(Ity_I32);
+                     t2 = newTemp(Ity_I64);
+                     t3 = newTemp(Ity_I64);
+
+                     assign(t0,
+                            binop(Iop_Mul32,
+                                  unop(Iop_8Uto32,
+                                       unop(Iop_16HIto8,
+                                            unop(Iop_32to16, getIReg(rs)))),
+                                  unop(Iop_8Uto32,
+                                       unop(Iop_16HIto8,
+                                            unop(Iop_32to16, getIReg(rt))))));
+                     assign(t1,
+                            binop(Iop_Mul32,
+                                  unop(Iop_8Uto32,
+                                       unop(Iop_16to8,
+                                            unop(Iop_32to16, getIReg(rs)))),
+                                  unop(Iop_8Uto32,
+                                       unop(Iop_16to8,
+                                            unop(Iop_32to16, getIReg(rt))))));
+                     assign(t2, unop(Iop_32Uto64,
+                                     binop(Iop_Add32, mkexpr(t0), mkexpr(t1))));
+                     assign(t3, binop(Iop_Add64, getAcc(ac), mkexpr(t2)));
+                     putAcc(ac, mkexpr(t3));
+                     break;
+                  }
+                  case 0x8: {  /* DPAX.W.PH */
+                     DIP("dpax.w.ph ac%d, r%d, r%d", ac, rs, rt);
+                     vassert(!mode64);
+                     t0 = newTemp(Ity_I64);
+                     t1 = newTemp(Ity_I64);
+                     t2 = newTemp(Ity_I64);
+
+                     assign(t0,
+                            unop(Iop_32Sto64,
+                                 binop(Iop_Mul32,
+                                       unop(Iop_16Sto32,
+                                            unop(Iop_32HIto16, getIReg(rs))),
+                                       unop(Iop_16Sto32,
+                                            unop(Iop_32to16, getIReg(rt))))));
+                     assign(t1,
+                            unop(Iop_32Sto64,
+                                 binop(Iop_Mul32,
+                                       unop(Iop_16Sto32,
+                                            unop(Iop_32to16, getIReg(rs))),
+                                       unop(Iop_16Sto32,
+                                            unop(Iop_32HIto16, getIReg(rt))))));
+                     assign(t2,
+                            binop(Iop_Add64,
+                                  getAcc(ac),
+                                  binop(Iop_Add64, mkexpr(t0), mkexpr(t1))));
+                     putAcc(ac, mkexpr(t2));
+                     break;
+                  }
+                  case 0x9: {  /* DPSX.W.PH */
+                     DIP("dpsx.w.ph ac%d r%d, r%d", ac, rs, rt);
+                     vassert(!mode64);
+
+                     t0 = newTemp(Ity_I64);
+                     t1 = newTemp(Ity_I64);
+                     t2 = newTemp(Ity_I64);
+
+                     assign(t0,
+                            unop(Iop_32Sto64,
+                                 binop(Iop_Mul32,
+                                       unop(Iop_16Sto32,
+                                            unop(Iop_32HIto16, getIReg(rs))),
+                                       unop(Iop_16Sto32,
+                                            unop(Iop_32to16, getIReg(rt))))));
+                     assign(t1,
+                            unop(Iop_32Sto64,
+                                 binop(Iop_Mul32,
+                                       unop(Iop_16Sto32,
+                                            unop(Iop_32to16, getIReg(rs))),
+                                       unop(Iop_16Sto32,
+                                            unop(Iop_32HIto16, getIReg(rt))))));
+                     assign(t2,
+                            binop(Iop_Sub64,
+                                  getAcc(ac),
+                                  binop(Iop_Add64, mkexpr(t0), mkexpr(t1))));
+                     putAcc(ac, mkexpr(t2));
+                     break;
+                  }
+                  case 0xB: {  /* DPSU.H.QBL */
+                     DIP("dpsu.h.qbl ac%d, r%d, r%d", ac, rs, rt);
+                     vassert(!mode64);
+
+                     t0 = newTemp(Ity_I32);
+                     t1 = newTemp(Ity_I32);
+                     t2 = newTemp(Ity_I64);
+                     t3 = newTemp(Ity_I64);
+
+                     assign(t0,
+                            binop(Iop_Mul32,
+                                  unop(Iop_8Uto32,
+                                       unop(Iop_16HIto8,
+                                            unop(Iop_32HIto16, getIReg(rs)))),
+                                  unop(Iop_8Uto32,
+                                       unop(Iop_16HIto8,
+                                            unop(Iop_32HIto16, getIReg(rt))))));
+                     assign(t1,
+                            binop(Iop_Mul32,
+                                  unop(Iop_8Uto32,
+                                       unop(Iop_16to8,
+                                            unop(Iop_32HIto16, getIReg(rs)))),
+                                  unop(Iop_8Uto32,
+                                       unop(Iop_16to8,
+                                            unop(Iop_32HIto16, getIReg(rt))))));
+                     assign(t2,
+                            unop(Iop_32Uto64,
+                                 binop(Iop_Add32, mkexpr(t0), mkexpr(t1))));
+                     assign(t3,
+                            binop(Iop_Sub64, getAcc(ac), mkexpr(t2)));
+                     putAcc(ac, mkexpr(t3));
+                     break;
+                  }
+                  case 0xC: {  /* DPAQ_SA.L.W */
+                     DIP("dpaq_sa.l.w ac%d, r%d, r%d", ac, rs, rt);
+                     vassert(!mode64);
+                     t0 = newTemp(Ity_I64);
+                     t1 = newTemp(Ity_I64);
+                     t2 = newTemp(Ity_I1);
+                     t3 = newTemp(Ity_I1);
+                     t4 = newTemp(Ity_I64);
+                     t5 = newTemp(Ity_I64);
+                     t6 = newTemp(Ity_I64);
+                     t7 = newTemp(Ity_I64);
+                     t8 = newTemp(Ity_I1);
+                     t9 = newTemp(Ity_I1);
+
+                     assign(t0, getAcc(ac));
+
+                     assign(t1, binop(Iop_Shl64,
+                                      binop(Iop_MullS32,
+                                            getIReg(rs), getIReg(rt)),
+                                      mkU8(0x1)));
+
+                     assign(t2, binop(Iop_CmpEQ32,
+                                      getIReg(rs),
+                                      mkU32(0x80000000)));
+                     assign(t3, binop(Iop_CmpEQ32,
+                                      getIReg(rt),
+                                      mkU32(0x80000000)));
+
+                     assign(t4,
+                            IRExpr_ITE(mkexpr(t2),
+                                       IRExpr_ITE(mkexpr(t3),
+                                                  mkU64(0x7fffffffffffffffULL),
+                                                  mkexpr(t1)),
+                                       mkexpr(t1)));
+
+                     putDSPControl(IRExpr_ITE(mkexpr(t2),
+                                              IRExpr_ITE(mkexpr(t3),
+                                                         binop(Iop_Or32,
+                                                               getDSPControl(),
+                                                               binop(Iop_Shl32,
+                                                                     mkU32(0x1),
+                                                                     mkU8(ac+16)
+                                                                    )
+                                                              ),
+                                                         getDSPControl()),
+                                              getDSPControl()));
+
+                     assign(t5, binop(Iop_Add64,
+                                      unop(Iop_32Uto64,
+                                           unop(Iop_64to32, mkexpr(t0))),
+                                      unop(Iop_32Uto64,
+                                           unop(Iop_64to32, mkexpr(t4)))));
+                     assign(t6,
+                            binop(Iop_Add64,
+                                  binop(Iop_Add64,
+                                        unop(Iop_32Sto64,
+                                             unop(Iop_64HIto32, mkexpr(t0))),
+                                        unop(Iop_32Sto64,
+                                             unop(Iop_64HIto32, mkexpr(t4)))),
+                                  unop(Iop_32Uto64,
+                                       binop(Iop_And32,
+                                             unop(Iop_64HIto32, mkexpr(t5)),
+                                             mkU32(0x1)))));
+                     assign(t7, binop(Iop_32HLto64,
+                                      unop(Iop_64to32, mkexpr(t6)),
+                                      unop(Iop_64to32, mkexpr(t5))));
+                     assign(t8, binop(Iop_CmpEQ32,
+                                      binop(Iop_Shr32,
+                                            binop(Iop_And32,
+                                                  unop(Iop_64to32, mkexpr(t6)),
+                                                  mkU32(0x80000000)),
+                                            mkU8(31)),
+                                      binop(Iop_And32,
+                                            unop(Iop_64HIto32, mkexpr(t6)),
+                                            mkU32(0x00000001))));
+                     assign(t9, binop(Iop_CmpEQ32,
+                                      binop(Iop_And32,
+                                            unop(Iop_64HIto32,
+                                                 mkexpr(t6)),
+                                            mkU32(0x00000001)),
+                                      mkU32(0x1)));
+                     putDSPControl(IRExpr_ITE(mkexpr(t8),
+                                              getDSPControl(),
+                                              binop(Iop_Or32,
+                                                    getDSPControl(),
+                                                    binop(Iop_Shl32,
+                                                          mkU32(0x1),
+                                                          mkU8(ac+16)))));
+                     putAcc(ac,
+                            IRExpr_ITE(mkexpr(t8),
+                                       mkexpr(t7),
+                                       IRExpr_ITE(mkexpr(t9),
+                                                  mkU64(0x8000000000000000ULL),
+                                                  mkU64(0x7fffffffffffffffULL)))
+                           );
+                     break;
+                  }
+                  case 0xD: {  /* DPSQ_SA.L.W */
+                     DIP("dpsq_sa.l.w ac%d, r%d, r%d", ac, rs, rt);
+                     vassert(!mode64);
+                     t0 = newTemp(Ity_I64);
+                     t1 = newTemp(Ity_I64);
+                     t2 = newTemp(Ity_I1);
+                     t3 = newTemp(Ity_I1);
+                     t4 = newTemp(Ity_I64);
+                     t5 = newTemp(Ity_I64);
+                     t6 = newTemp(Ity_I64);
+                     t7 = newTemp(Ity_I64);
+                     t8 = newTemp(Ity_I1);
+                     t9 = newTemp(Ity_I1);
+
+                     assign(t0, getAcc(ac));
+
+                     assign(t1, binop(Iop_Shl64,
+                                      binop(Iop_MullS32,
+                                            getIReg(rs), getIReg(rt)),
+                                      mkU8(0x1)));
+
+                     assign(t2, binop(Iop_CmpEQ32,
+                                      getIReg(rs),
+                                      mkU32(0x80000000)));
+                     assign(t3, binop(Iop_CmpEQ32,
+                                      getIReg(rt),
+                                      mkU32(0x80000000)));
+
+                     assign(t4,
+                            IRExpr_ITE(mkexpr(t2),
+                                       IRExpr_ITE(mkexpr(t3),
+                                                  mkU64(0x7fffffffffffffffULL),
+                                                  mkexpr(t1)),
+                                       mkexpr(t1)));
+
+                     putDSPControl(IRExpr_ITE(mkexpr(t2),
+                                              IRExpr_ITE(mkexpr(t3),
+                                                         binop(Iop_Or32,
+                                                               getDSPControl(),
+                                                               binop(Iop_Shl32,
+                                                                     mkU32(0x1),
+                                                                     mkU8(ac+16)
+                                                                    )
+                                                              ),
+                                                         getDSPControl()),
+                                              getDSPControl()));
+
+                     assign(t5, binop(Iop_Sub64,
+                                      unop(Iop_32Uto64,
+                                           unop(Iop_64to32, mkexpr(t0))),
+                                      unop(Iop_32Uto64,
+                                           unop(Iop_64to32, mkexpr(t4)))));
+                     assign(t6, binop(Iop_Sub64,
+                                      binop(Iop_Add64,
+                                            unop(Iop_32Sto64,
+                                                 unop(Iop_64HIto32, mkexpr(t0))
+                                                ),
+                                            unop(Iop_32Sto64,
+                                                 unop(Iop_1Sto32,
+                                                      binop(Iop_CmpLT32U,
+                                                            unop(Iop_64to32,
+                                                                 mkexpr(t0)),
+                                                            unop(Iop_64to32,
+                                                                mkexpr(t4)))))),
+                                      unop(Iop_32Sto64,
+                                           unop(Iop_64HIto32, mkexpr(t4)))));
+                     assign(t7, binop(Iop_32HLto64,
+                                      unop(Iop_64to32, mkexpr(t6)),
+                                      unop(Iop_64to32, mkexpr(t5))));
+                     assign(t8, binop(Iop_CmpEQ32,
+                                      binop(Iop_Shr32,
+                                            binop(Iop_And32,
+                                                  unop(Iop_64to32, mkexpr(t6)),
+                                                  mkU32(0x80000000)),
+                                            mkU8(31)),
+                                      binop(Iop_And32,
+                                            unop(Iop_64HIto32, mkexpr(t6)),
+                                            mkU32(0x00000001))));
+                     assign(t9, binop(Iop_CmpEQ32,
+                                      binop(Iop_And32,
+                                            unop(Iop_64HIto32, mkexpr(t6)),
+                                            mkU32(0x00000001)),
+                                      mkU32(0x1)));
+                     putDSPControl(IRExpr_ITE(mkexpr(t8),
+                                              getDSPControl(),
+                                              binop(Iop_Or32,
+                                                    getDSPControl(),
+                                                    binop(Iop_Shl32,
+                                                          mkU32(0x1),
+                                                          mkU8(ac+16)))));
+                     putAcc(ac,
+                            IRExpr_ITE(mkexpr(t8),
+                                       mkexpr(t7),
+                                       IRExpr_ITE(mkexpr(t9),
+                                                  mkU64(0x8000000000000000ULL),
+                                                  mkU64(0x7fffffffffffffffULL)))
+                           );
+                     break;
+                  }
+                  case 0xF: {  /* DPSU.H.QBR */
+                     DIP("dpsu.h.qbr ac%d r%d, r%d", ac, rs, rt);
+                     vassert(!mode64);
+
+                     t0 = newTemp(Ity_I32);
+                     t1 = newTemp(Ity_I32);
+                     t2 = newTemp(Ity_I64);
+                     t3 = newTemp(Ity_I64);
+
+                     assign(t0,
+                            binop(Iop_Mul32,
+                                  unop(Iop_8Uto32,
+                                       unop(Iop_16HIto8,
+                                            unop(Iop_32to16, getIReg(rs)))),
+                                  unop(Iop_8Uto32,
+                                       unop(Iop_16HIto8,
+                                            unop(Iop_32to16, getIReg(rt))))));
+                     assign(t1,
+                            binop(Iop_Mul32,
+                                  unop(Iop_8Uto32,
+                                       unop(Iop_16to8,
+                                            unop(Iop_32to16, getIReg(rs)))),
+                                  unop(Iop_8Uto32,
+                                       unop(Iop_16to8,
+                                            unop(Iop_32to16, getIReg(rt))))));
+                     assign(t2, unop(Iop_32Uto64,
+                                     binop(Iop_Add32, mkexpr(t0), mkexpr(t1))));
+                     assign(t3, binop(Iop_Sub64, getAcc(ac), mkexpr(t2)));
+                     putAcc(ac, mkexpr(t3));
+
+                     break;
+                  }
+                  case 0x10: {  /* MAQ_SA.W.PHL */
+                     DIP("maq_sa.w.phl ac%d, r%d, r%d", ac, rs, rt);
+                     vassert(!mode64);
+                     t0 = newTemp(Ity_I64);
+                     t1 = newTemp(Ity_I64);
+                     t2 = newTemp(Ity_I1);
+                     t3 = newTemp(Ity_I1);
+                     t4 = newTemp(Ity_I64);
+                     t5 = newTemp(Ity_I64);
+                     t6 = newTemp(Ity_I1);
+                     t7 = newTemp(Ity_I64);
+
+                     assign(t0, getAcc(ac));
+                     assign(t1, unop(Iop_32Sto64,
+                                     binop(Iop_Shl32,
+                                           binop(Iop_Mul32,
+                                                 unop(Iop_16Sto32,
+                                                      unop(Iop_32HIto16,
+                                                           getIReg(rs))),
+                                                 unop(Iop_16Sto32,
+                                                      unop(Iop_32HIto16,
+                                                           getIReg(rt)))),
+                                           mkU8(0x1))));
+
+                     /* If both input arguments are equal 0x8000, saturate
+                        intermediate product and write to DSPControl register.
+                     */
+                     assign(t2, binop(Iop_CmpEQ32,
+                                      unop(Iop_16Uto32,
+                                           unop(Iop_32HIto16, getIReg(rs))),
+                                      mkU32(0x00008000)));
+                     assign(t3, binop(Iop_CmpEQ32,
+                                      unop(Iop_16Uto32,
+                                           unop(Iop_32HIto16, getIReg(rt))),
+                                      mkU32(0x00008000)));
+
+                     assign(t4,
+                            IRExpr_ITE(mkexpr(t2),
+                                       IRExpr_ITE(mkexpr(t3),
+                                                  mkU64(0x000000007fffffffULL),
+                                                  mkexpr(t1)),
+                                       mkexpr(t1)));
+
+                     putDSPControl(IRExpr_ITE(mkexpr(t2),
+                                              IRExpr_ITE(mkexpr(t3),
+                                                         binop(Iop_Or32,
+                                                               getDSPControl(),
+                                                               binop(Iop_Shl32,
+                                                                     mkU32(0x1),
+                                                                     mkU8(ac+16)
+                                                                    )
+                                                              ),
+                                                         getDSPControl()),
+                                              getDSPControl()));
+                     /* Add intermediate product and value in the
+                        accumulator. */
+                     assign(t5, binop(Iop_Add64, mkexpr(t0), mkexpr(t4)));
+
+                     /* Compare bits 31 and 32 of the value in t5. */
+                     assign(t6, binop(Iop_CmpEQ32,
+                                      binop(Iop_Shr32,
+                                            binop(Iop_And32,
+                                                  unop(Iop_64to32, mkexpr(t5)),
+                                                  mkU32(0x80000000)),
+                                            mkU8(31)),
+                                      binop(Iop_And32,
+                                            unop(Iop_64HIto32, mkexpr(t5)),
+                                            mkU32(1))));
+                     putDSPControl(IRExpr_ITE(mkexpr(t6),
+                                              getDSPControl(),
+                                              binop(Iop_Or32,
+                                                    getDSPControl(),
+                                                    binop(Iop_Shl32,
+                                                          mkU32(0x1),
+                                                          mkU8(ac+16)))));
+                     assign(t7,
+                            IRExpr_ITE(mkexpr(t6),
+                                       mkexpr(t5),
+                                       IRExpr_ITE(binop(Iop_CmpEQ32,
+                                                        binop(Iop_And32,
+                                                              unop(Iop_64HIto32,
+                                                                   mkexpr(t5)),
+                                                              mkU32(1)),
+                                                        mkU32(0x0)),
+                                                  mkU64(0x000000007fffffffULL),
+                                                  mkU64(0xffffffff80000000ULL)))
+                           );
+                     putAcc(ac, mkexpr(t7));
+                     break;
+                  }
+                  case 0x12: {  /* MAQ_SA.W.PHR */
+                     DIP("maq_sa.w.phr ac%d, r%d, r%d", ac, rs, rt);
+                     vassert(!mode64);
+                     t0 = newTemp(Ity_I64);
+                     t1 = newTemp(Ity_I64);
+                     t2 = newTemp(Ity_I1);
+                     t3 = newTemp(Ity_I1);
+                     t4 = newTemp(Ity_I64);
+                     t5 = newTemp(Ity_I64);
+                     t6 = newTemp(Ity_I1);
+                     t7 = newTemp(Ity_I64);
+
+                     assign(t0, getAcc(ac));
+                     assign(t1, unop(Iop_32Sto64,
+                                     binop(Iop_Shl32,
+                                           binop(Iop_Mul32,
+                                                 unop(Iop_16Sto32,
+                                                      unop(Iop_32to16,
+                                                           getIReg(rs))),
+                                                 unop(Iop_16Sto32,
+                                                      unop(Iop_32to16,
+                                                           getIReg(rt)))),
+                                           mkU8(0x1))));
+
+                     /* If both input arguments are equal 0x8000, saturate
+                        intermediate product and write to DSPControl
+                        register. */
+                     assign(t2, binop(Iop_CmpEQ32,
+                                      unop(Iop_16Uto32,
+                                           unop(Iop_32to16, getIReg(rs))),
+                                      mkU32(0x00008000)));
+                     assign(t3, binop(Iop_CmpEQ32,
+                                      unop(Iop_16Uto32,
+                                           unop(Iop_32to16, getIReg(rt))),
+                                      mkU32(0x00008000)));
+
+                     assign(t4,
+                            IRExpr_ITE(mkexpr(t2),
+                                       IRExpr_ITE(mkexpr(t3),
+                                                  mkU64(0x000000007fffffffULL),
+                                                  mkexpr(t1)),
+                                       mkexpr(t1)));
+
+                     putDSPControl(IRExpr_ITE(mkexpr(t2),
+                                              IRExpr_ITE(mkexpr(t3),
+                                                         binop(Iop_Or32,
+                                                               getDSPControl(),
+                                                               binop(Iop_Shl32,
+                                                                     mkU32(0x1),
+                                                                     mkU8(ac+16)
+                                                                    )
+                                                              ),
+                                                         getDSPControl()),
+                                              getDSPControl()));
+                     /* Add intermediate product and value in the
+                        accumulator. */
+                     assign(t5, binop(Iop_Add64, mkexpr(t0), mkexpr(t4)));
+
+                     /* Compare bits 31 and 32 of the value in t5. */
+                     assign(t6, binop(Iop_CmpEQ32,
+                                      binop(Iop_Shr32,
+                                            binop(Iop_And32,
+                                                  unop(Iop_64to32, mkexpr(t5)),
+                                                  mkU32(0x80000000)),
+                                            mkU8(31)),
+                                      binop(Iop_And32,
+                                            unop(Iop_64HIto32, mkexpr(t5)),
+                                            mkU32(1))));
+                     putDSPControl(IRExpr_ITE(mkexpr(t6),
+                                              getDSPControl(),
+                                              binop(Iop_Or32,
+                                                    getDSPControl(),
+                                                    binop(Iop_Shl32,
+                                                          mkU32(0x1),
+                                                          mkU8(ac+16)))));
+                     assign(t7,
+                            IRExpr_ITE(mkexpr(t6),
+                                       mkexpr(t5),
+                                       IRExpr_ITE(binop(Iop_CmpEQ32,
+                                                        binop(Iop_And32,
+                                                              unop(Iop_64HIto32,
+                                                                   mkexpr(t5)),
+                                                              mkU32(1)),
+                                                        mkU32(0x0)),
+                                                  mkU64(0x000000007fffffffULL),
+                                                  mkU64(0xffffffff80000000ULL)))
+                           );
+                     putAcc(ac, mkexpr(t7));
+                     break;
+                  }
+                  case 0x14: {  /* MAQ_S.W.PHL */
+                     DIP("maq_s.w.phl ac%d, r%d, r%d", ac, rs, rt);
+                     vassert(!mode64);
+                     t0 = newTemp(Ity_I32);
+                     t1 = newTemp(Ity_I32);
+                     t2 = newTemp(Ity_I32);
+                     t3 = newTemp(Ity_I1);
+                     t4 = newTemp(Ity_I32);
+                     t5 = newTemp(Ity_I64);
+
+                     assign(t5, getAcc(ac));
+
+                     assign(t0, unop(Iop_16Sto32,
+                                     unop(Iop_32HIto16, getIReg(rs))));
+                     assign(t1, unop(Iop_16Sto32,
+                                     unop(Iop_32HIto16, getIReg(rt))));
+
+                     assign(t2, binop(Iop_And32,
+                                      unop(Iop_1Sto32,
+                                           binop(Iop_CmpEQ32,
+                                                 binop(Iop_And32,
+                                                       mkexpr(t0),
+                                                       mkU32(0xffff)),
+                                                 mkU32(0x8000))),
+                                      unop(Iop_1Sto32,
+                                           binop(Iop_CmpEQ32,
+                                                 binop(Iop_And32,
+                                                       mkexpr(t1),
+                                                       mkU32(0xffff)),
+                                                 mkU32(0x8000)))));
+
+                     assign(t3, binop(Iop_CmpEQ32, mkexpr(t2), mkU32(0x0)));
+
+                     putDSPControl(IRExpr_ITE(mkexpr(t3),
+                                              getDSPControl(),
+                                              binop(Iop_Or32,
+                                                    getDSPControl(),
+                                                    binop(Iop_Shl32,
+                                                          mkU32(0x1),
+                                                          mkU8(ac+16)))));
+
+                     assign(t4, unop(Iop_64to32,
+                                     binop(Iop_MullS32,
+                                           mkexpr(t0), mkexpr(t1))));
+                     putAcc(ac, IRExpr_ITE(mkexpr(t3),
+                                           binop(Iop_Add64,
+                                                 unop(Iop_32Sto64,
+                                                      binop(Iop_Shl32,
+                                                            mkexpr(t4),
+                                                            mkU8(0x1))),
+                                                 mkexpr(t5)),
+                                           binop(Iop_Add64,
+                                                 mkexpr(t5),
+                                                 unop(Iop_32Sto64,
+                                                      mkU32(0x7fffffff)))));
+                     break;
+                  }
+                  case 0x16: {  /* MAQ_S.W.PHR */
+                     DIP("maq_s.w.phr ac%d, r%d, r%d", ac, rs, rt);
+                     vassert(!mode64);
+                     t0 = newTemp(Ity_I32);
+                     t1 = newTemp(Ity_I32);
+                     t2 = newTemp(Ity_I32);
+                     t3 = newTemp(Ity_I1);
+                     t4 = newTemp(Ity_I32);
+                     t5 = newTemp(Ity_I64);
+
+                     assign(t5, getAcc(ac));
+
+                     assign(t0, unop(Iop_16Sto32,
+                                     unop(Iop_32to16, getIReg(rs))));
+                     assign(t1, unop(Iop_16Sto32,
+                                     unop(Iop_32to16, getIReg(rt))));
+
+                     assign(t2, binop(Iop_And32,
+                                      unop(Iop_1Sto32,
+                                           binop(Iop_CmpEQ32,
+                                                 binop(Iop_And32,
+                                                       mkexpr(t0),
+                                                       mkU32(0xffff)),
+                                                 mkU32(0x8000))),
+                                      unop(Iop_1Sto32,
+                                           binop(Iop_CmpEQ32,
+                                                 binop(Iop_And32,
+                                                       mkexpr(t1),
+                                                       mkU32(0xffff)),
+                                                 mkU32(0x8000)))));
+
+                     assign(t3, binop(Iop_CmpEQ32, mkexpr(t2), mkU32(0x0)));
+
+                     putDSPControl(IRExpr_ITE(mkexpr(t3),
+                                              getDSPControl(),
+                                              binop(Iop_Or32,
+                                                    getDSPControl(),
+                                                    binop(Iop_Shl32,
+                                                          mkU32(0x1),
+                                                          mkU8(ac+16)))));
+
+                     assign(t4, unop(Iop_64to32,
+                                     binop(Iop_MullS32,
+                                           mkexpr(t0), mkexpr(t1))));
+                     putAcc(ac, IRExpr_ITE(mkexpr(t3),
+                                           binop(Iop_Add64,
+                                                 unop(Iop_32Sto64,
+                                                      binop(Iop_Shl32,
+                                                            mkexpr(t4),
+                                                            mkU8(0x1))),
+                                                 mkexpr(t5)),
+                                           binop(Iop_Add64,
+                                                 mkexpr(t5),
+                                                 unop(Iop_32Sto64,
+                                                      mkU32(0x7fffffff)))));
+                     break;
+                  }
+                  case 0x18: {  /* DPAQX_S.W.PH */
+                     DIP("dpaqx_s.w.ph ac%d, r%d, r%d", ac, rs, rt);
+                     vassert(!mode64);
+                     t0 = newTemp(Ity_I64);
+                     t1 = newTemp(Ity_I64);
+                     t2 = newTemp(Ity_I1);
+                     t3 = newTemp(Ity_I1);
+                     t4 = newTemp(Ity_I64);
+                     t5 = newTemp(Ity_I64);
+                     t6 = newTemp(Ity_I1);
+                     t7 = newTemp(Ity_I1);
+                     t8 = newTemp(Ity_I64);
+                     t9 = newTemp(Ity_I64);
+
+                     assign(t0, getAcc(ac));
+
+                     assign(t1, binop(Iop_Shl64,
+                                      binop(Iop_MullS32,
+                                            unop(Iop_16Sto32,
+                                                 unop(Iop_32HIto16,
+                                                      getIReg(rs))),
+                                            unop(Iop_16Sto32,
+                                                 unop(Iop_32to16,
+                                                      getIReg(rt)))),
+                                      mkU8(0x1)));
+                     assign(t2, binop(Iop_CmpEQ32,
+                                      unop(Iop_16Uto32,
+                                           unop(Iop_32HIto16, getIReg(rs))),
+                                      mkU32(0x00008000)));
+                     assign(t3, binop(Iop_CmpEQ32,
+                                      unop(Iop_16Uto32,
+                                           unop(Iop_32to16, getIReg(rt))),
+                                      mkU32(0x00008000)));
+                     assign(t4,
+                            IRExpr_ITE(mkexpr(t2),
+                                       IRExpr_ITE(mkexpr(t3),
+                                                  mkU64(0x000000007fffffffULL),
+                                                  mkexpr(t1)),
+                                       mkexpr(t1)));
+
+                     putDSPControl(IRExpr_ITE(mkexpr(t2),
+                                              IRExpr_ITE(mkexpr(t3),
+                                                         binop(Iop_Or32,
+                                                               getDSPControl(),
+                                                               binop(Iop_Shl32,
+                                                                  mkU32(0x1),
+                                                                  mkU8(ac+16))),
+                                                         getDSPControl()),
+                                              getDSPControl()));
+
+                     assign(t5, binop(Iop_Shl64,
+                                      binop(Iop_MullS32,
+                                            unop(Iop_16Sto32,
+                                                 unop(Iop_32to16,
+                                                      getIReg(rs))),
+                                            unop(Iop_16Sto32,
+                                                 unop(Iop_32HIto16,
+                                                      getIReg(rt)))),
+                                      mkU8(0x1)));
+                     assign(t6, binop(Iop_CmpEQ32,
+                                      unop(Iop_16Uto32,
+                                           unop(Iop_32to16, getIReg(rs))),
+                                      mkU32(0x00008000)));
+                     assign(t7, binop(Iop_CmpEQ32,
+                                      unop(Iop_16Uto32,
+                                           unop(Iop_32HIto16, getIReg(rt))),
+                                      mkU32(0x00008000)));
+                     assign(t8,
+                            IRExpr_ITE(mkexpr(t6),
+                                       IRExpr_ITE(mkexpr(t7),
+                                                  mkU64(0x000000007fffffffULL),
+                                                  mkexpr(t5)),
+                                       mkexpr(t5)));
+
+                     putDSPControl(IRExpr_ITE(mkexpr(t6),
+                                              IRExpr_ITE(mkexpr(t7),
+                                                         binop(Iop_Or32,
+                                                               getDSPControl(),
+                                                               binop(Iop_Shl32,
+                                                                     mkU32(0x1),
+                                                                     mkU8(ac+16)
+                                                                    )
+                                                              ),
+                                                         getDSPControl()),
+                                              getDSPControl()));
+
+                     assign(t9, binop(Iop_Add64,
+                                      binop(Iop_Add64, mkexpr(t4), mkexpr(t8)),
+                                      mkexpr(t0)));
+                     putAcc(ac, mkexpr(t9));
+                     break;
+                  }
+                  case 0x19: {  /* DPSQX_S.W.PH */
+                     DIP("dpsqx_s.w.ph ac%d, r%d, r%d", ac, rs, rt);
+                     vassert(!mode64);
+                     t0 = newTemp(Ity_I64);
+                     t1 = newTemp(Ity_I64);
+                     t2 = newTemp(Ity_I1);
+                     t3 = newTemp(Ity_I1);
+                     t4 = newTemp(Ity_I64);
+                     t5 = newTemp(Ity_I64);
+                     t6 = newTemp(Ity_I1);
+                     t7 = newTemp(Ity_I1);
+                     t8 = newTemp(Ity_I64);
+                     t9 = newTemp(Ity_I64);
+
+                     assign(t0, getAcc(ac));
+
+                     assign(t1, binop(Iop_Shl64,
+                                      binop(Iop_MullS32,
+                                            unop(Iop_16Sto32,
+                                                 unop(Iop_32HIto16,
+                                                      getIReg(rs))),
+                                            unop(Iop_16Sto32,
+                                                 unop(Iop_32to16,
+                                                      getIReg(rt)))),
+                                      mkU8(0x1)));
+                     assign(t2, binop(Iop_CmpEQ32,
+                                      unop(Iop_16Uto32,
+                                           unop(Iop_32HIto16, getIReg(rs))),
+                                      mkU32(0x00008000)));
+                     assign(t3, binop(Iop_CmpEQ32,
+                                      unop(Iop_16Uto32,
+                                           unop(Iop_32to16, getIReg(rt))),
+                                      mkU32(0x00008000)));
+                     assign(t4,
+                            IRExpr_ITE(mkexpr(t2),
+                                       IRExpr_ITE(mkexpr(t3),
+                                                  mkU64(0x000000007fffffffULL),
+                                                  mkexpr(t1)),
+                                       mkexpr(t1)));
+
+                     putDSPControl(IRExpr_ITE(mkexpr(t2),
+                                              IRExpr_ITE(mkexpr(t3),
+                                                         binop(Iop_Or32,
+                                                               getDSPControl(),
+                                                               binop(Iop_Shl32,
+                                                                     mkU32(0x1),
+                                                                     mkU8(ac+16)
+                                                                    )
+                                                              ),
+                                                         getDSPControl()),
+                                              getDSPControl()));
+
+                     assign(t5, binop(Iop_Shl64,
+                                      binop(Iop_MullS32,
+                                            unop(Iop_16Sto32,
+                                                 unop(Iop_32to16,
+                                                      getIReg(rs))),
+                                            unop(Iop_16Sto32,
+                                                 unop(Iop_32HIto16,
+                                                      getIReg(rt)))),
+                                      mkU8(0x1)));
+                     assign(t6, binop(Iop_CmpEQ32,
+                                      unop(Iop_16Uto32,
+                                           unop(Iop_32to16, getIReg(rs))),
+                                      mkU32(0x00008000)));
+                     assign(t7, binop(Iop_CmpEQ32,
+                                      unop(Iop_16Uto32,
+                                           unop(Iop_32HIto16, getIReg(rt))),
+                                      mkU32(0x00008000)));
+                     assign(t8,
+                            IRExpr_ITE(mkexpr(t6),
+                                       IRExpr_ITE(mkexpr(t7),
+                                                  mkU64(0x000000007fffffffULL),
+                                                  mkexpr(t5)),
+                                       mkexpr(t5)));
+
+                     putDSPControl(IRExpr_ITE(mkexpr(t6),
+                                              IRExpr_ITE(mkexpr(t7),
+                                                         binop(Iop_Or32,
+                                                               getDSPControl(),
+                                                               binop(Iop_Shl32,
+                                                                     mkU32(0x1),
+                                                                     mkU8(ac+16)
+                                                                    )
+                                                              ),
+                                                         getDSPControl()),
+                                              getDSPControl()));
+
+                     assign(t9, binop(Iop_Sub64,
+                                     mkexpr(t0),
+                                     binop(Iop_Add64, mkexpr(t4), mkexpr(t8))));
+                     putAcc(ac, mkexpr(t9));
+                     break;
+                  }
+                  case 0x1A: {  /* DPAQX_SA.W.PH */
+                     DIP("dpaqx_sa.w.ph ac%d, r%d, r%d", ac, rs, rt);
+                     vassert(!mode64);
+                     t0 = newTemp(Ity_I64);
+                     t1 = newTemp(Ity_I64);
+                     t2 = newTemp(Ity_I1);
+                     t3 = newTemp(Ity_I1);
+                     t4 = newTemp(Ity_I64);
+                     t5 = newTemp(Ity_I64);
+                     t6 = newTemp(Ity_I1);
+                     t7 = newTemp(Ity_I1);
+                     t8 = newTemp(Ity_I64);
+                     t9 = newTemp(Ity_I64);
+                     t10 = newTemp(Ity_I32);
+                     t11 = newTemp(Ity_I32);
+
+                     assign(t0, getAcc(ac));
+                     /* Calculate first cross dot product and saturate if
+                        needed. */
+                     assign(t1, unop(Iop_32Sto64,
+                                     binop(Iop_Shl32,
+                                           binop(Iop_Mul32,
+                                                 unop(Iop_16Sto32,
+                                                      unop(Iop_32HIto16,
+                                                           getIReg(rs))),
+                                                 unop(Iop_16Sto32,
+                                                      unop(Iop_32to16,
+                                                           getIReg(rt)))),
+                                           mkU8(0x1))));
+
+                     /* If both input arguments are equal 0x8000, saturate
+                        intermediate product and write to DSPControl
+                        register. */
+                     assign(t2, binop(Iop_CmpEQ32,
+                                      unop(Iop_16Uto32,
+                                           unop(Iop_32HIto16, getIReg(rs))),
+                                      mkU32(0x00008000)));
+                     assign(t3, binop(Iop_CmpEQ32,
+                                      unop(Iop_16Uto32,
+                                           unop(Iop_32to16, getIReg(rt))),
+                                      mkU32(0x00008000)));
+
+                     assign(t4,
+                            IRExpr_ITE(mkexpr(t2),
+                                       IRExpr_ITE(mkexpr(t3),
+                                                  mkU64(0x000000007fffffffULL),
+                                                  mkexpr(t1)),
+                                       mkexpr(t1)));
+
+                     putDSPControl(IRExpr_ITE(mkexpr(t2),
+                                              IRExpr_ITE(mkexpr(t3),
+                                                         binop(Iop_Or32,
+                                                               getDSPControl(),
+                                                               binop(Iop_Shl32,
+                                                                     mkU32(0x1),
+                                                                     mkU8(ac+16)
+                                                                    )
+                                                              ),
+                                                         getDSPControl()),
+                                              getDSPControl()));
+                     /* Calculate second cross dot product and saturate if
+                        needed. */
+                     assign(t5, unop(Iop_32Sto64,
+                                     binop(Iop_Shl32,
+                                           binop(Iop_Mul32,
+                                                 unop(Iop_16Sto32,
+                                                      unop(Iop_32to16,
+                                                           getIReg(rs))),
+                                                 unop(Iop_16Sto32,
+                                                      unop(Iop_32HIto16,
+                                                           getIReg(rt)))),
+                                           mkU8(0x1))));
+
+                     /* If both input arguments are equal 0x8000, saturate
+                        intermediate product and write to DSPControl
+                        register. */
+                     assign(t6, binop(Iop_CmpEQ32,
+                                      unop(Iop_16Uto32,
+                                           unop(Iop_32to16, getIReg(rs))),
+                                      mkU32(0x00008000)));
+                     assign(t7, binop(Iop_CmpEQ32,
+                                      unop(Iop_16Uto32,
+                                           unop(Iop_32HIto16, getIReg(rt))),
+                                      mkU32(0x00008000)));
+
+                     assign(t8,
+                            IRExpr_ITE(mkexpr(t6),
+                                       IRExpr_ITE(mkexpr(t7),
+                                                  mkU64(0x000000007fffffffULL),
+                                                  mkexpr(t5)),
+                                       mkexpr(t5)));
+
+                     putDSPControl(IRExpr_ITE(mkexpr(t6),
+                                              IRExpr_ITE(mkexpr(t7),
+                                                         binop(Iop_Or32,
+                                                               getDSPControl(),
+                                                               binop(Iop_Shl32,
+                                                                     mkU32(0x1),
+                                                                     mkU8(ac+16)
+                                                                    )
+                                                              ),
+                                                         getDSPControl()),
+                                              getDSPControl()));
+                     /* Add intermediate products with value in the
+                        accumulator. */
+                     assign(t9, binop(Iop_Add64,
+                                     mkexpr(t0),
+                                     binop(Iop_Add64, mkexpr(t8), mkexpr(t4))));
+
+                     putAcc(ac,
+                            IRExpr_ITE(binop(Iop_CmpEQ32,
+                                             binop(Iop_And32,
+                                                   unop(Iop_64HIto32,
+                                                        mkexpr(t9)),
+                                                   mkU32(0x80000000)),
+                                             mkU32(0x0)),
+                                       IRExpr_ITE(binop(Iop_CmpNE32,
+                                                        unop(Iop_64HIto32,
+                                                             binop(Iop_Shl64,
+                                                                   mkexpr(t9),
+                                                                   mkU8(1))),
+                                                        mkU32(0x0)),
+                                                  mkU64(0x000000007fffffffULL),
+                                                  mkexpr(t9)),
+                                       IRExpr_ITE(binop(Iop_CmpNE32,
+                                                        unop(Iop_64HIto32,
+                                                             binop(Iop_Shl64,
+                                                                   mkexpr(t9),
+                                                                   mkU8(1))),
+                                                        mkU32(0xffffffff)),
+                                                  mkU64(0xffffffff80000000ULL),
+                                                  mkexpr(t9))));
+                     assign(t10, IRExpr_ITE(binop(Iop_CmpNE32,
+                                                  unop(Iop_64HIto32,
+                                                       binop(Iop_Shl64,
+                                                             mkexpr(t9),
+                                                             mkU8(1))),
+                                                  mkU32(0x0)),
+                                            binop(Iop_Or32,
+                                                  getDSPControl(),
+                                                  binop(Iop_Shl32,
+                                                        mkU32(0x1),
+                                                        mkU8(ac+16))),
+                                            getDSPControl()));
+                     assign(t11, IRExpr_ITE(binop(Iop_CmpNE32,
+                                                  unop(Iop_64HIto32,
+                                                       binop(Iop_Shl64,
+                                                             mkexpr(t9),
+                                                             mkU8(1))),
+                                                  mkU32(0xffffffff)),
+                                            binop(Iop_Or32,
+                                                  getDSPControl(),
+                                                  binop(Iop_Shl32,
+                                                        mkU32(0x1),
+                                                        mkU8(ac+16))),
+                                            getDSPControl()));
+                     putDSPControl(IRExpr_ITE(binop(Iop_CmpEQ32,
+                                                    binop(Iop_And32,
+                                                          unop(Iop_64HIto32,
+                                                               mkexpr(t9)),
+                                                          mkU32(0x80000000)),
+                                                    mkU32(0x0)),
+                                              mkexpr(t10),
+                                              mkexpr(t11)));
+                     break;
+                  }
+                  case 0x1B: {  /* DPSQX_SA.W.PH */
+                     DIP("dpsqx_sa.w.ph ac%d, r%d, r%d", ac, rs, rt);
+                     vassert(!mode64);
+                     t0 = newTemp(Ity_I64);
+                     t1 = newTemp(Ity_I64);
+                     t2 = newTemp(Ity_I1);
+                     t3 = newTemp(Ity_I1);
+                     t4 = newTemp(Ity_I64);
+                     t5 = newTemp(Ity_I64);
+                     t6 = newTemp(Ity_I1);
+                     t7 = newTemp(Ity_I1);
+                     t8 = newTemp(Ity_I64);
+                     t9 = newTemp(Ity_I64);
+                     t10 = newTemp(Ity_I32);
+                     t11 = newTemp(Ity_I32);
+
+                     assign(t0, getAcc(ac));
+                     /* Calculate first cross dot product and saturate if
+                        needed. */
+                     assign(t1, unop(Iop_32Sto64,
+                                     binop(Iop_Shl32,
+                                           binop(Iop_Mul32,
+                                                 unop(Iop_16Sto32,
+                                                      unop(Iop_32HIto16,
+                                                           getIReg(rs))),
+                                                 unop(Iop_16Sto32,
+                                                      unop(Iop_32to16,
+                                                           getIReg(rt)))),
+                                           mkU8(0x1))));
+
+                     /* If both input arguments are equal 0x8000, saturate
+                        intermediate product and write to DSPControl
+                        register. */
+                     assign(t2, binop(Iop_CmpEQ32,
+                                      unop(Iop_16Uto32,
+                                           unop(Iop_32HIto16, getIReg(rs))),
+                                      mkU32(0x00008000)));
+                     assign(t3, binop(Iop_CmpEQ32,
+                                      unop(Iop_16Uto32,
+                                           unop(Iop_32to16, getIReg(rt))),
+                                      mkU32(0x00008000)));
+
+                     assign(t4,
+                            IRExpr_ITE(mkexpr(t2),
+                                       IRExpr_ITE(mkexpr(t3),
+                                                  mkU64(0x000000007fffffffULL),
+                                                  mkexpr(t1)),
+                                       mkexpr(t1)));
+
+                     putDSPControl(IRExpr_ITE(mkexpr(t2),
+                                              IRExpr_ITE(mkexpr(t3),
+                                                         binop(Iop_Or32,
+                                                               getDSPControl(),
+                                                               binop(Iop_Shl32,
+                                                                     mkU32(0x1),
+                                                                     mkU8(ac+16)
+                                                                    )
+                                                              ),
+                                                         getDSPControl()),
+                                              getDSPControl()));
+                     /* Calculate second cross dot product and saturate if
+                        needed. */
+                     assign(t5, unop(Iop_32Sto64,
+                                     binop(Iop_Shl32,
+                                           binop(Iop_Mul32,
+                                                 unop(Iop_16Sto32,
+                                                      unop(Iop_32to16,
+                                                           getIReg(rs))),
+                                                 unop(Iop_16Sto32,
+                                                      unop(Iop_32HIto16,
+                                                           getIReg(rt)))),
+                                           mkU8(0x1))));
+
+                     /* If both input arguments are equal 0x8000, saturate
+                        intermediate product and write to DSPControl
+                        register. */
+                     assign(t6, binop(Iop_CmpEQ32,
+                                      binop(Iop_And32,
+                                            getIReg(rs),
+                                            mkU32(0x0000ffff)),
+                                      mkU32(0x00008000)));
+                     assign(t7, binop(Iop_CmpEQ32,
+                                      binop(Iop_And32,
+                                            getIReg(rt),
+                                            mkU32(0xffff0000)),
+                                      mkU32(0x80000000)));
+
+                     assign(t8,
+                            IRExpr_ITE(mkexpr(t6),
+                                       IRExpr_ITE(mkexpr(t7),
+                                                  mkU64(0x000000007fffffffULL),
+                                                  mkexpr(t5)),
+                                       mkexpr(t5)));
+
+                     putDSPControl(IRExpr_ITE(mkexpr(t6),
+                                              IRExpr_ITE(mkexpr(t7),
+                                                         binop(Iop_Or32,
+                                                         getDSPControl(),
+                                                         binop(Iop_Shl32,
+                                                               mkU32(0x1),
+                                                               mkU8(ac+16))),
+                                                         getDSPControl()),
+                                              getDSPControl()));
+                     /* Subtract intermediate products from value in the
+                        accumulator. */
+                     assign(t9,
+                            binop(Iop_Sub64,
+                                  mkexpr(t0),
+                                  binop(Iop_Add64, mkexpr(t8), mkexpr(t4))));
+
+                     putAcc(ac,
+                            IRExpr_ITE(binop(Iop_CmpEQ32,
+                                             binop(Iop_And32,
+                                                   unop(Iop_64HIto32,
+                                                        mkexpr(t9)),
+                                                   mkU32(0x80000000)),
+                                             mkU32(0x0)),
+                                       IRExpr_ITE(binop(Iop_CmpNE32,
+                                                        unop(Iop_64HIto32,
+                                                             binop(Iop_Shl64,
+                                                                   mkexpr(t9),
+                                                                   mkU8(1))),
+                                                        mkU32(0x0)),
+                                                  mkU64(0x000000007fffffffULL),
+                                                  mkexpr(t9)),
+                                       IRExpr_ITE(binop(Iop_CmpNE32,
+                                                        unop(Iop_64HIto32,
+                                                             binop(Iop_Shl64,
+                                                                   mkexpr(t9),
+                                                                   mkU8(1))),
+                                                        mkU32(0xffffffff)),
+                                                  mkU64(0xffffffff80000000ULL),
+                                                  mkexpr(t9))));
+                     assign(t10, IRExpr_ITE(binop(Iop_CmpNE32,
+                                                  unop(Iop_64HIto32,
+                                                       binop(Iop_Shl64,
+                                                             mkexpr(t9),
+                                                             mkU8(1))),
+                                                  mkU32(0x0)),
+                                            binop(Iop_Or32,
+                                                  getDSPControl(),
+                                                  binop(Iop_Shl32,
+                                                        mkU32(0x1),
+                                                        mkU8(ac+16))),
+                                            getDSPControl()));
+                     assign(t11, IRExpr_ITE(binop(Iop_CmpNE32,
+                                                  unop(Iop_64HIto32,
+                                                       binop(Iop_Shl64,
+                                                             mkexpr(t9),
+                                                             mkU8(1))),
+                                                  mkU32(0xffffffff)),
+                                            binop(Iop_Or32,
+                                                  getDSPControl(),
+                                                  binop(Iop_Shl32,
+                                                        mkU32(0x1),
+                                                        mkU8(ac+16))),
+                                            getDSPControl()));
+                     putDSPControl(IRExpr_ITE(binop(Iop_CmpEQ32,
+                                                    binop(Iop_And32,
+                                                          unop(Iop_64HIto32,
+                                                               mkexpr(t9)),
+                                                          mkU32(0x80000000)),
+                                                    mkU32(0x0)),
+                                              mkexpr(t10),
+                                              mkexpr(t11)));
+                     break;
+                  }
+                  default:
+                     return -1;
+               }
+               break;  /* end of DPAQ.W.PH */
+            }
+            case 0x31: {  /* APPEND */
+               switch(sa) {
+                  case 0x0: {  /* APPEND */
+                     DIP("append r%d, r%d, %d", rt, rs, rd);
+                     vassert(!mode64);
+                     t1 = newTemp(Ity_I32);
+                     t2 = newTemp(Ity_I32);
+                     t3 = newTemp(Ity_I32);
+
+                     assign(t1, binop(Iop_Shl32, getIReg(rt), mkU8(rd)));
+
+                     if (31 == rd) {
+                        putIReg(rt, binop(Iop_Or32,
+                                          mkexpr(t1),
+                                          binop(Iop_And32,
+                                                getIReg(rs),
+                                                mkU32(0x7fffffff))));
+                     } else if (1 == rd) {
+                        putIReg(rt,
+                                binop(Iop_Or32,
+                                      mkexpr(t1),
+                                      binop(Iop_And32,
+                                            getIReg(rs), mkU32(0x1))));
+                     } else {
+                        assign(t2,
+                               unop(Iop_Not32,
+                                    binop(Iop_Shl32,
+                                          mkU32(0xffffffff), mkU8(rd))));
+
+                        putIReg(rt, binop(Iop_Or32,
+                                          mkexpr(t1),
+                                          binop(Iop_And32,
+                                                getIReg(rs), mkexpr(t2))));
+                     }
+                     break;
+                  }
+                  case 0x1: {  /* PREPEND */
+                     DIP("prepend r%d, r%d, %d", rt, rs, rd);
+                     vassert(!mode64);
+                     t1 = newTemp(Ity_I32);
+                     t2 = newTemp(Ity_I32);
+                     t3 = newTemp(Ity_I32);
+
+                     if (0 != rd) {
+                        assign(t1, binop(Iop_Shr32, getIReg(rt), mkU8(rd)));
+
+                        if (31 == rd) {
+                           putIReg(rt, binop(Iop_Or32,
+                                             mkexpr(t1),
+                                             binop(Iop_Shl32,
+                                                   binop(Iop_And32,
+                                                         getIReg(rs),
+                                                         mkU32(0x7fffffff)),
+                                                   mkU8(1))));
+                        } else if (1 == rd) {
+                           putIReg(rt, binop(Iop_Or32,
+                                             mkexpr(t1),
+                                             binop(Iop_Shl32,
+                                                   binop(Iop_And32,
+                                                         getIReg(rs),
+                                                         mkU32(0x1)),
+                                                   mkU8(31))));
+                        } else {
+                           assign(t2, binop(Iop_Add32, mkU32(rd), mkU32(0x1)));
+
+                           assign(t3, unop(Iop_Not32,
+                                           binop(Iop_Shl32,
+                                                 mkU32(0xffffffff),
+                                                 unop(Iop_32to8, mkexpr(t2)))));
+
+                           putIReg(rt, binop(Iop_Or32,
+                                             mkexpr(t1),
+                                             binop(Iop_Shl32,
+                                                   binop(Iop_And32,
+                                                         getIReg(rs),
+                                                         mkexpr(t3)),
+                                                   mkU8(32-rd))));
+                        }
+                     }
+                     break;
+                  }
+                  case 0x10: {  /* BALIGN */
+                     DIP("balign r%d, r%d, %d", rt, rs, rd);
+                     vassert(!mode64);
+                     t1 = newTemp(Ity_I32);
+                     t2 = newTemp(Ity_I32);
+                     t3 = newTemp(Ity_I32);
+
+                     if ((2 != rd) && (0 != rd)) {
+                        assign(t1, binop(Iop_Shl32,
+                                         binop(Iop_And32,
+                                               mkU32(rd), mkU32(0x3)),
+                                         mkU8(0x3)));
+                        assign(t2, binop(Iop_Shl32,
+                                         getIReg(rt),
+                                         unop(Iop_32to8, mkexpr(t1))));
+                        assign(t3, binop(Iop_Shr32,
+                                         getIReg(rs),
+                                         unop(Iop_32to8,
+                                              binop(Iop_Shl32,
+                                                    binop(Iop_Sub32,
+                                                          mkU32(0x4),
+                                                          binop(Iop_And32,
+                                                                mkU32(rd),
+                                                                mkU32(0x3))),
+                                                    mkU8(0x3)))));
+                        putIReg(rt, binop(Iop_Or32, mkexpr(t2), mkexpr(t3)));
+                     }
+                     break;
+                  }
+                  default:
+                     return -1;
+               }
+               break;  /* end of APPEND */
+            }
+            default:
+               return -1;
          }
          break;
-      default:
-         return False;
       }
-   *set = IRStmt_Exit(eCond, jmpKind, mkSzConst(ty, addrTgt), OFFB_PC);
-   return True;
+      default:
+            return -1;
+   }
+   return 0;
 }
 
 /*------------------------------------------------------------*/
@@ -1933,8 +11137,11 @@ static DisResult disInstr_MIPS_WRK ( Bool(*resteerOkFn) (/*opaque */void *,
                                      Bool         sigill_diag )
 {
    IRTemp t0, t1 = 0, t2, t3, t4, t5, t6, t7;
+
    UInt opcode, cins, rs, rt, rd, sa, ft, fs, fd, fmt, tf, nd, function,
         trap_code, imm, instr_index, p, msb, lsb, size, rot, sel;
+   /* Additional variables for instruction fields in DSP ASE insructions */
+   UInt ac;
 
    DisResult dres;
 
@@ -1984,7 +11191,7 @@ static DisResult disInstr_MIPS_WRK ( Bool(*resteerOkFn) (/*opaque */void *,
 
    /* Spot "Special" instructions (see comment at top of file). */
    {
-      /* Spot the 16-byte preamble: 
+      /* Spot the 16-byte preamble:
        ****mips32****
        "srl $0, $0, 13
        "srl $0, $0, 29
@@ -2094,6 +11301,8 @@ static DisResult disInstr_MIPS_WRK ( Bool(*resteerOkFn) (/*opaque */void *,
    IRType ty = mode64 ? Ity_I64 : Ity_I32;
    IRType tyF = mode64 ? Ity_F64 : Ity_F32;
 
+   ac = get_acNo(cins);
+
    switch (opcode) {
 
    case 0x03:     /* JAL */
@@ -3444,7 +12653,7 @@ static DisResult disInstr_MIPS_WRK ( Bool(*resteerOkFn) (/*opaque */void *,
       }
 
       case 0x1: {  /* LDXC1 */
-         /* Load Doubleword  Indexed to Floating Point 
+         /* Load Doubleword  Indexed to Floating Point
             LDXC1 (MIPS32r2 and MIPS64) */
          if (mode64) {
             DIP("ldxc1 f%d, r%d(r%d)", fd, rt, rs);
@@ -3520,7 +12729,7 @@ static DisResult disInstr_MIPS_WRK ( Bool(*resteerOkFn) (/*opaque */void *,
          }
          break;
       }
-      case 0xD:  /* Store Doubleword Indexed Unaligned from Floating Point - 
+      case 0xD:  /* Store Doubleword Indexed Unaligned from Floating Point -
                     SUXC1; MIPS64 MIPS32r2 */
          DIP("suxc1 f%d, r%d(r%d)", fd, rt, rs);
          t0 = newTemp(Ity_I64);
@@ -3879,7 +13088,7 @@ static DisResult disInstr_MIPS_WRK ( Bool(*resteerOkFn) (/*opaque */void *,
       assign(E_pos, IRExpr_ITE(binop(Iop_CmpLT64U, mkexpr(t3), mkU64(0x4)),
                                mkU64(0x4),
                                mkU64(0x0)));
+
       assign(F_pos, IRExpr_ITE(binop(Iop_CmpLT64U, mkexpr(t3), mkU64(0x3)),
                                mkU64(0x5),
                                mkU64(0x0)));
@@ -4309,56 +13518,72 @@ static DisResult disInstr_MIPS_WRK ( Bool(*resteerOkFn) (/*opaque */void *,
          break;
       }
 
-      case 0x00: {  /* MADD */
-         DIP("madd r%d, r%d", rs, rt);
-         if (mode64) {
-            t1 = newTemp(Ity_I32);
-            t2 = newTemp(Ity_I32);
-            t3 = newTemp(Ity_I64);
-            t4 = newTemp(Ity_I64);
-            t5 = newTemp(Ity_I64);
-            t6 = newTemp(Ity_I32);
+         case 0x00: {  /* MADD */
+            if (mode64) {
+               DIP("madd r%d, r%d", rs, rt);
+               t1 = newTemp(Ity_I32);
+               t2 = newTemp(Ity_I32);
+               t3 = newTemp(Ity_I64);
+               t4 = newTemp(Ity_I64);
+               t5 = newTemp(Ity_I64);
+               t6 = newTemp(Ity_I32);
 
-            assign(t1, mkNarrowTo32(ty, getHI()));
-            assign(t2, mkNarrowTo32(ty, getLO()));
+               assign(t1, mkNarrowTo32(ty, getHI()));
+               assign(t2, mkNarrowTo32(ty, getLO()));
 
-            assign(t3, binop(Iop_MullS32, mkNarrowTo32(ty, getIReg(rs)),
-                                          mkNarrowTo32(ty, getIReg(rt))));
+               assign(t3, binop(Iop_MullS32, mkNarrowTo32(ty, getIReg(rs)),
+                                             mkNarrowTo32(ty, getIReg(rt))));
 
-            assign(t4, binop(Iop_32HLto64, mkexpr(t1), mkexpr(t2)));
-            assign(t5, binop(Iop_Add64, mkexpr(t3), mkexpr(t4)));
+               assign(t4, binop(Iop_32HLto64, mkexpr(t1), mkexpr(t2)));
+               assign(t5, binop(Iop_Add64, mkexpr(t3), mkexpr(t4)));
 
-            putHI(mkWidenFrom32(ty, unop(Iop_64HIto32, mkexpr(t5)), True));
-            putLO(mkWidenFrom32(ty, unop(Iop_64to32, mkexpr(t5)), True));
-         } else {
-            t1 = newTemp(Ity_I32);
-            t2 = newTemp(Ity_I32);
-            t3 = newTemp(Ity_I64);
-            t4 = newTemp(Ity_I32);
-            t5 = newTemp(Ity_I32);
-            t6 = newTemp(Ity_I32);
+               putHI(mkWidenFrom32(ty, unop(Iop_64HIto32, mkexpr(t5)), True));
+               putLO(mkWidenFrom32(ty, unop(Iop_64to32, mkexpr(t5)), True));
+            } else {
+               if ( (1 <= ac) && ( 3 >= ac) ) {
+                  if ((archinfo->hwcaps & VEX_MIPS_ASE_DSP)) {
+                     /* If DSP is present -> DSP ASE MADD */
+                     UInt retVal = disDSPInstr_MIPS_WRK ( cins );
+                     if (0 != retVal ) {
+                        goto decode_failure_dsp;
+                     }
+                     break;
+                  } else {
+                     goto decode_failure_dsp;
+                  }
+               } else {
+                  DIP("madd r%d, r%d", rs, rt);
+                  t1 = newTemp(Ity_I32);
+                  t2 = newTemp(Ity_I32);
+                  t3 = newTemp(Ity_I64);
+                  t4 = newTemp(Ity_I32);
+                  t5 = newTemp(Ity_I32);
+                  t6 = newTemp(Ity_I32);
 
-            assign(t1, getHI());
-            assign(t2, getLO());
+                  assign(t1, getHI());
+                  assign(t2, getLO());
 
-            assign(t3, binop(Iop_MullS32, getIReg(rs), getIReg(rt)));
+                  assign(t3, binop(Iop_MullS32, getIReg(rs), getIReg(rt)));
 
-            assign(t4, binop(Iop_Add32, mkexpr(t2), unop(Iop_64to32,
-                                                         mkexpr(t3))));
+                  assign(t4, binop(Iop_Add32, mkexpr(t2), unop(Iop_64to32,
+                                                               mkexpr(t3))));
 
-            assign(t5, unop(Iop_1Uto32, binop(Iop_CmpLT32U, mkexpr(t4),
-                                        unop(Iop_64to32, mkexpr(t3)))));
-            assign(t6, binop(Iop_Add32, mkexpr(t5), mkexpr(t1)));
+                  assign(t5, unop(Iop_1Uto32, binop(Iop_CmpLT32U, mkexpr(t4),
+                                              unop(Iop_64to32, mkexpr(t3)))));
+                  assign(t6, binop(Iop_Add32, mkexpr(t5), mkexpr(t1)));
 
-            putHI(binop(Iop_Add32, mkexpr(t6), unop(Iop_64HIto32, mkexpr(t3))));
-            putLO(mkexpr(t4));
+                  putHI(binop(Iop_Add32, mkexpr(t6), unop(Iop_64HIto32,
+                                                          mkexpr(t3))));
+                  putLO(mkexpr(t4));
+                  break;
+               }
+            }
+            break;
          }
-         break;
-      }
 
       case 0x01: {  /* MADDU */
-         DIP("maddu r%d, r%d", rs, rt);
          if (mode64) {
+            DIP("maddu r%d, r%d", rs, rt);
             t1 = newTemp(Ity_I32);
             t2 = newTemp(Ity_I32);
             t3 = newTemp(Ity_I64);
@@ -4378,33 +13603,49 @@ static DisResult disInstr_MIPS_WRK ( Bool(*resteerOkFn) (/*opaque */void *,
             putHI(mkWidenFrom32(ty, unop(Iop_64HIto32, mkexpr(t5)), True));
             putLO(mkWidenFrom32(ty, unop(Iop_64to32, mkexpr(t5)), True));
          } else {
-            t1 = newTemp(Ity_I32);
-            t2 = newTemp(Ity_I32);
-            t3 = newTemp(Ity_I64);
-            t4 = newTemp(Ity_I32);
-            t5 = newTemp(Ity_I32);
-            t6 = newTemp(Ity_I32);
+            if ( (1 <= ac) && ( 3 >= ac) ) {
+               if ((archinfo->hwcaps & VEX_MIPS_ASE_DSP)) {
+                  /* If DSP is present -> DSP ASE MADDU */
+                  UInt retVal = disDSPInstr_MIPS_WRK ( cins );
+                  if (0 != retVal ) {
+                     goto decode_failure_dsp;
+                  }
+                  break;
+               } else {
+                  goto decode_failure_dsp;
+               }
+            } else {
+               DIP("maddu r%d, r%d", rs, rt);
+               t1 = newTemp(Ity_I32);
+               t2 = newTemp(Ity_I32);
+               t3 = newTemp(Ity_I64);
+               t4 = newTemp(Ity_I32);
+               t5 = newTemp(Ity_I32);
+               t6 = newTemp(Ity_I32);
 
-            assign(t1, getHI());
-            assign(t2, getLO());
+               assign(t1, getHI());
+               assign(t2, getLO());
 
-            assign(t3, binop(Iop_MullU32, getIReg(rs), getIReg(rt)));
+               assign(t3, binop(Iop_MullU32, getIReg(rs), getIReg(rt)));
 
-            assign(t4, binop(Iop_Add32, mkexpr(t2), unop(Iop_64to32,
-                                                         mkexpr(t3))));
-            assign(t5, unop(Iop_1Uto32, binop(Iop_CmpLT32U, mkexpr(t4),
-                                        unop(Iop_64to32, mkexpr(t3)))));
-            assign(t6, binop(Iop_Add32, mkexpr(t5), mkexpr(t1)));
+               assign(t4, binop(Iop_Add32, mkexpr(t2), unop(Iop_64to32,
+                                                            mkexpr(t3))));
+               assign(t5, unop(Iop_1Uto32, binop(Iop_CmpLT32U, mkexpr(t4),
+                                           unop(Iop_64to32, mkexpr(t3)))));
+               assign(t6, binop(Iop_Add32, mkexpr(t5), mkexpr(t1)));
 
-            putHI(binop(Iop_Add32, mkexpr(t6), unop(Iop_64HIto32, mkexpr(t3))));
-            putLO(mkexpr(t4));
+               putHI(binop(Iop_Add32, mkexpr(t6), unop(Iop_64HIto32,
+                                                      mkexpr(t3))));
+               putLO(mkexpr(t4));
+               break;
+            }
          }
          break;
       }
 
       case 0x04: {  /* MSUB */
-         DIP("msub r%d, r%d", rs, rt);
          if (mode64) {
+            DIP("msub r%d, r%d", rs, rt);
             t1 = newTemp(Ity_I32);
             t2 = newTemp(Ity_I32);
             t3 = newTemp(Ity_I64);
@@ -4424,35 +13665,53 @@ static DisResult disInstr_MIPS_WRK ( Bool(*resteerOkFn) (/*opaque */void *,
             putHI(mkWidenFrom32(ty, unop(Iop_64HIto32, mkexpr(t5)), True));
             putLO(mkWidenFrom32(ty, unop(Iop_64to32, mkexpr(t5)), True));
          } else {
-            t1 = newTemp(Ity_I32);
-            t2 = newTemp(Ity_I32);
-            t3 = newTemp(Ity_I64);
-            t4 = newTemp(Ity_I32);
-            t5 = newTemp(Ity_I1);
-            t6 = newTemp(Ity_I32);
+            if ( (1 <= ac) && ( 3 >= ac) ) {
+               if ((archinfo->hwcaps & VEX_MIPS_ASE_DSP)) {
+                  /* If DSP is present -> DSP ASE MSUB */
+                  UInt retVal = disDSPInstr_MIPS_WRK ( cins );
+                  if (0 != retVal ) {
+                     goto decode_failure_dsp;
+                  }
+                  break;
+               } else {
+                  goto decode_failure_dsp;
+               }
+            } else {
+               DIP("msub r%d, r%d", rs, rt);
+               t1 = newTemp(Ity_I32);
+               t2 = newTemp(Ity_I32);
+               t3 = newTemp(Ity_I64);
+               t4 = newTemp(Ity_I32);
+               t5 = newTemp(Ity_I1);
+               t6 = newTemp(Ity_I32);
 
-            assign(t1, getHI());
-            assign(t2, getLO());
+               assign(t1, getHI());
+               assign(t2, getLO());
 
-            assign(t3, binop(Iop_MullS32, getIReg(rs), getIReg(rt)));
-            assign(t4, unop(Iop_64to32, mkexpr(t3))); /* new lo */
+               assign(t3, binop(Iop_MullS32, getIReg(rs), getIReg(rt)));
+               assign(t4, unop(Iop_64to32, mkexpr(t3)));  /* new lo */
 
-            /* if lo<lo(mul) hi = hi - 1 */
-            assign(t5, binop(Iop_CmpLT32U, mkexpr(t2), mkexpr(t4)));
+               /* if lo<lo(mul) hi = hi - 1 */
+               assign(t5, binop(Iop_CmpLT32U,
+                                 mkexpr(t2),
+                                 mkexpr(t4)));
 
-            assign(t6, IRExpr_ITE(mkexpr(t5),
-                                  binop(Iop_Sub32, mkexpr(t1), mkU32(0x1)),
-                                  mkexpr(t1)));
+               assign(t6, IRExpr_ITE(mkexpr(t5),
+                                       binop(Iop_Sub32, mkexpr(t1), mkU32(0x1)),
+                                       mkexpr(t1)));
 
-            putHI(binop(Iop_Sub32, mkexpr(t6), unop(Iop_64HIto32, mkexpr(t3))));
-            putLO(binop(Iop_Sub32, mkexpr(t2), mkexpr(t4)));
+               putHI(binop(Iop_Sub32, mkexpr(t6), unop(Iop_64HIto32,
+                                                      mkexpr(t3))));
+               putLO(binop(Iop_Sub32, mkexpr(t2), mkexpr(t4)));
+               break;
+            }
          }
          break;
       }
 
-      case 0x05: { /* MSUBU */
-         DIP("msubu r%d, r%d", rs, rt);
+      case 0x05: {  /* MSUBU */
          if (mode64) {
+            DIP("msubu r%d, r%d", rs, rt);
             t1 = newTemp(Ity_I32);
             t2 = newTemp(Ity_I32);
             t3 = newTemp(Ity_I64);
@@ -4472,28 +13731,48 @@ static DisResult disInstr_MIPS_WRK ( Bool(*resteerOkFn) (/*opaque */void *,
             putHI(mkWidenFrom32(ty, unop(Iop_64HIto32, mkexpr(t5)), True));
             putLO(mkWidenFrom32(ty, unop(Iop_64to32, mkexpr(t5)), True));
          } else {
-            t1 = newTemp(Ity_I32);
-            t2 = newTemp(Ity_I32);
-            t3 = newTemp(Ity_I64);
-            t4 = newTemp(Ity_I32);
-            t5 = newTemp(Ity_I1);
-            t6 = newTemp(Ity_I32);
+            if ( (1 <= ac) && ( 3 >= ac) ) {
+               if ((archinfo->hwcaps & VEX_MIPS_ASE_DSP)) {
+                  /* If DSP is present -> DSP ASE MSUBU */
+                  UInt retVal = disDSPInstr_MIPS_WRK ( cins );
+                  if (0 != retVal ) {
+                     goto decode_failure_dsp;
+                  }
+                  break;
+               } else {
+                  goto decode_failure_dsp;
+               }
+            } else {
+               DIP("msubu r%d, r%d", rs, rt);
+               t1 = newTemp(Ity_I32);
+               t2 = newTemp(Ity_I32);
+               t3 = newTemp(Ity_I64);
+               t4 = newTemp(Ity_I32);
+               t5 = newTemp(Ity_I1);
+               t6 = newTemp(Ity_I32);
 
-            assign(t1, getHI());
-            assign(t2, getLO());
+               assign(t1, getHI());
+               assign(t2, getLO());
 
-            assign(t3, binop(Iop_MullU32, getIReg(rs), getIReg(rt)));
-            assign(t4, unop(Iop_64to32, mkexpr(t3)));  /* new lo */
+               assign(t3, binop(Iop_MullU32, getIReg(rs), getIReg(rt)));
+               assign(t4, unop(Iop_64to32, mkexpr(t3)));  /* new lo */
 
-            /* if lo<lo(mul) hi = hi - 1 */
-            assign(t5, binop(Iop_CmpLT32U, mkexpr(t2), mkexpr(t4)));
+               /* if lo<lo(mul) hi = hi - 1 */
+               assign(t5, binop(Iop_CmpLT32U,
+                                 mkexpr(t2),
+                                 mkexpr(t4)));
 
-            assign(t6, IRExpr_ITE(mkexpr(t5),
-                                  binop(Iop_Sub32, mkexpr(t1), mkU32(0x1)),
-                                  mkexpr(t1)));
+               assign(t6, IRExpr_ITE(mkexpr(t5),
+                                    binop(Iop_Sub32,
+                                          mkexpr(t1),
+                                          mkU32(0x1)),
+                                    mkexpr(t1)));
 
-            putHI(binop(Iop_Sub32, mkexpr(t6), unop(Iop_64HIto32, mkexpr(t3))));
-            putLO(binop(Iop_Sub32, mkexpr(t2), mkexpr(t4)));
+               putHI(binop(Iop_Sub32, mkexpr(t6), unop(Iop_64HIto32,
+                                                      mkexpr(t3))));
+               putLO(binop(Iop_Sub32, mkexpr(t2), mkexpr(t4)));
+               break;
+            }
          }
          break;
       }
@@ -4926,7 +14205,7 @@ static DisResult disInstr_MIPS_WRK ( Bool(*resteerOkFn) (/*opaque */void *,
             assign(t2, binop(Iop_Shl32, mkNarrowTo32(ty, getIReg(rt)),
                              mkU8(32 - lsb)));
             assign(t3, binop(Iop_Shr32, mkexpr(t2), mkU8(32 - lsb)));
-         } else 
+         } else
             assign(t3, mkU32(0));
 
          if (msb < 31) {
@@ -5037,10 +14316,203 @@ static DisResult disInstr_MIPS_WRK ( Bool(*resteerOkFn) (/*opaque */void *,
 
          }
          break;  /* BSHFL */
-         default:
-            goto decode_failure;
 
+      /* -------- MIPS32(r2) DSP ASE(r2) instructions -------- */
+      case 0xA:  /* LX */
+      case 0xC:  /* INSV */
+      case 0x38: {  /* EXTR.W */
+         if ((archinfo->hwcaps & VEX_MIPS_ASE_DSP)) {
+            UInt retVal = disDSPInstr_MIPS_WRK ( cins );
+            if (0 != retVal ) {
+               goto decode_failure_dsp;
+            }
+            break;
+         } else {
+            goto decode_failure_dsp;
+         }
+         break;
+      }
+      case 0x10: {  /* ADDU.QB */
+         switch(sa) {
+            case  0xC:  /* SUBU_S.PH */
+            case  0xD:  /* ADDU_S.PH */
+            case 0x1E: {  /* MULQ_S.PH */
+               if ((archinfo->hwcaps & VEX_MIPS_ASE_DSP2P)) {
+                  UInt retVal = disDSPInstr_MIPS_WRK ( cins );
+                  if (0 != retVal ) {
+                     goto decode_failure_dsp;
+                  }
+                  break;
+               } else {
+                  goto decode_failure_dsp;
+               }
+               break;
+            }
+            default: {
+               if ((archinfo->hwcaps & VEX_MIPS_ASE_DSP)) {
+                  UInt retVal = disDSPInstr_MIPS_WRK ( cins );
+                  if (0 != retVal ) {
+                     goto decode_failure_dsp;
+                  }
+                  break;
+               } else {
+                  goto decode_failure_dsp;
+               }
+               break;
+            }
+         }
+         break;
       }
+      case 0x11: {  /* CMPU.EQ.QB */
+         switch(sa) {
+            case 0x18:  /* CMPGDU.EQ.QB */
+            case 0x19:  /* CMPGDU.LT.QB */
+            case 0x1A:  /* CMPGDU.LE.QB */
+            case 0x0D:  /* PRECR.QB.PH */
+            case 0x1E:  /* PRECR_SRA.PH.W */
+            case 0x1F: {  /* PRECR_SRA_R.PH.W */
+               if ((archinfo->hwcaps & VEX_MIPS_ASE_DSP2P)) {
+                  UInt retVal = disDSPInstr_MIPS_WRK ( cins );
+                  if (0 != retVal ) {
+                     goto decode_failure_dsp;
+                  }
+                  break;
+               } else {
+                  goto decode_failure_dsp;
+               }
+               break;
+            }
+            default: {
+               if ((archinfo->hwcaps & VEX_MIPS_ASE_DSP)) {
+                  UInt retVal = disDSPInstr_MIPS_WRK ( cins );
+                  if (0 != retVal ) {
+                     goto decode_failure_dsp;
+                  }
+                  break;
+               } else {
+                  goto decode_failure_dsp;
+               }
+               break;
+            }
+         }
+         break;
+      }
+      case 0x12: {  /* ABSQ_S.PH */
+         switch(sa){
+            case 0x1: {  /* ABSQ_S.QB */
+               if ((archinfo->hwcaps & VEX_MIPS_ASE_DSP2P)) {
+                  UInt retVal = disDSPInstr_MIPS_WRK ( cins );
+                  if (0 != retVal ) {
+                     goto decode_failure_dsp;
+                  }
+                  break;
+               } else {
+                  goto decode_failure_dsp;
+               }
+               break;
+            }
+            default: {
+               if ((archinfo->hwcaps & VEX_MIPS_ASE_DSP)) {
+                  UInt retVal = disDSPInstr_MIPS_WRK ( cins );
+                  if (0 != retVal ) {
+                     goto decode_failure_dsp;
+                  }
+                  break;
+               } else {
+                  goto decode_failure_dsp;
+               }
+               break;
+            }
+         }
+         break;
+      }
+      case 0x13: {  /* SHLL.QB */
+         switch(sa) {
+            case 0x04:  /* SHRA.QB */
+            case 0x05:  /* SHRA_R.QB */
+            case 0x06:  /* SHRAV.QB */
+            case 0x07:  /* SHRAV_R.QB */
+            case 0x19:  /* SHLR.PH */
+            case 0x1B: {  /* SHLRV.PH */
+               if ((archinfo->hwcaps & VEX_MIPS_ASE_DSP2P)) {
+                  UInt retVal = disDSPInstr_MIPS_WRK ( cins );
+                  if (0 != retVal ) {
+                     goto decode_failure_dsp;
+                  }
+                  break;
+               } else {
+                  goto decode_failure_dsp;
+               }
+               break;
+            }
+            default: {
+               if ((archinfo->hwcaps & VEX_MIPS_ASE_DSP)) {
+                  UInt retVal = disDSPInstr_MIPS_WRK ( cins );
+                  if (0 != retVal ) {
+                     goto decode_failure_dsp;
+                  }
+                  break;
+               } else {
+                  goto decode_failure_dsp;
+               }
+               break;
+            }
+         }
+         break;
+      }
+      case 0x30: {  /* DPAQ.W.PH */
+         switch(sa) {
+            case  0x0:  /* DPA.W.PH */
+            case 0x18:  /* DPAQX_S.W.PH */
+            case 0x1A:  /* DPAQX_SA.W.PH */
+            case  0x8:  /* DPAX.W.PH */
+            case  0x1:  /* DPS.W.PH */
+            case 0x19:  /* DPSQX_S.W.PH */
+            case 0x1B:  /* DPSQX_SA.W.PH */
+            case  0x9:  /* DPSX.W.PH */
+            case  0x2: {  /* MULSA.W.PH */
+               if ((archinfo->hwcaps & VEX_MIPS_ASE_DSP2P)) {
+                  UInt retVal = disDSPInstr_MIPS_WRK ( cins );
+                  if (0 != retVal ) {
+                     goto decode_failure_dsp;
+                  }
+                  break;
+               } else {
+                  goto decode_failure_dsp;
+               }
+               break;
+            }
+            default: {
+               if ((archinfo->hwcaps & VEX_MIPS_ASE_DSP)) {
+                  UInt retVal = disDSPInstr_MIPS_WRK ( cins );
+                  if (0 != retVal ) {
+                     goto decode_failure_dsp;
+                  }
+                  break;
+               } else {
+                  goto decode_failure_dsp;
+               }
+               break;
+            }
+         }
+         break;
+      }
+      case 0x18:  /* ADDUH.QB/MUL.PH */
+      case 0x31: {  /* APPEND */
+         if ((archinfo->hwcaps & VEX_MIPS_ASE_DSP2P)) {
+            UInt retVal = disDSPInstr_MIPS_WRK ( cins );
+            if (0 != retVal ) {
+               goto decode_failure_dsp;
+            }
+            break;
+         } else {
+            goto decode_failure_dsp;
+         }
+      }
+      default:
+         goto decode_failure;
+
+   }
       break;  /* Special3 */
 
    case 0x3B:
@@ -5149,28 +14621,54 @@ static DisResult disInstr_MIPS_WRK ( Bool(*resteerOkFn) (/*opaque */void *,
          break;
       }
 
-      case 0x18:  /* MULT */
-         DIP("mult r%d, r%d", rs, rt);
-         t2 = newTemp(Ity_I64);
-
-         assign(t2, binop(Iop_MullS32, mkNarrowTo32(ty, getIReg(rs)),
-                          mkNarrowTo32(ty, getIReg(rt))));
-
-         putHI(mkWidenFrom32(ty, unop(Iop_64HIto32, mkexpr(t2)), True));
-         putLO(mkWidenFrom32(ty, unop(Iop_64to32, mkexpr(t2)), True));
-         break;
+      case 0x18:  {  /* MULT */
+         if ( (1 <= ac) && ( 3 >= ac) ) {
+            if ((archinfo->hwcaps & VEX_MIPS_ASE_DSP)) {
+               /* If DSP is present -> DSP ASE MULT */
+               UInt retVal = disDSPInstr_MIPS_WRK ( cins );
+               if (0 != retVal ) {
+                  goto decode_failure_dsp;
+               }
+               break;
+            } else {
+               goto decode_failure_dsp;
+            }
+         } else {
+            DIP("mult r%d, r%d", rs, rt);
+            t2 = newTemp(Ity_I64);
 
-      case 0x19:  /* MULTU */
-         DIP("multu r%d, r%d", rs, rt);
-         t2 = newTemp(Ity_I64);
+            assign(t2, binop(Iop_MullS32, mkNarrowTo32(ty, getIReg(rs)),
+                                          mkNarrowTo32(ty, getIReg(rt))));
 
-         assign(t2, binop(Iop_MullU32, mkNarrowTo32(ty, getIReg(rs)),
-                                       mkNarrowTo32(ty, getIReg(rt))));
+            putHI(mkWidenFrom32(ty, unop(Iop_64HIto32, mkexpr(t2)), True));
+            putLO(mkWidenFrom32(ty, unop(Iop_64to32, mkexpr(t2)), True));
+            break;
+         }
+      }
+      case 0x19:  {  /* MULTU */
+         if ( (1 <= ac) && ( 3 >= ac) ) {
+            if ((archinfo->hwcaps & VEX_MIPS_ASE_DSP)) {
+               /* If DSP is present -> DSP ASE MULTU */
+               UInt retVal = disDSPInstr_MIPS_WRK ( cins );
+               if (0 != retVal ) {
+                  goto decode_failure_dsp;
+               }
+               break;
+            } else {
+               goto decode_failure_dsp;
+            }
+         } else {
+            DIP("multu r%d, r%d", rs, rt);
+            t2 = newTemp(Ity_I64);
 
-         putHI(mkWidenFrom32(ty, unop(Iop_64HIto32, mkexpr(t2)), True));
-         putLO(mkWidenFrom32(ty, unop(Iop_64to32, mkexpr(t2)), True));
-         break;
+            assign(t2, binop(Iop_MullU32, mkNarrowTo32(ty, getIReg(rs)),
+                                          mkNarrowTo32(ty, getIReg(rt))));
 
+            putHI(mkWidenFrom32(ty, unop(Iop_64HIto32, mkexpr(t2)), True));
+            putLO(mkWidenFrom32(ty, unop(Iop_64to32, mkexpr(t2)), True));
+            break;
+         }
+      }
       case 0x20: {  /* ADD */
          DIP("add r%d, r%d, r%d", rd, rs, rt);
          IRTemp tmpRs32 = newTemp(Ity_I32);
@@ -5185,9 +14683,9 @@ static DisResult disInstr_MIPS_WRK ( Bool(*resteerOkFn) (/*opaque */void *,
          t3 = newTemp(Ity_I32);
          t4 = newTemp(Ity_I32);
          /* dst = src0 + src1
-            if(sign(src0 ) != sign(src1 ))
+            if (sign(src0 ) != sign(src1 ))
             goto no overflow;
-            if(sign(dst) == sign(src0 ))
+            if (sign(dst) == sign(src0 ))
             goto no overflow;
             we have overflow! */
 
@@ -5300,25 +14798,65 @@ static DisResult disInstr_MIPS_WRK ( Bool(*resteerOkFn) (/*opaque */void *,
          putLO(unop(Iop_128to64, mkexpr(t2)));
          break;
 
-      case 0x10:  /* MFHI */
-         DIP("mfhi r%d", rd);
-         putIReg(rd, getHI());
-         break;
+      case 0x10: {  /* MFHI */
+         if ((archinfo->hwcaps & VEX_MIPS_ASE_DSP)) {
+            /* If DSP is present -> DSP ASE MFHI */
+            UInt retVal = disDSPInstr_MIPS_WRK ( cins );
+            if (0 != retVal ) {
+               goto decode_failure;
+            }
+            break;
+         } else {
+            DIP("mfhi r%d", rd);
+            putIReg(rd, getHI());
+            break;
+         }
+      }
 
-      case 0x11:  /* MTHI */
-         DIP("mthi r%d", rs);
-         putHI(getIReg(rs));
-         break;
+      case 0x11:  {  /* MTHI */
+         if ((archinfo->hwcaps & VEX_MIPS_ASE_DSP)) {
+            /* If DSP is present -> DSP ASE MTHI */
+            UInt retVal = disDSPInstr_MIPS_WRK ( cins );
+            if (0 != retVal ) {
+               goto decode_failure;
+            }
+            break;
+         } else {
+            DIP("mthi r%d", rs);
+            putHI(getIReg(rs));
+            break;
+         }
+      }
 
-      case 0x12:  /* MFLO */
-         DIP("mflo r%d", rd);
-         putIReg(rd, getLO());
-         break;
+      case 0x12:  {  /* MFLO */
+         if ((archinfo->hwcaps & VEX_MIPS_ASE_DSP)) {
+            /* If DSP is present -> DSP ASE MFLO */
+            UInt retVal = disDSPInstr_MIPS_WRK ( cins );
+            if (0 != retVal ) {
+               goto decode_failure;
+            }
+            break;
+         } else {
+            DIP("mflo r%d", rd);
+            putIReg(rd, getLO());
+            break;
+         }
+      }
 
-      case 0x13:  /* MTLO */
-         DIP("mtlo r%d", rs);
-         putLO(getIReg(rs));
-         break;
+      case 0x13:  {  /* MTLO */
+         if ((archinfo->hwcaps & VEX_MIPS_ASE_DSP)) {
+            /* If DSP is present -> DSP ASE MTLO */
+            UInt retVal = disDSPInstr_MIPS_WRK ( cins );
+            if (0 != retVal ) {
+               goto decode_failure;
+            }
+            break;
+         } else {
+            DIP("mtlo r%d", rs);
+            putLO(getIReg(rs));
+            break;
+         }
+      }
 
       case 0x21:  /* ADDU */
          DIP("addu r%d, r%d, r%d", rd, rs, rt);
@@ -5590,7 +15128,7 @@ static DisResult disInstr_MIPS_WRK ( Bool(*resteerOkFn) (/*opaque */void *,
             }
             break;
          }
-      } 
+      }
 
       case 0x0D:  /* BREAK */
          DIP("break 0x%x", trap_code);
@@ -6133,7 +15671,7 @@ static DisResult disInstr_MIPS_WRK ( Bool(*resteerOkFn) (/*opaque */void *,
          }
          break;
       }
-      case 0x0A: { /* TLTI */
+      case 0x0A: {  /* TLTI */
          DIP("tlti r%d, %d %d", rs, imm, trap_code);
          if (mode64) {
             stmt (IRStmt_Exit (binop (Iop_CmpLT64S, getIReg (rs),
@@ -6201,6 +15739,15 @@ static DisResult disInstr_MIPS_WRK ( Bool(*resteerOkFn) (/*opaque */void *,
          }
          break;
       }
+      case 0x1C: {  /* BPOSGE32 */
+         DIP("bposge32 %d", imm);
+         vassert(!mode64);
+         t0 = newTemp(Ity_I32);
+         /* Get pos field from DSPControl register. */
+         assign(t0, binop(Iop_And32, getDSPControl(), mkU32(0x3f)));
+         dis_branch(False, unop(Iop_Not1, binop(Iop_CmpLT32U, mkexpr(t0),
+                                mkU32(32))), imm, &bstmt);
+      }
       case 0x1F:
          /* SYNCI */
          /* Just ignore it */
@@ -6568,6 +16115,10 @@ static DisResult disInstr_MIPS_WRK ( Bool(*resteerOkFn) (/*opaque */void *,
       store(mkexpr(t1), getIReg(rt));
       break;
 
+   decode_failure_dsp:
+      vex_printf("Error occured while trying to decode MIPS32 DSP "
+                  "instruction.\nYour platform probably doesn't support "
+                  "MIPS32 DSP ASE.\n");
    decode_failure:
       /* All decode failures end up here. */
       if (sigill_diag)
@@ -6644,8 +16195,8 @@ static DisResult disInstr_MIPS_WRK ( Bool(*resteerOkFn) (/*opaque */void *,
          break;
    }
 
-   /* On MIPS we need to check if the last instruction
-      in block is branch or jump. */
+   /* On MIPS we need to check if the last instruction in block is branch or
+      jump. */
    if (((vex_control.guest_max_insns - 1) == (delta + 4) / 4)
        &&  (dres.whatNext != Dis_StopHere))
       if (branch_or_jump(guest_code + delta + 4)) {
index cba7f1885aac9f155c668f5d6087931d0c2d7b43..b6ea1751f2d3a935e66dad2e8302776fe96d3d06 100644 (file)
@@ -678,124 +678,121 @@ const HChar *showMIPSFpOp(MIPSFpOp op)
    const HChar *ret;
    switch (op) {
       case Mfp_ADDD:
-         ret = "ADD.D";
+         ret = "add.d";
          break;
       case Mfp_SUBD:
-         ret = "SUB.D";
+         ret = "sub.d";
          break;
       case Mfp_MULD:
-         ret = "MUL.D";
+         ret = "mul.d";
          break;
       case Mfp_DIVD:
-         ret = "DIV.D";
+         ret = "div.d";
          break;
       case Mfp_MADDD:
-         ret = "MADD.D";
+         ret = "madd.d";
          break;
       case Mfp_MSUBD:
-         ret = "MSUB.D";
+         ret = "msub.d";
          break;
       case Mfp_MADDS:
-         ret = "MADD.S";
+         ret = "madd.s";
          break;
       case Mfp_MSUBS:
-         ret = "MSUB.S";
+         ret = "msub.s";
          break;
       case Mfp_ADDS:
-         ret = "ADD.S";
+         ret = "add.s";
          break;
       case Mfp_SUBS:
-         ret = "SUB.S";
+         ret = "sub.s";
          break;
       case Mfp_MULS:
-         ret = "MUL.S";
+         ret = "mul.s";
          break;
       case Mfp_DIVS:
-         ret = "DIV.S";
+         ret = "div.s";
          break;
       case Mfp_SQRTS:
-         ret = "SQRT.S";
+         ret = "sqrt.s";
          break;
       case Mfp_SQRTD:
-         ret = "SQRT.D";
-         break;
-      case Mfp_RSQRTS:
-         ret = "RSQRT.S";
-         break;
-      case Mfp_RSQRTD:
-         ret = "RSQRT.D";
-         break;
-      case Mfp_RECIPS:
-         ret = "RECIP.S";
-         break;
-      case Mfp_RECIPD:
-         ret = "RECIP.D";
+         ret = "sqrt.d";
          break;
       case Mfp_ABSS:
-         ret = "ABS.S";
+         ret = "abs.s";
          break;
       case Mfp_ABSD:
-         ret = "ABS.D";
+         ret = "abs.d";
          break;
       case Mfp_NEGS:
-         ret = "NEG.S";
+         ret = "neg.s";
          break;
       case Mfp_NEGD:
-         ret = "NEG.D";
+         ret = "neg.d";
          break;
       case Mfp_MOVS:
-         ret = "MOV.S";
+         ret = "mov.s";
          break;
       case Mfp_MOVD:
-         ret = "MOV.D";
+         ret = "mov.d";
          break;
       case Mfp_ROUNDWS:
-         ret = "ROUND.W.S";
+         ret = "round.w.s";
          break;
       case Mfp_ROUNDWD:
-         ret = "ROUND.W.D";
+         ret = "round.w.d";
          break;
       case Mfp_FLOORWS:
-         ret = "FLOOR.W.S";
+         ret = "floor.w.s";
          break;
       case Mfp_FLOORWD:
-         ret = "FLOOR.W.D";
-         break;
-      case Mfp_RSQRTE:
-         ret = "frsqrte";
+         ret = "floor.w.d";
          break;
       case Mfp_CVTDW:
-         ret = "CVT.D.W";
+         ret = "cvt.d.w";
          break;
       case Mfp_CVTDL:
-         ret = "CVT.D.L";
+         ret = "cvt.d.l";
          break;
       case Mfp_CVTDS:
-         ret = "CVT.D.S";
+         ret = "cvt.d.s";
          break;
       case Mfp_CVTSD:
+         ret = "cvt.s.d";
+         break;
       case Mfp_CVTSW:
-         ret = "CVT.S";
+         ret = "cvt.s.w";
          break;
       case Mfp_CVTWS:
+         ret = "cvt.w.s";
+         break;
       case Mfp_CVTWD:
-         ret = "CVT.W";
+         ret = "cvt.w.d";
          break;
       case Mfp_TRUWD:
+         ret = "trunc.w.d";
+         break;
       case Mfp_TRUWS:
-         ret = "TRUNC.W";
+         ret = "trunc.w.s";
          break;
       case Mfp_TRULD:
+         ret = "trunc.l.d";
+         break;
       case Mfp_TRULS:
-         ret = "TRUNC.L";
+         ret = "trunc.l.s";
          break;
       case Mfp_CEILWS:
+         ret = "ceil.w.s";
+         break;
       case Mfp_CEILWD:
-         ret = "CEIL.W";
+         ret = "ceil.w.d";
          break;
       case Mfp_CEILLS:
+         ret = "ceil.l.s";
+         break;
       case Mfp_CEILLD:
-         ret = "CEIL.L";
+         ret = "ceil.l.d";
          break;
       case Mfp_CMP:
          ret = "C.cond.d";
@@ -1131,7 +1128,7 @@ const HChar *showMIPSShftOp(MIPSShftOp op, Bool immR, Bool sz32)
    const HChar *ret;
    switch (op) {
       case Mshft_SRA:
-         ret = immR ? (sz32 ? "sar" : "dsar") : (sz32 ? "sarv" : "dsrav");
+         ret = immR ? (sz32 ? "sra" : "dsra") : (sz32 ? "srav" : "dsrav");
          break;
       case Mshft_SLL:
          ret = immR ? (sz32 ? "sll" : "dsll") : (sz32 ? "sllv" : "dsllv");
@@ -1719,7 +1716,7 @@ void ppMIPSInstr(MIPSInstr * i, Bool mode64)
       case Min_XIndir:
          vex_printf("(xIndir) ");
          vex_printf("if (guest_COND.%s) { sw ",
-                       showMIPSCondCode(i->Min.XIndir.cond));
+                    showMIPSCondCode(i->Min.XIndir.cond));
          ppHRegMIPS(i->Min.XIndir.dstGA, mode64);
          vex_printf(", ");
          ppMIPSAMode(i->Min.XIndir.amPC, mode64);
@@ -1852,13 +1849,13 @@ void ppMIPSInstr(MIPSInstr * i, Bool mode64)
          return;
       }
       case Min_MtFCSR: {
-         vex_printf("ctc1  ");
+         vex_printf("ctc1 ");
          ppHRegMIPS(i->Min.MtFCSR.src, mode64);
          vex_printf(", $31");
          return;
       }
       case Min_MfFCSR: {
-         vex_printf("ctc1  ");
+         vex_printf("ctc1 ");
          ppHRegMIPS(i->Min.MfFCSR.dst, mode64);
          vex_printf(", $31");
          return;
@@ -2278,7 +2275,7 @@ void mapRegs_MIPSInstr(HRegRemap * m, MIPSInstr * i, Bool mode64)
 
 /* Figure out if i represents a reg-reg move, and if so assign the
    source and destination to *src and *dst.  If in doubt say No.  Used
-   by the register allocator to do move coalescing. 
+   by the register allocator to do move coalescing.
 */
 Bool isMove_MIPSInstr(MIPSInstr * i, HReg * src, HReg * dst)
 {
@@ -2289,7 +2286,7 @@ Bool isMove_MIPSInstr(MIPSInstr * i, HReg * src, HReg * dst)
          return False;
       if (i->Min.Alu.srcR->tag != Mrh_Reg)
          return False;
-      if (hregNumber(i->Min.Alu.srcR->Mrh.Reg.reg) 
+      if (hregNumber(i->Min.Alu.srcR->Mrh.Reg.reg)
           != hregNumber(i->Min.Alu.srcL))
          return False;
       *src = i->Min.Alu.srcL;
@@ -2432,7 +2429,7 @@ static UInt fetch32 ( UChar* p )
 }
 
 /* physical structure of mips instructions */
-/* type I : opcode    - 6 bits 
+/* type I : opcode    - 6 bits
          rs         - 5 bits
          rt         - 5 bits
          immediate - 16 bits
@@ -2557,9 +2554,9 @@ static UChar *doAMode_RR(UChar * p, UInt opc1, UInt rSD, MIPSAMode * am,
    if (mode64) {
    /* addiu sp, sp, -8
       sd rA, 0(sp)
-      daddu rA, rA, rB 
+      daddu rA, rA, rB
       sd/ld r_dst, 0(rA)
-      ld rA, 0(sp) 
+      ld rA, 0(sp)
       daddiu sp, sp, 8 */
       p = mkFormI(p, 25, 29, 29, 0xFFF8);
       p = mkFormI(p, 63, 29, rA, 0);
@@ -2570,9 +2567,9 @@ static UChar *doAMode_RR(UChar * p, UInt opc1, UInt rSD, MIPSAMode * am,
    } else {
    /* addiu sp, sp, -4
       sw rA, 0(sp)
-      addu rA, rA, rB 
+      addu rA, rA, rB
       sw/lw r_dst, 0(rA)
-      lw rA, 0(sp) 
+      lw rA, 0(sp)
       addiu sp, sp, 4 */
       p = mkFormI(p, 9, 29, 29, 0xFFFC);
       p = mkFormI(p, 43, 29, rA, 0);
@@ -2842,7 +2839,7 @@ static UChar *mkMoveReg(UChar * p, UInt r_dst, UInt r_src)
    instruction was a profiler inc, set *is_profInc to True, else
    leave it unchanged. */
 Int emit_MIPSInstr ( /*MB_MOD*/Bool* is_profInc,
-                     UChar* buf, Int nbuf, MIPSInstr* i, 
+                     UChar* buf, Int nbuf, MIPSInstr* i,
                      Bool mode64,
                      void* disp_cp_chain_me_to_slowEP,
                      void* disp_cp_chain_me_to_fastEP,
@@ -3059,7 +3056,7 @@ Int emit_MIPSInstr ( /*MB_MOD*/Bool* is_profInc,
                   }
                }
                break;
-   
+
             default:
                goto bad;
          }
@@ -3074,19 +3071,19 @@ Int emit_MIPSInstr ( /*MB_MOD*/Bool* is_profInc,
          switch (i->Min.Unary.op) {
             /* Mun_CLO, Mun_CLZ, Mun_NOP, Mun_DCLO, Mun_DCLZ */
             case Mun_CLO:  /* clo */
-               p = mkFormR(p, 28, r_src, 0 /*whatever */ , r_dst, 0, 33);
+               p = mkFormR(p, 28, r_src, r_dst , r_dst, 0, 33);
                break;
             case Mun_CLZ:  /* clz */
-               p = mkFormR(p, 28, r_src, 0 /*whatever */ , r_dst, 0, 32);
+               p = mkFormR(p, 28, r_src, r_dst , r_dst, 0, 32);
                break;
             case Mun_NOP:  /* nop (sll r0,r0,0) */
                p = mkFormR(p, 0, 0, 0, 0, 0, 0);
                break;
             case Mun_DCLO:  /* clo */
-               p = mkFormR(p, 28, r_src, 0 /*whatever */ , r_dst, 0, 37);
+               p = mkFormR(p, 28, r_src, r_dst , r_dst, 0, 37);
                break;
             case Mun_DCLZ:  /* clz */
-               p = mkFormR(p, 28, r_src, 0 /*whatever */ , r_dst, 0, 36);
+               p = mkFormR(p, 28, r_src, r_dst , r_dst, 0, 36);
                break;
          }
          goto done;
@@ -3300,7 +3297,7 @@ Int emit_MIPSInstr ( /*MB_MOD*/Bool* is_profInc,
             goto bad;
          }
          MIPSCondCode cond = i->Min.Call.cond;
-         UInt r_dst = 25;  /* using %r25 as address temporary - 
+         UInt r_dst = 25;  /* using %r25 as address temporary -
                               see getRegUsage_MIPSInstr */
 
          /* jump over the following insns if condition does not hold */
@@ -3380,7 +3377,7 @@ Int emit_MIPSInstr ( /*MB_MOD*/Bool* is_profInc,
          /* move r9, VG_(disp_cp_chain_me_to_{slowEP,fastEP}) */
          /* jr  r9  */
          void* disp_cp_chain_me
-                  = i->Min.XDirect.toFastEP ? disp_cp_chain_me_to_fastEP 
+                  = i->Min.XDirect.toFastEP ? disp_cp_chain_me_to_fastEP
                                               : disp_cp_chain_me_to_slowEP;
          p = mkLoadImm_EXACTLY2or6(p, /*r*/ 9,
                                      Ptr_to_ULong(disp_cp_chain_me), mode64);
@@ -3496,7 +3493,7 @@ Int emit_MIPSInstr ( /*MB_MOD*/Bool* is_profInc,
                case Ijk_Ret:
                case Ijk_Call:
                fallthrough */
-            default: 
+            default:
                ppIRJumpKind(i->Min.XAssisted.jk);
                vpanic("emit_MIPSInstr.Min_XAssisted: unexpected jump kind");
          }
@@ -3725,25 +3722,25 @@ Int emit_MIPSInstr ( /*MB_MOD*/Bool* is_profInc,
                 p = mkFormR(p, 0x11, 0x11, 0, fr_src, fr_dst, 0x6);
                 break;
              }
-            case Mfp_ABSS: {  /* ABSS */
+            case Mfp_ABSS: {  /* ABS.S */
                UInt fr_dst = fregNo(i->Min.FpUnary.dst, mode64);
                UInt fr_src = fregNo(i->Min.FpUnary.src, mode64);
                p = mkFormR(p, 0x11, 0x10, 0, fr_src, fr_dst, 0x5);
                break;
             }
-            case Mfp_ABSD: {  /* ABSD */
+            case Mfp_ABSD: {  /* ABS.D */
                UInt fr_dst = dregNo(i->Min.FpUnary.dst);
                UInt fr_src = dregNo(i->Min.FpUnary.src);
                p = mkFormR(p, 0x11, 0x11, 0, fr_src, fr_dst, 0x5);
                break;
             }
-            case Mfp_NEGS: {  /* ABSS */
+            case Mfp_NEGS: {  /* NEG.S */
                UInt fr_dst = fregNo(i->Min.FpUnary.dst, mode64);
                UInt fr_src = fregNo(i->Min.FpUnary.src, mode64);
                p = mkFormR(p, 0x11, 0x10, 0, fr_src, fr_dst, 0x7);
                break;
             }
-            case Mfp_NEGD: {  /* ABSD */
+            case Mfp_NEGD: {  /* NEG.D */
                UInt fr_dst = dregNo(i->Min.FpUnary.dst);
                UInt fr_src = dregNo(i->Min.FpUnary.src);
                p = mkFormR(p, 0x11, 0x11, 0, fr_src, fr_dst, 0x7);
@@ -3761,30 +3758,6 @@ Int emit_MIPSInstr ( /*MB_MOD*/Bool* is_profInc,
                p = mkFormR(p, 0x11, 0x11, 0, fr_src, fr_dst, 0x04);
                break;
             }
-            case Mfp_RSQRTS: {  /* RSQRT.S */
-                UInt fr_dst = fregNo(i->Min.FpUnary.dst, mode64);
-                UInt fr_src = fregNo(i->Min.FpUnary.src, mode64);
-                p = mkFormR(p, 0x11, 0x10, 0, fr_src, fr_dst, 0x16);
-                break;
-             }
-            case Mfp_RSQRTD: {  /* RSQRT.D */
-               UInt fr_dst = dregNo(i->Min.FpUnary.dst);
-               UInt fr_src = dregNo(i->Min.FpUnary.src);
-               p = mkFormR(p, 0x11, 0x11, 0, fr_src, fr_dst, 0x16);
-               break;
-            }
-            case Mfp_RECIPS: {  /* RECIP.S */
-               UInt fr_dst = fregNo(i->Min.FpUnary.dst, mode64);
-               UInt fr_src = fregNo(i->Min.FpUnary.src, mode64);
-               p = mkFormR(p, 0x11, 0x10, 0, fr_src, fr_dst, 0x15);
-               break;
-            }
-            case Mfp_RECIPD: {  /* RECIP.D */
-               UInt fr_dst = dregNo(i->Min.FpUnary.dst);
-               UInt fr_src = dregNo(i->Min.FpUnary.src);
-               p = mkFormR(p, 0x11, 0x11, 0, fr_src, fr_dst, 0x15);
-               break;
-            }
             default:
                goto bad;
          }
index a7f6d770328cd2d795ca4fdbcc8ff31884571819..d4c0c8c22199cc27d1e88652dafb0eae62581c84 100644 (file)
@@ -359,9 +359,8 @@ typedef enum {
    Mfp_ADDS, Mfp_SUBS, Mfp_MULS, Mfp_DIVS,
 
    /* Unary */
-   Mfp_SQRTS, Mfp_SQRTD, Mfp_RSQRTS, Mfp_RSQRTD, Mfp_RECIPS, Mfp_RECIPD,
+   Mfp_SQRTS, Mfp_SQRTD,
    Mfp_ABSS, Mfp_ABSD, Mfp_NEGS, Mfp_NEGD, Mfp_MOVS, Mfp_MOVD,
-   Mfp_RSQRTE,
 
    /* FP convert */
    Mfp_CVTSD, Mfp_CVTSW, Mfp_CVTWD,
index 7be6c93f9adada26de0a0e2ca6762821c3b0fd9b..0c573afd07e81543f52f88e4cf8295fad1d72b45 100644 (file)
@@ -35,6 +35,7 @@
 #include "main_util.h"
 #include "main_globals.h"
 #include "host_generic_regs.h"
+#include "host_generic_simd64.h"  /* for 64-bit SIMD helpers */
 #include "host_mips_defs.h"
 
 /*---------------------------------------------------------*/
@@ -87,7 +88,7 @@ static Bool mode64 = False;
 
    - A counter, for generating new virtual registers.
 
-   - The host subarchitecture we are selecting insns for.  
+   - The host subarchitecture we are selecting insns for.
      This is set at the start and does not change.
 
    - A Bool for indicating whether we may generate chain-me
@@ -164,7 +165,7 @@ static void addInstr(ISelEnv * env, MIPSInstr * instr)
 
 static HReg newVRegI(ISelEnv * env)
 {
-   HReg reg = mkHReg(env->vreg_ctr, HRcGPR(env->mode64), 
+   HReg reg = mkHReg(env->vreg_ctr, HRcGPR(env->mode64),
                      True /*virtual reg */ );
    env->vreg_ctr++;
    return reg;
@@ -179,7 +180,7 @@ static HReg newVRegD(ISelEnv * env)
 
 static HReg newVRegF(ISelEnv * env)
 {
-   HReg reg = mkHReg(env->vreg_ctr, HRcFPR(env->mode64), 
+   HReg reg = mkHReg(env->vreg_ctr, HRcFPR(env->mode64),
                      True /*virtual reg */ );
    env->vreg_ctr++;
    return reg;
@@ -224,7 +225,7 @@ static void sub_from_sp(ISelEnv * env, UInt n)
    It's important to specify whether the immediate is to be regarded
    as signed or not.  If yes, this will never return -32768 as an
    immediate; this guaranteed that all signed immediates that are
-   return can have their sign inverted if need be. 
+   return can have their sign inverted if need be.
 */
 static MIPSRH *iselWordExpr_RH_wrk(ISelEnv * env, Bool syned, IRExpr * e);
 static MIPSRH *iselWordExpr_RH(ISelEnv * env, Bool syned, IRExpr * e);
@@ -396,14 +397,14 @@ static void doHelperCall(ISelEnv * env, Bool passBBP, IRExpr * guard,
 
    /* MIPS O32 calling convention: up to four registers ($a0 ... $a3)
       are allowed to be used for passing integer arguments. They correspond
-      to regs GPR4 ... GPR7. Note that the cee->regparms field is meaningless 
-      on MIPS host (since we only implement one calling convention) and so we 
+      to regs GPR4 ... GPR7. Note that the cee->regparms field is meaningless
+      on MIPS host (since we only implement one calling convention) and so we
       always ignore it. */
 
    /* MIPS 64 calling convention: up to four registers ($a0 ... $a7)
       are allowed to be used for passing integer arguments. They correspond
-      to regs GPR4 ... GPR11. Note that the cee->regparms field is meaningless 
-      on MIPS host (since we only implement one calling convention) and so we 
+      to regs GPR4 ... GPR11. Note that the cee->regparms field is meaningless
+      on MIPS host (since we only implement one calling convention) and so we
       always ignore it. */
    n_args = 0;
    for (i = 0; args[i]; i++)
@@ -518,7 +519,7 @@ static void doHelperCall(ISelEnv * env, Bool passBBP, IRExpr * guard,
             iselInt64Expr(&raHi, &raLo, env, args[i]);
             tmpregs[argreg] = raLo;
             argreg++;
-            tmpregs[argreg] = raHi;             
+            tmpregs[argreg] = raHi;
          }
          argreg++;
       }
@@ -698,6 +699,7 @@ static HReg iselWordExpr_R(ISelEnv * env, IRExpr * e)
 /* DO NOT CALL THIS DIRECTLY ! */
 static HReg iselWordExpr_R_wrk(ISelEnv * env, IRExpr * e)
 {
+   UInt argiregs = 0;
    IRType ty = typeOfIRExpr(env->type_env, e);
    vassert(ty == Ity_I8 || ty == Ity_I16 || ty == Ity_I32 || ty == Ity_I1
            || ty == Ity_F32 || (ty == Ity_I64 && mode64)
@@ -729,39 +731,43 @@ static HReg iselWordExpr_R_wrk(ISelEnv * env, IRExpr * e)
 
          /* Is it an addition or logical style op? */
          switch (e->Iex.Binop.op) {
+            case Iop_Add8:
+            case Iop_Add16:
             case Iop_Add32:
                aluOp = Malu_ADD;
                break;
-   
+
             case Iop_Sub8:
             case Iop_Sub16:
             case Iop_Sub32:
                aluOp = Malu_SUB;
                break;
-   
+
             case Iop_Sub64:
                aluOp = Malu_DSUB;
                break;
-   
+
             case Iop_And32:
             case Iop_And64:
                aluOp = Malu_AND;
                break;
-   
+
+            case Iop_Or8:
+            case Iop_Or16:
             case Iop_Or32:
             case Iop_Or64:
                aluOp = Malu_OR;
                break;
-   
+
             case Iop_Xor32:
             case Iop_Xor64:
                aluOp = Malu_XOR;
                break;
-   
+
             case Iop_Add64:
                aluOp = Malu_DADD;
                break;
-   
+
             default:
                aluOp = Malu_INVALID;
                break;
@@ -818,27 +824,39 @@ static HReg iselWordExpr_R_wrk(ISelEnv * env, IRExpr * e)
          if (shftOp != Mshft_INVALID) {
             HReg r_dst = newVRegI(env);
             HReg r_srcL = iselWordExpr_R(env, e->Iex.Binop.arg1);
-            MIPSRH *ri_srcR = NULL;
-            /* get right arg into an RH, in the appropriate way */
-            switch (shftOp) {
-               case Mshft_SLL:
-               case Mshft_SRL:
-               case Mshft_SRA:
-                  if (mode64)
-                     ri_srcR = iselWordExpr_RH6u(env, e->Iex.Binop.arg2);
-                  else
-                     ri_srcR = iselWordExpr_RH5u(env, e->Iex.Binop.arg2);
-                  break;
-               default:
-                  vpanic("iselIntExpr_R_wrk-shftOp-arg2");
-            }
-            if (ty == Ity_I64) {
+            MIPSRH *ri_srcR;
+            if (mode64)
+               ri_srcR = iselWordExpr_RH6u(env, e->Iex.Binop.arg2);
+            else
+               ri_srcR = iselWordExpr_RH5u(env, e->Iex.Binop.arg2);
+
+            if (ty == Ity_I8) {
+               vassert(0);
+            } else if (ty == Ity_I32) {
+               if (mode64 && (shftOp == Mshft_SRA || shftOp == Mshft_SRL)) {
+                  HReg tmp = newVRegI(env);
+                  HReg r_srcL_se = newVRegI(env);
+                  /* SRA, SRAV, SRL, SRLV: On 64-bit processors, if GPR rt does
+                     not contain a sign-extended 32-bit value (bits 63..31
+                     equal), then the result of the operation is UNPREDICTABLE.
+                     So we need to sign-extend r_srcL:
+                     DSLLV tmp, r_srcL, 32
+                     DSRAV r_srcL_se, tmp, 32
+                  */
+                  addInstr(env, MIPSInstr_Shft(Mshft_SLL, False, tmp,
+                                               r_srcL, MIPSRH_Imm(False, 32)));
+                  addInstr(env, MIPSInstr_Shft(Mshft_SRA, False, r_srcL_se,
+                                               tmp, MIPSRH_Imm(False, 32)));
+                  /* And finally do the shift. */
+                  addInstr(env, MIPSInstr_Shft(shftOp, True /*32bit shift */,
+                                               r_dst, r_srcL_se, ri_srcR));
+               } else
+                  addInstr(env, MIPSInstr_Shft(shftOp, True /*32bit shift */,
+                                               r_dst, r_srcL, ri_srcR));
+            } else if (ty == Ity_I64) {
                vassert(mode64);
                addInstr(env, MIPSInstr_Shft(shftOp, False/*64bit shift */,
                                             r_dst, r_srcL, ri_srcR));
-            } else if (ty == Ity_I32) {
-               addInstr(env, MIPSInstr_Shft(shftOp, True /*32bit shift */,
-                                            r_dst, r_srcL, ri_srcR));
             } else
                goto irreducible;
             return r_dst;
@@ -846,11 +864,13 @@ static HReg iselWordExpr_R_wrk(ISelEnv * env, IRExpr * e)
 
          /* Cmp*32*(x,y) ? */
          if (e->Iex.Binop.op == Iop_CmpEQ32
+             || e->Iex.Binop.op == Iop_CmpEQ16
              || e->Iex.Binop.op == Iop_CmpNE32
              || e->Iex.Binop.op == Iop_CmpNE64
              || e->Iex.Binop.op == Iop_CmpLT32S
              || e->Iex.Binop.op == Iop_CmpLT32U
              || e->Iex.Binop.op == Iop_CmpLT64U
+             || e->Iex.Binop.op == Iop_CmpLE32U
              || e->Iex.Binop.op == Iop_CmpLE32S
              || e->Iex.Binop.op == Iop_CmpLE64S
              || e->Iex.Binop.op == Iop_CmpLT64S
@@ -872,6 +892,10 @@ static HReg iselWordExpr_R_wrk(ISelEnv * env, IRExpr * e)
                   cc = MIPScc_EQ;
                   size32 = True;
                   break;
+               case Iop_CmpEQ16:
+                  cc = MIPScc_EQ;
+                  size32 = True;
+                  break;
                case Iop_CmpNE32:
                   cc = MIPScc_NE;
                   size32 = True;
@@ -892,6 +916,10 @@ static HReg iselWordExpr_R_wrk(ISelEnv * env, IRExpr * e)
                   cc = MIPScc_LO;
                   size32 = False;
                   break;
+               case Iop_CmpLE32U:
+                  cc = MIPScc_LE;
+                  size32 = True;
+                  break;
                case Iop_CmpLE32S:
                   cc = MIPScc_LE;
                   size32 = True;
@@ -1099,6 +1127,46 @@ static HReg iselWordExpr_R_wrk(ISelEnv * env, IRExpr * e)
             return r_dst;
          }
 
+         if (e->Iex.Binop.op == Iop_8HLto16) {
+            HReg tHi = iselWordExpr_R(env, e->Iex.Binop.arg1);
+            HReg tLo = iselWordExpr_R(env, e->Iex.Binop.arg2);
+            HReg tLo_1 = newVRegI(env);
+            HReg tHi_1 = newVRegI(env);
+            HReg r_dst = newVRegI(env);
+            HReg mask = newVRegI(env);
+
+            addInstr(env, MIPSInstr_Shft(Mshft_SLL, True, tHi_1, tHi,
+                                         MIPSRH_Imm(False, 8)));
+
+            addInstr(env, MIPSInstr_LI(mask, 0xff));
+            addInstr(env, MIPSInstr_Alu(Malu_AND, tLo_1, tLo,
+                          MIPSRH_Reg(mask)));
+            addInstr(env, MIPSInstr_Alu(Malu_OR, r_dst, tHi_1,
+                          MIPSRH_Reg(tLo_1)));
+
+            return r_dst;
+         }
+
+         if (e->Iex.Binop.op == Iop_16HLto32) {
+            HReg tHi = iselWordExpr_R(env, e->Iex.Binop.arg1);
+            HReg tLo = iselWordExpr_R(env, e->Iex.Binop.arg2);
+            HReg tLo_1 = newVRegI(env);
+            HReg tHi_1 = newVRegI(env);
+            HReg r_dst = newVRegI(env);
+            HReg mask = newVRegI(env);
+
+            addInstr(env, MIPSInstr_Shft(Mshft_SLL, True, tHi_1, tHi,
+                                         MIPSRH_Imm(False, 16)));
+
+            addInstr(env, MIPSInstr_LI(mask, 0xffff));
+            addInstr(env, MIPSInstr_Alu(Malu_AND, tLo_1, tLo,
+                          MIPSRH_Reg(mask)));
+            addInstr(env, MIPSInstr_Alu(Malu_OR, r_dst, tHi_1,
+                          MIPSRH_Reg(tLo_1)));
+
+            return r_dst;
+         }
+
          if (e->Iex.Binop.op == Iop_32HLto64) {
             vassert(mode64);
             HReg tHi = iselWordExpr_R(env, e->Iex.Binop.arg1);
@@ -1159,6 +1227,48 @@ static HReg iselWordExpr_R_wrk(ISelEnv * env, IRExpr * e)
             return r_dst;
          }
 
+         /* -------- DSP ASE -------- */
+         /* All used cases involving host-side helper calls. */
+         void* fn = NULL;
+         switch (e->Iex.Binop.op) {
+            case Iop_HAdd8Ux4:
+               fn = &h_generic_calc_HAdd8Ux4; break;
+            case Iop_HSub8Ux4:
+               fn = &h_generic_calc_HSub8Ux4; break;
+            case Iop_HSub16Sx2:
+               fn = &h_generic_calc_HSub16Sx2; break;
+            case Iop_QSub8Ux4:
+               fn = &h_generic_calc_QSub8Ux4; break;
+            default:
+                  break;
+         }
+
+         /* What's the retloc? */
+         RetLoc rloc = RetLocINVALID;
+         if (ty == Ity_I32) {
+            rloc = RetLocInt;
+         }
+         else if (ty == Ity_I64) {
+            rloc = mode64 ? RetLocInt : RetLoc2Int;
+         }
+         else {
+            goto irreducible;
+         }
+
+         if (fn) {
+            HReg regL = iselWordExpr_R(env, e->Iex.Binop.arg1);
+            HReg regR = iselWordExpr_R(env, e->Iex.Binop.arg2);
+            HReg res  = newVRegI(env);
+            addInstr(env, mk_iMOVds_RR(hregMIPS_GPR4(env->mode64), regL));
+            addInstr(env, mk_iMOVds_RR(hregMIPS_GPR5(env->mode64), regR));
+            argiregs |= (1 << 4);
+            argiregs |= (1 << 5);
+            addInstr(env, MIPSInstr_CallAlways( MIPScc_AL,
+                                                (HWord)Ptr_to_ULong(fn),
+                                                argiregs, rloc));
+            addInstr(env, mk_iMOVds_RR(res, hregMIPS_GPR2(env->mode64)));
+            return res;
+         }
       break;
    }
 
@@ -1167,6 +1277,8 @@ static HReg iselWordExpr_R_wrk(ISelEnv * env, IRExpr * e)
       IROp op_unop = e->Iex.Unop.op;
 
       switch (op_unop) {
+         case Iop_1Sto8:
+         case Iop_1Sto16:
          case Iop_1Sto32:
          case Iop_8Sto32:
          case Iop_16Sto32:
@@ -1178,6 +1290,14 @@ static HReg iselWordExpr_R_wrk(ISelEnv * env, IRExpr * e)
             Bool sz32;
             UShort amt;
             switch (op_unop) {
+               case Iop_1Sto8:
+                  amt = 31;
+                  sz32 = True;
+                  break;
+               case Iop_1Sto16:
+                  amt = 31;
+                  sz32 = True;
+                  break;
                case Iop_1Sto32:
                   amt = 31;
                   sz32 = True;
@@ -1224,6 +1344,8 @@ static HReg iselWordExpr_R_wrk(ISelEnv * env, IRExpr * e)
             return r_dst;
          }
 
+         case Iop_Not8:
+         case Iop_Not16:
          case Iop_Not32:
          case Iop_Not64: {
             HReg r_dst = newVRegI(env);
@@ -1277,9 +1399,20 @@ static HReg iselWordExpr_R_wrk(ISelEnv * env, IRExpr * e)
             return r_dst;
          }
 
+         case Iop_16to8:
          case Iop_32to8:
          case Iop_32to16:
             return iselWordExpr_R(env, e->Iex.Unop.arg);
+         case Iop_32to1:
+            return iselWordExpr_R(env, e->Iex.Unop.arg);
+
+         case Iop_32HIto16: {
+            HReg r_dst = newVRegI(env);
+            HReg r_src = iselWordExpr_R(env, e->Iex.Unop.arg);
+            addInstr(env, MIPSInstr_Shft(Mshft_SRL, True /* 32bit shift */,
+                                         r_dst, r_src, MIPSRH_Imm(False, 16)));
+            return r_dst;
+         }
 
          case Iop_64to8: {
             vassert(mode64);
@@ -1291,6 +1424,14 @@ static HReg iselWordExpr_R_wrk(ISelEnv * env, IRExpr * e)
             return r_dst;
          }
 
+         case Iop_16HIto8: {
+            HReg r_dst = newVRegI(env);
+            HReg r_src = iselWordExpr_R(env, e->Iex.Unop.arg);
+            addInstr(env, MIPSInstr_Shft(Mshft_SRL, True /* 32bit shift */,
+                                         r_dst, r_src, MIPSRH_Imm(False, 8)));
+            return r_dst;
+         }
+
          case Iop_1Uto32:
          case Iop_8Uto32:
          case Iop_16Uto32: {
@@ -1403,6 +1544,21 @@ static HReg iselWordExpr_R_wrk(ISelEnv * env, IRExpr * e)
             return r_dst;
          }
 
+         case Iop_CmpNEZ16: {
+            HReg r_dst = newVRegI(env);
+            HReg tmp = newVRegI(env);
+            HReg r_src = iselWordExpr_R(env, e->Iex.Unop.arg);
+
+            MIPSCondCode cc;
+
+            cc = MIPScc_NE;
+            addInstr(env, MIPSInstr_Alu(Malu_AND, tmp, r_src,
+                                        MIPSRH_Imm(False, 0xFFFF)));
+            addInstr(env, MIPSInstr_Cmp(False, True, r_dst, tmp,
+                                        hregMIPS_GPR0(mode64), cc));
+            return r_dst;
+         }
+
          case Iop_CmpNEZ32: {
             HReg r_dst = newVRegI(env);
             HReg r_src = iselWordExpr_R(env, e->Iex.Unop.arg);
@@ -1431,6 +1587,7 @@ static HReg iselWordExpr_R_wrk(ISelEnv * env, IRExpr * e)
          }
 
          case Iop_Left8:
+         case Iop_Left16:
          case Iop_Left32:
          case Iop_Left64: {
             if (op_unop == Iop_Left64 && !mode64)
@@ -1511,6 +1668,42 @@ static HReg iselWordExpr_R_wrk(ISelEnv * env, IRExpr * e)
          default:
             break;
       }
+
+      /* -------- DSP ASE -------- */
+      /* All Unop cases involving host-side helper calls. */
+      void* fn = NULL;
+      switch (e->Iex.Unop.op) {
+         case Iop_CmpNEZ16x2:
+            fn = &h_generic_calc_CmpNEZ16x2; break;
+         case Iop_CmpNEZ8x4:
+            fn = &h_generic_calc_CmpNEZ8x4; break;
+         default:
+            break;
+      }
+
+      RetLoc rloc = RetLocINVALID;
+      if (ty == Ity_I32) {
+         rloc = RetLocInt;
+      }
+      else if (ty == Ity_I64) {
+         rloc = mode64 ? RetLocInt : RetLoc2Int;
+      }
+      else {
+         goto irreducible;
+      }
+
+      if (fn) {
+         HReg regL = iselWordExpr_R(env, e->Iex.Unop.arg);
+         HReg res  = newVRegI(env);
+         addInstr(env, mk_iMOVds_RR(hregMIPS_GPR4(env->mode64), regL));
+         argiregs |= (1 << 4);
+         addInstr(env, MIPSInstr_CallAlways( MIPScc_AL,
+                                             (HWord)Ptr_to_ULong(fn),
+                                             argiregs, rloc));
+         addInstr(env, mk_iMOVds_RR(res, hregMIPS_GPR2(env->mode64)));
+         return res;
+      }
+
       break;
    }
 
@@ -1610,7 +1803,7 @@ static HReg iselWordExpr_R_wrk(ISelEnv * env, IRExpr * e)
       RetLoc rloc = RetLocINVALID;
       if (ty == Ity_I32) {
          rloc = RetLocInt;
-      } 
+      }
       else if (ty == Ity_I64) {
          rloc = mode64 ? RetLocInt : RetLoc2Int;
       }
@@ -1984,13 +2177,13 @@ static void iselInt128Expr_wrk(HReg * rHi, HReg * rLo, ISelEnv * env,
                *rLo = tLo;
                return;
             }
-   
+
          /* 64HLto128(e1,e2) */
          case Iop_64HLto128:
             *rHi = iselWordExpr_R(env, e->Iex.Binop.arg1);
             *rLo = iselWordExpr_R(env, e->Iex.Binop.arg2);
             return;
-   
+
          case Iop_DivModS64to64: {
             HReg r_srcL = iselWordExpr_R(env, e->Iex.Binop.arg1);
             HReg r_srcR = iselWordExpr_R(env, e->Iex.Binop.arg2);
@@ -2005,7 +2198,7 @@ static void iselInt128Expr_wrk(HReg * rHi, HReg * rLo, ISelEnv * env,
             *rLo = tLo;
             return;
          }
-   
+
          case Iop_DivModU128to64: {
             vassert(mode64);
             HReg rHi1, rLo1;
@@ -2023,7 +2216,7 @@ static void iselInt128Expr_wrk(HReg * rHi, HReg * rLo, ISelEnv * env,
             *rLo = tLo;
             return;
          }
-   
+
          default:
             break;
       }
@@ -2037,7 +2230,7 @@ static void iselInt128Expr_wrk(HReg * rHi, HReg * rLo, ISelEnv * env,
 /*--- ISEL: Integer expressions (64 bit)                ---*/
 /*---------------------------------------------------------*/
 
-/* 32-bit mode ONLY. Compute a 64-bit value into the register 
+/* 32-bit mode ONLY. Compute a 64-bit value into the register
  * pair HI, LO. HI and LO must not be changed by subsequent
  *  code emitted by the caller. */
 
@@ -2115,9 +2308,9 @@ static void iselInt64Expr_wrk(HReg * rHi, HReg * rLo, ISelEnv * env, IRExpr * e)
    /* 64-bit ITE */
    if (e->tag == Iex_ITE) {
       vassert(typeOfIRExpr(env->type_env, e->Iex.ITE.cond) == Ity_I1);
-      vassert(!mode64);
       HReg expr0Lo, expr0Hi;
       HReg expr1Lo, expr1Hi;
+      HReg carryBit;
       HReg tmpHi = newVRegI(env);
       HReg tmpLo = newVRegI(env);
       HReg tmp1Hi = newVRegI(env);
@@ -2128,6 +2321,8 @@ static void iselInt64Expr_wrk(HReg * rHi, HReg * rLo, ISelEnv * env, IRExpr * e)
       HReg mask = newVRegI(env);
       HReg desLo = newVRegI(env);
       HReg desHi = newVRegI(env);
+      carryBit = newVRegI(env);
+
       /* r_cond = 0 - r_cond_1 */
       addInstr(env, MIPSInstr_LI(mask, 0x0));
       addInstr(env, MIPSInstr_Alu(Malu_SUB, r_cond,
@@ -2145,11 +2340,16 @@ static void iselInt64Expr_wrk(HReg * rHi, HReg * rLo, ISelEnv * env, IRExpr * e)
       addInstr(env, MIPSInstr_Alu(Malu_NOR, r_cond_neg, r_cond,
                                   MIPSRH_Reg(r_cond)));
       addInstr(env, MIPSInstr_Alu(Malu_AND, tmp1Lo, r_cond_neg,
-                                  MIPSRH_Reg(expr1Lo)));
+                                  MIPSRH_Reg(expr0Lo)));
       addInstr(env, MIPSInstr_Alu(Malu_AND, tmp1Hi, r_cond_neg,
-                                  MIPSRH_Reg(expr1Hi)));
+                                  MIPSRH_Reg(expr0Hi)));
+
       addInstr(env, MIPSInstr_Alu(Malu_ADD, desLo, tmpLo,
                                   MIPSRH_Reg(tmp1Lo)));
+      addInstr(env, MIPSInstr_Cmp(False, True, carryBit, desLo,
+                                  tmpLo, MIPScc_LO));
+      addInstr(env, MIPSInstr_Alu(Malu_ADD, tmpHi, tmpHi,
+                                  MIPSRH_Reg(carryBit)));
       addInstr(env, MIPSInstr_Alu(Malu_ADD, desHi, tmpHi,
                                   MIPSRH_Reg(tmp1Hi)));
       *rHi = desHi;
@@ -2164,13 +2364,53 @@ static void iselInt64Expr_wrk(HReg * rHi, HReg * rLo, ISelEnv * env, IRExpr * e)
          /* 32 x 32 -> 64 multiply */
          /* Add64 */
          case Iop_Add64: {
-            HReg xLo, xHi, yLo, yHi;
+            HReg xLo, xHi, yLo, yHi, carryBit;
+
             HReg tHi = newVRegI(env);
+            HReg tHi1 = newVRegI(env);
             HReg tLo = newVRegI(env);
+
+            carryBit = newVRegI(env);
+
+            Bool size32 = True;
+            MIPSCondCode cc = MIPScc_LO;
+
             iselInt64Expr(&xHi, &xLo, env, e->Iex.Binop.arg1);
             iselInt64Expr(&yHi, &yLo, env, e->Iex.Binop.arg2);
-            addInstr(env, MIPSInstr_Alu(Malu_ADD, tHi, xHi, MIPSRH_Reg(yHi)));
             addInstr(env, MIPSInstr_Alu(Malu_ADD, tLo, xLo, MIPSRH_Reg(yLo)));
+
+            /* Check carry. */
+            addInstr(env, MIPSInstr_Cmp(False, size32, carryBit, tLo, xLo, cc));
+
+            addInstr(env, MIPSInstr_Alu(Malu_ADD, tHi1, xHi, MIPSRH_Reg(yHi)));
+            addInstr(env, MIPSInstr_Alu(Malu_ADD, tHi, tHi1,
+                                        MIPSRH_Reg(carryBit)));
+
+            *rHi = tHi;
+            *rLo = tLo;
+            return;
+         }
+         case Iop_Sub64: {
+            HReg xLo, xHi, yLo, yHi, borrow;
+            Bool size32 = True;
+            MIPSCondCode cc = MIPScc_LO;
+
+            HReg tHi = newVRegI(env);
+            HReg tLo = newVRegI(env);
+
+            borrow = newVRegI(env);
+
+            iselInt64Expr(&xHi, &xLo, env, e->Iex.Binop.arg1);
+            iselInt64Expr(&yHi, &yLo, env, e->Iex.Binop.arg2);
+
+            addInstr(env, MIPSInstr_Alu(Malu_SUB, tLo, xLo, MIPSRH_Reg(yLo)));
+
+            /* Check if borrow is nedded. */
+            addInstr(env, MIPSInstr_Cmp(False, size32, borrow, xLo, yLo, cc));
+
+            addInstr(env, MIPSInstr_Alu(Malu_ADD, yHi, yHi, MIPSRH_Reg(borrow)));
+            addInstr(env, MIPSInstr_Alu(Malu_SUB, tHi, xHi, MIPSRH_Reg(yHi)));
+
             *rHi = tHi;
             *rLo = tLo;
             return;
@@ -2236,6 +2476,181 @@ static void iselInt64Expr_wrk(HReg * rHi, HReg * rLo, ISelEnv * env, IRExpr * e)
             return;
          }
 
+         case Iop_Shr64: {
+            HReg xLo, xHi;
+            HReg tLo = newVRegI(env);
+            HReg tLo1 = newVRegI(env);
+            HReg tHi = newVRegI(env);
+            HReg tmp = newVRegI(env);
+            HReg tmp2 = newVRegI(env);
+            HReg tmp3 = newVRegI(env);
+            HReg mask = newVRegI(env);
+            HReg tMask = newVRegI(env);
+            HReg discard = newVRegI(env);
+            HReg discard1 = newVRegI(env);
+
+            /* We assume any literal values are on the second operand. */
+            iselInt64Expr(&xHi, &xLo, env, e->Iex.Binop.arg1);
+            MIPSRH *ri_srcR = NULL;
+            MIPSRH *ri_srcR_sub = NULL;
+
+            ri_srcR = iselWordExpr_RH5u(env, e->Iex.Binop.arg2);
+            ri_srcR_sub = iselWordExpr_RH(env, True /*signed */ ,
+                                          e->Iex.Binop.arg2);
+
+            /* Steps:
+               1. Take shift-amount (arg2) least significant bits from upper
+                  half of 64bit input value (arg1)
+               2. Shift upper half
+               3. Shift lower half
+               4. Put discarded bits (those from step 1) to most significant
+                  bit positions of lower half */
+
+            /* Mask for extraction of bits that will be discarded. */
+            addInstr(env, MIPSInstr_LI(tmp, 0xffffffff));
+            addInstr(env, MIPSInstr_Shft(Mshft_SLL, True /*32bit shift */,
+                                         tMask, tmp, ri_srcR));
+            addInstr(env, MIPSInstr_Alu(Malu_NOR, mask,
+                                        tMask, MIPSRH_Reg(tMask)));
+
+            /* Extraction of bits that will be discarded. */
+            addInstr(env, MIPSInstr_Alu(Malu_AND, discard, xHi,
+                                        MIPSRH_Reg(mask)));
+            /* Position discarded bits to most significant bit positions. */
+            addInstr(env, MIPSInstr_LI(tmp3, 32));
+            addInstr(env, MIPSInstr_Alu(Malu_SUB, tmp2,
+                                        tmp3, ri_srcR_sub));
+            addInstr(env, MIPSInstr_Shft(Mshft_SLL, True /*32bit shift */,
+                                         discard1, discard, MIPSRH_Reg(tmp2)));
+
+            addInstr(env, MIPSInstr_Shft(Mshft_SRL, True /*32bit shift */,
+                                         tHi, xHi, ri_srcR));
+            addInstr(env, MIPSInstr_Shft(Mshft_SRL, True /*32bit shift */,
+                                         tLo1, xLo, ri_srcR));
+
+            addInstr(env, MIPSInstr_Alu(Malu_OR, tLo,
+                                        tLo1, MIPSRH_Reg(discard1)));
+            *rHi = tHi;
+            *rLo = tLo;
+            return;
+         }
+         case Iop_Shl64: {
+            HReg xLo, xHi;
+            HReg tLo = newVRegI(env);
+            HReg tHi1 = newVRegI(env);
+            HReg tHi = newVRegI(env);
+            HReg tmp = newVRegI(env);
+            HReg tmp2 = newVRegI(env);
+            HReg tmp3 = newVRegI(env);
+            HReg mask = newVRegI(env);
+            HReg tMask = newVRegI(env);
+            HReg discard = newVRegI(env);
+            HReg discard1 = newVRegI(env);
+
+            /* We assume any literal values are on the second operand. */
+            iselInt64Expr(&xHi, &xLo, env, e->Iex.Binop.arg1);
+            MIPSRH *ri_srcR = NULL;
+            MIPSRH *ri_srcR_sub = NULL;
+
+            ri_srcR = iselWordExpr_RH5u(env, e->Iex.Binop.arg2);
+            ri_srcR_sub = iselWordExpr_RH(env, True /*signed */ ,
+                                          e->Iex.Binop.arg2);
+
+            /* Steps:
+               1. Take shift-amount (arg2) most significant bits from lower
+                  half of 64bit input value (arg1)
+               2. Shift lower half
+               3. Shift upper half
+               4. Put discarded bits (those from step 1) to least significant
+                  bit positions of upper half */
+
+            /* Mask for extraction of bits that will be discarded. */
+            addInstr(env, MIPSInstr_LI(tmp, 0xffffffff));
+            addInstr(env, MIPSInstr_Shft(Mshft_SRL, True /*32bit shift */,
+                                         tMask, tmp, ri_srcR));
+            addInstr(env, MIPSInstr_Alu(Malu_NOR, mask,
+                                        tMask, MIPSRH_Reg(tMask)));
+
+            /* Extraction of bits that will be discarded. */
+            addInstr(env, MIPSInstr_Alu(Malu_AND, discard, xLo,
+                                        MIPSRH_Reg(mask)));
+            /* Position discarded bits to least significant bit positions. */
+            addInstr(env, MIPSInstr_LI(tmp3, 32));
+            addInstr(env, MIPSInstr_Alu(Malu_SUB, tmp2,
+                                        tmp3, ri_srcR_sub));
+            addInstr(env, MIPSInstr_Shft(Mshft_SRL, True /*32bit shift */,
+                                         discard1, discard, MIPSRH_Reg(tmp2)));
+
+            addInstr(env, MIPSInstr_Shft(Mshft_SLL, True /*32bit shift */,
+                                         tHi1, xHi, ri_srcR));
+            addInstr(env, MIPSInstr_Shft(Mshft_SLL, True /*32bit shift */,
+                                         tLo, xLo, ri_srcR));
+
+            addInstr(env, MIPSInstr_Alu(Malu_OR, tHi,
+                                        tHi1, MIPSRH_Reg(discard1)));
+            *rHi = tHi;
+            *rLo = tLo;
+            return;
+         }
+         case Iop_Sar64: {
+            HReg xLo, xHi;
+            HReg tLo = newVRegI(env);
+            HReg tLo1 = newVRegI(env);
+            HReg tHi = newVRegI(env);
+            HReg tmp = newVRegI(env);
+            HReg tmp2 = newVRegI(env);
+            HReg tmp3 = newVRegI(env);
+            HReg mask = newVRegI(env);
+            HReg tMask = newVRegI(env);
+            HReg discard = newVRegI(env);
+            HReg discard1 = newVRegI(env);
+
+            /* We assume any literal values are on the second operand. */
+            iselInt64Expr(&xHi, &xLo, env, e->Iex.Binop.arg1);
+            MIPSRH *ri_srcR = NULL;
+            MIPSRH *ri_srcR_sub = NULL;
+
+            ri_srcR = iselWordExpr_RH5u(env, e->Iex.Binop.arg2);
+            ri_srcR_sub = iselWordExpr_RH(env, True /*signed */ ,
+                                          e->Iex.Binop.arg2);
+
+            /* Steps:
+               1. Take shift-amount (arg2) least significant bits from upper
+                  half of 64bit input value (arg1)
+               2. Shift upper half
+               3. Shift lower half
+               4. Put discarded bits (those from step 1) to most significant
+                  bit positions of lower half */
+
+            /* Mask for extraction of bits that will be discarded. */
+            addInstr(env, MIPSInstr_LI(tmp, 0xffffffff));
+            addInstr(env, MIPSInstr_Shft(Mshft_SLL, True /*32bit shift */,
+                                         tMask, tmp, ri_srcR));
+            addInstr(env, MIPSInstr_Alu(Malu_NOR, mask,
+                                        tMask, MIPSRH_Reg(tMask)));
+
+            /* Extraction of bits that will be discarded. */
+            addInstr(env, MIPSInstr_Alu(Malu_AND, discard, xHi,
+                                        MIPSRH_Reg(mask)));
+            /* Position discarded bits to most significant bit positions. */
+            addInstr(env, MIPSInstr_LI(tmp3, 32));
+            addInstr(env, MIPSInstr_Alu(Malu_SUB, tmp2,
+                                        tmp3, ri_srcR_sub));
+            addInstr(env, MIPSInstr_Shft(Mshft_SLL, True /*32bit shift */,
+                                         discard1, discard, MIPSRH_Reg(tmp2)));
+
+            addInstr(env, MIPSInstr_Shft(Mshft_SRA, True /*32bit shift */,
+                                         tHi, xHi, ri_srcR));
+            addInstr(env, MIPSInstr_Shft(Mshft_SRL, True /*32bit shift */,
+                                         tLo1, xLo, ri_srcR));
+
+            addInstr(env, MIPSInstr_Alu(Malu_OR, tLo,
+                                        tLo1, MIPSRH_Reg(discard1)));
+            *rHi = tHi;
+            *rLo = tLo;
+            return;
+         }
+
          default:
             break;
       }
@@ -2304,7 +2719,42 @@ static void iselInt64Expr_wrk(HReg * rHi, HReg * rLo, ISelEnv * env, IRExpr * e)
             *rLo = tLo;
             return;
          }
-   
+
+         case Iop_Left64: {
+            HReg yLo, yHi, borrow;
+            HReg tHi  = newVRegI(env);
+            HReg tLo  = newVRegI(env);
+            HReg zero = newVRegI(env);
+            Bool size32 = True;
+            MIPSCondCode cc = MIPScc_LO;
+
+            borrow = newVRegI(env);
+
+            /* yHi:yLo = arg */
+            iselInt64Expr(&yHi, &yLo, env, e->Iex.Unop.arg);
+            /* zero = 0 */
+            addInstr(env, MIPSInstr_LI(zero, 0x00000000));
+
+            /* tLo = 0 - yLo */
+            addInstr(env, MIPSInstr_Alu(Malu_SUB, tLo, zero, MIPSRH_Reg(yLo)));
+
+            /* Check if borrow is needed. */
+            addInstr(env, MIPSInstr_Cmp(False, size32, borrow, zero, yLo, cc));
+
+            /* tHi = 0 - (yHi + borrow) */
+            addInstr(env, MIPSInstr_Alu(Malu_ADD,
+                                        yHi, yHi, MIPSRH_Reg(borrow)));
+            addInstr(env, MIPSInstr_Alu(Malu_SUB, tHi, zero, MIPSRH_Reg(yHi)));
+            /* So now we have tHi:tLo = -arg.  To finish off, or 'arg'
+               back in, so as to give the final result
+               tHi:tLo = arg | -arg. */
+            addInstr(env, MIPSInstr_Alu(Malu_OR, tHi, tHi, MIPSRH_Reg(yHi)));
+            addInstr(env, MIPSInstr_Alu(Malu_OR, tLo, tLo, MIPSRH_Reg(yLo)));
+            *rHi = tHi;
+            *rLo = tLo;
+            return;
+         }
+
          case Iop_CmpwNEZ64: {
             HReg srcLo, srcHi;
             HReg tmp1 = newVRegI(env);
@@ -2441,21 +2891,21 @@ static HReg iselFltExpr_wrk(ISelEnv * env, IRExpr * e)
             MIPSAMode *am_addr;
             HReg src = iselFltExpr(env, e->Iex.Unop.arg);
             HReg dst = newVRegF(env);
-   
+
             sub_from_sp(env, 16);  /* Move SP down 16 bytes */
             am_addr = MIPSAMode_IR(0, StackPointer(mode64));
-   
+
             addInstr(env, MIPSInstr_Store(4,
                                           MIPSAMode_IR(am_addr->Mam.IR.index +4,
                                           am_addr->Mam.IR.base),
                                           hregMIPS_GPR0(mode64), mode64));
             addInstr(env, MIPSInstr_FpLdSt(False /* store */, 4, src, am_addr));
-   
+
             /* load as Ity_F64 */
             addInstr(env, MIPSInstr_FpLdSt(True /* load */, 8, dst, am_addr));
             /* Reset SP */
             add_to_sp(env, 16);
-   
+
             return dst;
          }
       }
@@ -3140,7 +3590,7 @@ static void iselStmt(ISelEnv * env, IRStmt * stmt)
       /* --------- PUT --------- */
       case Ist_Put: {
          IRType ty = typeOfIRExpr(env->type_env, stmt->Ist.Put.data);
-   
+
          if (ty == Ity_I8 || ty == Ity_I16 || ty == Ity_I32 ||
              (ty == Ity_I64 && mode64)) {
             HReg r_src = iselWordExpr_R(env, stmt->Ist.Put.data);
@@ -3150,7 +3600,7 @@ static void iselStmt(ISelEnv * env, IRStmt * stmt)
                                           am_addr, r_src, mode64));
             return;
          }
-   
+
          if (ty == Ity_I64 && !mode64) {
             HReg vHi, vLo;
             MIPSAMode *am_addr = MIPSAMode_IR(stmt->Ist.Put.offset,
@@ -3163,9 +3613,9 @@ static void iselStmt(ISelEnv * env, IRStmt * stmt)
             addInstr(env, MIPSInstr_Store(toUChar(sizeofIRType(Ity_I32)),
                                           am_addr4, vHi, mode64));
             return;
-   
+
          }
-   
+
          if (ty == Ity_F32) {
             HReg fr_src = iselFltExpr(env, stmt->Ist.Put.data);
             MIPSAMode *am_addr = MIPSAMode_IR(stmt->Ist.Put.offset,
@@ -3174,7 +3624,7 @@ static void iselStmt(ISelEnv * env, IRStmt * stmt)
                                            am_addr));
             return;
          }
-   
+
          if (ty == Ity_F64) {
             HReg fr_src;
             if (mode64) {
@@ -3350,7 +3800,7 @@ static void iselStmt(ISelEnv * env, IRStmt * stmt)
             r_addr = iselWordExpr_AMode(env, stmt->Ist.LLSC.addr, tyAddr);
             HReg r_src = iselWordExpr_R(env, stmt->Ist.LLSC.storedata);
             HReg r_dst = lookupIRTemp(env, res);
-            IRType tyData = typeOfIRExpr(env->type_env, 
+            IRType tyData = typeOfIRExpr(env->type_env,
                                          stmt->Ist.LLSC.storedata);
 
             if (tyData == Ity_I32) {
index a2920fefe1f4a196c3783644cb68fd9f7e8a1668..05ca8fa7061abe67d4f4a39ab8b69cc4cc7031d8 100644 (file)
@@ -1418,8 +1418,45 @@ static const HChar* show_hwcaps_s390x ( UInt hwcaps )
 
 static const HChar* show_hwcaps_mips32 ( UInt hwcaps )
 {
-   if (hwcaps == 0x00010000) return "MIPS-baseline";
-   if (hwcaps == 0x00020000) return "Broadcom-baseline";
+   /* MIPS baseline. */
+   if (hwcaps && VEX_PRID_COMP_MIPS == VEX_PRID_COMP_MIPS) {
+      /* MIPS baseline with dspr2. */
+      if (hwcaps && VEX_MIPS_ASE_DSP2P == VEX_MIPS_ASE_DSP2P) {
+         return "MIPS-baseline-dspr2";
+      }
+      /* MIPS baseline with dsp. */
+      if (hwcaps && VEX_MIPS_ASE_DSP == VEX_MIPS_ASE_DSP) {
+         return "MIPS-baseline-dsp";
+      }
+      return "MIPS-baseline";
+   }
+
+   /* Broadcom baseline. */
+   if (hwcaps && VEX_PRID_COMP_BROADCOM == VEX_PRID_COMP_BROADCOM) {
+      /* Broadcom baseline with dspr2. */
+      if (hwcaps && VEX_MIPS_ASE_DSP2P == VEX_MIPS_ASE_DSP2P) {
+         return "Broadcom-baseline-dspr2";
+      }
+      /* Broadcom baseline with dsp. */
+      if (hwcaps && VEX_MIPS_ASE_DSP == VEX_MIPS_ASE_DSP) {
+         return "Broadcom-baseline-dsp";
+      }
+      return "Broadcom-baseline";
+   }
+
+   /* Netlogic baseline. */
+   if (hwcaps && VEX_PRID_COMP_NETLOGIC == VEX_PRID_COMP_NETLOGIC) {
+      /* Netlogic baseline with dspr2. */
+      if (hwcaps && VEX_MIPS_ASE_DSP2P == VEX_MIPS_ASE_DSP2P) {
+         return "Netlogic-baseline-dspr2";
+      }
+      /* Netlogic baseline with dsp. */
+      if (hwcaps && VEX_MIPS_ASE_DSP == VEX_MIPS_ASE_DSP) {
+         return "Netlogic-baseline-dsp";
+      }
+      return "Netlogic-baseline";
+   }
+
    return NULL;
 }
 
index fafb8144e74a2fe9c88858022e317d0d3eba5864..8b26c3e8825213b651a66c3e62a61351e2bb3608 100644 (file)
@@ -185,6 +185,10 @@ typedef
 #define VEX_PRID_COMP_BROADCOM  0x00020000
 #define VEX_PRID_COMP_NETLOGIC  0x000c0000
 
+/* MIPS additional capabilities */
+#define VEX_MIPS_ASE_DSP    0x00000010  /* Signal Processing ASE */
+#define VEX_MIPS_ASE_DSP2P  0x00000040  /* Signal Processing ASE Rev 2 */
+
 /* These return statically allocated strings. */
 
 extern const HChar* LibVEX_ppVexArch    ( VexArch );
index cdcadfc8e0bedc57813fa2deb103bd97a2db6b4c..a49c646d522931342e610027d2252b7de094cd83 100644 (file)
@@ -139,6 +139,16 @@ typedef
         UInt host_EvC_FAILADDR; /* 308 */
         UInt host_EvC_COUNTER;  /* 312 */
         UInt guest_COND;        /* 316 */
+
+        UInt padding1;
+      /* MIPS32 DSP ASE(r2) specific registers. */
+        UInt guest_DSPControl;  /* 324 */
+        ULong guest_ac0;        /* 328 */
+        ULong guest_ac1;        /* 336 */
+        ULong guest_ac2;        /* 344 */
+        ULong guest_ac3;        /* 352 */
+        
+        UInt padding[6];
 } VexGuestMIPS32State;
 /*---------------------------------------------------------------*/
 /*--- Utility functions for MIPS32 guest stuff.               ---*/