1
2/*--------------------------------------------------------------------*/
3/*--- begin                                      guest_mips_toIR.c ---*/
4/*--------------------------------------------------------------------*/
5
6/*
7   This file is part of Valgrind, a dynamic binary instrumentation
8   framework.
9
10   Copyright (C) 2010-2013 RT-RK
11      mips-valgrind@rt-rk.com
12
13   This program is free software; you can redistribute it and/or
14   modify it under the terms of the GNU General Public License as
15   published by the Free Software Foundation; either version 2 of the
16   License, or (at your option) any later version.
17
18   This program is distributed in the hope that it will be useful, but
19   WITHOUT ANY WARRANTY; without even the implied warranty of
20   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
21   General Public License for more details.
22
23   You should have received a copy of the GNU General Public License
24   along with this program; if not, write to the Free Software
25   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
26   02111-1307, USA.
27
28   The GNU General Public License is contained in the file COPYING.
29*/
30
31/* Translates MIPS code to IR. */
32
33#include "libvex_basictypes.h"
34#include "libvex_ir.h"
35#include "libvex.h"
36#include "libvex_guest_mips32.h"
37#include "libvex_guest_mips64.h"
38
39#include "main_util.h"
40#include "main_globals.h"
41#include "guest_generic_bb_to_IR.h"
42#include "guest_mips_defs.h"
43
44/*------------------------------------------------------------*/
45/*---                      Globals                         ---*/
46/*------------------------------------------------------------*/
47
48/* These are set at the start of the translation of a instruction, so
49   that we don't have to pass them around endlessly. CONST means does
50   not change during translation of the instruction. */
51
52/* CONST: is the host bigendian?  This has to do with float vs double
53   register accesses on VFP, but it's complex and not properly thought
54   out. */
55static Bool host_is_bigendian;
56
57/* Pointer to the guest code area. */
58static UChar *guest_code;
59
60/* CONST: The guest address for the instruction currently being
61   translated. */
62#if defined(VGP_mips32_linux)
63static Addr32 guest_PC_curr_instr;
64#else
65static Addr64 guest_PC_curr_instr;
66#endif
67
68/* MOD: The IRSB* into which we're generating code. */
69static IRSB *irsb;
70
71/* Is our guest binary 32 or 64bit? Set at each call to
72   disInstr_MIPS below. */
73static Bool mode64 = False;
74
75/* CPU has FPU and 32 dbl. prec. FP registers. */
76static Bool fp_mode64 = False;
77
78/* Define 1.0 in single and double precision. */
79#define ONE_SINGLE 0x3F800000
80#define ONE_DOUBLE 0x3FF0000000000000ULL
81
82/*------------------------------------------------------------*/
83/*---                  Debugging output                    ---*/
84/*------------------------------------------------------------*/
85
86#define DIP(format, args...)           \
87   if (vex_traceflags & VEX_TRACE_FE)  \
88      vex_printf(format, ## args)
89
90/*------------------------------------------------------------*/
91/*--- Helper bits and pieces for deconstructing the        ---*/
92/*--- mips insn stream.                                    ---*/
93/*------------------------------------------------------------*/
94
95/* ---------------- Integer registers ---------------- */
96
97static UInt integerGuestRegOffset(UInt iregNo)
98{
99   /* Do we care about endianness here?  We do if sub-parts of integer
100      registers are accessed, but I don't think that ever happens on
101      MIPS. */
102   UInt ret;
103   if (!mode64)
104      switch (iregNo) {
105         case 0:
106            ret = offsetof(VexGuestMIPS32State, guest_r0); break;
107         case 1:
108            ret = offsetof(VexGuestMIPS32State, guest_r1); break;
109         case 2:
110            ret = offsetof(VexGuestMIPS32State, guest_r2); break;
111         case 3:
112            ret = offsetof(VexGuestMIPS32State, guest_r3); break;
113         case 4:
114            ret = offsetof(VexGuestMIPS32State, guest_r4); break;
115         case 5:
116            ret = offsetof(VexGuestMIPS32State, guest_r5); break;
117         case 6:
118            ret = offsetof(VexGuestMIPS32State, guest_r6); break;
119         case 7:
120            ret = offsetof(VexGuestMIPS32State, guest_r7); break;
121         case 8:
122            ret = offsetof(VexGuestMIPS32State, guest_r8); break;
123         case 9:
124            ret = offsetof(VexGuestMIPS32State, guest_r9); break;
125         case 10:
126            ret = offsetof(VexGuestMIPS32State, guest_r10); break;
127         case 11:
128            ret = offsetof(VexGuestMIPS32State, guest_r11); break;
129         case 12:
130            ret = offsetof(VexGuestMIPS32State, guest_r12); break;
131         case 13:
132            ret = offsetof(VexGuestMIPS32State, guest_r13); break;
133         case 14:
134            ret = offsetof(VexGuestMIPS32State, guest_r14); break;
135         case 15:
136            ret = offsetof(VexGuestMIPS32State, guest_r15); break;
137         case 16:
138            ret = offsetof(VexGuestMIPS32State, guest_r16); break;
139         case 17:
140            ret = offsetof(VexGuestMIPS32State, guest_r17); break;
141         case 18:
142            ret = offsetof(VexGuestMIPS32State, guest_r18); break;
143         case 19:
144            ret = offsetof(VexGuestMIPS32State, guest_r19); break;
145         case 20:
146            ret = offsetof(VexGuestMIPS32State, guest_r20); break;
147         case 21:
148            ret = offsetof(VexGuestMIPS32State, guest_r21); break;
149         case 22:
150            ret = offsetof(VexGuestMIPS32State, guest_r22); break;
151         case 23:
152            ret = offsetof(VexGuestMIPS32State, guest_r23); break;
153         case 24:
154            ret = offsetof(VexGuestMIPS32State, guest_r24); break;
155         case 25:
156            ret = offsetof(VexGuestMIPS32State, guest_r25); break;
157         case 26:
158            ret = offsetof(VexGuestMIPS32State, guest_r26); break;
159         case 27:
160            ret = offsetof(VexGuestMIPS32State, guest_r27); break;
161         case 28:
162            ret = offsetof(VexGuestMIPS32State, guest_r28); break;
163         case 29:
164            ret = offsetof(VexGuestMIPS32State, guest_r29); break;
165         case 30:
166            ret = offsetof(VexGuestMIPS32State, guest_r30); break;
167         case 31:
168            ret = offsetof(VexGuestMIPS32State, guest_r31); break;
169         default:
170            vassert(0);
171            break;
172      }
173   else
174      switch (iregNo) {
175         case 0:
176            ret = offsetof(VexGuestMIPS64State, guest_r0); break;
177         case 1:
178            ret = offsetof(VexGuestMIPS64State, guest_r1); break;
179         case 2:
180            ret = offsetof(VexGuestMIPS64State, guest_r2); break;
181         case 3:
182            ret = offsetof(VexGuestMIPS64State, guest_r3); break;
183         case 4:
184            ret = offsetof(VexGuestMIPS64State, guest_r4); break;
185         case 5:
186            ret = offsetof(VexGuestMIPS64State, guest_r5); break;
187         case 6:
188            ret = offsetof(VexGuestMIPS64State, guest_r6); break;
189         case 7:
190            ret = offsetof(VexGuestMIPS64State, guest_r7); break;
191         case 8:
192            ret = offsetof(VexGuestMIPS64State, guest_r8); break;
193         case 9:
194            ret = offsetof(VexGuestMIPS64State, guest_r9); break;
195         case 10:
196            ret = offsetof(VexGuestMIPS64State, guest_r10); break;
197         case 11:
198            ret = offsetof(VexGuestMIPS64State, guest_r11); break;
199         case 12:
200            ret = offsetof(VexGuestMIPS64State, guest_r12); break;
201         case 13:
202            ret = offsetof(VexGuestMIPS64State, guest_r13); break;
203         case 14:
204            ret = offsetof(VexGuestMIPS64State, guest_r14); break;
205         case 15:
206            ret = offsetof(VexGuestMIPS64State, guest_r15); break;
207         case 16:
208            ret = offsetof(VexGuestMIPS64State, guest_r16); break;
209         case 17:
210            ret = offsetof(VexGuestMIPS64State, guest_r17); break;
211         case 18:
212            ret = offsetof(VexGuestMIPS64State, guest_r18); break;
213         case 19:
214            ret = offsetof(VexGuestMIPS64State, guest_r19); break;
215         case 20:
216            ret = offsetof(VexGuestMIPS64State, guest_r20); break;
217         case 21:
218            ret = offsetof(VexGuestMIPS64State, guest_r21); break;
219         case 22:
220            ret = offsetof(VexGuestMIPS64State, guest_r22); break;
221         case 23:
222            ret = offsetof(VexGuestMIPS64State, guest_r23); break;
223         case 24:
224            ret = offsetof(VexGuestMIPS64State, guest_r24); break;
225         case 25:
226            ret = offsetof(VexGuestMIPS64State, guest_r25); break;
227         case 26:
228            ret = offsetof(VexGuestMIPS64State, guest_r26); break;
229         case 27:
230            ret = offsetof(VexGuestMIPS64State, guest_r27); break;
231         case 28:
232            ret = offsetof(VexGuestMIPS64State, guest_r28); break;
233         case 29:
234            ret = offsetof(VexGuestMIPS64State, guest_r29); break;
235         case 30:
236            ret = offsetof(VexGuestMIPS64State, guest_r30); break;
237         case 31:
238            ret = offsetof(VexGuestMIPS64State, guest_r31); break;
239         default:
240            vassert(0);
241            break;
242      }
243   return ret;
244}
245
246#if defined(VGP_mips32_linux)
247#define OFFB_PC     offsetof(VexGuestMIPS32State, guest_PC)
248#else
249#define OFFB_PC     offsetof(VexGuestMIPS64State, guest_PC)
250#endif
251
252/* ---------------- Floating point registers ---------------- */
253
254static UInt floatGuestRegOffset(UInt fregNo)
255{
256   vassert(fregNo < 32);
257   UInt ret;
258   if (!mode64)
259      switch (fregNo) {
260         case 0:
261            ret = offsetof(VexGuestMIPS32State, guest_f0); break;
262         case 1:
263            ret = offsetof(VexGuestMIPS32State, guest_f1); break;
264         case 2:
265            ret = offsetof(VexGuestMIPS32State, guest_f2); break;
266         case 3:
267            ret = offsetof(VexGuestMIPS32State, guest_f3); break;
268         case 4:
269            ret = offsetof(VexGuestMIPS32State, guest_f4); break;
270         case 5:
271            ret = offsetof(VexGuestMIPS32State, guest_f5); break;
272         case 6:
273            ret = offsetof(VexGuestMIPS32State, guest_f6); break;
274         case 7:
275            ret = offsetof(VexGuestMIPS32State, guest_f7); break;
276         case 8:
277            ret = offsetof(VexGuestMIPS32State, guest_f8); break;
278         case 9:
279            ret = offsetof(VexGuestMIPS32State, guest_f9); break;
280         case 10:
281            ret = offsetof(VexGuestMIPS32State, guest_f10); break;
282         case 11:
283            ret = offsetof(VexGuestMIPS32State, guest_f11); break;
284         case 12:
285            ret = offsetof(VexGuestMIPS32State, guest_f12); break;
286         case 13:
287            ret = offsetof(VexGuestMIPS32State, guest_f13); break;
288         case 14:
289            ret = offsetof(VexGuestMIPS32State, guest_f14); break;
290         case 15:
291            ret = offsetof(VexGuestMIPS32State, guest_f15); break;
292         case 16:
293            ret = offsetof(VexGuestMIPS32State, guest_f16); break;
294         case 17:
295            ret = offsetof(VexGuestMIPS32State, guest_f17); break;
296         case 18:
297            ret = offsetof(VexGuestMIPS32State, guest_f18); break;
298         case 19:
299            ret = offsetof(VexGuestMIPS32State, guest_f19); break;
300         case 20:
301            ret = offsetof(VexGuestMIPS32State, guest_f20); break;
302         case 21:
303            ret = offsetof(VexGuestMIPS32State, guest_f21); break;
304         case 22:
305            ret = offsetof(VexGuestMIPS32State, guest_f22); break;
306         case 23:
307            ret = offsetof(VexGuestMIPS32State, guest_f23); break;
308         case 24:
309            ret = offsetof(VexGuestMIPS32State, guest_f24); break;
310         case 25:
311            ret = offsetof(VexGuestMIPS32State, guest_f25); break;
312         case 26:
313            ret = offsetof(VexGuestMIPS32State, guest_f26); break;
314         case 27:
315            ret = offsetof(VexGuestMIPS32State, guest_f27); break;
316         case 28:
317            ret = offsetof(VexGuestMIPS32State, guest_f28); break;
318         case 29:
319            ret = offsetof(VexGuestMIPS32State, guest_f29); break;
320         case 30:
321            ret = offsetof(VexGuestMIPS32State, guest_f30); break;
322         case 31:
323            ret = offsetof(VexGuestMIPS32State, guest_f31); break;
324         default:
325            vassert(0);
326            break;
327      }
328   else
329      switch (fregNo) {
330         case 0:
331            ret = offsetof(VexGuestMIPS64State, guest_f0); break;
332         case 1:
333            ret = offsetof(VexGuestMIPS64State, guest_f1); break;
334         case 2:
335            ret = offsetof(VexGuestMIPS64State, guest_f2); break;
336         case 3:
337            ret = offsetof(VexGuestMIPS64State, guest_f3); break;
338         case 4:
339            ret = offsetof(VexGuestMIPS64State, guest_f4); break;
340         case 5:
341            ret = offsetof(VexGuestMIPS64State, guest_f5); break;
342         case 6:
343            ret = offsetof(VexGuestMIPS64State, guest_f6); break;
344         case 7:
345            ret = offsetof(VexGuestMIPS64State, guest_f7); break;
346         case 8:
347            ret = offsetof(VexGuestMIPS64State, guest_f8); break;
348         case 9:
349            ret = offsetof(VexGuestMIPS64State, guest_f9); break;
350         case 10:
351            ret = offsetof(VexGuestMIPS64State, guest_f10); break;
352         case 11:
353            ret = offsetof(VexGuestMIPS64State, guest_f11); break;
354         case 12:
355            ret = offsetof(VexGuestMIPS64State, guest_f12); break;
356         case 13:
357            ret = offsetof(VexGuestMIPS64State, guest_f13); break;
358         case 14:
359            ret = offsetof(VexGuestMIPS64State, guest_f14); break;
360         case 15:
361            ret = offsetof(VexGuestMIPS64State, guest_f15); break;
362         case 16:
363            ret = offsetof(VexGuestMIPS64State, guest_f16); break;
364         case 17:
365            ret = offsetof(VexGuestMIPS64State, guest_f17); break;
366         case 18:
367            ret = offsetof(VexGuestMIPS64State, guest_f18); break;
368         case 19:
369            ret = offsetof(VexGuestMIPS64State, guest_f19); break;
370         case 20:
371            ret = offsetof(VexGuestMIPS64State, guest_f20); break;
372         case 21:
373            ret = offsetof(VexGuestMIPS64State, guest_f21); break;
374         case 22:
375            ret = offsetof(VexGuestMIPS64State, guest_f22); break;
376         case 23:
377            ret = offsetof(VexGuestMIPS64State, guest_f23); break;
378         case 24:
379            ret = offsetof(VexGuestMIPS64State, guest_f24); break;
380         case 25:
381            ret = offsetof(VexGuestMIPS64State, guest_f25); break;
382         case 26:
383            ret = offsetof(VexGuestMIPS64State, guest_f26); break;
384         case 27:
385            ret = offsetof(VexGuestMIPS64State, guest_f27); break;
386         case 28:
387            ret = offsetof(VexGuestMIPS64State, guest_f28); break;
388         case 29:
389            ret = offsetof(VexGuestMIPS64State, guest_f29); break;
390         case 30:
391            ret = offsetof(VexGuestMIPS64State, guest_f30); break;
392         case 31:
393            ret = offsetof(VexGuestMIPS64State, guest_f31); break;
394         default:
395            vassert(0);
396            break;
397      }
398   return ret;
399}
400
401/* ---------------- MIPS32 DSP ASE(r2) accumulators ---------------- */
402
403static UInt accumulatorGuestRegOffset(UInt acNo)
404{
405   vassert(!mode64);
406   vassert(acNo <= 3);
407   UInt ret;
408   switch (acNo) {
409      case 0:
410         ret = offsetof(VexGuestMIPS32State, guest_ac0); break;
411      case 1:
412         ret = offsetof(VexGuestMIPS32State, guest_ac1); break;
413      case 2:
414         ret = offsetof(VexGuestMIPS32State, guest_ac2); break;
415      case 3:
416         ret = offsetof(VexGuestMIPS32State, guest_ac3); break;
417      default:
418         vassert(0);
419    break;
420   }
421   return ret;
422}
423
424/* Do a endian load of a 32-bit word, regardless of the endianness of the
425   underlying host. */
426static inline UInt getUInt(UChar * p)
427{
428   UInt w = 0;
429#if defined (_MIPSEL)
430   w = (w << 8) | p[3];
431   w = (w << 8) | p[2];
432   w = (w << 8) | p[1];
433   w = (w << 8) | p[0];
434#elif defined (_MIPSEB)
435   w = (w << 8) | p[0];
436   w = (w << 8) | p[1];
437   w = (w << 8) | p[2];
438   w = (w << 8) | p[3];
439#endif
440   return w;
441}
442
443#define BITS2(_b1,_b0) \
444   (((_b1) << 1) | (_b0))
445
446#define BITS3(_b2,_b1,_b0)                      \
447  (((_b2) << 2) | ((_b1) << 1) | (_b0))
448
449#define BITS4(_b3,_b2,_b1,_b0) \
450   (((_b3) << 3) | ((_b2) << 2) | ((_b1) << 1) | (_b0))
451
452#define BITS5(_b4,_b3,_b2,_b1,_b0)  \
453   (((_b4) << 4) | BITS4((_b3),(_b2),(_b1),(_b0)))
454
455#define BITS6(_b5,_b4,_b3,_b2,_b1,_b0)  \
456   ((BITS2((_b5),(_b4)) << 4) \
457    | BITS4((_b3),(_b2),(_b1),(_b0)))
458
459#define BITS8(_b7,_b6,_b5,_b4,_b3,_b2,_b1,_b0)  \
460   ((BITS4((_b7),(_b6),(_b5),(_b4)) << 4) \
461    | BITS4((_b3),(_b2),(_b1),(_b0)))
462
463#define LOAD_STORE_PATTERN \
464   t1 = newTemp(mode64 ? Ity_I64 : Ity_I32); \
465      if(!mode64) \
466         assign(t1, binop(Iop_Add32, getIReg(rs), \
467                                     mkU32(extend_s_16to32(imm)))); \
468      else \
469         assign(t1, binop(Iop_Add64, getIReg(rs), \
470                                     mkU64(extend_s_16to64(imm)))); \
471
472#define LOADX_STORE_PATTERN \
473   t1 = newTemp(mode64 ? Ity_I64 : Ity_I32); \
474      if(!mode64) \
475         assign(t1, binop(Iop_Add32, getIReg(regRs), getIReg(regRt))); \
476      else \
477         assign(t1, binop(Iop_Add64, getIReg(regRs), getIReg(regRt)));
478
479#define LWX_SWX_PATTERN64 \
480   t2 = newTemp(Ity_I64); \
481   assign(t2, binop(Iop_And64, mkexpr(t1), mkU64(0xFFFFFFFFFFFFFFFCULL))); \
482   t4 = newTemp(Ity_I32); \
483   assign(t4, mkNarrowTo32( ty, binop(Iop_And64, \
484                                      mkexpr(t1), mkU64(0x3))));
485
486#define LWX_SWX_PATTERN64_1 \
487   t2 = newTemp(Ity_I64); \
488   assign(t2, binop(Iop_And64, mkexpr(t1), mkU64(0xFFFFFFFFFFFFFFF8ULL))); \
489   t4 = newTemp(Ity_I64); \
490   assign(t4, binop(Iop_And64, mkexpr(t1), mkU64(0x7)));
491
492#define LWX_SWX_PATTERN \
493   t2 = newTemp(Ity_I32); \
494   assign(t2, binop(Iop_And32, mkexpr(t1), mkU32(0xFFFFFFFC))); \
495   t4 = newTemp(Ity_I32); \
496   assign(t4, binop(Iop_And32, mkexpr(t1), mkU32(0x00000003)))
497
498#define SXXV_PATTERN(op) \
499   putIReg(rd, binop(op, \
500         getIReg(rt), \
501            unop(Iop_32to8, \
502               binop(Iop_And32, \
503                  getIReg(rs), \
504                  mkU32(0x0000001F) \
505               ) \
506            ) \
507         ) \
508      )
509
510#define SXXV_PATTERN64(op) \
511   putIReg(rd, mkWidenFrom32(ty, binop(op, \
512           mkNarrowTo32(ty, getIReg(rt)), \
513             unop(Iop_32to8, \
514                binop(Iop_And32, \
515                   mkNarrowTo32(ty, getIReg(rs)), \
516                   mkU32(0x0000001F) \
517                ) \
518             ) \
519          ), True \
520       ))
521
522#define SXX_PATTERN(op) \
523   putIReg(rd, binop(op, getIReg(rt), mkU8(sa)));
524
525#define ALU_PATTERN(op) \
526   putIReg(rd, binop(op, getIReg(rs), getIReg(rt)));
527
528#define ALUI_PATTERN(op) \
529   putIReg(rt, binop(op, getIReg(rs), mkU32(imm)));
530
531#define ALUI_PATTERN64(op) \
532   putIReg(rt, binop(op, getIReg(rs), mkU64(imm)));
533
534#define ALU_PATTERN64(op) \
535   putIReg(rd, mkWidenFrom32(ty, binop(op, \
536                             mkNarrowTo32(ty, getIReg(rs)), \
537                             mkNarrowTo32(ty, getIReg(rt))), True));
538
539#define FP_CONDITIONAL_CODE \
540   t3 = newTemp(Ity_I32);   \
541   assign(t3, binop(Iop_And32, \
542                 IRExpr_ITE( binop(Iop_CmpEQ32, mkU32(cc), mkU32(0)), \
543                             binop(Iop_Shr32, getFCSR(), mkU8(23)), \
544                             binop(Iop_Shr32, getFCSR(), mkU8(24+cc))), \
545                 mkU32(0x1)));
546
547#define ILLEGAL_INSTRUCTON \
548   putPC(mkU32(guest_PC_curr_instr + 4)); \
549   dres.jk_StopHere = Ijk_SigILL; \
550   dres.whatNext    = Dis_StopHere;
551
552/*------------------------------------------------------------*/
553/*---                  Field helpers                       ---*/
554/*------------------------------------------------------------*/
555
556static UInt get_opcode(UInt mipsins)
557{
558   return (0xFC000000 & mipsins) >> 26;
559}
560
561static UInt get_rs(UInt mipsins)
562{
563   return (0x03E00000 & mipsins) >> 21;
564}
565
566static UInt get_rt(UInt mipsins)
567{
568   return (0x001F0000 & mipsins) >> 16;
569}
570
571static UInt get_imm(UInt mipsins)
572{
573   return (0x0000FFFF & mipsins);
574}
575
576static UInt get_instr_index(UInt mipsins)
577{
578   return (0x03FFFFFF & mipsins);
579}
580
581static UInt get_rd(UInt mipsins)
582{
583   return (0x0000F800 & mipsins) >> 11;
584}
585
586static UInt get_sa(UInt mipsins)
587{
588   return (0x000007C0 & mipsins) >> 6;
589}
590
591static UInt get_function(UInt mipsins)
592{
593   return (0x0000003F & mipsins);
594}
595
596static UInt get_ft(UInt mipsins)
597{
598   return (0x001F0000 & mipsins) >> 16;
599}
600
601static UInt get_fs(UInt mipsins)
602{
603   return (0x0000F800 & mipsins) >> 11;
604}
605
606static UInt get_fd(UInt mipsins)
607{
608   return (0x000007C0 & mipsins) >> 6;
609}
610
611static UInt get_mov_cc(UInt mipsins)
612{
613   return (0x001C0000 & mipsins) >> 18;
614}
615
616static UInt get_bc1_cc(UInt mipsins)
617{
618   return (0x001C0000 & mipsins) >> 18;
619}
620
621static UInt get_fpc_cc(UInt mipsins)
622{
623   return (0x00000700 & mipsins) >> 8;
624}
625
626static UInt get_tf(UInt mipsins)
627{
628   return (0x00010000 & mipsins) >> 16;
629}
630
631static UInt get_nd(UInt mipsins)
632{
633   return (0x00020000 & mipsins) >> 17;
634}
635
636static UInt get_fmt(UInt mipsins)
637{
638   return (0x03E00000 & mipsins) >> 21;
639}
640
641static UInt get_FC(UInt mipsins)
642{
643   return (0x000000F0 & mipsins) >> 4;
644}
645
646static UInt get_cond(UInt mipsins)
647{
648   return (0x0000000F & mipsins);
649}
650
651/* for break & syscall */
652static UInt get_code(UInt mipsins)
653{
654   return (0xFFC0 & mipsins) >> 6;
655}
656
657static UInt get_lsb(UInt mipsins)
658{
659   return (0x7C0 & mipsins) >> 6;
660}
661
662static UInt get_msb(UInt mipsins)
663{
664   return (0x0000F800 & mipsins) >> 11;
665}
666
667static UInt get_rot(UInt mipsins)
668{
669   return (0x00200000 & mipsins) >> 21;
670}
671
672static UInt get_rotv(UInt mipsins)
673{
674   return (0x00000040 & mipsins) >> 6;
675}
676
677static UInt get_sel(UInt mipsins)
678{
679   return (0x00000007 & mipsins);
680}
681
682/* Get acc number for all MIPS32 DSP ASE(r2) instructions that use them,
683   except for MFHI and MFLO. */
684static UInt get_acNo(UInt mipsins)
685{
686   return (0x00001800 & mipsins) >> 11;
687}
688
689/* Get accumulator number for MIPS32 DSP ASEr2 MFHI and MFLO instructions. */
690static UInt get_acNo_mfhilo(UInt mipsins)
691{
692   return (0x00600000 & mipsins) >> 21;
693}
694
695/* Get mask field (helper function for wrdsp instruction). */
696static UInt get_wrdspMask(UInt mipsins)
697{
698   return (0x001ff800 & mipsins) >> 11;
699}
700
701/* Get mask field (helper function for rddsp instruction). */
702static UInt get_rddspMask(UInt mipsins)
703{
704   return (0x03ff0000 & mipsins) >> 16;
705}
706
707/* Get shift field (helper function for DSP ASE instructions). */
708static UInt get_shift(UInt mipsins)
709{
710   return (0x03f00000 & mipsins) >> 20;
711}
712
713/* Get immediate field for DSP ASE instructions. */
714static UInt get_dspImm(UInt mipsins)
715{
716   return (0x03ff0000 & mipsins) >> 16;
717}
718
719static Bool branch_or_jump(UChar * addr)
720{
721   UInt fmt;
722   UInt cins = getUInt(addr);
723
724   UInt opcode = get_opcode(cins);
725   UInt rt = get_rt(cins);
726   UInt function = get_function(cins);
727
728   /* bgtz, blez, bne, beq, jal */
729   if (opcode == 0x07 || opcode == 0x06 || opcode == 0x05 || opcode == 0x04
730       || opcode == 0x03 || opcode == 0x02) {
731      return True;
732   }
733
734   /* bgez */
735   if (opcode == 0x01 && rt == 0x01) {
736      return True;
737   }
738
739   /* bgezal */
740   if (opcode == 0x01 && rt == 0x11) {
741      return True;
742   }
743
744   /* bltzal */
745   if (opcode == 0x01 && rt == 0x10) {
746      return True;
747   }
748
749   /* bltz */
750   if (opcode == 0x01 && rt == 0x00) {
751      return True;
752   }
753
754   /* jalr */
755   if (opcode == 0x00 && function == 0x09) {
756      return True;
757   }
758
759   /* jr */
760   if (opcode == 0x00 && function == 0x08) {
761      return True;
762   }
763
764   if (opcode == 0x11) {
765      /*bc1f & bc1t */
766      fmt = get_fmt(cins);
767      if (fmt == 0x08) {
768         return True;
769      }
770   }
771
772   /* bposge32 */
773   if (opcode == 0x01 && rt == 0x1c) {
774      return True;
775   }
776
777   return False;
778}
779
780static Bool is_Branch_or_Jump_and_Link(UChar * addr)
781{
782   UInt cins = getUInt(addr);
783
784   UInt opcode = get_opcode(cins);
785   UInt rt = get_rt(cins);
786   UInt function = get_function(cins);
787
788   /* jal */
789   if (opcode == 0x02) {
790      return True;
791   }
792
793   /* bgezal */
794   if (opcode == 0x01 && rt == 0x11) {
795      return True;
796   }
797
798   /* bltzal */
799   if (opcode == 0x01 && rt == 0x10) {
800      return True;
801   }
802
803   /* jalr */
804   if (opcode == 0x00 && function == 0x09) {
805      return True;
806   }
807
808   return False;
809}
810
811static Bool branch_or_link_likely(UChar * addr)
812{
813   UInt cins = getUInt(addr);
814   UInt opcode = get_opcode(cins);
815   UInt rt = get_rt(cins);
816
817   /* bgtzl, blezl, bnel, beql */
818   if (opcode == 0x17 || opcode == 0x16 || opcode == 0x15 || opcode == 0x14)
819      return True;
820
821   /* bgezl */
822   if (opcode == 0x01 && rt == 0x03)
823      return True;
824
825   /* bgezall */
826   if (opcode == 0x01 && rt == 0x13)
827      return True;
828
829   /* bltzall */
830   if (opcode == 0x01 && rt == 0x12)
831      return True;
832
833   /* bltzl */
834   if (opcode == 0x01 && rt == 0x02)
835      return True;
836
837   return False;
838}
839
840/*------------------------------------------------------------*/
841/*--- Helper bits and pieces for creating IR fragments.    ---*/
842/*------------------------------------------------------------*/
843
844static IRExpr *mkU8(UInt i)
845{
846   vassert(i < 256);
847   return IRExpr_Const(IRConst_U8((UChar) i));
848}
849
850/* Create an expression node for a 16-bit integer constant. */
851static IRExpr *mkU16(UInt i)
852{
853   return IRExpr_Const(IRConst_U16(i));
854}
855
856/* Create an expression node for a 32-bit integer constant. */
857static IRExpr *mkU32(UInt i)
858{
859   return IRExpr_Const(IRConst_U32(i));
860}
861
862/* Create an expression node for a 64-bit integer constant. */
863static IRExpr *mkU64(ULong i)
864{
865   return IRExpr_Const(IRConst_U64(i));
866}
867
868static IRExpr *mkexpr(IRTemp tmp)
869{
870   return IRExpr_RdTmp(tmp);
871}
872
873static IRExpr *unop(IROp op, IRExpr * a)
874{
875   return IRExpr_Unop(op, a);
876}
877
878static IRExpr *binop(IROp op, IRExpr * a1, IRExpr * a2)
879{
880   return IRExpr_Binop(op, a1, a2);
881}
882
883static IRExpr *triop(IROp op, IRExpr * a1, IRExpr * a2, IRExpr * a3)
884{
885   return IRExpr_Triop(op, a1, a2, a3);
886}
887
888static IRExpr *qop ( IROp op, IRExpr * a1, IRExpr * a2, IRExpr * a3,
889                     IRExpr * a4 )
890{
891   return IRExpr_Qop(op, a1, a2, a3, a4);
892}
893
894static IRExpr *load(IRType ty, IRExpr * addr)
895{
896   IRExpr *load1 = NULL;
897#if defined (_MIPSEL)
898   load1 = IRExpr_Load(Iend_LE, ty, addr);
899#elif defined (_MIPSEB)
900   load1 = IRExpr_Load(Iend_BE, ty, addr);
901#endif
902   return load1;
903}
904
905/* Add a statement to the list held by "irsb". */
906static void stmt(IRStmt * st)
907{
908   addStmtToIRSB(irsb, st);
909}
910
911static void assign(IRTemp dst, IRExpr * e)
912{
913   stmt(IRStmt_WrTmp(dst, e));
914}
915
916static void store(IRExpr * addr, IRExpr * data)
917{
918#if defined (_MIPSEL)
919   stmt(IRStmt_Store(Iend_LE, addr, data));
920#elif defined (_MIPSEB)
921   stmt(IRStmt_Store(Iend_BE, addr, data));
922#endif
923}
924
925/* Generate a new temporary of the given type. */
926static IRTemp newTemp(IRType ty)
927{
928   vassert(isPlausibleIRType(ty));
929   return newIRTemp(irsb->tyenv, ty);
930}
931
932/* Generate an expression for SRC rotated right by ROT. */
933static IRExpr *genROR32(IRExpr * src, Int rot)
934{
935   vassert(rot >= 0 && rot < 32);
936   if (rot == 0)
937      return src;
938   return binop(Iop_Or32, binop(Iop_Shl32, src, mkU8(32 - rot)),
939                          binop(Iop_Shr32, src, mkU8(rot)));
940}
941
942static IRExpr *genRORV32(IRExpr * src, IRExpr * rs)
943{
944   IRTemp t0 = newTemp(Ity_I8);
945   IRTemp t1 = newTemp(Ity_I8);
946
947   assign(t0, unop(Iop_32to8, binop(Iop_And32, rs, mkU32(0x0000001F))));
948   assign(t1, binop(Iop_Sub8, mkU8(32), mkexpr(t0)));
949   return binop(Iop_Or32, binop(Iop_Shl32, src, mkexpr(t1)),
950                          binop(Iop_Shr32, src, mkexpr(t0)));
951}
952
953static UShort extend_s_10to16(UInt x)
954{
955   return (UShort) ((((Int) x) << 22) >> 22);
956}
957
958static ULong extend_s_10to32(UInt x)
959{
960   return (ULong)((((Long) x) << 22) >> 22);
961}
962
963static ULong extend_s_10to64(UInt x)
964{
965   return (ULong)((((Long) x) << 54) >> 54);
966}
967
968static UInt extend_s_16to32(UInt x)
969{
970   return (UInt) ((((Int) x) << 16) >> 16);
971}
972
973static UInt extend_s_18to32(UInt x)
974{
975   return (UInt) ((((Int) x) << 14) >> 14);
976}
977
978static ULong extend_s_16to64 ( UInt x )
979{
980   return (ULong) ((((Long) x) << 48) >> 48);
981}
982
983static ULong extend_s_18to64 ( UInt x )
984{
985   return (ULong) ((((Long) x) << 46) >> 46);
986}
987
988static ULong extend_s_32to64 ( UInt x )
989{
990   return (ULong) ((((Long) x) << 32) >> 32);
991}
992
993static void jmp_lit32 ( /*MOD*/ DisResult* dres, IRJumpKind kind, Addr32 d32 )
994{
995   vassert(dres->whatNext    == Dis_Continue);
996   vassert(dres->len         == 0);
997   vassert(dres->continueAt  == 0);
998   vassert(dres->jk_StopHere == Ijk_INVALID);
999   dres->whatNext    = Dis_StopHere;
1000   dres->jk_StopHere = kind;
1001   stmt( IRStmt_Put( OFFB_PC, mkU32(d32) ) );
1002}
1003
1004static void jmp_lit64 ( /*MOD*/ DisResult* dres, IRJumpKind kind, Addr64 d64 )
1005{
1006   vassert(dres->whatNext    == Dis_Continue);
1007   vassert(dres->len         == 0);
1008   vassert(dres->continueAt  == 0);
1009   vassert(dres->jk_StopHere == Ijk_INVALID);
1010   dres->whatNext    = Dis_StopHere;
1011   dres->jk_StopHere = kind;
1012   stmt(IRStmt_Put(OFFB_PC, mkU64(d64)));
1013}
1014
1015/* Get value from accumulator (helper function for MIPS32 DSP ASE instructions).
1016   This function should be called before any other operation if widening
1017   multiplications are used. */
1018static IRExpr *getAcc(UInt acNo)
1019{
1020   vassert(!mode64);
1021   vassert(acNo <= 3);
1022   return IRExpr_Get(accumulatorGuestRegOffset(acNo), Ity_I64);
1023}
1024
1025/* Get value from DSPControl register (helper function for MIPS32 DSP ASE
1026   instructions). */
1027static IRExpr *getDSPControl(void)
1028{
1029   vassert(!mode64);
1030   return IRExpr_Get(offsetof(VexGuestMIPS32State, guest_DSPControl), Ity_I32);
1031}
1032
1033/* Put value to DSPControl register. Expression e is written to DSPControl as
1034   is. If only certain bits of DSPControl need to be changed, it should be done
1035   before calling putDSPControl(). It could be done by reading DSPControl and
1036   ORing it with appropriate mask. */
1037static void putDSPControl(IRExpr * e)
1038{
1039   vassert(!mode64);
1040   stmt(IRStmt_Put(offsetof(VexGuestMIPS32State, guest_DSPControl), e));
1041}
1042
1043/* Fetch a byte from the guest insn stream. */
1044static UChar getIByte(Int delta)
1045{
1046   return guest_code[delta];
1047}
1048
1049static IRExpr *getIReg(UInt iregNo)
1050{
1051   if (0 == iregNo) {
1052      return mode64 ? mkU64(0x0) : mkU32(0x0);
1053   } else {
1054      IRType ty = mode64 ? Ity_I64 : Ity_I32;
1055      vassert(iregNo < 32);
1056      return IRExpr_Get(integerGuestRegOffset(iregNo), ty);
1057   }
1058}
1059
1060static IRExpr *getHI(void)
1061{
1062   if (mode64)
1063      return IRExpr_Get(offsetof(VexGuestMIPS64State, guest_HI), Ity_I64);
1064   else
1065      return IRExpr_Get(offsetof(VexGuestMIPS32State, guest_HI), Ity_I32);
1066}
1067
1068static IRExpr *getLO(void)
1069{
1070   if (mode64)
1071      return IRExpr_Get(offsetof(VexGuestMIPS64State, guest_LO), Ity_I64);
1072   else
1073      return IRExpr_Get(offsetof(VexGuestMIPS32State, guest_LO), Ity_I32);
1074}
1075
1076static IRExpr *getFCSR(void)
1077{
1078   if (mode64)
1079      return IRExpr_Get(offsetof(VexGuestMIPS64State, guest_FCSR), Ity_I32);
1080   else
1081      return IRExpr_Get(offsetof(VexGuestMIPS32State, guest_FCSR), Ity_I32);
1082}
1083
1084/* Get byte from register reg, byte pos from 0 to 3 (or 7 for MIPS64) . */
1085static IRExpr *getByteFromReg(UInt reg, UInt byte_pos)
1086{
1087  UInt pos = byte_pos * 8;
1088  if (mode64)
1089      return unop(Iop_64to8, binop(Iop_And64,
1090                                   binop(Iop_Shr64, getIReg(reg), mkU8(pos)),
1091                                   mkU64(0xFF)));
1092   else
1093      return unop(Iop_32to8, binop(Iop_And32,
1094                                   binop(Iop_Shr32, getIReg(reg), mkU8(pos)),
1095                                   mkU32(0xFF)));
1096}
1097
1098static void putFCSR(IRExpr * e)
1099{
1100   if (mode64)
1101      stmt(IRStmt_Put(offsetof(VexGuestMIPS64State, guest_FCSR), e));
1102   else
1103      stmt(IRStmt_Put(offsetof(VexGuestMIPS32State, guest_FCSR), e));
1104}
1105
1106/* fs   - fpu source register number.
1107   inst - fpu instruction that needs to be executed.
1108   sz32 - size of source register.
1109   opN  - number of operads:
1110          1 - unary operation.
1111          2 - binary operation. */
1112static void calculateFCSR(UInt fs, UInt ft, UInt inst, Bool sz32, UInt opN)
1113{
1114   IRDirty *d;
1115   IRTemp fcsr = newTemp(Ity_I32);
1116   /* IRExpr_BBPTR() => Need to pass pointer to guest state to helper. */
1117   if (fp_mode64)
1118      d = unsafeIRDirty_1_N(fcsr, 0,
1119                            "mips_dirtyhelper_calculate_FCSR_fp64",
1120                            &mips_dirtyhelper_calculate_FCSR_fp64,
1121                            mkIRExprVec_4(IRExpr_BBPTR(),
1122                                          mkU32(fs),
1123                                          mkU32(ft),
1124                                          mkU32(inst)));
1125   else
1126      d = unsafeIRDirty_1_N(fcsr, 0,
1127                            "mips_dirtyhelper_calculate_FCSR_fp32",
1128                            &mips_dirtyhelper_calculate_FCSR_fp32,
1129                            mkIRExprVec_4(IRExpr_BBPTR(),
1130                                          mkU32(fs),
1131                                          mkU32(ft),
1132                                          mkU32(inst)));
1133
1134   if (opN == 1) {  /* Unary operation. */
1135      /* Declare we're reading guest state. */
1136      if (sz32 || fp_mode64)
1137         d->nFxState = 2;
1138      else
1139         d->nFxState = 3;
1140      vex_bzero(&d->fxState, sizeof(d->fxState));
1141
1142      d->fxState[0].fx     = Ifx_Read;  /* read */
1143      if (mode64)
1144         d->fxState[0].offset = offsetof(VexGuestMIPS64State, guest_FCSR);
1145      else
1146         d->fxState[0].offset = offsetof(VexGuestMIPS32State, guest_FCSR);
1147      d->fxState[0].size   = sizeof(UInt);
1148      d->fxState[1].fx     = Ifx_Read;  /* read */
1149      d->fxState[1].offset = floatGuestRegOffset(fs);
1150      d->fxState[1].size   = sizeof(ULong);
1151
1152      if (!(sz32 || fp_mode64)) {
1153         d->fxState[2].fx     = Ifx_Read;  /* read */
1154         d->fxState[2].offset = floatGuestRegOffset(fs+1);
1155         d->fxState[2].size   = sizeof(ULong);
1156      }
1157   } else if (opN == 2) {  /* Binary operation. */
1158      /* Declare we're reading guest state. */
1159      if (sz32 || fp_mode64)
1160         d->nFxState = 3;
1161      else
1162         d->nFxState = 5;
1163      vex_bzero(&d->fxState, sizeof(d->fxState));
1164
1165      d->fxState[0].fx     = Ifx_Read;  /* read */
1166      if (mode64)
1167         d->fxState[0].offset = offsetof(VexGuestMIPS64State, guest_FCSR);
1168      else
1169         d->fxState[0].offset = offsetof(VexGuestMIPS32State, guest_FCSR);
1170      d->fxState[0].size   = sizeof(UInt);
1171      d->fxState[1].fx     = Ifx_Read;  /* read */
1172      d->fxState[1].offset = floatGuestRegOffset(fs);
1173      d->fxState[1].size   = sizeof(ULong);
1174      d->fxState[2].fx     = Ifx_Read;  /* read */
1175      d->fxState[2].offset = floatGuestRegOffset(ft);
1176      d->fxState[2].size   = sizeof(ULong);
1177
1178      if (!(sz32 || fp_mode64)) {
1179         d->fxState[3].fx     = Ifx_Read;  /* read */
1180         d->fxState[3].offset = floatGuestRegOffset(fs+1);
1181         d->fxState[3].size   = sizeof(ULong);
1182         d->fxState[4].fx     = Ifx_Read;  /* read */
1183         d->fxState[4].offset = floatGuestRegOffset(ft+1);
1184         d->fxState[4].size   = sizeof(ULong);
1185      }
1186   }
1187
1188   stmt(IRStmt_Dirty(d));
1189
1190   putFCSR(mkexpr(fcsr));
1191}
1192
1193static IRExpr *getULR(void)
1194{
1195   if (mode64)
1196      return IRExpr_Get(offsetof(VexGuestMIPS64State, guest_ULR), Ity_I64);
1197   else
1198      return IRExpr_Get(offsetof(VexGuestMIPS32State, guest_ULR), Ity_I32);
1199}
1200
1201static void putIReg(UInt archreg, IRExpr * e)
1202{
1203   IRType ty = mode64 ? Ity_I64 : Ity_I32;
1204   vassert(archreg < 32);
1205   vassert(typeOfIRExpr(irsb->tyenv, e) == ty);
1206   if (archreg != 0)
1207      stmt(IRStmt_Put(integerGuestRegOffset(archreg), e));
1208}
1209
1210static IRExpr *mkNarrowTo32(IRType ty, IRExpr * src)
1211{
1212   vassert(ty == Ity_I32 || ty == Ity_I64);
1213   return ty == Ity_I64 ? unop(Iop_64to32, src) : src;
1214}
1215
1216static void putLO(IRExpr * e)
1217{
1218   if (mode64) {
1219      stmt(IRStmt_Put(offsetof(VexGuestMIPS64State, guest_LO), e));
1220   } else {
1221      stmt(IRStmt_Put(offsetof(VexGuestMIPS32State, guest_LO), e));
1222   /* Add value to lower 32 bits of ac0 to maintain compatibility between
1223      regular MIPS32 instruction set and MIPS DSP ASE. Keep higher 32bits
1224      unchanged. */
1225      IRTemp t_lo = newTemp(Ity_I32);
1226      IRTemp t_hi = newTemp(Ity_I32);
1227      assign(t_lo, e);
1228      assign(t_hi, unop(Iop_64HIto32, getAcc(0)));
1229      stmt(IRStmt_Put(accumulatorGuestRegOffset(0),
1230           binop(Iop_32HLto64, mkexpr(t_hi), mkexpr(t_lo))));
1231   }
1232}
1233
1234static void putHI(IRExpr * e)
1235{
1236   if (mode64) {
1237      stmt(IRStmt_Put(offsetof(VexGuestMIPS64State, guest_HI), e));
1238   } else {
1239      stmt(IRStmt_Put(offsetof(VexGuestMIPS32State, guest_HI), e));
1240   /* Add value to higher 32 bits of ac0 to maintain compatibility between
1241      regular MIPS32 instruction set and MIPS DSP ASE. Keep lower 32bits
1242      unchanged. */
1243      IRTemp t_lo = newTemp(Ity_I32);
1244      IRTemp t_hi = newTemp(Ity_I32);
1245      assign(t_hi, e);
1246      assign(t_lo, unop(Iop_64to32, getAcc(0)));
1247      stmt(IRStmt_Put(accumulatorGuestRegOffset(0),
1248           binop(Iop_32HLto64, mkexpr(t_hi), mkexpr(t_lo))));
1249   }
1250}
1251
1252/* Put value to accumulator(helper function for MIPS32 DSP ASE instructions). */
1253static void putAcc(UInt acNo, IRExpr * e)
1254{
1255   vassert(!mode64);
1256   vassert(acNo <= 3);
1257   vassert(typeOfIRExpr(irsb->tyenv, e) == Ity_I64);
1258   stmt(IRStmt_Put(accumulatorGuestRegOffset(acNo), e));
1259/* If acNo = 0, split value to HI and LO regs in order to maintain compatibility
1260   between MIPS32 and MIPS DSP ASE insn sets. */
1261   if (0 == acNo) {
1262     putLO(unop(Iop_64to32, e));
1263     putHI(unop(Iop_64HIto32, e));
1264   }
1265}
1266
1267static IRExpr *mkNarrowTo8 ( IRType ty, IRExpr * src )
1268{
1269   vassert(ty == Ity_I32 || ty == Ity_I64);
1270   return ty == Ity_I64 ? unop(Iop_64to8, src) : unop(Iop_32to8, src);
1271}
1272
1273static void putPC(IRExpr * e)
1274{
1275   stmt(IRStmt_Put(OFFB_PC, e));
1276}
1277
1278static IRExpr *mkWidenFrom32(IRType ty, IRExpr * src, Bool sined)
1279{
1280   vassert(ty == Ity_I32 || ty == Ity_I64);
1281   if (ty == Ity_I32)
1282      return src;
1283   return (sined) ? unop(Iop_32Sto64, src) : unop(Iop_32Uto64, src);
1284}
1285
1286/* Narrow 8/16/32 bit int expr to 8/16/32.  Clearly only some
1287   of these combinations make sense. */
1288static IRExpr *narrowTo(IRType dst_ty, IRExpr * e)
1289{
1290   IRType src_ty = typeOfIRExpr(irsb->tyenv, e);
1291   if (src_ty == dst_ty)
1292      return e;
1293   if (src_ty == Ity_I32 && dst_ty == Ity_I16)
1294      return unop(Iop_32to16, e);
1295   if (src_ty == Ity_I32 && dst_ty == Ity_I8)
1296      return unop(Iop_32to8, e);
1297   if (src_ty == Ity_I64 && dst_ty == Ity_I8) {
1298      vassert(mode64);
1299      return unop(Iop_64to8, e);
1300   }
1301   if (src_ty == Ity_I64 && dst_ty == Ity_I16) {
1302      vassert(mode64);
1303      return unop(Iop_64to16, e);
1304   }
1305   vpanic("narrowTo(mips)");
1306   return 0;
1307}
1308
1309static IRExpr *getLoFromF64(IRType ty, IRExpr * src)
1310{
1311   vassert(ty == Ity_F32 || ty == Ity_F64);
1312   if (ty == Ity_F64) {
1313      IRTemp t0, t1;
1314      t0 = newTemp(Ity_I64);
1315      t1 = newTemp(Ity_I32);
1316      assign(t0, unop(Iop_ReinterpF64asI64, src));
1317      assign(t1, unop(Iop_64to32, mkexpr(t0)));
1318      return unop(Iop_ReinterpI32asF32, mkexpr(t1));
1319   } else
1320      return src;
1321}
1322
1323static IRExpr *mkWidenFromF32(IRType ty, IRExpr * src)
1324{
1325   vassert(ty == Ity_F32 || ty == Ity_F64);
1326   if (ty == Ity_F64) {
1327      IRTemp t0 = newTemp(Ity_I32);
1328      IRTemp t1 = newTemp(Ity_I64);
1329      assign(t0, unop(Iop_ReinterpF32asI32, src));
1330      assign(t1, binop(Iop_32HLto64, mkU32(0x0), mkexpr(t0)));
1331      return unop(Iop_ReinterpI64asF64, mkexpr(t1));
1332   } else
1333      return src;
1334}
1335
1336static IRExpr *dis_branch_likely(IRExpr * guard, UInt imm)
1337{
1338   ULong branch_offset;
1339   IRTemp t0;
1340
1341   /* PC = PC + (SignExtend(signed_immed_24) << 2)
1342      An 18-bit signed offset (the 16-bit offset field shifted left 2 bits)
1343      is added to the address of the instruction following
1344      the branch (not the branch itself), in the branch delay slot, to form
1345      a PC-relative effective target address. */
1346   if (mode64)
1347      branch_offset = extend_s_18to64(imm << 2);
1348   else
1349      branch_offset = extend_s_18to32(imm << 2);
1350
1351   t0 = newTemp(Ity_I1);
1352   assign(t0, guard);
1353
1354   if (mode64)
1355      stmt(IRStmt_Exit(mkexpr(t0), Ijk_Boring,
1356                       IRConst_U64(guest_PC_curr_instr + 8), OFFB_PC));
1357   else
1358      stmt(IRStmt_Exit(mkexpr(t0), Ijk_Boring,
1359                       IRConst_U32(guest_PC_curr_instr + 8), OFFB_PC));
1360
1361   irsb->jumpkind = Ijk_Boring;
1362
1363   if (mode64)
1364      return mkU64(guest_PC_curr_instr + 4 + branch_offset);
1365   else
1366      return mkU32(guest_PC_curr_instr + 4 + branch_offset);
1367}
1368
1369static void dis_branch(Bool link, IRExpr * guard, UInt imm, IRStmt ** set)
1370{
1371   ULong branch_offset;
1372   IRTemp t0;
1373
1374   if (link) {  /* LR (GPR31) = addr of the 2nd instr after branch instr */
1375      if (mode64)
1376         putIReg(31, mkU64(guest_PC_curr_instr + 8));
1377      else
1378         putIReg(31, mkU32(guest_PC_curr_instr + 8));
1379   }
1380
1381   /* PC = PC + (SignExtend(signed_immed_24) << 2)
1382      An 18-bit signed offset (the 16-bit offset field shifted left 2 bits)
1383      is added to the address of the instruction following
1384      the branch (not the branch itself), in the branch delay slot, to form
1385      a PC-relative effective target address. */
1386
1387   if (mode64)
1388      branch_offset = extend_s_18to64(imm << 2);
1389   else
1390      branch_offset = extend_s_18to32(imm << 2);
1391
1392   t0 = newTemp(Ity_I1);
1393   assign(t0, guard);
1394   if (mode64)
1395      *set = IRStmt_Exit(mkexpr(t0), link ? Ijk_Call : Ijk_Boring,
1396                         IRConst_U64(guest_PC_curr_instr + 4 + branch_offset),
1397                         OFFB_PC);
1398   else
1399      *set = IRStmt_Exit(mkexpr(t0), link ? Ijk_Call : Ijk_Boring,
1400                         IRConst_U32(guest_PC_curr_instr + 4 +
1401                                     (UInt) branch_offset), OFFB_PC);
1402}
1403
1404static IRExpr *getFReg(UInt fregNo)
1405{
1406   vassert(fregNo < 32);
1407   IRType ty = fp_mode64 ? Ity_F64 : Ity_F32;
1408   return IRExpr_Get(floatGuestRegOffset(fregNo), ty);
1409}
1410
1411static IRExpr *getDReg(UInt dregNo)
1412{
1413   vassert(dregNo < 32);
1414   if (fp_mode64) {
1415      return IRExpr_Get(floatGuestRegOffset(dregNo), Ity_F64);
1416   } else {
1417      /* Read a floating point register pair and combine their contents into a
1418         64-bit value */
1419      IRTemp t0 = newTemp(Ity_F32);
1420      IRTemp t1 = newTemp(Ity_F32);
1421      IRTemp t2 = newTemp(Ity_F64);
1422      IRTemp t3 = newTemp(Ity_I32);
1423      IRTemp t4 = newTemp(Ity_I32);
1424      IRTemp t5 = newTemp(Ity_I64);
1425
1426      assign(t0, getFReg(dregNo));
1427      assign(t1, getFReg(dregNo + 1));
1428
1429      assign(t3, unop(Iop_ReinterpF32asI32, mkexpr(t0)));
1430      assign(t4, unop(Iop_ReinterpF32asI32, mkexpr(t1)));
1431      assign(t5, binop(Iop_32HLto64, mkexpr(t4), mkexpr(t3)));
1432      assign(t2, unop(Iop_ReinterpI64asF64, mkexpr(t5)));
1433
1434      return mkexpr(t2);
1435   }
1436}
1437
1438static void putFReg(UInt dregNo, IRExpr * e)
1439{
1440   vassert(dregNo < 32);
1441   IRType ty = fp_mode64 ? Ity_F64 : Ity_F32;
1442   vassert(typeOfIRExpr(irsb->tyenv, e) == ty);
1443   stmt(IRStmt_Put(floatGuestRegOffset(dregNo), e));
1444}
1445
1446static void putDReg(UInt dregNo, IRExpr * e)
1447{
1448   if (fp_mode64) {
1449      vassert(dregNo < 32);
1450      IRType ty = Ity_F64;
1451      vassert(typeOfIRExpr(irsb->tyenv, e) == ty);
1452      stmt(IRStmt_Put(floatGuestRegOffset(dregNo), e));
1453   } else {
1454      vassert(dregNo < 32);
1455      vassert(typeOfIRExpr(irsb->tyenv, e) == Ity_F64);
1456      IRTemp t1 = newTemp(Ity_F64);
1457      IRTemp t4 = newTemp(Ity_I32);
1458      IRTemp t5 = newTemp(Ity_I32);
1459      IRTemp t6 = newTemp(Ity_I64);
1460      assign(t1, e);
1461      assign(t6, unop(Iop_ReinterpF64asI64, mkexpr(t1)));
1462      assign(t4, unop(Iop_64HIto32, mkexpr(t6)));  /* hi */
1463      assign(t5, unop(Iop_64to32, mkexpr(t6)));    /* lo */
1464      putFReg(dregNo, unop(Iop_ReinterpI32asF32, mkexpr(t5)));
1465      putFReg(dregNo + 1, unop(Iop_ReinterpI32asF32, mkexpr(t4)));
1466   }
1467}
1468
1469static void setFPUCondCode(IRExpr * e, UInt cc)
1470{
1471   if (cc == 0) {
1472      putFCSR(binop(Iop_And32, getFCSR(), mkU32(0xFF7FFFFF)));
1473      putFCSR(binop(Iop_Or32, getFCSR(), binop(Iop_Shl32, e, mkU8(23))));
1474   } else {
1475      putFCSR(binop(Iop_And32, getFCSR(), unop(Iop_Not32,
1476                               binop(Iop_Shl32, mkU32(0x01000000), mkU8(cc)))));
1477      putFCSR(binop(Iop_Or32, getFCSR(), binop(Iop_Shl32, e, mkU8(24 + cc))));
1478   }
1479}
1480
1481static IRExpr* get_IR_roundingmode ( void )
1482{
1483/*
1484   rounding mode | MIPS | IR
1485   ------------------------
1486   to nearest    | 00  | 00
1487   to zero       | 01  | 11
1488   to +infinity  | 10  | 10
1489   to -infinity  | 11  | 01
1490*/
1491   IRTemp rm_MIPS = newTemp(Ity_I32);
1492   /* Last two bits in FCSR are rounding mode. */
1493
1494   if (mode64)
1495      assign(rm_MIPS, binop(Iop_And32, IRExpr_Get(offsetof(VexGuestMIPS64State,
1496                                       guest_FCSR), Ity_I32), mkU32(3)));
1497   else
1498      assign(rm_MIPS, binop(Iop_And32, IRExpr_Get(offsetof(VexGuestMIPS32State,
1499                                       guest_FCSR), Ity_I32), mkU32(3)));
1500
1501   /* rm_IR = XOR( rm_MIPS32, (rm_MIPS32 << 1) & 2) */
1502
1503   return binop(Iop_Xor32, mkexpr(rm_MIPS), binop(Iop_And32,
1504                binop(Iop_Shl32, mkexpr(rm_MIPS), mkU8(1)), mkU32(2)));
1505}
1506
1507/* sz, ULong -> IRExpr */
1508static IRExpr *mkSzImm ( IRType ty, ULong imm64 )
1509{
1510   vassert(ty == Ity_I32 || ty == Ity_I64);
1511   return ty == Ity_I64 ? mkU64(imm64) : mkU32((UInt) imm64);
1512}
1513
1514static IRConst *mkSzConst ( IRType ty, ULong imm64 )
1515{
1516   vassert(ty == Ity_I32 || ty == Ity_I64);
1517   return (ty == Ity_I64 ? IRConst_U64(imm64) : IRConst_U32((UInt) imm64));
1518}
1519
1520/* Make sure we get valid 32 and 64bit addresses */
1521static Addr64 mkSzAddr ( IRType ty, Addr64 addr )
1522{
1523   vassert(ty == Ity_I32 || ty == Ity_I64);
1524   return (ty == Ity_I64 ? (Addr64) addr :
1525                           (Addr64) extend_s_32to64(toUInt(addr)));
1526}
1527
1528/* Shift and Rotate instructions for MIPS64 */
1529static Bool dis_instr_shrt ( UInt theInstr )
1530{
1531   UInt opc2 = get_function(theInstr);
1532   UChar regRs = get_rs(theInstr);
1533   UChar regRt = get_rt(theInstr);
1534   UChar regRd = get_rd(theInstr);
1535   UChar uImmsa = get_sa(theInstr);
1536   Long sImmsa = extend_s_16to64(uImmsa);
1537   IRType ty = mode64 ? Ity_I64 : Ity_I32;
1538   IRTemp tmp = newTemp(ty);
1539   IRTemp tmpOr = newTemp(ty);
1540   IRTemp tmpRt = newTemp(ty);
1541   IRTemp tmpRs = newTemp(ty);
1542   IRTemp tmpRd = newTemp(ty);
1543
1544   assign(tmpRs, getIReg(regRs));
1545   assign(tmpRt, getIReg(regRt));
1546
1547   switch (opc2) {
1548      case 0x3A:
1549         if ((regRs & 0x01) == 0) {
1550            /* Doubleword Shift Right Logical - DSRL; MIPS64 */
1551            DIP("dsrl r%u, r%u, %d", regRd, regRt, (Int)sImmsa);
1552            assign(tmpRd, binop(Iop_Shr64, mkexpr(tmpRt), mkU8(uImmsa)));
1553            putIReg(regRd, mkexpr(tmpRd));
1554         } else if ((regRs & 0x01) == 1) {
1555            /* Doubleword Rotate Right - DROTR; MIPS64r2 */
1556            vassert(mode64);
1557            DIP("drotr r%u, r%u, %d", regRd, regRt, (Int)sImmsa);
1558            IRTemp tmpL = newTemp(ty);
1559            IRTemp tmpR = newTemp(ty);
1560            assign(tmpR, binop(Iop_Shr64, mkexpr(tmpRt), mkU8(uImmsa)));
1561            assign(tmp, binop(Iop_Shl64, mkexpr(tmpRt), mkU8(63 - uImmsa)));
1562            assign(tmpL, binop(Iop_Shl64, mkexpr(tmp), mkU8(1)));
1563            assign(tmpRd, binop(Iop_Or64, mkexpr(tmpL), mkexpr(tmpR)));
1564            putIReg(regRd, mkexpr(tmpRd));
1565         } else
1566            return False;
1567         break;
1568
1569      case 0x3E:
1570         if ((regRs & 0x01) == 0) {
1571            /* Doubleword Shift Right Logical Plus 32 - DSRL32; MIPS64 */
1572            DIP("dsrl32 r%u, r%u, %d", regRd, regRt, (Int)(sImmsa + 32));
1573            assign(tmpRd, binop(Iop_Shr64, mkexpr(tmpRt), mkU8(uImmsa + 32)));
1574            putIReg(regRd, mkexpr(tmpRd));
1575         } else if ((regRs & 0x01) == 1) {
1576            /* Doubleword Rotate Right Plus 32 - DROTR32; MIPS64r2 */
1577            DIP("drotr32 r%u, r%u, %d", regRd, regRt, (Int)sImmsa);
1578            vassert(mode64);
1579            IRTemp tmpL = newTemp(ty);
1580            IRTemp tmpR = newTemp(ty);
1581            /* (tmpRt >> sa) | (tmpRt << (64 - sa)) */
1582            assign(tmpR, binop(Iop_Shr64, mkexpr(tmpRt), mkU8(uImmsa + 32)));
1583            assign(tmp, binop(Iop_Shl64, mkexpr(tmpRt),
1584                              mkU8(63 - (uImmsa + 32))));
1585            assign(tmpL, binop(Iop_Shl64, mkexpr(tmp), mkU8(1)));
1586            assign(tmpRd, binop(Iop_Or64, mkexpr(tmpL), mkexpr(tmpR)));
1587            putIReg(regRd, mkexpr(tmpRd));
1588         } else
1589            return False;
1590         break;
1591
1592      case 0x16:
1593         if ((uImmsa & 0x01) == 0) {
1594            /* Doubleword Shift Right Logical Variable - DSRLV; MIPS64 */
1595            DIP("dsrlv r%u, r%u, r%u", regRd, regRt, regRs);
1596            IRTemp tmpRs8 = newTemp(Ity_I8);
1597            /* s = tmpRs[5..0] */
1598            assign(tmp, binop(Iop_And64, mkexpr(tmpRs), mkU64(63)));
1599            assign(tmpRs8, mkNarrowTo8(ty, mkexpr(tmp)));
1600            assign(tmpRd, binop(Iop_Shr64, mkexpr(tmpRt), mkexpr(tmpRs8)));
1601            putIReg(regRd, mkexpr(tmpRd));
1602         } else if ((uImmsa & 0x01) == 1) {
1603            /* Doubleword Rotate Right Variable - DROTRV; MIPS64r2 */
1604            DIP("drotrv r%u, r%u, r%u", regRd, regRt, regRs);
1605            IRTemp tmpL = newTemp(ty);
1606            IRTemp tmpR = newTemp(ty);
1607            IRTemp tmpRs8 = newTemp(Ity_I8);
1608            IRTemp tmpLs8 = newTemp(Ity_I8);
1609            IRTemp tmp64 = newTemp(ty);
1610            /* s = tmpRs[5...0]
1611               m = 64 - s
1612               (tmpRt << s) | (tmpRt >> m) */
1613
1614            assign(tmp64, binop(Iop_And64, mkexpr(tmpRs), mkSzImm(ty, 63)));
1615            assign(tmp, binop(Iop_Sub64, mkU64(63), mkexpr(tmp64)));
1616
1617            assign(tmpLs8, mkNarrowTo8(ty, mkexpr(tmp)));
1618            assign(tmpRs8, mkNarrowTo8(ty, mkexpr(tmp64)));
1619
1620            assign(tmpR, binop(Iop_Shr64, mkexpr(tmpRt), mkexpr(tmpRs8)));
1621            assign(tmpL, binop(Iop_Shl64, mkexpr(tmpRt), mkexpr(tmpLs8)));
1622            assign(tmpRd, binop(Iop_Shl64, mkexpr(tmpL), mkU8(1)));
1623            assign(tmpOr, binop(Iop_Or64, mkexpr(tmpRd), mkexpr(tmpR)));
1624
1625            putIReg(regRd, mkexpr(tmpOr));
1626         } else
1627            return False;
1628         break;
1629
1630      case 0x38:  /* Doubleword Shift Left Logical - DSLL; MIPS64 */
1631         DIP("dsll r%u, r%u, %d", regRd, regRt, (Int)sImmsa);
1632         vassert(mode64);
1633         assign(tmpRd, binop(Iop_Shl64, mkexpr(tmpRt), mkU8(uImmsa)));
1634         putIReg(regRd, mkexpr(tmpRd));
1635         break;
1636
1637      case 0x3C:  /* Doubleword Shift Left Logical Plus 32 - DSLL32; MIPS64 */
1638         DIP("dsll32 r%u, r%u, %d", regRd, regRt, (Int)sImmsa);
1639         assign(tmpRd, binop(Iop_Shl64, mkexpr(tmpRt), mkU8(uImmsa + 32)));
1640         putIReg(regRd, mkexpr(tmpRd));
1641         break;
1642
1643      case 0x14: {  /* Doubleword Shift Left Logical Variable - DSLLV; MIPS64 */
1644         DIP("dsllv r%u, r%u, r%u", regRd, regRt, regRs);
1645         IRTemp tmpRs8 = newTemp(Ity_I8);
1646
1647         assign(tmp, binop(Iop_And64, mkexpr(tmpRs), mkSzImm(ty, 63)));
1648         assign(tmpRs8, mkNarrowTo8(ty, mkexpr(tmp)));
1649         assign(tmpRd, binop(Iop_Shl64, mkexpr(tmpRt), mkexpr(tmpRs8)));
1650         putIReg(regRd, mkexpr(tmpRd));
1651         break;
1652      }
1653
1654      case 0x3B:  /* Doubleword Shift Right Arithmetic - DSRA; MIPS64 */
1655         DIP("dsra r%u, r%u, %d", regRd, regRt, (Int)sImmsa);
1656         assign(tmpRd, binop(Iop_Sar64, mkexpr(tmpRt), mkU8(uImmsa)));
1657         putIReg(regRd, mkexpr(tmpRd));
1658         break;
1659
1660      case 0x3F:  /* Doubleword Shift Right Arithmetic Plus 32 - DSRA32;
1661                     MIPS64 */
1662         DIP("dsra32 r%u, r%u, %d", regRd, regRt, (Int)sImmsa);
1663         assign(tmpRd, binop(Iop_Sar64, mkexpr(tmpRt), mkU8(uImmsa + 32)));
1664         putIReg(regRd, mkexpr(tmpRd));
1665         break;
1666
1667      case 0x17: {  /* Doubleword Shift Right Arithmetic Variable - DSRAV;
1668                       MIPS64 */
1669         DIP("dsrav r%u, r%u, r%u", regRd, regRt, regRs);
1670         IRTemp tmpRs8 = newTemp(Ity_I8);
1671         assign(tmp, binop(Iop_And64, mkexpr(tmpRs), mkSzImm(ty, 63)));
1672         assign(tmpRs8, mkNarrowTo8(ty, mkexpr(tmp)));
1673         assign(tmpRd, binop(Iop_Sar64, mkexpr(tmpRt), mkexpr(tmpRs8)));
1674         putIReg(regRd, mkexpr(tmpRd));
1675         break;
1676
1677      }
1678
1679      default:
1680         return False;
1681
1682   }
1683   return True;
1684}
1685
1686static IROp mkSzOp ( IRType ty, IROp op8 )
1687{
1688   Int adj;
1689   vassert(ty == Ity_I8 || ty == Ity_I16 || ty == Ity_I32 || ty == Ity_I64);
1690   vassert(op8 == Iop_Add8 || op8 == Iop_Sub8 || op8 == Iop_Mul8
1691           || op8 == Iop_Or8 || op8 == Iop_And8 || op8 == Iop_Xor8
1692           || op8 == Iop_Shl8 || op8 == Iop_Shr8 || op8 == Iop_Sar8
1693           || op8 == Iop_CmpEQ8 || op8 == Iop_CmpNE8 || op8 == Iop_Not8);
1694   adj = ty == Ity_I8 ? 0 : (ty == Ity_I16 ? 1 : (ty == Ity_I32 ? 2 : 3));
1695   return adj + op8;
1696}
1697
1698/*********************************************************/
1699/*---             Floating Point Compare              ---*/
1700/*********************************************************/
1701/* Function that returns a string that represent mips cond
1702   mnemonic for the input code. */
1703static const HChar* showCondCode(UInt code) {
1704   const HChar* ret;
1705   switch (code) {
1706      case 0: ret = "f"; break;
1707      case 1: ret = "un"; break;
1708      case 2: ret = "eq"; break;
1709      case 3: ret = "ueq"; break;
1710      case 4: ret = "olt"; break;
1711      case 5: ret = "ult"; break;
1712      case 6: ret = "ole"; break;
1713      case 7: ret = "ule"; break;
1714      case 8: ret = "sf"; break;
1715      case 9: ret = "ngle"; break;
1716      case 10: ret = "seq"; break;
1717      case 11: ret = "ngl"; break;
1718      case 12: ret = "lt"; break;
1719      case 13: ret = "nge"; break;
1720      case 14: ret = "le"; break;
1721      case 15: ret = "ngt"; break;
1722      default: vpanic("showCondCode"); break;
1723   }
1724   return ret;
1725}
1726
1727static Bool dis_instr_CCondFmt ( UInt cins )
1728{
1729   IRTemp t0, t1, t2, t3, tmp5, tmp6;
1730   IRTemp ccIR = newTemp(Ity_I32);
1731   IRTemp ccMIPS = newTemp(Ity_I32);
1732   UInt FC = get_FC(cins);
1733   UInt fmt = get_fmt(cins);
1734   UInt fs = get_fs(cins);
1735   UInt ft = get_ft(cins);
1736   UInt cond = get_cond(cins);
1737
1738   if (FC == 0x3) {  /* C.cond.fmt */
1739      UInt fpc_cc = get_fpc_cc(cins);
1740      switch (fmt) {
1741         case 0x10: {  /* C.cond.S */
1742            DIP("c.%s.s %d, f%d, f%d", showCondCode(cond), fpc_cc, fs, ft);
1743            if (fp_mode64) {
1744               t0 = newTemp(Ity_I32);
1745               t1 = newTemp(Ity_I32);
1746               t2 = newTemp(Ity_I32);
1747               t3 = newTemp(Ity_I32);
1748
1749               tmp5 = newTemp(Ity_F64);
1750               tmp6 = newTemp(Ity_F64);
1751
1752               assign(tmp5, unop(Iop_F32toF64, getLoFromF64(Ity_F64,
1753                                 getFReg(fs))));
1754               assign(tmp6, unop(Iop_F32toF64, getLoFromF64(Ity_F64,
1755                                 getFReg(ft))));
1756
1757               assign(ccIR, binop(Iop_CmpF64, mkexpr(tmp5), mkexpr(tmp6)));
1758               putHI(mkWidenFrom32(mode64 ? Ity_I64: Ity_I32,
1759                                   mkexpr(ccIR), True));
1760               /* Map compare result from IR to MIPS
1761                  FP cmp result | MIPS | IR
1762                  --------------------------
1763                  UN            | 0x1 | 0x45
1764                  EQ            | 0x2 | 0x40
1765                  GT            | 0x4 | 0x00
1766                  LT            | 0x8 | 0x01
1767                */
1768
1769               /* ccMIPS = Shl(1, (~(ccIR>>5) & 2) | ((ccIR ^ (ccIR>>6)) & 1) */
1770               assign(ccMIPS, binop(Iop_Shl32, mkU32(1), unop(Iop_32to8,
1771                              binop(Iop_Or32, binop(Iop_And32, unop(Iop_Not32,
1772                              binop(Iop_Shr32, mkexpr(ccIR),mkU8(5))),mkU32(2)),
1773                              binop(Iop_And32, binop(Iop_Xor32, mkexpr(ccIR),
1774                              binop(Iop_Shr32, mkexpr(ccIR), mkU8(6))),
1775                              mkU32(1))))));
1776               putLO(mkWidenFrom32(mode64 ? Ity_I64: Ity_I32,
1777                                   mkexpr(ccMIPS), True));
1778
1779               /* UN */
1780               assign(t0, binop(Iop_And32, mkexpr(ccMIPS), mkU32(0x1)));
1781               /* EQ */
1782               assign(t1, binop(Iop_And32, binop(Iop_Shr32, mkexpr(ccMIPS),
1783                                                 mkU8(0x1)), mkU32(0x1)));
1784               /* NGT */
1785               assign(t2, binop(Iop_And32, unop(Iop_Not32, binop(Iop_Shr32,
1786                                 mkexpr(ccMIPS), mkU8(0x2))),mkU32(0x1)));
1787               /* LT */
1788               assign(t3, binop(Iop_And32, binop(Iop_Shr32, mkexpr(ccMIPS),
1789                                                 mkU8(0x3)), mkU32(0x1)));
1790               switch (cond) {
1791                  case 0x0:
1792                     setFPUCondCode(mkU32(0), fpc_cc);
1793                     break;
1794                  case 0x1:
1795                     setFPUCondCode(mkexpr(t0), fpc_cc);
1796                     break;
1797                  case 0x2:
1798                     setFPUCondCode(mkexpr(t1), fpc_cc);
1799                     break;
1800                  case 0x3:
1801                     setFPUCondCode(binop(Iop_Or32, mkexpr(t0), mkexpr(t1)),
1802                                          fpc_cc);
1803                     break;
1804                  case 0x4:
1805                     setFPUCondCode(mkexpr(t3), fpc_cc);
1806                     break;
1807                  case 0x5:
1808                     setFPUCondCode(binop(Iop_Or32, mkexpr(t0), mkexpr(t3)),
1809                                          fpc_cc);
1810                     break;
1811                  case 0x6:
1812                     setFPUCondCode(binop(Iop_Or32, mkexpr(t3), mkexpr(t1)),
1813                                          fpc_cc);
1814                     break;
1815                  case 0x7:
1816                     setFPUCondCode(mkexpr(t2), fpc_cc);
1817                     break;
1818                  case 0x8:
1819                     setFPUCondCode(mkU32(0), fpc_cc);
1820                     break;
1821                  case 0x9:
1822                     setFPUCondCode(mkexpr(t0), fpc_cc);
1823                     break;
1824                  case 0xA:
1825                     setFPUCondCode(mkexpr(t1), fpc_cc);
1826                     break;
1827                  case 0xB:
1828                     setFPUCondCode(binop(Iop_Or32, mkexpr(t0), mkexpr(t1)),
1829                                          fpc_cc);
1830                     break;
1831                  case 0xC:
1832                     setFPUCondCode(mkexpr(t3), fpc_cc);
1833                     break;
1834                  case 0xD:
1835                     setFPUCondCode(binop(Iop_Or32, mkexpr(t0), mkexpr(t3)),
1836                                          fpc_cc);
1837                     break;
1838                  case 0xE:
1839                     setFPUCondCode(binop(Iop_Or32, mkexpr(t3), mkexpr(t1)),
1840                                          fpc_cc);
1841                     break;
1842                  case 0xF:
1843                     setFPUCondCode(mkexpr(t2), fpc_cc);
1844                     break;
1845
1846                  default:
1847                     return False;
1848               }
1849
1850            } else {
1851               t0 = newTemp(Ity_I32);
1852               t1 = newTemp(Ity_I32);
1853               t2 = newTemp(Ity_I32);
1854               t3 = newTemp(Ity_I32);
1855
1856               assign(ccIR, binop(Iop_CmpF64, unop(Iop_F32toF64, getFReg(fs)),
1857                                  unop(Iop_F32toF64, getFReg(ft))));
1858               /* Map compare result from IR to MIPS
1859                  FP cmp result | MIPS | IR
1860                  --------------------------
1861                  UN            | 0x1 | 0x45
1862                  EQ            | 0x2 | 0x40
1863                  GT            | 0x4 | 0x00
1864                  LT            | 0x8 | 0x01
1865                */
1866
1867               /* ccMIPS = Shl(1, (~(ccIR>>5) & 2) | ((ccIR ^ (ccIR>>6)) & 1) */
1868               assign(ccMIPS, binop(Iop_Shl32, mkU32(1), unop(Iop_32to8,
1869                              binop(Iop_Or32, binop(Iop_And32, unop(Iop_Not32,
1870                              binop(Iop_Shr32, mkexpr(ccIR), mkU8(5))),
1871                                    mkU32(2)), binop(Iop_And32,
1872                              binop(Iop_Xor32, mkexpr(ccIR),
1873                              binop(Iop_Shr32, mkexpr(ccIR), mkU8(6))),
1874                              mkU32(1))))));
1875               /* UN */
1876               assign(t0, binop(Iop_And32, mkexpr(ccMIPS), mkU32(0x1)));
1877               /* EQ */
1878               assign(t1, binop(Iop_And32, binop(Iop_Shr32, mkexpr(ccMIPS),
1879                      mkU8(0x1)), mkU32(0x1)));
1880               /* NGT */
1881               assign(t2, binop(Iop_And32, unop(Iop_Not32, binop(Iop_Shr32,
1882                      mkexpr(ccMIPS), mkU8(0x2))), mkU32(0x1)));
1883               /* LT */
1884               assign(t3, binop(Iop_And32, binop(Iop_Shr32, mkexpr(ccMIPS),
1885                      mkU8(0x3)), mkU32(0x1)));
1886
1887               switch (cond) {
1888                  case 0x0:
1889                     setFPUCondCode(mkU32(0), fpc_cc);
1890                     break;
1891                  case 0x1:
1892                     setFPUCondCode(mkexpr(t0), fpc_cc);
1893                     break;
1894                  case 0x2:
1895                     setFPUCondCode(mkexpr(t1), fpc_cc);
1896                     break;
1897                  case 0x3:
1898                     setFPUCondCode(binop(Iop_Or32, mkexpr(t0), mkexpr(t1)),
1899                                          fpc_cc);
1900                     break;
1901                  case 0x4:
1902                     setFPUCondCode(mkexpr(t3), fpc_cc);
1903                     break;
1904                  case 0x5:
1905                     setFPUCondCode(binop(Iop_Or32, mkexpr(t0), mkexpr(t3)),
1906                                          fpc_cc);
1907                     break;
1908                  case 0x6:
1909                     setFPUCondCode(binop(Iop_Or32, mkexpr(t3), mkexpr(t1)),
1910                                          fpc_cc);
1911                     break;
1912                  case 0x7:
1913                     setFPUCondCode(mkexpr(t2), fpc_cc);
1914                     break;
1915                  case 0x8:
1916                     setFPUCondCode(mkU32(0), fpc_cc);
1917                     break;
1918                  case 0x9:
1919                     setFPUCondCode(mkexpr(t0), fpc_cc);
1920                     break;
1921                  case 0xA:
1922                     setFPUCondCode(mkexpr(t1), fpc_cc);
1923                     break;
1924                  case 0xB:
1925                     setFPUCondCode(binop(Iop_Or32, mkexpr(t0), mkexpr(t1)),
1926                                          fpc_cc);
1927                     break;
1928                  case 0xC:
1929                     setFPUCondCode(mkexpr(t3), fpc_cc);
1930                     break;
1931                  case 0xD:
1932                     setFPUCondCode(binop(Iop_Or32, mkexpr(t0), mkexpr(t3)),
1933                                          fpc_cc);
1934                     break;
1935                  case 0xE:
1936                     setFPUCondCode(binop(Iop_Or32, mkexpr(t3), mkexpr(t1)),
1937                                          fpc_cc);
1938                     break;
1939                  case 0xF:
1940                     setFPUCondCode(mkexpr(t2), fpc_cc);
1941                     break;
1942
1943                  default:
1944                     return False;
1945               }
1946            }
1947         }
1948            break;
1949
1950         case 0x11: {  /* C.cond.D */
1951            DIP("c.%s.d %d, f%d, f%d", showCondCode(cond), fpc_cc, fs, ft);
1952            t0 = newTemp(Ity_I32);
1953            t1 = newTemp(Ity_I32);
1954            t2 = newTemp(Ity_I32);
1955            t3 = newTemp(Ity_I32);
1956            assign(ccIR, binop(Iop_CmpF64, getDReg(fs), getDReg(ft)));
1957            /* Map compare result from IR to MIPS
1958               FP cmp result | MIPS | IR
1959               --------------------------
1960               UN            | 0x1 | 0x45
1961               EQ            | 0x2 | 0x40
1962               GT            | 0x4 | 0x00
1963               LT            | 0x8 | 0x01
1964             */
1965
1966            /* ccMIPS = Shl(1, (~(ccIR>>5) & 2) | ((ccIR ^ (ccIR>>6)) & 1) */
1967            assign(ccMIPS, binop(Iop_Shl32, mkU32(1), unop(Iop_32to8,
1968                           binop(Iop_Or32, binop(Iop_And32, unop(Iop_Not32,
1969                           binop(Iop_Shr32, mkexpr(ccIR), mkU8(5))), mkU32(2)),
1970                           binop(Iop_And32, binop(Iop_Xor32, mkexpr(ccIR),
1971                           binop(Iop_Shr32, mkexpr(ccIR), mkU8(6))),
1972                           mkU32(1))))));
1973
1974            /* UN */
1975            assign(t0, binop(Iop_And32, mkexpr(ccMIPS), mkU32(0x1)));
1976            /* EQ */
1977            assign(t1, binop(Iop_And32, binop(Iop_Shr32, mkexpr(ccMIPS),
1978                   mkU8(0x1)), mkU32(0x1)));
1979            /* NGT */
1980            assign(t2, binop(Iop_And32, unop(Iop_Not32, binop(Iop_Shr32,
1981                   mkexpr(ccMIPS), mkU8(0x2))), mkU32(0x1)));
1982            /* LT */
1983            assign(t3, binop(Iop_And32, binop(Iop_Shr32, mkexpr(ccMIPS),
1984                   mkU8(0x3)), mkU32(0x1)));
1985
1986            switch (cond) {
1987               case 0x0:
1988                  setFPUCondCode(mkU32(0), fpc_cc);
1989                  break;
1990               case 0x1:
1991                  setFPUCondCode(mkexpr(t0), fpc_cc);
1992                  break;
1993               case 0x2:
1994                  setFPUCondCode(mkexpr(t1), fpc_cc);
1995                  break;
1996               case 0x3:
1997                  setFPUCondCode(binop(Iop_Or32, mkexpr(t0), mkexpr(t1)),
1998                                       fpc_cc);
1999                  break;
2000               case 0x4:
2001                  setFPUCondCode(mkexpr(t3), fpc_cc);
2002                  break;
2003               case 0x5:
2004                  setFPUCondCode(binop(Iop_Or32, mkexpr(t0), mkexpr(t3)),
2005                                       fpc_cc);
2006                  break;
2007               case 0x6:
2008                  setFPUCondCode(binop(Iop_Or32, mkexpr(t3), mkexpr(t1)),
2009                                       fpc_cc);
2010                  break;
2011               case 0x7:
2012                  setFPUCondCode(mkexpr(t2), fpc_cc);
2013                  break;
2014               case 0x8:
2015                  setFPUCondCode(mkU32(0), fpc_cc);
2016                  break;
2017               case 0x9:
2018                  setFPUCondCode(mkexpr(t0), fpc_cc);
2019                  break;
2020               case 0xA:
2021                  setFPUCondCode(mkexpr(t1), fpc_cc);
2022                  break;
2023               case 0xB:
2024                  setFPUCondCode(binop(Iop_Or32, mkexpr(t0), mkexpr(t1)),
2025                                       fpc_cc);
2026                  break;
2027               case 0xC:
2028                  setFPUCondCode(mkexpr(t3), fpc_cc);
2029                  break;
2030               case 0xD:
2031                  setFPUCondCode(binop(Iop_Or32, mkexpr(t0), mkexpr(t3)),
2032                                       fpc_cc);
2033                  break;
2034               case 0xE:
2035                  setFPUCondCode(binop(Iop_Or32, mkexpr(t3), mkexpr(t1)),
2036                                       fpc_cc);
2037                  break;
2038               case 0xF:
2039                  setFPUCondCode(mkexpr(t2), fpc_cc);
2040                  break;
2041               default:
2042                  return False;
2043            }
2044         }
2045         break;
2046
2047         default:
2048            return False;
2049      }
2050   } else {
2051      return False;
2052   }
2053
2054   return True;
2055}
2056
2057/*********************************************************/
2058/*---        Branch Instructions for mips64           ---*/
2059/*********************************************************/
2060static Bool dis_instr_branch ( UInt theInstr, DisResult * dres,
2061                               Bool(*resteerOkFn) (void *, Addr64),
2062                               void *callback_opaque, IRStmt ** set )
2063{
2064   UInt jmpKind = 0;
2065   UChar opc1 = get_opcode(theInstr);
2066   UChar regRs = get_rs(theInstr);
2067   UChar regRt = get_rt(theInstr);
2068   UInt offset = get_imm(theInstr);
2069   Long sOffset = extend_s_16to64(offset);
2070   IRType ty = mode64 ? Ity_I64 : Ity_I32;
2071   IROp opSlt = mode64 ? Iop_CmpLT64S : Iop_CmpLT32S;
2072
2073   IRTemp tmp = newTemp(ty);
2074   IRTemp tmpRs = newTemp(ty);
2075   IRTemp tmpRt = newTemp(ty);
2076   IRTemp tmpLt = newTemp(ty);
2077   IRTemp tmpReg0 = newTemp(ty);
2078
2079   UChar regLnk = 31;   /* reg 31 is link reg in MIPS */
2080   Addr64 addrTgt = 0;
2081   Addr64 cia = guest_PC_curr_instr;
2082
2083   IRExpr *eConst0 = mkSzImm(ty, (UInt) 0);
2084   IRExpr *eNia = mkSzImm(ty, cia + 8);
2085   IRExpr *eCond = NULL;
2086
2087   assign(tmpRs, getIReg(regRs));
2088   assign(tmpRt, getIReg(regRt));
2089   assign(tmpReg0, getIReg(0));
2090
2091   eCond = binop(mkSzOp(ty, Iop_CmpNE8), mkexpr(tmpReg0), mkexpr(tmpReg0));
2092
2093   switch (opc1) {
2094      case 0x01:
2095         switch (regRt) {
2096            case 0x00: {  /* BLTZ rs, offset */
2097               addrTgt = mkSzAddr(ty, cia + 4 + (sOffset << 2));
2098               IRTemp tmpLtRes = newTemp(Ity_I1);
2099
2100               assign(tmp, eConst0);
2101               assign(tmpLtRes, binop(opSlt, mkexpr(tmpRs), mkexpr(tmp)));
2102               assign(tmpLt, mode64 ? unop(Iop_1Uto64, mkexpr(tmpLtRes)) :
2103                      unop(Iop_1Uto32, mkexpr(tmpLtRes)));
2104
2105               eCond = binop(mkSzOp(ty, Iop_CmpNE8), mkexpr(tmpLt),
2106                             mkexpr(tmpReg0));
2107
2108               jmpKind = Ijk_Call;
2109               break;
2110            }
2111
2112            case 0x01: {  /* BGEZ rs, offset */
2113               IRTemp tmpLtRes = newTemp(Ity_I1);
2114               addrTgt = mkSzAddr(ty, cia + 4 + (sOffset << 2));
2115
2116               assign(tmp, eConst0);
2117               assign(tmpLtRes, binop(opSlt, mkexpr(tmpRs), mkexpr(tmp)));
2118               assign(tmpLt, mode64 ? unop(Iop_1Uto64, mkexpr(tmpLtRes)) :
2119                                      unop(Iop_1Uto32, mkexpr(tmpLtRes)));
2120               eCond = binop(mkSzOp(ty, Iop_CmpEQ8), mkexpr(tmpLt),
2121                                    mkexpr(tmpReg0));
2122
2123               jmpKind = Ijk_Call;
2124               break;
2125            }
2126
2127            case 0x11: {  /* BGEZAL rs, offset */
2128               addrTgt = mkSzAddr(ty, cia + 4 + (sOffset << 2));
2129               putIReg(regLnk, eNia);
2130               IRTemp tmpLtRes = newTemp(Ity_I1);
2131
2132               assign(tmpLtRes, binop(opSlt, mkexpr(tmpRs), eConst0));
2133               assign(tmpLt, mode64 ? unop(Iop_1Uto64, mkexpr(tmpLtRes)) :
2134                                      unop(Iop_1Uto32, mkexpr(tmpLtRes)));
2135
2136               eCond = binop(mkSzOp(ty, Iop_CmpEQ8), mkexpr(tmpLt),
2137                                    mkexpr(tmpReg0));
2138
2139               jmpKind = Ijk_Call;
2140               break;
2141            }
2142
2143            case 0x10: {  /* BLTZAL rs, offset */
2144               IRTemp tmpLtRes = newTemp(Ity_I1);
2145               IRTemp tmpRes = newTemp(ty);
2146
2147               addrTgt = mkSzAddr(ty, cia + 4 + (sOffset << 2));
2148               putIReg(regLnk, eNia);
2149
2150               assign(tmp, eConst0);
2151               assign(tmpLtRes, binop(opSlt, mkexpr(tmpRs), mkexpr(tmp)));
2152               assign(tmpRes, mode64 ? unop(Iop_1Uto64,
2153                      mkexpr(tmpLtRes)) : unop(Iop_1Uto32, mkexpr(tmpLtRes)));
2154               eCond = binop(mkSzOp(ty, Iop_CmpNE8), mkexpr(tmpRes),
2155                                                     mkexpr(tmpReg0));
2156
2157               jmpKind = Ijk_Call;
2158               break;
2159            }
2160
2161         }
2162         break;
2163      default:
2164         return False;
2165      }
2166   *set = IRStmt_Exit(eCond, jmpKind, mkSzConst(ty, addrTgt), OFFB_PC);
2167   return True;
2168}
2169
2170/*********************************************************/
2171/*---         Cavium Specific Instructions            ---*/
2172/*********************************************************/
2173static Bool dis_instr_CVM ( UInt theInstr )
2174{
2175   UChar  opc2     = get_function(theInstr);
2176   UChar  opc1     = get_opcode(theInstr);
2177   UChar  regRs    = get_rs(theInstr);
2178   UChar  regRt    = get_rt(theInstr);
2179   UChar  regRd    = get_rd(theInstr);
2180   UInt   imm 	   = get_imm(theInstr);
2181   UChar  lenM1    = get_msb(theInstr);
2182   UChar  p        = get_lsb(theInstr);
2183   IRType ty       = mode64? Ity_I64 : Ity_I32;
2184   IRTemp tmp      = newTemp(ty);
2185   IRTemp tmpRs    = newTemp(ty);
2186   IRTemp tmpRt    = newTemp(ty);
2187   IRTemp t1       = newTemp(ty);
2188   UInt size;
2189   assign(tmpRs, getIReg(regRs));
2190
2191   switch(opc1){
2192      case 0x1C:  {
2193         switch(opc2) {
2194            case 0x03: {  /* DMUL rd, rs, rt */
2195               DIP("dmul r%d, r%d, r%d", regRd, regRs, regRt);
2196               IRType t0 = newTemp(Ity_I128);
2197               assign(t0, binop(Iop_MullU64, getIReg(regRs), getIReg(regRt)));
2198               putIReg(regRd, unop(Iop_128to64, mkexpr(t0)));
2199               break;
2200            }
2201
2202            case 0x32:  /* 5. CINS rd, rs, p, lenm1 */
2203               DIP("cins r%u, r%u, %d, %d\n", regRt, regRs, p, lenM1);
2204               assign ( tmp  , binop(Iop_Shl64, mkexpr(tmpRs),
2205                                     mkU8(64-( lenM1+1 ))));
2206               assign ( tmpRt, binop(Iop_Shr64, mkexpr( tmp ),
2207                                     mkU8(64-(p+lenM1+1))));
2208               putIReg( regRt, mkexpr(tmpRt));
2209               break;
2210
2211            case 0x33:  /* 6. CINS32 rd, rs, p+32, lenm1 */
2212               DIP("cins32 r%u, r%u, %d, %d\n", regRt, regRs, p+32, lenM1);
2213               assign ( tmp  , binop(Iop_Shl64, mkexpr(tmpRs),
2214                                     mkU8(64-( lenM1+1 ))));
2215               assign ( tmpRt, binop(Iop_Shr64, mkexpr( tmp ),
2216                                     mkU8(32-(p+lenM1+1))));
2217               putIReg( regRt, mkexpr(tmpRt));
2218               break;
2219
2220            case 0x3A:  /* 3. EXTS rt, rs, p len */
2221               DIP("exts r%u, r%u, %d, %d\n", regRt, regRs, p, lenM1);
2222               size = lenM1 + 1;  /* lenm1+1 */
2223               UChar lsAmt = 64 - (p + size);  /* p+lenm1+1 */
2224               UChar rsAmt = 64 - size;  /* lenm1+1 */
2225               tmp = newTemp(Ity_I64);
2226               assign(tmp, binop(Iop_Shl64, mkexpr(tmpRs), mkU8(lsAmt)));
2227               putIReg(regRt, binop(Iop_Sar64, mkexpr(tmp), mkU8(rsAmt)));
2228               break;
2229
2230            case 0x3B:  /* 4. EXTS32 rt, rs, p len */
2231               DIP("exts32 r%u, r%u, %d, %d\n", regRt, regRs, p, lenM1);
2232               assign ( tmp  , binop(Iop_Shl64, mkexpr(tmpRs),
2233                                     mkU8(32-(p+lenM1+1))));
2234               assign ( tmpRt, binop(Iop_Sar64, mkexpr(tmp),
2235                                     mkU8(64-(lenM1+1))) );
2236               putIReg( regRt, mkexpr(tmpRt));
2237               break;
2238
2239            case 0x2B:  /* 20. SNE rd, rs, rt */
2240               DIP("sne r%d, r%d, r%d", regRd,regRs, regRt);
2241               if (mode64)
2242                  putIReg(regRd, unop(Iop_1Uto64, binop(Iop_CmpNE64,
2243                                                        getIReg(regRs),
2244                                                        getIReg(regRt))));
2245               else
2246                  putIReg(regRd,unop(Iop_1Uto32, binop(Iop_CmpNE32,
2247                                                       getIReg(regRs),
2248                                                       getIReg(regRt))));
2249               break;
2250
2251            case 0x2A:  /* Set Equals - SEQ; Cavium OCTEON */
2252               DIP("seq r%d, r%d, %d", regRd, regRs, regRt);
2253               if (mode64)
2254                  putIReg(regRd, unop(Iop_1Uto64,
2255                                      binop(Iop_CmpEQ64, getIReg(regRs),
2256                                            getIReg(regRt))));
2257               else
2258                  putIReg(regRd, unop(Iop_1Uto32,
2259                                      binop(Iop_CmpEQ32, getIReg(regRs),
2260                                            getIReg(regRt))));
2261               break;
2262
2263            case 0x2E:  /* Set Equals Immediate - SEQI; Cavium OCTEON */
2264               DIP("seqi r%d, r%d, %d", regRt, regRs, imm);
2265               if (mode64)
2266                  putIReg(regRt, unop(Iop_1Uto64,
2267                                      binop(Iop_CmpEQ64, getIReg(regRs),
2268                                            mkU64(extend_s_10to64(imm)))));
2269               else
2270                  putIReg(regRt, unop(Iop_1Uto32,
2271                                      binop(Iop_CmpEQ32, getIReg(regRs),
2272                                            mkU32(extend_s_10to32(imm)))));
2273               break;
2274
2275            case 0x2F:  /* Set Not Equals Immediate - SNEI; Cavium OCTEON */
2276               DIP("snei r%d, r%d, %d", regRt, regRs, imm);
2277               if (mode64)
2278                  putIReg(regRt, unop(Iop_1Uto64,
2279                                   binop(Iop_CmpNE64,
2280                                         getIReg(regRs),
2281                                         mkU64(extend_s_10to64(imm)))));
2282               else
2283                  putIReg(regRt, unop(Iop_1Uto32,
2284                                   binop(Iop_CmpNE32,
2285                                         getIReg(regRs),
2286                                         mkU32(extend_s_10to32(imm)))));
2287               break;
2288
2289            default:
2290               return False;
2291         }
2292         break;
2293      } /* opc1 0x1C ends here*/
2294      case 0x1F:{
2295         switch(opc2) {
2296            case 0x0A: {  // lx - Load indexed instructions
2297               switch (get_sa(theInstr)) {
2298                  case 0x00: {  // LWX rd, index(base)
2299                     DIP("lwx r%d, r%d(r%d)", regRd, regRt, regRs);
2300                     LOADX_STORE_PATTERN;
2301                     putIReg(regRd, mkWidenFrom32(ty, load(Ity_I32, mkexpr(t1)),
2302                                                  True));
2303                     break;
2304                  }
2305                  case 0x08: {  // LDX rd, index(base)
2306                     DIP("ldx r%d, r%d(r%d)", regRd, regRt, regRs);
2307                     vassert(mode64); /* Currently Implemented only for n64 */
2308                     LOADX_STORE_PATTERN;
2309                     putIReg(regRd, load(Ity_I64, mkexpr(t1)));
2310                     break;
2311                  }
2312                  case 0x06: {  // LBUX rd, index(base)
2313                     DIP("lbux r%d, r%d(r%d)", regRd, regRt, regRs);
2314                     LOADX_STORE_PATTERN;
2315                     if (mode64)
2316                        putIReg(regRd, unop(Iop_8Uto64, load(Ity_I8,
2317                                                             mkexpr(t1))));
2318                     else
2319                        putIReg(regRd, unop(Iop_8Uto32, load(Ity_I8,
2320                                                             mkexpr(t1))));
2321                     break;
2322                  }
2323                  case 0x10: {  // LWUX rd, index(base) (Cavium OCTEON)
2324                     DIP("lwux r%d, r%d(r%d)", regRd, regRt, regRs);
2325                     LOADX_STORE_PATTERN; /* same for both 32 and 64 modes*/
2326                     putIReg(regRd, mkWidenFrom32(ty, load(Ity_I32, mkexpr(t1)),
2327                                                  False));
2328                     break;
2329                  }
2330                  case 0x14: {  // LHUX rd, index(base) (Cavium OCTEON)
2331                     DIP("lhux r%d, r%d(r%d)", regRd, regRt, regRs);
2332                     LOADX_STORE_PATTERN;
2333                     if (mode64)
2334                        putIReg(regRd,
2335                                unop(Iop_16Uto64, load(Ity_I16, mkexpr(t1))));
2336                     else
2337                        putIReg(regRd,
2338                                unop(Iop_16Uto32, load(Ity_I16, mkexpr(t1))));
2339                     break;
2340                  }
2341                  case 0x16: {  // LBX rd, index(base) (Cavium OCTEON)
2342                     DIP("lbx r%d, r%d(r%d)", regRd, regRs, regRt);
2343                     LOADX_STORE_PATTERN;
2344                     if (mode64)
2345                        putIReg(regRd,
2346                                unop(Iop_8Sto64, load(Ity_I8, mkexpr(t1))));
2347                     else
2348                        putIReg(regRd,
2349                                unop(Iop_8Sto32, load(Ity_I8, mkexpr(t1))));
2350                     break;
2351                  }
2352                  default:
2353                     vex_printf("\nUnhandled LX instruction opc3 = %x\n",
2354                                get_sa(theInstr));
2355                     return False;
2356               }
2357               break;
2358            }
2359         } /* opc1 = 0x1F & opc2 = 0xA (LX) ends here*/
2360         break;
2361      } /* opc1 = 0x1F ends here*/
2362      default:
2363         return False;
2364   } /* main opc1 switch ends here */
2365   return True;
2366}
2367
2368/*------------------------------------------------------------*/
2369/*---       Disassemble a single DSP ASE instruction       ---*/
2370/*------------------------------------------------------------*/
2371
2372static UInt disDSPInstr_MIPS_WRK ( UInt cins )
2373{
2374   IRTemp t0, t1 = 0, t2, t3, t4, t5, t6, t7, t8, t9, t10, t11, t12, t13, t14,
2375          t15, t16, t17;
2376   UInt opcode, rs, rt, rd, sa, function, ac, ac_mfhilo, rddsp_mask,
2377        wrdsp_mask, dsp_imm, shift;
2378
2379   opcode = get_opcode(cins);
2380   rs = get_rs(cins);
2381   rt = get_rt(cins);
2382   rd = get_rd(cins);
2383   sa = get_sa(cins);
2384   function = get_function(cins);
2385   ac = get_acNo(cins);
2386   ac_mfhilo = get_acNo_mfhilo(cins);
2387   rddsp_mask = get_rddspMask(cins);
2388   wrdsp_mask = get_wrdspMask(cins);
2389   dsp_imm = get_dspImm(cins);
2390   shift = get_shift(cins);
2391
2392   switch (opcode) {
2393      case 0x00: {  /* Special */
2394         switch (function) {
2395            case 0x10: {  /* MFHI */
2396               DIP("mfhi ac%d r%d", ac_mfhilo, rd);
2397               putIReg(rd, unop(Iop_64HIto32, getAcc(ac_mfhilo)));
2398               break;
2399            }
2400
2401            case 0x11: {  /* MTHI */
2402               DIP("mthi ac%d r%d", ac, rs);
2403               t1 = newTemp(Ity_I32);
2404               assign(t1, unop(Iop_64to32, getAcc(ac)));
2405               putAcc(ac, binop(Iop_32HLto64, getIReg(rs), mkexpr(t1)));
2406               break;
2407            }
2408
2409            case 0x12: {  /* MFLO */
2410               DIP("mflo ac%d r%d", ac_mfhilo, rd);
2411               putIReg(rd, unop(Iop_64to32, getAcc(ac_mfhilo)));
2412               break;
2413            }
2414
2415            case 0x13: {  /* MTLO */
2416               DIP("mtlo ac%d r%d", ac, rs);
2417               t1 = newTemp(Ity_I32);
2418               assign(t1, unop(Iop_64HIto32, getAcc(ac)));
2419               putAcc(ac, binop(Iop_32HLto64, mkexpr(t1), getIReg(rs)));
2420               break;
2421            }
2422
2423            case 0x18: {  /* MULT */
2424               DIP("mult ac%d r%d, r%d", ac, rs, rt);
2425               t1 = newTemp(Ity_I64);
2426               assign(t1, binop(Iop_MullS32, mkNarrowTo32(Ity_I32, getIReg(rs)),
2427                                mkNarrowTo32(Ity_I32, getIReg(rt))));
2428               putAcc(ac, mkexpr(t1));
2429               break;
2430            }
2431
2432            case 0x19: {  /* MULTU */
2433               DIP("multu ac%d r%d, r%d", ac, rs, rt);
2434               t1 = newTemp(Ity_I64);
2435               assign(t1, binop(Iop_MullU32, mkNarrowTo32(Ity_I32, getIReg(rs)),
2436                                             mkNarrowTo32(Ity_I32,
2437                                                          getIReg(rt))));
2438               putAcc(ac, mkexpr(t1));
2439            break;
2440            }
2441         }
2442         break;
2443      }
2444      case 0x1C: {  /* Special2 */
2445         switch (function) {
2446            case 0x00: {  /* MADD */
2447               DIP("madd ac%d, r%d, r%d", ac, rs, rt);
2448               t1 = newTemp(Ity_I64);
2449               t2 = newTemp(Ity_I64);
2450               t3 = newTemp(Ity_I64);
2451
2452               assign(t1, getAcc(ac));
2453               assign(t2, binop(Iop_MullS32, getIReg(rs), getIReg(rt)));
2454               assign(t3, binop(Iop_Add64, mkexpr(t1), mkexpr(t2)));
2455
2456               putAcc(ac, mkexpr(t3));
2457               break;
2458            }
2459            case 0x01: {  /* MADDU */
2460               DIP("maddu ac%d r%d, r%d", ac, rs, rt);
2461               t1 = newTemp(Ity_I64);
2462               t2 = newTemp(Ity_I64);
2463               t3 = newTemp(Ity_I64);
2464
2465               assign(t1, getAcc(ac));
2466               assign(t2, binop(Iop_MullU32, getIReg(rs), getIReg(rt)));
2467               assign(t3, binop(Iop_Add64, mkexpr(t2), mkexpr(t1)));
2468
2469               putAcc(ac, mkexpr(t3));
2470               break;
2471            }
2472            case 0x04: {  /* MSUB */
2473               DIP("msub ac%d r%d, r%d", ac, rs, rt);
2474               t1 = newTemp(Ity_I64);
2475               t2 = newTemp(Ity_I64);
2476               t3 = newTemp(Ity_I64);
2477
2478               assign(t1, getAcc(ac));
2479               assign(t2, binop(Iop_MullS32, getIReg(rs), getIReg(rt)));
2480               assign(t3, binop(Iop_Sub64, mkexpr(t1), mkexpr(t2)));
2481
2482               putAcc(ac, mkexpr(t3));
2483               break;
2484            }
2485            case 0x05: {  /* MSUBU */
2486               DIP("msubu ac%d r%d, r%d", ac, rs, rt);
2487               t1 = newTemp(Ity_I64);
2488               t2 = newTemp(Ity_I64);
2489               t3 = newTemp(Ity_I64);
2490
2491               assign(t1, getAcc(ac));
2492               assign(t2, binop(Iop_MullU32, getIReg(rs), getIReg(rt)));
2493               assign(t3, binop(Iop_Sub64, mkexpr(t1), mkexpr(t2)));
2494
2495               putAcc(ac, mkexpr(t3));
2496               break;
2497            }
2498         }
2499         break;
2500      }
2501      case 0x1F: {  /* Special3 */
2502         switch (function) {
2503            case 0x12: {  /* ABSQ_S.PH */
2504               switch (sa) {
2505                  case 0x1: {  /* ABSQ_S.QB */
2506                     DIP("absq_s.qb r%d, r%d", rd, rt);
2507                     vassert(!mode64);
2508                     t0 = newTemp(Ity_I8);
2509                     t1 = newTemp(Ity_I1);
2510                     t2 = newTemp(Ity_I1);
2511                     t3 = newTemp(Ity_I8);
2512                     t4 = newTemp(Ity_I8);
2513                     t5 = newTemp(Ity_I1);
2514                     t6 = newTemp(Ity_I1);
2515                     t7 = newTemp(Ity_I8);
2516                     t8 = newTemp(Ity_I8);
2517                     t9 = newTemp(Ity_I1);
2518                     t10 = newTemp(Ity_I1);
2519                     t11 = newTemp(Ity_I8);
2520                     t12 = newTemp(Ity_I8);
2521                     t13 = newTemp(Ity_I1);
2522                     t14 = newTemp(Ity_I1);
2523                     t15 = newTemp(Ity_I8);
2524                     t16 = newTemp(Ity_I32);
2525                     t17 = newTemp(Ity_I32);
2526
2527                     /* Absolute value of the rightmost byte (bits 7-0). */
2528                     /* t0 - rightmost byte. */
2529                     assign(t0, unop(Iop_16to8, unop(Iop_32to16, getIReg(rt))));
2530                     /* t1 holds 1 if t0 is equal to 0x80, or 0 otherwise. */
2531                     assign(t1, binop(Iop_CmpEQ32,
2532                                      unop(Iop_8Uto32, mkexpr(t0)),
2533                                      mkU32(0x00000080)));
2534                     /* t2 holds 1 if value in t0 is negative, 0 otherwise. */
2535                     assign(t2, unop(Iop_32to1,
2536                                     binop(Iop_Shr32,
2537                                           binop(Iop_And32,
2538                                                 getIReg(rt),
2539                                                 mkU32(0x00000080)),
2540                                           mkU8(0x7))));
2541                     /* t3 holds abs(t0). */
2542                     assign(t3, IRExpr_ITE(mkexpr(t1),
2543                                           mkU8(0x7F),
2544                                           IRExpr_ITE(mkexpr(t2),
2545                                                      binop(Iop_Add8,
2546                                                            unop(Iop_Not8,
2547                                                                 mkexpr(t0)),
2548                                                            mkU8(0x1)),
2549                                                      mkexpr(t0))));
2550
2551                     /* Absolute value of bits 15-8. */
2552                     /* t4 - input byte. */
2553                     assign(t4,
2554                            unop(Iop_16HIto8, unop(Iop_32to16, getIReg(rt))));
2555                     /* t5 holds 1 if t4 is equal to 0x80, or 0 otherwise. */
2556                     assign(t5, binop(Iop_CmpEQ32,
2557                                      unop(Iop_8Uto32, mkexpr(t4)),
2558                                      mkU32(0x00000080)));
2559                     /* t6 holds 1 if value in t4 is negative, 0 otherwise. */
2560                     assign(t6, unop(Iop_32to1,
2561                                     binop(Iop_Shr32,
2562                                           binop(Iop_And32,
2563                                                 getIReg(rt),
2564                                                 mkU32(0x00008000)),
2565                                           mkU8(15))));
2566                     /* t3 holds abs(t4). */
2567                     assign(t7, IRExpr_ITE(mkexpr(t5),
2568                                           mkU8(0x7F),
2569                                           IRExpr_ITE(mkexpr(t6),
2570                                                      binop(Iop_Add8,
2571                                                            unop(Iop_Not8,
2572                                                                 mkexpr(t4)),
2573                                                            mkU8(0x1)),
2574                                                      mkexpr(t4))));
2575
2576                     /* Absolute value of bits 23-15. */
2577                     /* t8 - input byte. */
2578                     assign(t8,
2579                            unop(Iop_16to8, unop(Iop_32HIto16, getIReg(rt))));
2580                     /* t9 holds 1 if t8 is equal to 0x80, or 0 otherwise. */
2581                     assign(t9, binop(Iop_CmpEQ32,
2582                                      unop(Iop_8Uto32, mkexpr(t8)),
2583                                      mkU32(0x00000080)));
2584                     /* t6 holds 1 if value in t8 is negative, 0 otherwise. */
2585                     assign(t10, unop(Iop_32to1,
2586                                      binop(Iop_Shr32,
2587                                            binop(Iop_And32,
2588                                                  getIReg(rt),
2589                                                  mkU32(0x00800000)),
2590                                            mkU8(23))));
2591                     /* t3 holds abs(t8). */
2592                     assign(t11, IRExpr_ITE(mkexpr(t9),
2593                                            mkU8(0x7F),
2594                                            IRExpr_ITE(mkexpr(t10),
2595                                                       binop(Iop_Add8,
2596                                                             unop(Iop_Not8,
2597                                                                  mkexpr(t8)),
2598                                                             mkU8(0x1)),
2599                                                       mkexpr(t8))));
2600
2601                     /* Absolute value of bits 31-24. */
2602                     /* t12 - input byte. */
2603                     assign(t12,
2604                            unop(Iop_16HIto8, unop(Iop_32HIto16, getIReg(rt))));
2605                     /* t13 holds 1 if t12 is equal to 0x80, or 0 otherwise. */
2606                     assign(t13, binop(Iop_CmpEQ32,
2607                                       unop(Iop_8Uto32, mkexpr(t12)),
2608                                       mkU32(0x00000080)));
2609                     /* t14 holds 1 if value in t12 is negative, 0 otherwise. */
2610                     assign(t14, unop(Iop_32to1,
2611                                      binop(Iop_Shr32,
2612                                            binop(Iop_And32,
2613                                                  getIReg(rt),
2614                                                  mkU32(0x80000000)),
2615                                            mkU8(31))));
2616                     /* t15 holds abs(t12). */
2617                     assign(t15, IRExpr_ITE(mkexpr(t13),
2618                                            mkU8(0x7F),
2619                                            IRExpr_ITE(mkexpr(t14),
2620                                                       binop(Iop_Add8,
2621                                                             unop(Iop_Not8,
2622                                                                  mkexpr(t12)),
2623                                                             mkU8(0x1)),
2624                                                       mkexpr(t12))));
2625
2626                     /* t16 holds !0 if any of input bytes is 0x80 or 0
2627                        otherwise. */
2628                     assign(t16,
2629                            binop(Iop_Or32,
2630                                  binop(Iop_Or32,
2631                                        binop(Iop_Or32,
2632                                              unop(Iop_1Sto32, mkexpr(t13)),
2633                                              unop(Iop_1Sto32, mkexpr(t9))),
2634                                        unop(Iop_1Sto32, mkexpr(t5))),
2635                                  unop(Iop_1Sto32, mkexpr(t1))));
2636
2637                     putDSPControl(IRExpr_ITE(binop(Iop_CmpEQ32,
2638                                                    mkexpr(t16),
2639                                                    mkU32(0x0)),
2640                                              getDSPControl(),
2641                                              binop(Iop_Or32,
2642                                                    getDSPControl(),
2643                                                    mkU32(0x00100000))));
2644
2645                     /* t17 = t15|t11|t7|t3 */
2646                     assign(t17,
2647                            binop(Iop_16HLto32,
2648                                  binop(Iop_8HLto16, mkexpr(t15), mkexpr(t11)),
2649                                  binop(Iop_8HLto16, mkexpr(t7), mkexpr(t3))));
2650
2651                     putIReg(rd, mkexpr(t17));
2652                     break;
2653                  }
2654                  case 0x2: {  /* REPL.QB */
2655                     DIP("repl.qb r%d, %d", rd, dsp_imm);
2656                     vassert(!mode64);
2657
2658                     putIReg(rd, mkU32((dsp_imm << 24) | (dsp_imm << 16) |
2659                                       (dsp_imm << 8) | (dsp_imm)));
2660                     break;
2661                  }
2662                  case 0x3: {  /* REPLV.QB */
2663                     DIP("replv.qb r%d, r%d", rd, rt);
2664                     vassert(!mode64);
2665                     t0 = newTemp(Ity_I8);
2666
2667                     assign(t0, unop(Iop_32to8,
2668                                binop(Iop_And32, getIReg(rt), mkU32(0xff))));
2669                     putIReg(rd,
2670                             binop(Iop_16HLto32,
2671                                   binop(Iop_8HLto16, mkexpr(t0), mkexpr(t0)),
2672                                   binop(Iop_8HLto16, mkexpr(t0), mkexpr(t0))));
2673                     break;
2674                  }
2675                  case 0x4: {  /* PRECEQU.PH.QBL */
2676                     DIP("precequ.ph.qbl r%d, r%d", rd, rt);
2677                     vassert(!mode64);
2678
2679                     putIReg(rd, binop(Iop_Or32,
2680                                       binop(Iop_Shr32,
2681                                             binop(Iop_And32,
2682                                                   getIReg(rt),
2683                                                   mkU32(0xff000000)),
2684                                             mkU8(1)),
2685                                       binop(Iop_Shr32,
2686                                             binop(Iop_And32,
2687                                                   getIReg(rt),
2688                                                   mkU32(0x00ff0000)),
2689                                             mkU8(9))));
2690                     break;
2691                  }
2692                  case 0x5: {  /* PRECEQU.PH.QBR */
2693                     DIP("precequ.ph.qbr r%d, r%d", rd, rt);
2694                     vassert(!mode64);
2695
2696                     putIReg(rd, binop(Iop_Or32,
2697                                       binop(Iop_Shl32,
2698                                             binop(Iop_And32,
2699                                                   getIReg(rt),
2700                                                   mkU32(0x0000ff00)),
2701                                             mkU8(15)),
2702                                       binop(Iop_Shl32,
2703                                             binop(Iop_And32,
2704                                                   getIReg(rt),
2705                                                   mkU32(0x000000ff)),
2706                                             mkU8(7))));
2707                     break;
2708                  }
2709                  case 0x6: {  /* PRECEQU.PH.QBLA */
2710                     DIP("precequ.ph.qbla r%d, r%d", rd, rt);
2711                     vassert(!mode64);
2712
2713                     putIReg(rd, binop(Iop_Or32,
2714                                       binop(Iop_Shr32,
2715                                             binop(Iop_And32,
2716                                                   getIReg(rt),
2717                                                   mkU32(0xff000000)),
2718                                             mkU8(1)),
2719                                       binop(Iop_Shr32,
2720                                             binop(Iop_And32,
2721                                                   getIReg(rt),
2722                                                   mkU32(0x0000ff00)),
2723                                             mkU8(1))));
2724                     break;
2725                  }
2726                  case 0x7: {  /* PRECEQU.PH.QBRA */
2727                     DIP("precequ.ph.qbra r%d, r%d", rd, rt);
2728                     vassert(!mode64);
2729
2730                     putIReg(rd, binop(Iop_Or32,
2731                                       binop(Iop_Shl32,
2732                                             binop(Iop_And32,
2733                                                   getIReg(rt),
2734                                                   mkU32(0x00ff0000)),
2735                                             mkU8(7)),
2736                                       binop(Iop_Shl32,
2737                                             binop(Iop_And32,
2738                                                   getIReg(rt),
2739                                                   mkU32(0x000000ff)),
2740                                             mkU8(7))));
2741                     break;
2742                  }
2743                  case 0x9: {  /* ABSQ_S.PH */
2744                     DIP("absq_s.ph r%d, r%d", rd, rt);
2745                     vassert(!mode64);
2746                     t0 = newTemp(Ity_I16);
2747                     t1 = newTemp(Ity_I1);
2748                     t2 = newTemp(Ity_I1);
2749                     t3 = newTemp(Ity_I16);
2750                     t4 = newTemp(Ity_I16);
2751                     t5 = newTemp(Ity_I1);
2752                     t6 = newTemp(Ity_I1);
2753                     t7 = newTemp(Ity_I16);
2754                     t8 = newTemp(Ity_I32);
2755                     t9 = newTemp(Ity_I32);
2756
2757                     /* t0 holds lower 16 bits of value in rt. */
2758                     assign(t0, unop(Iop_32to16, getIReg(rt)));
2759                     /* t1 holds 1 if t0 is equal to 0x8000. */
2760                     assign(t1, binop(Iop_CmpEQ32,
2761                                      unop(Iop_16Uto32, mkexpr(t0)),
2762                                      mkU32(0x00008000)));
2763                     /* t2 holds 1 if value in t0 is negative, 0 otherwise. */
2764                     assign(t2, unop(Iop_32to1,
2765                                     binop(Iop_Shr32,
2766                                           binop(Iop_And32,
2767                                                 getIReg(rt),
2768                                                 mkU32(0x00008000)),
2769                                           mkU8(15))));
2770                     /* t3 holds abs(t0). */
2771                     assign(t3, IRExpr_ITE(mkexpr(t1),
2772                                           mkU16(0x7FFF),
2773                                           IRExpr_ITE(mkexpr(t2),
2774                                                      binop(Iop_Add16,
2775                                                            unop(Iop_Not16,
2776                                                                 mkexpr(t0)),
2777                                                            mkU16(0x1)),
2778                                                      mkexpr(t0))));
2779
2780                     /* t4 holds lower 16 bits of value in rt. */
2781                     assign(t4, unop(Iop_32HIto16, getIReg(rt)));
2782                     /* t5 holds 1 if t4 is equal to 0x8000. */
2783                     assign(t5, binop(Iop_CmpEQ32,
2784                                      unop(Iop_16Uto32, mkexpr(t4)),
2785                                      mkU32(0x00008000)));
2786                     /* t6 holds 1 if value in t4 is negative, 0 otherwise. */
2787                     assign(t6, unop(Iop_32to1,
2788                                     binop(Iop_Shr32,
2789                                           binop(Iop_And32,
2790                                                 getIReg(rt),
2791                                                 mkU32(0x80000000)),
2792                                           mkU8(31))));
2793                     /* t7 holds abs(t4). */
2794                     assign(t7, IRExpr_ITE(mkexpr(t5),
2795                                           mkU16(0x7FFF),
2796                                           IRExpr_ITE(mkexpr(t6),
2797                                                      binop(Iop_Add16,
2798                                                            unop(Iop_Not16,
2799                                                                 mkexpr(t4)),
2800                                                            mkU16(0x1)),
2801                                                      mkexpr(t4))));
2802                     /* If any of the two input halfwords is equal 0x8000,
2803                        set bit 20 in DSPControl register. */
2804                     assign(t8, binop(Iop_Or32,
2805                                      unop(Iop_1Sto32, mkexpr(t5)),
2806                                      unop(Iop_1Sto32, mkexpr(t1))));
2807
2808                     putDSPControl(IRExpr_ITE(binop(Iop_CmpEQ32,
2809                                                    mkexpr(t8),
2810                                                    mkU32(0x0)),
2811                                              getDSPControl(),
2812                                              binop(Iop_Or32,
2813                                                    getDSPControl(),
2814                                                    mkU32(0x00100000))));
2815
2816                     /* t9 = t7|t3 */
2817                     assign(t9, binop(Iop_16HLto32, mkexpr(t7), mkexpr(t3)));
2818
2819                     putIReg(rd, mkexpr(t9));
2820                     break;
2821                  }
2822                  case 0xA: {  /* REPL.PH */
2823                     DIP("repl.ph r%d, %d", rd, dsp_imm);
2824                     vassert(!mode64);
2825                     UShort immediate = extend_s_10to16(dsp_imm);
2826
2827                     putIReg(rd, mkU32(immediate << 16 | immediate));
2828                     break;
2829                  }
2830                  case 0xB: {  /* REPLV.PH */
2831                     DIP("replv.ph r%d, r%d", rd, rt);
2832                     vassert(!mode64);
2833
2834                     putIReg(rd, binop(Iop_16HLto32,
2835                                       unop(Iop_32to16, getIReg(rt)),
2836                                       unop(Iop_32to16, getIReg(rt))));
2837                     break;
2838                  }
2839                  case 0xC: {  /* PRECEQ.W.PHL */
2840                     DIP("preceq.w.phl r%d, r%d", rd, rt);
2841                     vassert(!mode64);
2842                     putIReg(rd, binop(Iop_And32,
2843                                       getIReg(rt),
2844                                       mkU32(0xffff0000)));
2845                     break;
2846                  }
2847                  case 0xD: {  /* PRECEQ.W.PHR */
2848                     DIP("preceq.w.phr r%d, r%d", rd, rt);
2849                     vassert(!mode64);
2850                     putIReg(rd, binop(Iop_16HLto32,
2851                                       unop(Iop_32to16, getIReg(rt)),
2852                                       mkU16(0x0)));
2853                     break;
2854                  }
2855                  case 0x11: {  /* ABSQ_S.W */
2856                     DIP("absq_s.w r%d, r%d", rd, rt);
2857                     vassert(!mode64);
2858                     t0 = newTemp(Ity_I1);
2859                     t1 = newTemp(Ity_I1);
2860                     t2 = newTemp(Ity_I32);
2861
2862                     assign(t0,
2863                            binop(Iop_CmpEQ32, getIReg(rt), mkU32(0x80000000)));
2864
2865                     putDSPControl(IRExpr_ITE(mkexpr(t0),
2866                                              binop(Iop_Or32,
2867                                                    getDSPControl(),
2868                                                    mkU32(0x00100000)),
2869                                              getDSPControl()));
2870
2871                     assign(t1, binop(Iop_CmpLT32S, getIReg(rt), mkU32(0x0)));
2872
2873                     assign(t2, IRExpr_ITE(mkexpr(t0),
2874                                           mkU32(0x7FFFFFFF),
2875                                           IRExpr_ITE(mkexpr(t1),
2876                                                      binop(Iop_Add32,
2877                                                            unop(Iop_Not32,
2878                                                                 getIReg(rt)),
2879                                                            mkU32(0x1)),
2880                                                      getIReg(rt))));
2881                     putIReg(rd, mkexpr(t2));
2882                     break;
2883                  }
2884                  case 0x1B: {  /* BITREV */
2885                     DIP("bitrev r%d, r%d", rd, rt);
2886                     vassert(!mode64);
2887                     /* 32bit reversal as seen on Bit Twiddling Hacks site
2888                        http://graphics.stanford.edu/~seander/bithacks.html
2889                        section ReverseParallel */
2890                     t1 = newTemp(Ity_I32);
2891                     t2 = newTemp(Ity_I32);
2892                     t3 = newTemp(Ity_I32);
2893                     t4 = newTemp(Ity_I32);
2894                     t5 = newTemp(Ity_I32);
2895
2896                     assign(t1, binop(Iop_Or32,
2897                                      binop(Iop_Shr32,
2898                                            binop(Iop_And32,
2899                                                  getIReg(rt),
2900                                                  mkU32(0xaaaaaaaa)),
2901                                            mkU8(0x1)),
2902                                      binop(Iop_Shl32,
2903                                            binop(Iop_And32,
2904                                                  getIReg(rt),
2905                                                  mkU32(0x55555555)),
2906                                            mkU8(0x1))));
2907                     assign(t2, binop(Iop_Or32,
2908                                      binop(Iop_Shr32,
2909                                            binop(Iop_And32,
2910                                                  mkexpr(t1),
2911                                                  mkU32(0xcccccccc)),
2912                                            mkU8(0x2)),
2913                                      binop(Iop_Shl32,
2914                                            binop(Iop_And32,
2915                                                  mkexpr(t1),
2916                                                  mkU32(0x33333333)),
2917                                            mkU8(0x2))));
2918                     assign(t3, binop(Iop_Or32,
2919                                      binop(Iop_Shr32,
2920                                            binop(Iop_And32,
2921                                                  mkexpr(t2),
2922                                                  mkU32(0xf0f0f0f0)),
2923                                            mkU8(0x4)),
2924                                      binop(Iop_Shl32,
2925                                            binop(Iop_And32,
2926                                                  mkexpr(t2),
2927                                                  mkU32(0x0f0f0f0f)),
2928                                            mkU8(0x4))));
2929                     assign(t4, binop(Iop_Or32,
2930                                      binop(Iop_Shr32,
2931                                            binop(Iop_And32,
2932                                                  mkexpr(t3),
2933                                                  mkU32(0xff00ff00)),
2934                                            mkU8(0x8)),
2935                                      binop(Iop_Shl32,
2936                                            binop(Iop_And32,
2937                                                  mkexpr(t3),
2938                                                  mkU32(0x00ff00ff)),
2939                                            mkU8(0x8))));
2940                     assign(t5, binop(Iop_Or32,
2941                                      binop(Iop_Shr32,
2942                                            mkexpr(t4),
2943                                            mkU8(0x10)),
2944                                      binop(Iop_Shl32,
2945                                            mkexpr(t4),
2946                                            mkU8(0x10))));
2947                     putIReg(rd, binop(Iop_Shr32,
2948                                       mkexpr(t5),
2949                                       mkU8(16)));
2950                     break;
2951                  }
2952                  case 0x1C: {  /* PRECEU.PH.QBL */
2953                     DIP("preceu.ph.qbl r%d, r%d", rd, rt);
2954                     vassert(!mode64);
2955
2956                     putIReg(rd, binop(Iop_Or32,
2957                                       binop(Iop_Shr32,
2958                                             binop(Iop_And32,
2959                                                   getIReg(rt),
2960                                                   mkU32(0xff000000)),
2961                                             mkU8(8)),
2962                                       binop(Iop_Shr32,
2963                                             binop(Iop_And32,
2964                                                   getIReg(rt),
2965                                                   mkU32(0x00ff0000)),
2966                                             mkU8(16))));
2967                     break;
2968                  }
2969                  case 0x1E: {  /* PRECEU.PH.QBLA */
2970                     DIP("preceu.ph.qbla r%d, r%d", rd, rt);
2971                     vassert(!mode64);
2972
2973                     putIReg(rd, binop(Iop_Or32,
2974                                       binop(Iop_Shr32,
2975                                             binop(Iop_And32,
2976                                                   getIReg(rt),
2977                                                   mkU32(0xff000000)),
2978                                             mkU8(8)),
2979                                       binop(Iop_Shr32,
2980                                             binop(Iop_And32,
2981                                                   getIReg(rt),
2982                                                   mkU32(0x0000ff00)),
2983                                             mkU8(8))));
2984                     break;
2985                  }
2986                  case 0x1D: {  /* PRECEU.PH.QBR */
2987                     DIP("preceu.ph.qbr r%d, r%d", rd, rt);
2988                     vassert(!mode64);
2989
2990                     putIReg(rd, binop(Iop_Or32,
2991                                       binop(Iop_Shl32,
2992                                             binop(Iop_And32,
2993                                                   getIReg(rt),
2994                                                   mkU32(0x0000ff00)),
2995                                             mkU8(8)),
2996                                       binop(Iop_And32,
2997                                             getIReg(rt),
2998                                             mkU32(0x000000ff))));
2999                     break;
3000                  }
3001                  case 0x1F: {  /* PRECEU.PH.QBRA */
3002                     DIP("preceu.ph.qbra r%d, r%d", rd, rt);
3003                     vassert(!mode64);
3004
3005                     putIReg(rd, binop(Iop_Or32,
3006                                       binop(Iop_And32,
3007                                             getIReg(rt),
3008                                             mkU32(0x00ff0000)),
3009                                       binop(Iop_And32,
3010                                             getIReg(rt),
3011                                             mkU32(0x000000ff))));
3012                     break;
3013                  }
3014                  default:
3015                     return -1;
3016               }
3017               break;  /* end of ABSQ_S.PH */
3018            }
3019            case 0x38: {  /* EXTR.W */
3020               switch(sa) {
3021                  case 0x0: {  /* EXTR.W */
3022                     DIP("extr.w r%d, ac%d, %d", rt, ac, rs);
3023                     vassert(!mode64);
3024                     t0 = newTemp(Ity_I64);
3025                     t1 = newTemp(Ity_I64);
3026                     t2 = newTemp(Ity_I32);
3027                     t3 = newTemp(Ity_I1);
3028                     t4 = newTemp(Ity_I1);
3029                     t5 = newTemp(Ity_I1);
3030                     t6 = newTemp(Ity_I1);
3031                     t7 = newTemp(Ity_I32);
3032                     t8 = newTemp(Ity_I64);
3033                     t9 = newTemp(Ity_I64);
3034                     t10 = newTemp(Ity_I1);
3035                     t11 = newTemp(Ity_I1);
3036                     t12 = newTemp(Ity_I1);
3037                     t13 = newTemp(Ity_I1);
3038                     t14 = newTemp(Ity_I32);
3039
3040                     assign(t0, getAcc(ac));
3041                     if (0 == rs) {
3042                        assign(t1, mkexpr(t0));
3043                     } else {
3044                        assign(t1, binop(Iop_Sar64, mkexpr(t0), mkU8(rs)));
3045                     }
3046                     /* Check if bits 63..31 of the result in t1 aren't 0. */
3047                     assign(t3, binop(Iop_CmpNE32,
3048                                      unop(Iop_64HIto32,
3049                                           mkexpr(t1)),
3050                                      mkU32(0)));
3051                     assign(t4, binop(Iop_CmpNE32,
3052                                      binop(Iop_And32,
3053                                            unop(Iop_64to32,
3054                                                 mkexpr(t1)),
3055                                            mkU32(0x80000000)),
3056                                      mkU32(0)));
3057                     /* Check if bits 63..31 of the result in t1 aren't
3058                        0x1ffffffff. */
3059                     assign(t5, binop(Iop_CmpNE32,
3060                                      unop(Iop_64HIto32,
3061                                           mkexpr(t1)),
3062                                      mkU32(0xffffffff)));
3063                     assign(t6, binop(Iop_CmpNE32,
3064                                      binop(Iop_And32,
3065                                            unop(Iop_64to32,
3066                                                 mkexpr(t1)),
3067                                            mkU32(0x80000000)),
3068                                      mkU32(0x80000000)));
3069                     /* If bits 63..31 aren't 0 nor 0x1ffffffff, set DSP
3070                        control register. */
3071                     assign(t7, binop(Iop_And32,
3072                                      binop(Iop_Or32,
3073                                            unop(Iop_1Sto32, mkexpr(t3)),
3074                                            unop(Iop_1Sto32, mkexpr(t4))),
3075                                      binop(Iop_Or32,
3076                                            unop(Iop_1Sto32, mkexpr(t5)),
3077                                            unop(Iop_1Sto32, mkexpr(t6)))));
3078                     putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32,
3079                                                    mkexpr(t7),
3080                                                    mkU32(0)),
3081                                              binop(Iop_Or32,
3082                                                    getDSPControl(),
3083                                                    mkU32(0x00800000)),
3084                                              getDSPControl()));
3085
3086                     /* If the last discarded bit is 1, there would be carry
3087                        when rounding, otherwise there wouldn't. We use that
3088                        fact and just add the value of the last discarded bit
3089                        to the least sifgnificant bit of the shifted value
3090                        from acc. */
3091                     if (0 == rs) {
3092                        assign(t8, mkU64(0x0ULL));
3093                     } else {
3094                        assign(t8, binop(Iop_And64,
3095                                         binop(Iop_Shr64,
3096                                               mkexpr(t0),
3097                                               mkU8(rs-1)),
3098                                         mkU64(0x1ULL)));
3099                     }
3100                     assign(t9, binop(Iop_Add64, mkexpr(t1), mkexpr(t8)));
3101
3102                     /* Repeat previous steps for the rounded value. */
3103                     assign(t10, binop(Iop_CmpNE32,
3104                                      unop(Iop_64HIto32,
3105                                           mkexpr(t9)),
3106                                      mkU32(0)));
3107                     assign(t11, binop(Iop_CmpNE32,
3108                                      binop(Iop_And32,
3109                                            unop(Iop_64to32,
3110                                                 mkexpr(t9)),
3111                                            mkU32(0x80000000)),
3112                                      mkU32(0)));
3113
3114                     assign(t12, binop(Iop_CmpNE32,
3115                                      unop(Iop_64HIto32,
3116                                           mkexpr(t9)),
3117                                      mkU32(0xffffffff)));
3118                     assign(t13, binop(Iop_CmpNE32,
3119                                      binop(Iop_And32,
3120                                            unop(Iop_64to32,
3121                                                 mkexpr(t9)),
3122                                            mkU32(0x80000000)),
3123                                      mkU32(0x80000000)));
3124
3125                     assign(t14, binop(Iop_And32,
3126                                      binop(Iop_Or32,
3127                                            unop(Iop_1Sto32, mkexpr(t10)),
3128                                            unop(Iop_1Sto32, mkexpr(t11))),
3129                                      binop(Iop_Or32,
3130                                            unop(Iop_1Sto32, mkexpr(t12)),
3131                                            unop(Iop_1Sto32, mkexpr(t13)))));
3132                     putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32,
3133                                                    mkexpr(t14),
3134                                                    mkU32(0)),
3135                                              binop(Iop_Or32,
3136                                                    getDSPControl(),
3137                                                    mkU32(0x00800000)),
3138                                              getDSPControl()));
3139                     if (0 == rs) {
3140                        putIReg(rt, unop(Iop_64to32, mkexpr(t0)));
3141                     } else {
3142                        putIReg(rt, unop(Iop_64to32, mkexpr(t1)));
3143                     }
3144                     break;
3145                  }
3146                  case 0x1: {  /* EXTRV.W */
3147                     DIP("extrv.w r%d, ac%d, r%d", rt, ac, rs);
3148                     vassert(!mode64);
3149                     t0 = newTemp(Ity_I64);
3150                     t1 = newTemp(Ity_I64);
3151                     t2 = newTemp(Ity_I32);
3152                     t3 = newTemp(Ity_I1);
3153                     t4 = newTemp(Ity_I1);
3154                     t5 = newTemp(Ity_I1);
3155                     t6 = newTemp(Ity_I1);
3156                     t7 = newTemp(Ity_I32);
3157                     t8 = newTemp(Ity_I64);
3158                     t9 = newTemp(Ity_I64);
3159                     t10 = newTemp(Ity_I1);
3160                     t11 = newTemp(Ity_I1);
3161                     t12 = newTemp(Ity_I1);
3162                     t13 = newTemp(Ity_I1);
3163                     t14 = newTemp(Ity_I32);
3164                     t15 = newTemp(Ity_I8);
3165
3166                     assign(t15, unop(Iop_32to8,
3167                                      binop(Iop_And32,
3168                                            getIReg(rs),
3169                                            mkU32(0x1f))));
3170                     assign(t0, getAcc(ac));
3171                     assign(t1, binop(Iop_Sar64, mkexpr(t0), mkexpr(t15)));
3172                     putIReg(rt, IRExpr_ITE(binop(Iop_CmpEQ32,
3173                                                        unop(Iop_8Uto32,
3174                                                             mkexpr(t15)),
3175                                                        mkU32(0)),
3176                                                  unop(Iop_64to32, mkexpr(t0)),
3177                                                  unop(Iop_64to32, mkexpr(t1))));
3178
3179                     /* Check if bits 63..31 of the result in t1 aren't 0. */
3180                     assign(t3, binop(Iop_CmpNE32,
3181                                      unop(Iop_64HIto32,
3182                                           mkexpr(t1)),
3183                                      mkU32(0)));
3184                     assign(t4, binop(Iop_CmpNE32,
3185                                      binop(Iop_And32,
3186                                            unop(Iop_64to32,
3187                                                 mkexpr(t1)),
3188                                            mkU32(0x80000000)),
3189                                      mkU32(0)));
3190                     /* Check if bits 63..31 of the result in t1 aren't
3191                        0x1ffffffff. */
3192                     assign(t5, binop(Iop_CmpNE32,
3193                                      unop(Iop_64HIto32,
3194                                           mkexpr(t1)),
3195                                      mkU32(0xffffffff)));
3196                     assign(t6, binop(Iop_CmpNE32,
3197                                      binop(Iop_And32,
3198                                            unop(Iop_64to32,
3199                                                 mkexpr(t1)),
3200                                            mkU32(0x80000000)),
3201                                      mkU32(0x80000000)));
3202                     /* If bits 63..31 aren't 0 nor 0x1ffffffff, set DSP
3203                        control register. */
3204                     assign(t7, binop(Iop_And32,
3205                                      binop(Iop_Or32,
3206                                            unop(Iop_1Sto32, mkexpr(t3)),
3207                                            unop(Iop_1Sto32, mkexpr(t4))),
3208                                      binop(Iop_Or32,
3209                                            unop(Iop_1Sto32, mkexpr(t5)),
3210                                            unop(Iop_1Sto32, mkexpr(t6)))));
3211                     putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32,
3212                                                    mkexpr(t7),
3213                                                    mkU32(0)),
3214                                              binop(Iop_Or32,
3215                                                    getDSPControl(),
3216                                                    mkU32(0x00800000)),
3217                                              getDSPControl()));
3218
3219                     /* If the last discarded bit is 1, there would be carry
3220                        when rounding, otherwise there wouldn't. We use that
3221                        fact and just add the value of the last discarded bit
3222                        to the least sifgnificant bit of the shifted value
3223                        from acc. */
3224                     assign(t8,
3225                            IRExpr_ITE(binop(Iop_CmpEQ32,
3226                                             unop(Iop_8Uto32,
3227                                                  mkexpr(t15)),
3228                                             mkU32(0)),
3229                                       mkU64(0x0ULL),
3230                                       binop(Iop_And64,
3231                                             binop(Iop_Shr64,
3232                                                   mkexpr(t0),
3233                                                   unop(Iop_32to8,
3234                                                        binop(Iop_Sub32,
3235                                                              unop(Iop_8Uto32,
3236                                                                   mkexpr(t15)),
3237                                                                   mkU32(1)))),
3238                                             mkU64(0x1ULL))));
3239
3240                     assign(t9, binop(Iop_Add64, mkexpr(t1), mkexpr(t8)));
3241
3242                     /* Repeat previous steps for the rounded value. */
3243                     assign(t10, binop(Iop_CmpNE32,
3244                                      unop(Iop_64HIto32,
3245                                           mkexpr(t9)),
3246                                      mkU32(0)));
3247                     assign(t11, binop(Iop_CmpNE32,
3248                                      binop(Iop_And32,
3249                                            unop(Iop_64to32,
3250                                                 mkexpr(t9)),
3251                                            mkU32(0x80000000)),
3252                                      mkU32(0)));
3253
3254                     assign(t12, binop(Iop_CmpNE32,
3255                                      unop(Iop_64HIto32,
3256                                           mkexpr(t9)),
3257                                      mkU32(0xffffffff)));
3258                     assign(t13, binop(Iop_CmpNE32,
3259                                      binop(Iop_And32,
3260                                            unop(Iop_64to32,
3261                                                 mkexpr(t9)),
3262                                            mkU32(0x80000000)),
3263                                      mkU32(0x80000000)));
3264
3265                     assign(t14, binop(Iop_And32,
3266                                      binop(Iop_Or32,
3267                                            unop(Iop_1Sto32, mkexpr(t10)),
3268                                            unop(Iop_1Sto32, mkexpr(t11))),
3269                                      binop(Iop_Or32,
3270                                            unop(Iop_1Sto32, mkexpr(t12)),
3271                                            unop(Iop_1Sto32, mkexpr(t13)))));
3272                     putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32,
3273                                                    mkexpr(t14),
3274                                                    mkU32(0)),
3275                                              binop(Iop_Or32,
3276                                                    getDSPControl(),
3277                                                    mkU32(0x00800000)),
3278                                              getDSPControl()));
3279                     break;
3280                  }
3281                  case 0x2: {  /* EXTP */
3282                     DIP("extp r%d, ac%d, %d", rt, ac, rs);
3283                     vassert(!mode64);
3284                     t0 = newTemp(Ity_I64);
3285                     t1 = newTemp(Ity_I32);
3286                     t2 = newTemp(Ity_I1);
3287                     t3 = newTemp(Ity_I1);
3288                     t4 = newTemp(Ity_I8);
3289                     t5 = newTemp(Ity_I64);
3290                     t6 = newTemp(Ity_I64);
3291                     t7 = newTemp(Ity_I32);
3292
3293                     assign(t0, getAcc(ac));
3294                     /* Extract pos field of DSPControl register. */
3295                     assign(t1, binop(Iop_And32, getDSPControl(), mkU32(0x3f)));
3296
3297                     /* Check if (pos - size) >= 0 [size <= pos]
3298                        if (pos < size)
3299                           put 1 to EFI field of DSPControl register
3300                        else
3301                           extract bits from acc and put 0 to EFI field of
3302                           DSPCtrl */
3303                     assign(t2, binop(Iop_CmpLT32U, mkexpr(t1), mkU32(rs)));
3304
3305                     putDSPControl(IRExpr_ITE(mkexpr(t2),
3306                                              binop(Iop_Or32,
3307                                                    binop(Iop_And32,
3308                                                          getDSPControl(),
3309                                                          mkU32(0xffffbfff)),
3310                                                    mkU32(0x4000)),
3311                                              binop(Iop_And32,
3312                                                    getDSPControl(),
3313                                                    mkU32(0xffffbfff))));
3314
3315                     /* If pos <= 31, shift right the value from the acc
3316                        (pos-size) times and take (size+1) bits from the least
3317                        significant positions. Otherwise, shift left the value
3318                        (63-pos) times, take (size+1) bits from the most
3319                        significant positions and shift right (31-size) times.*/
3320                     assign(t3, binop(Iop_CmpLE32U, mkexpr(t1), mkU32(31)));
3321
3322                     assign(t4,
3323                           IRExpr_ITE(mkexpr(t3),
3324                                      unop(Iop_32to8,
3325                                           binop(Iop_Sub32,
3326                                                 mkexpr(t1), mkU32(rs))),
3327                                      unop(Iop_32to8,
3328                                           binop(Iop_Sub32,
3329                                                 mkU32(63), mkexpr(t1)))));
3330
3331                     assign(t5, IRExpr_ITE(mkexpr(t3),
3332                                           binop(Iop_Shr64,
3333                                                 mkexpr(t0), mkexpr(t4)),
3334                                           binop(Iop_Shl64,
3335                                                 mkexpr(t0), mkexpr(t4))));
3336
3337                     /* t6 holds a mask for bit extraction */
3338                     assign(t6,
3339                            IRExpr_ITE(mkexpr(t3),
3340                                       unop(Iop_Not64,
3341                                            binop(Iop_Shl64,
3342                                                  mkU64(0xffffffffffffffffULL),
3343                                                  mkU8(rs+1))),
3344                                       unop(Iop_Not64,
3345                                            binop(Iop_Shr64,
3346                                                  mkU64(0xffffffffffffffffULL),
3347                                                  mkU8(rs+1)))));
3348
3349                     assign(t7, IRExpr_ITE(mkexpr(t3),
3350                                           unop(Iop_64to32,
3351                                                binop(Iop_And64,
3352                                                      mkexpr(t5),
3353                                                      mkexpr(t6))),
3354                                           binop(Iop_Shr32,
3355                                                 unop(Iop_64HIto32,
3356                                                      binop(Iop_And64,
3357                                                            mkexpr(t5),
3358                                                            mkexpr(t6))),
3359                                                 mkU8(31-rs))));
3360
3361                     putIReg(rt, mkexpr(t7));
3362                     break;
3363                  }
3364                  case 0x3: {  /* EXTPV */
3365                     DIP("extpv r%d, ac%d, r%d", rt, ac, rs);
3366                     vassert(!mode64);
3367                     t0 = newTemp(Ity_I64);
3368                     t1 = newTemp(Ity_I32);
3369                     t2 = newTemp(Ity_I1);
3370                     t3 = newTemp(Ity_I1);
3371                     t4 = newTemp(Ity_I8);
3372                     t5 = newTemp(Ity_I64);
3373                     t6 = newTemp(Ity_I64);
3374                     t7 = newTemp(Ity_I32);
3375                     t8 = newTemp(Ity_I32);
3376
3377                     assign(t8, binop(Iop_And32, getIReg(rs), mkU32(0x1f)));
3378                     assign(t0, getAcc(ac));
3379                     /* Extract pos field of DSPControl register. */
3380                     assign(t1, binop(Iop_And32, getDSPControl(), mkU32(0x3f)));
3381
3382                     /* Check if (pos - size) >= 0 [size <= pos]
3383                        if (pos < size)
3384                           put 1 to EFI field of DSPControl register
3385                        else
3386                           extract bits from acc and put 0 to EFI field of
3387                           DSPCtrl */
3388                     assign(t2, binop(Iop_CmpLT32U, mkexpr(t1), mkexpr(t8)));
3389
3390                     putDSPControl(IRExpr_ITE(mkexpr(t2),
3391                                              binop(Iop_Or32,
3392                                                    binop(Iop_And32,
3393                                                          getDSPControl(),
3394                                                          mkU32(0xffffbfff)),
3395                                                    mkU32(0x4000)),
3396                                              binop(Iop_And32,
3397                                                    getDSPControl(),
3398                                                    mkU32(0xffffbfff))));
3399
3400                     /* If pos <= 31, shift right the value from the acc
3401                        (pos-size) times and take (size+1) bits from the least
3402                        significant positions. Otherwise, shift left the value
3403                        (63-pos) times, take (size+1) bits from the most
3404                        significant positions and shift right (31-size)
3405                        times. */
3406                     assign(t3, binop(Iop_CmpLE32U, mkexpr(t1), mkU32(31)));
3407
3408                     assign(t4,
3409                           IRExpr_ITE(mkexpr(t3),
3410                                      unop(Iop_32to8,
3411                                           binop(Iop_Sub32,
3412                                                 mkexpr(t1), mkexpr(t8))),
3413                                      unop(Iop_32to8,
3414                                           binop(Iop_Sub32,
3415                                                 mkU32(63), mkexpr(t1)))));
3416
3417                     assign(t5, IRExpr_ITE(mkexpr(t3),
3418                                           binop(Iop_Shr64,
3419                                                 mkexpr(t0), mkexpr(t4)),
3420                                           binop(Iop_Shl64,
3421                                                 mkexpr(t0), mkexpr(t4))));
3422
3423                     /* t6 holds a mask for bit extraction. */
3424                     assign(t6,
3425                            IRExpr_ITE(mkexpr(t3),
3426                                       unop(Iop_Not64,
3427                                            binop(Iop_Shl64,
3428                                                  mkU64(0xffffffffffffffffULL),
3429                                                  unop(Iop_32to8,
3430                                                       binop(Iop_Add32,
3431                                                             mkexpr(t8),
3432                                                             mkU32(1))))),
3433                                       unop(Iop_Not64,
3434                                            binop(Iop_Shr64,
3435                                                  mkU64(0xffffffffffffffffULL),
3436                                                  unop(Iop_32to8,
3437                                                       binop(Iop_Add32,
3438                                                             mkexpr(t8),
3439                                                             mkU32(1)))))));
3440
3441                     assign(t7, IRExpr_ITE(mkexpr(t3),
3442                                           unop(Iop_64to32,
3443                                                binop(Iop_And64,
3444                                                      mkexpr(t5),
3445                                                      mkexpr(t6))),
3446                                           binop(Iop_Shr32,
3447                                                 unop(Iop_64HIto32,
3448                                                      binop(Iop_And64,
3449                                                            mkexpr(t5),
3450                                                            mkexpr(t6))),
3451                                                 unop(Iop_32to8,
3452                                                      binop(Iop_Sub32,
3453                                                            mkU32(31),
3454                                                            mkexpr(t8))))));
3455
3456                     putIReg(rt, mkexpr(t7));
3457                     break;
3458                  }
3459                  case 0x4: {  /* EXTR_R.W */
3460                     DIP("extr_r.w r%d, ac%d, %d", rt, ac, rs);
3461                     vassert(!mode64);
3462                     t0 = newTemp(Ity_I64);
3463                     t1 = newTemp(Ity_I64);
3464                     t2 = newTemp(Ity_I32);
3465                     t3 = newTemp(Ity_I1);
3466                     t4 = newTemp(Ity_I1);
3467                     t5 = newTemp(Ity_I1);
3468                     t6 = newTemp(Ity_I1);
3469                     t7 = newTemp(Ity_I32);
3470                     t8 = newTemp(Ity_I64);
3471                     t9 = newTemp(Ity_I64);
3472                     t10 = newTemp(Ity_I1);
3473                     t11 = newTemp(Ity_I1);
3474                     t12 = newTemp(Ity_I1);
3475                     t13 = newTemp(Ity_I1);
3476                     t14 = newTemp(Ity_I32);
3477                     t15 = newTemp(Ity_I64);
3478                     t16 = newTemp(Ity_I1);
3479
3480                     assign(t0, getAcc(ac));
3481                     assign(t16, binop(Iop_CmpEQ32,
3482                                       mkU32(rs),
3483                                       mkU32(0)));
3484                     assign(t1, IRExpr_ITE(mkexpr(t16),
3485                                           mkexpr(t0),
3486                                           binop(Iop_Sar64,
3487                                                 mkexpr(t0),
3488                                                 mkU8(rs))));
3489                     /* If the last discarded bit is 1, there would be carry
3490                        when rounding, otherwise there wouldn't. We use that
3491                        fact and just add the value of the last discarded bit
3492                        to the least significant bit of the shifted value
3493                        from acc. */
3494                     assign(t15, binop(Iop_Shr64,
3495                                       mkexpr(t0),
3496                                       unop(Iop_32to8,
3497                                            binop(Iop_Sub32,
3498                                                  binop(Iop_And32,
3499                                                        mkU32(rs),
3500                                                        mkU32(0x1f)),
3501                                                  mkU32(1)))));
3502
3503                     assign(t8,
3504                            IRExpr_ITE(mkexpr(t16),
3505                                       mkU64(0x0ULL),
3506                                       binop(Iop_And64,
3507                                             mkexpr(t15),
3508                                             mkU64(0x0000000000000001ULL))));
3509                     assign(t9, binop(Iop_Add64, mkexpr(t1), mkexpr(t8)));
3510                     putIReg(rt, unop(Iop_64to32, mkexpr(t9)));
3511
3512                     /* Check if bits 63..31 of the result in t1 aren't 0. */
3513                     assign(t3, binop(Iop_CmpNE32,
3514                                      unop(Iop_64HIto32,
3515                                           mkexpr(t1)),
3516                                      mkU32(0)));
3517                     assign(t4, binop(Iop_CmpNE32,
3518                                      binop(Iop_And32,
3519                                            unop(Iop_64to32,
3520                                                 mkexpr(t1)),
3521                                            mkU32(0x80000000)),
3522                                      mkU32(0)));
3523
3524                     /* Check if bits 63..31 of the result in t1 aren't
3525                        0x1ffffffff. */
3526                     assign(t5, binop(Iop_CmpNE32,
3527                                      unop(Iop_64HIto32,
3528                                           mkexpr(t1)),
3529                                      mkU32(0xffffffff)));
3530                     assign(t6, binop(Iop_CmpNE32,
3531                                      binop(Iop_And32,
3532                                            unop(Iop_64to32,
3533                                                 mkexpr(t1)),
3534                                            mkU32(0x80000000)),
3535                                      mkU32(0x80000000)));
3536                     /* If bits 63..31 aren't 0 nor 0x1ffffffff, set DSP
3537                        control register. */
3538                     assign(t7, binop(Iop_And32,
3539                                      binop(Iop_Or32,
3540                                            unop(Iop_1Sto32, mkexpr(t3)),
3541                                            unop(Iop_1Sto32, mkexpr(t4))),
3542                                      binop(Iop_Or32,
3543                                            unop(Iop_1Sto32, mkexpr(t5)),
3544                                            unop(Iop_1Sto32, mkexpr(t6)))));
3545                     putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32,
3546                                                    mkexpr(t7),
3547                                                    mkU32(0)),
3548                                              binop(Iop_Or32,
3549                                                    getDSPControl(),
3550                                                    mkU32(0x00800000)),
3551                                              getDSPControl()));
3552
3553                     /* Repeat previous steps for the rounded value. */
3554                     assign(t10, binop(Iop_CmpNE32,
3555                                      unop(Iop_64HIto32,
3556                                           mkexpr(t9)),
3557                                      mkU32(0)));
3558                     assign(t11, binop(Iop_CmpNE32,
3559                                      binop(Iop_And32,
3560                                            unop(Iop_64to32,
3561                                                 mkexpr(t9)),
3562                                            mkU32(0x80000000)),
3563                                      mkU32(0)));
3564
3565                     assign(t12, binop(Iop_CmpNE32,
3566                                      unop(Iop_64HIto32,
3567                                           mkexpr(t9)),
3568                                      mkU32(0xffffffff)));
3569                     assign(t13, binop(Iop_CmpNE32,
3570                                      binop(Iop_And32,
3571                                            unop(Iop_64to32,
3572                                                 mkexpr(t9)),
3573                                            mkU32(0x80000000)),
3574                                      mkU32(0x80000000)));
3575
3576                     assign(t14, binop(Iop_And32,
3577                                      binop(Iop_Or32,
3578                                            unop(Iop_1Sto32, mkexpr(t10)),
3579                                            unop(Iop_1Sto32, mkexpr(t11))),
3580                                      binop(Iop_Or32,
3581                                            unop(Iop_1Sto32, mkexpr(t12)),
3582                                            unop(Iop_1Sto32, mkexpr(t13)))));
3583                     putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32,
3584                                                    mkexpr(t14),
3585                                                    mkU32(0)),
3586                                              binop(Iop_Or32,
3587                                                    getDSPControl(),
3588                                                    mkU32(0x00800000)),
3589                                              getDSPControl()));
3590                     break;
3591                  }
3592                  case 0x5: {  /* EXTRV_R.W */
3593                     DIP("extrv_r.w r%d, ac%d, r%d", rt, ac, rs);
3594                     vassert(!mode64);
3595                     t0 = newTemp(Ity_I64);
3596                     t1 = newTemp(Ity_I64);
3597                     t2 = newTemp(Ity_I32);
3598                     t3 = newTemp(Ity_I1);
3599                     t4 = newTemp(Ity_I1);
3600                     t5 = newTemp(Ity_I1);
3601                     t6 = newTemp(Ity_I1);
3602                     t7 = newTemp(Ity_I32);
3603                     t8 = newTemp(Ity_I64);
3604                     t9 = newTemp(Ity_I64);
3605                     t10 = newTemp(Ity_I1);
3606                     t11 = newTemp(Ity_I1);
3607                     t12 = newTemp(Ity_I1);
3608                     t13 = newTemp(Ity_I1);
3609                     t14 = newTemp(Ity_I32);
3610                     t15 = newTemp(Ity_I8);
3611
3612                     assign(t15, unop(Iop_32to8,
3613                                      binop(Iop_And32,
3614                                            getIReg(rs),
3615                                            mkU32(0x1f))));
3616                     assign(t0, getAcc(ac));
3617                     assign(t1, binop(Iop_Sar64, mkexpr(t0), mkexpr(t15)));
3618
3619                     /* Check if bits 63..31 of the result in t1 aren't 0. */
3620                     assign(t3, binop(Iop_CmpNE32,
3621                                      unop(Iop_64HIto32,
3622                                           mkexpr(t1)),
3623                                      mkU32(0)));
3624                     assign(t4, binop(Iop_CmpNE32,
3625                                      binop(Iop_And32,
3626                                            unop(Iop_64to32,
3627                                                 mkexpr(t1)),
3628                                            mkU32(0x80000000)),
3629                                      mkU32(0)));
3630                     /* Check if bits 63..31 of the result in t1 aren't
3631                        0x1ffffffff. */
3632                     assign(t5, binop(Iop_CmpNE32,
3633                                      unop(Iop_64HIto32,
3634                                           mkexpr(t1)),
3635                                      mkU32(0xffffffff)));
3636                     assign(t6, binop(Iop_CmpNE32,
3637                                      binop(Iop_And32,
3638                                            unop(Iop_64to32,
3639                                                 mkexpr(t1)),
3640                                            mkU32(0x80000000)),
3641                                      mkU32(0x80000000)));
3642                     /* If bits 63..31 aren't 0 nor 0x1ffffffff, set DSP
3643                        control register. */
3644                     assign(t7, binop(Iop_And32,
3645                                      binop(Iop_Or32,
3646                                            unop(Iop_1Sto32, mkexpr(t3)),
3647                                            unop(Iop_1Sto32, mkexpr(t4))),
3648                                      binop(Iop_Or32,
3649                                            unop(Iop_1Sto32, mkexpr(t5)),
3650                                            unop(Iop_1Sto32, mkexpr(t6)))));
3651                     putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32,
3652                                                    mkexpr(t7),
3653                                                    mkU32(0)),
3654                                              binop(Iop_Or32,
3655                                                    getDSPControl(),
3656                                                    mkU32(0x00800000)),
3657                                              getDSPControl()));
3658
3659                     /* If the last discarded bit is 1, there would be carry
3660                        when rounding, otherwise there wouldn't. We use that
3661                        fact and just add the value of the last discarded bit
3662                        to the least sifgnificant bit of the shifted value
3663                        from acc. */
3664                     assign(t8,
3665                            IRExpr_ITE(binop(Iop_CmpEQ32,
3666                                             unop(Iop_8Uto32,
3667                                                  mkexpr(t15)),
3668                                             mkU32(0)),
3669                                       mkU64(0x0ULL),
3670                                       binop(Iop_And64,
3671                                             binop(Iop_Shr64,
3672                                                   mkexpr(t0),
3673                                                   unop(Iop_32to8,
3674                                                        binop(Iop_Sub32,
3675                                                              unop(Iop_8Uto32,
3676                                                                   mkexpr(t15)),
3677                                                                   mkU32(1)))),
3678                                             mkU64(0x1ULL))));
3679
3680                     assign(t9, binop(Iop_Add64, mkexpr(t1), mkexpr(t8)));
3681                     /* Put rounded value in destination register. */
3682                     putIReg(rt, unop(Iop_64to32, mkexpr(t9)));
3683
3684                     /* Repeat previous steps for the rounded value. */
3685                     assign(t10, binop(Iop_CmpNE32,
3686                                      unop(Iop_64HIto32,
3687                                           mkexpr(t9)),
3688                                      mkU32(0)));
3689                     assign(t11, binop(Iop_CmpNE32,
3690                                      binop(Iop_And32,
3691                                            unop(Iop_64to32,
3692                                                 mkexpr(t9)),
3693                                            mkU32(0x80000000)),
3694                                      mkU32(0)));
3695
3696                     assign(t12, binop(Iop_CmpNE32,
3697                                      unop(Iop_64HIto32,
3698                                           mkexpr(t9)),
3699                                      mkU32(0xffffffff)));
3700                     assign(t13, binop(Iop_CmpNE32,
3701                                      binop(Iop_And32,
3702                                            unop(Iop_64to32,
3703                                                 mkexpr(t9)),
3704                                            mkU32(0x80000000)),
3705                                      mkU32(0x80000000)));
3706
3707                     assign(t14, binop(Iop_And32,
3708                                      binop(Iop_Or32,
3709                                            unop(Iop_1Sto32, mkexpr(t10)),
3710                                            unop(Iop_1Sto32, mkexpr(t11))),
3711                                      binop(Iop_Or32,
3712                                            unop(Iop_1Sto32, mkexpr(t12)),
3713                                            unop(Iop_1Sto32, mkexpr(t13)))));
3714                     putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32,
3715                                                    mkexpr(t14),
3716                                                    mkU32(0)),
3717                                              binop(Iop_Or32,
3718                                                    getDSPControl(),
3719                                                    mkU32(0x00800000)),
3720                                              getDSPControl()));
3721                     break;
3722                  }
3723                  case 0x6: {  /* EXTR_RS.W */
3724                     DIP("extr_rs.w r%d, ac%d, %d", rt, ac, rs);
3725                     vassert(!mode64);
3726                     t0 = newTemp(Ity_I64);
3727                     t1 = newTemp(Ity_I64);
3728                     t2 = newTemp(Ity_I32);
3729                     t3 = newTemp(Ity_I1);
3730                     t4 = newTemp(Ity_I1);
3731                     t5 = newTemp(Ity_I1);
3732                     t6 = newTemp(Ity_I1);
3733                     t7 = newTemp(Ity_I32);
3734                     t8 = newTemp(Ity_I64);
3735                     t9 = newTemp(Ity_I64);
3736                     t10 = newTemp(Ity_I1);
3737                     t11 = newTemp(Ity_I1);
3738                     t12 = newTemp(Ity_I1);
3739                     t13 = newTemp(Ity_I1);
3740                     t14 = newTemp(Ity_I32);
3741                     t16 = newTemp(Ity_I32);
3742
3743                     assign(t0, getAcc(ac));
3744                     if (0 == rs) {
3745                        assign(t1, mkexpr(t0));
3746                     } else {
3747                        assign(t1, binop(Iop_Sar64, mkexpr(t0), mkU8(rs)));
3748                     }
3749
3750                     /* Check if bits 63..31 of the result in t1 aren't 0. */
3751                     assign(t3, binop(Iop_CmpNE32,
3752                                      unop(Iop_64HIto32,
3753                                           mkexpr(t1)),
3754                                      mkU32(0)));
3755                     assign(t4, binop(Iop_CmpNE32,
3756                                      binop(Iop_And32,
3757                                            unop(Iop_64to32,
3758                                                 mkexpr(t1)),
3759                                            mkU32(0x80000000)),
3760                                      mkU32(0)));
3761                     /* Check if bits 63..31 of the result in t1 aren't
3762                        0x1ffffffff. */
3763                     assign(t5, binop(Iop_CmpNE32,
3764                                      unop(Iop_64HIto32,
3765                                           mkexpr(t1)),
3766                                      mkU32(0xffffffff)));
3767                     assign(t6, binop(Iop_CmpNE32,
3768                                      binop(Iop_And32,
3769                                            unop(Iop_64to32,
3770                                                 mkexpr(t1)),
3771                                            mkU32(0x80000000)),
3772                                      mkU32(0x80000000)));
3773                     /* If bits 63..31 aren't 0 nor 0x1ffffffff, set DSP
3774                        control register. */
3775                     assign(t7, binop(Iop_And32,
3776                                      binop(Iop_Or32,
3777                                            unop(Iop_1Sto32, mkexpr(t3)),
3778                                            unop(Iop_1Sto32, mkexpr(t4))),
3779                                      binop(Iop_Or32,
3780                                            unop(Iop_1Sto32, mkexpr(t5)),
3781                                            unop(Iop_1Sto32, mkexpr(t6)))));
3782                     putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32,
3783                                                    mkexpr(t7),
3784                                                    mkU32(0)),
3785                                              binop(Iop_Or32,
3786                                                    getDSPControl(),
3787                                                    mkU32(0x00800000)),
3788                                              getDSPControl()));
3789
3790                     /* If the last discarded bit is 1, there would be carry
3791                        when rounding, otherwise there wouldn't. We use that
3792                        fact and just add the value of the last discarded bit
3793                        to the least sifgnificant bit of the shifted value
3794                        from acc. */
3795                     if (0 == rs) {
3796                        assign(t8, mkU64(0x0ULL));
3797                     } else {
3798                        assign(t8, binop(Iop_And64,
3799                                         binop(Iop_Shr64,
3800                                               mkexpr(t0),
3801                                               mkU8(rs-1)),
3802                                         mkU64(0x1ULL)));
3803                     }
3804
3805                     assign(t9, binop(Iop_Add64, mkexpr(t1), mkexpr(t8)));
3806
3807                     /* Repeat previous steps for the rounded value. */
3808                     assign(t10, binop(Iop_CmpNE32,
3809                                      unop(Iop_64HIto32,
3810                                           mkexpr(t9)),
3811                                      mkU32(0)));
3812                     assign(t11, binop(Iop_CmpNE32,
3813                                      binop(Iop_And32,
3814                                            unop(Iop_64to32,
3815                                                 mkexpr(t9)),
3816                                            mkU32(0x80000000)),
3817                                      mkU32(0)));
3818
3819                     assign(t12, binop(Iop_CmpNE32,
3820                                      unop(Iop_64HIto32,
3821                                           mkexpr(t9)),
3822                                      mkU32(0xffffffff)));
3823                     assign(t13, binop(Iop_CmpNE32,
3824                                      binop(Iop_And32,
3825                                            unop(Iop_64to32,
3826                                                 mkexpr(t9)),
3827                                            mkU32(0x80000000)),
3828                                      mkU32(0x80000000)));
3829
3830                     assign(t14, binop(Iop_And32,
3831                                      binop(Iop_Or32,
3832                                            unop(Iop_1Sto32, mkexpr(t10)),
3833                                            unop(Iop_1Sto32, mkexpr(t11))),
3834                                      binop(Iop_Or32,
3835                                            unop(Iop_1Sto32, mkexpr(t12)),
3836                                            unop(Iop_1Sto32, mkexpr(t13)))));
3837                     putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32,
3838                                                    mkexpr(t14),
3839                                                    mkU32(0)),
3840                                              binop(Iop_Or32,
3841                                                    getDSPControl(),
3842                                                    mkU32(0x00800000)),
3843                                              getDSPControl()));
3844
3845                     assign(t16, binop(Iop_And32,
3846                                       unop(Iop_64HIto32,
3847                                            mkexpr(t9)),
3848                                       mkU32(0x80000000)));
3849                     putIReg(rt, IRExpr_ITE(binop(Iop_CmpNE32,
3850                                                  mkexpr(t14),
3851                                                  mkU32(0)),
3852                                            IRExpr_ITE(binop(Iop_CmpEQ32,
3853                                                             mkexpr(t16),
3854                                                             mkU32(0)),
3855                                                       mkU32(0x7fffffff),
3856                                                       mkU32(0x80000000)),
3857                                            unop(Iop_64to32, mkexpr(t9))));
3858                     break;
3859                  }
3860                  case 0x7: {  /* EXTRV_RS.W */
3861                     DIP("extrv_rs.w r%d, ac%d, r%d", rt, ac, rs);
3862                     vassert(!mode64);
3863                     t0 = newTemp(Ity_I64);
3864                     t1 = newTemp(Ity_I64);
3865                     t2 = newTemp(Ity_I32);
3866                     t3 = newTemp(Ity_I1);
3867                     t4 = newTemp(Ity_I1);
3868                     t5 = newTemp(Ity_I1);
3869                     t6 = newTemp(Ity_I1);
3870                     t7 = newTemp(Ity_I32);
3871                     t8 = newTemp(Ity_I64);
3872                     t9 = newTemp(Ity_I64);
3873                     t10 = newTemp(Ity_I1);
3874                     t11 = newTemp(Ity_I1);
3875                     t12 = newTemp(Ity_I1);
3876                     t13 = newTemp(Ity_I1);
3877                     t14 = newTemp(Ity_I32);
3878                     t15 = newTemp(Ity_I32);
3879                     t16 = newTemp(Ity_I32);
3880                     t17 = newTemp(Ity_I1);
3881
3882                     assign(t15, binop(Iop_And32,
3883                                       getIReg(rs),
3884                                       mkU32(0x1f)));
3885                     assign(t17, binop(Iop_CmpEQ32,
3886                                       mkexpr(t15),
3887                                       mkU32(0)));
3888                     assign(t0, getAcc(ac));
3889                     assign(t1, IRExpr_ITE(mkexpr(t17),
3890                                           mkexpr(t0),
3891                                           binop(Iop_Sar64,
3892                                                 mkexpr(t0),
3893                                                 unop(Iop_32to8,
3894                                                      mkexpr(t15)))));
3895
3896                     /* Check if bits 63..31 of the result in t1 aren't 0. */
3897                     assign(t3, binop(Iop_CmpNE32,
3898                                      unop(Iop_64HIto32,
3899                                           mkexpr(t1)),
3900                                      mkU32(0)));
3901                     assign(t4, binop(Iop_CmpNE32,
3902                                      binop(Iop_And32,
3903                                            unop(Iop_64to32,
3904                                                 mkexpr(t1)),
3905                                            mkU32(0x80000000)),
3906                                      mkU32(0)));
3907                     /* Check if bits 63..31 of the result in t1 aren't
3908                        0x1ffffffff. */
3909                     assign(t5, binop(Iop_CmpNE32,
3910                                      unop(Iop_64HIto32,
3911                                           mkexpr(t1)),
3912                                      mkU32(0xffffffff)));
3913                     assign(t6, binop(Iop_CmpNE32,
3914                                      binop(Iop_And32,
3915                                            unop(Iop_64to32,
3916                                                 mkexpr(t1)),
3917                                            mkU32(0x80000000)),
3918                                      mkU32(0x80000000)));
3919                     /* If bits 63..31 aren't 0 nor 0x1ffffffff, set DSP
3920                        control register. */
3921                     assign(t7, binop(Iop_And32,
3922                                      binop(Iop_Or32,
3923                                            unop(Iop_1Sto32, mkexpr(t3)),
3924                                            unop(Iop_1Sto32, mkexpr(t4))),
3925                                      binop(Iop_Or32,
3926                                            unop(Iop_1Sto32, mkexpr(t5)),
3927                                            unop(Iop_1Sto32, mkexpr(t6)))));
3928                     putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32,
3929                                                    mkexpr(t7),
3930                                                    mkU32(0)),
3931                                              binop(Iop_Or32,
3932                                                    getDSPControl(),
3933                                                    mkU32(0x00800000)),
3934                                              getDSPControl()));
3935
3936                     /* If the last discarded bit is 1, there would be carry
3937                        when rounding, otherwise there wouldn't. We use that
3938                        fact and just add the value of the last discarded bit
3939                        to the least sifgnificant bit of the shifted value
3940                        from acc. */
3941                     assign(t8,
3942                            IRExpr_ITE(mkexpr(t17),
3943                                       mkU64(0x0ULL),
3944                                       binop(Iop_And64,
3945                                             binop(Iop_Shr64,
3946                                                   mkexpr(t0),
3947                                                   unop(Iop_32to8,
3948                                                        binop(Iop_Sub32,
3949                                                              mkexpr(t15),
3950                                                              mkU32(1)))),
3951                                             mkU64(0x1ULL))));
3952
3953                     assign(t9, binop(Iop_Add64, mkexpr(t1), mkexpr(t8)));
3954
3955                     /* Repeat previous steps for the rounded value. */
3956                     assign(t10, binop(Iop_CmpNE32,
3957                                      unop(Iop_64HIto32,
3958                                           mkexpr(t9)),
3959                                      mkU32(0)));
3960                     assign(t11, binop(Iop_CmpNE32,
3961                                      binop(Iop_And32,
3962                                            unop(Iop_64to32,
3963                                                 mkexpr(t9)),
3964                                            mkU32(0x80000000)),
3965                                      mkU32(0)));
3966
3967                     assign(t12, binop(Iop_CmpNE32,
3968                                      unop(Iop_64HIto32,
3969                                           mkexpr(t9)),
3970                                      mkU32(0xffffffff)));
3971                     assign(t13, binop(Iop_CmpNE32,
3972                                      binop(Iop_And32,
3973                                            unop(Iop_64to32,
3974                                                 mkexpr(t9)),
3975                                            mkU32(0x80000000)),
3976                                      mkU32(0x80000000)));
3977
3978                     assign(t14, binop(Iop_And32,
3979                                      binop(Iop_Or32,
3980                                            unop(Iop_1Sto32, mkexpr(t10)),
3981                                            unop(Iop_1Sto32, mkexpr(t11))),
3982                                      binop(Iop_Or32,
3983                                            unop(Iop_1Sto32, mkexpr(t12)),
3984                                            unop(Iop_1Sto32, mkexpr(t13)))));
3985                     putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32,
3986                                                    mkexpr(t14),
3987                                                    mkU32(0)),
3988                                              binop(Iop_Or32,
3989                                                    getDSPControl(),
3990                                                    mkU32(0x00800000)),
3991                                              getDSPControl()));
3992
3993                     assign(t16, binop(Iop_And32,
3994                                       unop(Iop_64HIto32,
3995                                            mkexpr(t9)),
3996                                       mkU32(0x80000000)));
3997                     putIReg(rt, IRExpr_ITE(binop(Iop_CmpNE32,
3998                                                  mkexpr(t14),
3999                                                  mkU32(0)),
4000                                            IRExpr_ITE(binop(Iop_CmpEQ32,
4001                                                             mkexpr(t16),
4002                                                             mkU32(0)),
4003                                                       mkU32(0x7fffffff),
4004                                                       mkU32(0x80000000)),
4005                                            unop(Iop_64to32, mkexpr(t9))));
4006                     break;
4007                  }
4008                  case 0xA: {  /* EXTPDP */
4009                     DIP("extpdp r%d, ac%d, %d", rt, ac, rs);
4010                     vassert(!mode64);
4011                     t0 = newTemp(Ity_I64);
4012                     t1 = newTemp(Ity_I32);
4013                     t2 = newTemp(Ity_I1);
4014                     t3 = newTemp(Ity_I1);
4015                     t4 = newTemp(Ity_I8);
4016                     t5 = newTemp(Ity_I64);
4017                     t6 = newTemp(Ity_I64);
4018                     t7 = newTemp(Ity_I32);
4019                     t8 = newTemp(Ity_I32);
4020
4021                     assign(t0, getAcc(ac));
4022                     /* Extract pos field of DSPControl register. */
4023                     assign(t1, binop(Iop_And32, getDSPControl(), mkU32(0x3f)));
4024
4025                     /* Check if (pos - size) >= 0 [size <= pos]
4026                        if (pos < size)
4027                           put 1 to EFI field of DSPControl register
4028                        else
4029                           extract bits from acc and put 0 to EFI field of
4030                           DSPCtrl */
4031                     assign(t2, binop(Iop_CmpLT32U, mkexpr(t1), mkU32(rs)));
4032
4033                     assign(t8, binop(Iop_Or32,
4034                                      binop(Iop_And32,
4035                                            getDSPControl(),
4036                                            mkU32(0xffffbfc0)),
4037                                      binop(Iop_And32,
4038                                            binop(Iop_Sub32,
4039                                                  binop(Iop_And32,
4040                                                        getDSPControl(),
4041                                                        mkU32(0x3f)),
4042                                                  mkU32(rs+1)),
4043                                            mkU32(0x3f))));
4044                     putDSPControl(IRExpr_ITE(mkexpr(t2),
4045                                              binop(Iop_Or32,
4046                                                     binop(Iop_And32,
4047                                                           getDSPControl(),
4048                                                           mkU32(0xffffbfff)),
4049                                                     mkU32(0x4000)),
4050                                              mkexpr(t8)));
4051
4052                     /* If pos <= 31, shift right the value from the acc
4053                        (pos-size) times and take (size+1) bits from the least
4054                        significant positions. Otherwise, shift left the value
4055                        (63-pos) times, take (size+1) bits from the most
4056                        significant positions and shift right (31-size) times.
4057                     */
4058                     assign(t3, binop(Iop_CmpLE32U, mkexpr(t1), mkU32(31)));
4059
4060                     assign(t4,
4061                            IRExpr_ITE(mkexpr(t3),
4062                                       unop(Iop_32to8,
4063                                            binop(Iop_Sub32,
4064                                                  mkexpr(t1), mkU32(rs))),
4065                                       unop(Iop_32to8,
4066                                            binop(Iop_Sub32,
4067                                                  mkU32(63), mkexpr(t1)))));
4068
4069                     assign(t5, IRExpr_ITE(mkexpr(t3),
4070                                           binop(Iop_Shr64,
4071                                                 mkexpr(t0), mkexpr(t4)),
4072                                           binop(Iop_Shl64,
4073                                                 mkexpr(t0), mkexpr(t4))));
4074
4075                     /* t6 holds a mask for bit extraction. */
4076                     assign(t6,
4077                            IRExpr_ITE(mkexpr(t3),
4078                                       unop(Iop_Not64,
4079                                            binop(Iop_Shl64,
4080                                                  mkU64(0xffffffffffffffffULL),
4081                                                  mkU8(rs+1))),
4082                                       unop(Iop_Not64,
4083                                            binop(Iop_Shr64,
4084                                                  mkU64(0xffffffffffffffffULL),
4085                                                  mkU8(rs+1)))));
4086
4087                     assign(t7, IRExpr_ITE(mkexpr(t3),
4088                                           unop(Iop_64to32,
4089                                                binop(Iop_And64,
4090                                                      mkexpr(t5),
4091                                                      mkexpr(t6))),
4092                                           binop(Iop_Shr32,
4093                                                 unop(Iop_64HIto32,
4094                                                      binop(Iop_And64,
4095                                                            mkexpr(t5),
4096                                                            mkexpr(t6))),
4097                                                 mkU8(31-rs))));
4098
4099                     putIReg(rt, mkexpr(t7));
4100                     break;
4101                  }
4102                  case 0xB: {  /* EXTPDPV */
4103                     DIP("extpdpv r%d, ac%d, r%d", rt, ac, rs);
4104                     vassert(!mode64);
4105                     t0 = newTemp(Ity_I64);
4106                     t1 = newTemp(Ity_I32);
4107                     t2 = newTemp(Ity_I1);
4108                     t3 = newTemp(Ity_I1);
4109                     t4 = newTemp(Ity_I8);
4110                     t5 = newTemp(Ity_I64);
4111                     t6 = newTemp(Ity_I64);
4112                     t7 = newTemp(Ity_I32);
4113                     t8 = newTemp(Ity_I32);
4114                     t9 = newTemp(Ity_I32);
4115
4116                     assign(t8, binop(Iop_And32, getIReg(rs), mkU32(0x1f)));
4117                     assign(t0, getAcc(ac));
4118                     /* Extract pos field of DSPControl register. */
4119                     assign(t1, binop(Iop_And32, getDSPControl(), mkU32(0x3f)));
4120
4121                     /* Check if (pos - size) >= 0 [size <= pos]
4122                        if (pos < size)
4123                           put 1 to EFI field of DSPControl register
4124                        else
4125                           extract bits from acc and put 0 to EFI field of
4126                           DSPCtrl */
4127                     assign(t2, binop(Iop_CmpLT32U, mkexpr(t1), mkexpr(t8)));
4128
4129                     assign(t9, binop(Iop_Or32,
4130                                      binop(Iop_And32,
4131                                            getDSPControl(),
4132                                            mkU32(0xffffbfc0)),
4133                                      binop(Iop_And32,
4134                                            binop(Iop_Sub32,
4135                                                  binop(Iop_And32,
4136                                                        getDSPControl(),
4137                                                        mkU32(0x3f)),
4138                                                  binop(Iop_Add32,
4139                                                        mkexpr(t8),
4140                                                        mkU32(0x1))),
4141                                            mkU32(0x3f))));
4142                     putDSPControl(IRExpr_ITE(mkexpr(t2),
4143                                              binop(Iop_Or32,
4144                                                    binop(Iop_And32,
4145                                                          getDSPControl(),
4146                                                          mkU32(0xffffbfff)),
4147                                                    mkU32(0x4000)),
4148                                              mkexpr(t9)));
4149
4150                     /* If pos <= 31, shift right the value from the acc
4151                        (pos-size) times and take (size+1) bits from the least
4152                        significant positions. Otherwise, shift left the value
4153                        (63-pos) times, take (size+1) bits from the most
4154                        significant positions and shift right (31-size) times.
4155                     */
4156                     assign(t3, binop(Iop_CmpLE32U, mkexpr(t1), mkU32(31)));
4157
4158                     assign(t4,
4159                            IRExpr_ITE(mkexpr(t3),
4160                                      unop(Iop_32to8,
4161                                           binop(Iop_Sub32,
4162                                                 mkexpr(t1), mkexpr(t8))),
4163                                      unop(Iop_32to8,
4164                                           binop(Iop_Sub32,
4165                                                 mkU32(63), mkexpr(t1)))));
4166
4167                     assign(t5, IRExpr_ITE(mkexpr(t3),
4168                                           binop(Iop_Shr64,
4169                                                 mkexpr(t0), mkexpr(t4)),
4170                                           binop(Iop_Shl64,
4171                                                 mkexpr(t0), mkexpr(t4))));
4172
4173                     /* t6 holds a mask for bit extraction. */
4174                     assign(t6,
4175                            IRExpr_ITE(mkexpr(t3),
4176                                       unop(Iop_Not64,
4177                                            binop(Iop_Shl64,
4178                                                  mkU64(0xffffffffffffffffULL),
4179                                                  unop(Iop_32to8,
4180                                                       binop(Iop_Add32,
4181                                                             mkexpr(t8),
4182                                                             mkU32(1))))),
4183                                       unop(Iop_Not64,
4184                                            binop(Iop_Shr64,
4185                                                  mkU64(0xffffffffffffffffULL),
4186                                                  unop(Iop_32to8,
4187                                                       binop(Iop_Add32,
4188                                                             mkexpr(t8),
4189                                                             mkU32(1)))))));
4190
4191                     assign(t7, IRExpr_ITE(mkexpr(t3),
4192                                           unop(Iop_64to32,
4193                                                binop(Iop_And64,
4194                                                      mkexpr(t5),
4195                                                      mkexpr(t6))),
4196                                           binop(Iop_Shr32,
4197                                                 unop(Iop_64HIto32,
4198                                                      binop(Iop_And64,
4199                                                            mkexpr(t5),
4200                                                            mkexpr(t6))),
4201                                                 unop(Iop_32to8,
4202                                                      binop(Iop_Sub32,
4203                                                            mkU32(31),
4204                                                            mkexpr(t8))))));
4205
4206                     putIReg(rt, mkexpr(t7));
4207                     break;
4208                  }
4209                  case 0xE: {  /* EXTR_S.H */
4210                     DIP("extr_s.h r%d, ac%d, %d", rt, ac, rs);
4211                     vassert(!mode64);
4212                     t0 = newTemp(Ity_I64);
4213                     t1 = newTemp(Ity_I64);
4214                     t2 = newTemp(Ity_I32);
4215                     t3 = newTemp(Ity_I64);
4216                     t4 = newTemp(Ity_I32);
4217                     t5 = newTemp(Ity_I32);
4218                     t6 = newTemp(Ity_I64);
4219                     t7 = newTemp(Ity_I32);
4220                     t9 = newTemp(Ity_I32);
4221
4222                     assign(t0, getAcc(ac));
4223
4224                     assign(t1, binop(Iop_Sar64, mkexpr(t0), mkU8(rs)));
4225
4226                     assign(t2, binop(Iop_Or32,
4227                                      getDSPControl(), mkU32(0x00800000)));
4228
4229                     assign(t9, binop(Iop_And32,
4230                                      unop(Iop_64to32,
4231                                           mkexpr(t1)),
4232                                      mkU32(0x80000000)));
4233                     putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32,
4234                                                    mkexpr(t9),
4235                                                    binop(Iop_And32,
4236                                                          unop(Iop_64HIto32,
4237                                                               mkexpr(t0)),
4238                                                          mkU32(0x80000000))),
4239                                              mkexpr(t2),
4240                                              getDSPControl()));
4241
4242                     /* Check if t1 > 0x7fff ((t1 - 0x7fff) > 0)
4243                        1. subtract 0x7fff from t1
4244                        2. if the resulting number is positive (sign bit = 0)
4245                           and any of the other bits is 1, the value is > 0. */
4246                     assign(t3, binop(Iop_Sub64,
4247                                      mkexpr(t1),
4248                                      mkU64(0x0000000000007fffULL)));
4249                     assign(t4, binop(Iop_And32,
4250                                       binop(Iop_Or32,
4251                                            unop(Iop_1Sto32,
4252                                                 binop(Iop_CmpNE32,
4253                                                       mkU32(0),
4254                                                       binop(Iop_And32,
4255                                                             unop(Iop_64HIto32,
4256                                                                  mkexpr(t3)),
4257                                                             mkU32(0x7fffffff)))),
4258                                            unop(Iop_1Sto32,
4259                                                 binop(Iop_CmpNE32,
4260                                                       mkU32(0),
4261                                                       unop(Iop_64to32,
4262                                                            mkexpr(t3))))),
4263                                       unop(Iop_1Sto32,
4264                                            binop(Iop_CmpEQ32,
4265                                                  binop(Iop_And32,
4266                                                        unop(Iop_64HIto32,
4267                                                                  mkexpr(t3)),
4268                                                             mkU32(0x80000000)),
4269                                                  mkU32(0)))));
4270                     putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32,
4271                                                    mkU32(0),
4272                                                    mkexpr(t4)),
4273                                              binop(Iop_Or32,
4274                                                    getDSPControl(),
4275                                                    mkU32(0x00800000)),
4276                                              getDSPControl()));
4277                     /* Check if t1<0xffffffffffff8000 (0xffffffffffff8000-t1)>0
4278                        1. subtract t1 from 0xffffffffffff8000
4279                        2. if the resulting number is positive (sign bit = 0)
4280                            and any of the other bits is 1, the value is > 0 */
4281                     assign(t6, binop(Iop_Sub64,
4282                                       mkU64(0xffffffffffff8000ULL),
4283                                       mkexpr(t1)));
4284                     assign(t7, binop(Iop_And32,
4285                                      binop(Iop_Or32,
4286                                            unop(Iop_1Sto32,
4287                                                 binop(Iop_CmpNE32,
4288                                                       mkU32(0),
4289                                                       binop(Iop_And32,
4290                                                             unop(Iop_64HIto32,
4291                                                                  mkexpr(t6)),
4292                                                             mkU32(0x7fffffff)))),
4293                                            unop(Iop_1Sto32,
4294                                                 binop(Iop_CmpNE32,
4295                                                       mkU32(0),
4296                                                       unop(Iop_64to32,
4297                                                            mkexpr(t6))))),
4298                                      unop(Iop_1Sto32,
4299                                            binop(Iop_CmpEQ32,
4300                                                  binop(Iop_And32,
4301                                                        unop(Iop_64HIto32,
4302                                                                  mkexpr(t6)),
4303                                                             mkU32(0x80000000)),
4304                                                  mkU32(0)))));
4305                     putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32,
4306                                                    mkU32(0),
4307                                                    mkexpr(t7)),
4308                                              binop(Iop_Or32,
4309                                                    getDSPControl(),
4310                                                    mkU32(0x00800000)),
4311                                              getDSPControl()));
4312                     putIReg(rt, IRExpr_ITE(binop(Iop_CmpNE32,
4313                                                    mkU32(0),
4314                                                    mkexpr(t4)),
4315                                            mkU32(0x00007fff),
4316                                            IRExpr_ITE(binop(Iop_CmpNE32,
4317                                                             mkU32(0),
4318                                                             mkexpr(t7)),
4319                                                       mkU32(0xffff8000),
4320                                                       unop(Iop_64to32,
4321                                                            mkexpr(t1)))));
4322                     break;
4323                  }
4324                  case 0xF: {  /* EXTRV_S.H */
4325                     DIP("extrv_s.h r%d, ac%d, %d", rt, ac, rs);
4326                     vassert(!mode64);
4327                     t0 = newTemp(Ity_I64);
4328                     t1 = newTemp(Ity_I64);
4329                     t2 = newTemp(Ity_I32);
4330                     t3 = newTemp(Ity_I64);
4331                     t4 = newTemp(Ity_I32);
4332                     t5 = newTemp(Ity_I32);
4333                     t6 = newTemp(Ity_I64);
4334                     t7 = newTemp(Ity_I32);
4335                     t9 = newTemp(Ity_I32);
4336
4337                     assign(t0, getAcc(ac));
4338
4339                     assign(t1, binop(Iop_Sar64,
4340                                      mkexpr(t0),
4341                                      unop(Iop_32to8,
4342                                           binop(Iop_And32,
4343                                                 getIReg(rs),
4344                                                 mkU32(0x1f)))));
4345
4346                     assign(t2, binop(Iop_Or32,
4347                                      getDSPControl(), mkU32(0x00800000)));
4348
4349                     assign(t9, binop(Iop_And32,
4350                                      unop(Iop_64to32,
4351                                           mkexpr(t1)),
4352                                      mkU32(0x80000000)));
4353                     putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32,
4354                                                    mkexpr(t9),
4355                                                    binop(Iop_And32,
4356                                                          unop(Iop_64HIto32,
4357                                                               mkexpr(t0)),
4358                                                          mkU32(0x80000000))),
4359                                              mkexpr(t2),
4360                                              getDSPControl()));
4361
4362                     /* Check if t1 > 0x7fff ((t1 - 0x7fff) > 0)
4363                        1. subtract 0x7fff from t1
4364                        2. if the resulting number is positive (sign bit = 0)
4365                           and any of the other bits is 1, the value is > 0. */
4366                     assign(t3, binop(Iop_Sub64,
4367                                      mkexpr(t1),
4368                                      mkU64(0x0000000000007fffULL)));
4369                     assign(t4, binop(Iop_And32,
4370                                       binop(Iop_Or32,
4371                                            unop(Iop_1Sto32,
4372                                                 binop(Iop_CmpNE32,
4373                                                       mkU32(0),
4374                                                       binop(Iop_And32,
4375                                                             unop(Iop_64HIto32,
4376                                                                  mkexpr(t3)),
4377                                                             mkU32(0x7fffffff)))),
4378                                            unop(Iop_1Sto32,
4379                                                 binop(Iop_CmpNE32,
4380                                                       mkU32(0),
4381                                                       unop(Iop_64to32,
4382                                                            mkexpr(t3))))),
4383                                       unop(Iop_1Sto32,
4384                                            binop(Iop_CmpEQ32,
4385                                                  binop(Iop_And32,
4386                                                        unop(Iop_64HIto32,
4387                                                                  mkexpr(t3)),
4388                                                             mkU32(0x80000000)),
4389                                                  mkU32(0)))));
4390                     putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32,
4391                                                    mkU32(0),
4392                                                    mkexpr(t4)),
4393                                              binop(Iop_Or32,
4394                                                    getDSPControl(),
4395                                                    mkU32(0x00800000)),
4396                                              getDSPControl()));
4397                     /* Check if t1<0xffffffffffff8000 (0xffffffffffff8000-t1)>0
4398                        1. subtract t1 from 0xffffffffffff8000
4399                        2. if the resulting number is positive (sign bit = 0)
4400                            and any of the other bits is 1, the value is > 0 */
4401                     assign(t6, binop(Iop_Sub64,
4402                                       mkU64(0xffffffffffff8000ULL),
4403                                       mkexpr(t1)));
4404                     assign(t7, binop(Iop_And32,
4405                                      binop(Iop_Or32,
4406                                            unop(Iop_1Sto32,
4407                                                 binop(Iop_CmpNE32,
4408                                                       mkU32(0),
4409                                                       binop(Iop_And32,
4410                                                             unop(Iop_64HIto32,
4411                                                                  mkexpr(t6)),
4412                                                             mkU32(0x7fffffff)))),
4413                                            unop(Iop_1Sto32,
4414                                                 binop(Iop_CmpNE32,
4415                                                       mkU32(0),
4416                                                       unop(Iop_64to32,
4417                                                            mkexpr(t6))))),
4418                                      unop(Iop_1Sto32,
4419                                            binop(Iop_CmpEQ32,
4420                                                  binop(Iop_And32,
4421                                                        unop(Iop_64HIto32,
4422                                                                  mkexpr(t6)),
4423                                                             mkU32(0x80000000)),
4424                                                  mkU32(0)))));
4425                     putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32,
4426                                                    mkU32(0),
4427                                                    mkexpr(t7)),
4428                                              binop(Iop_Or32,
4429                                                    getDSPControl(),
4430                                                    mkU32(0x00800000)),
4431                                              getDSPControl()));
4432                     putIReg(rt, IRExpr_ITE(binop(Iop_CmpNE32,
4433                                                    mkU32(0),
4434                                                    mkexpr(t4)),
4435                                            mkU32(0x00007fff),
4436                                            IRExpr_ITE(binop(Iop_CmpNE32,
4437                                                             mkU32(0),
4438                                                             mkexpr(t7)),
4439                                                       mkU32(0xffff8000),
4440                                                       unop(Iop_64to32,
4441                                                            mkexpr(t1)))));
4442                     break;
4443                  }
4444                  case 0x12: {  /* RDDSP*/
4445                     DIP("rddsp r%d, mask 0x%x", rd, rddsp_mask);
4446                     vassert(!mode64);
4447
4448                     putIReg(rd, mkU32(0x0));
4449
4450                     if ((rddsp_mask & 0x1) == 0x1) {
4451                        /* Read pos field (bits 5-0) of DSPControl register. */
4452                        putIReg(rd, binop(Iop_Or32,
4453                                          getIReg(rd),
4454                                          binop(Iop_And32,
4455                                                getDSPControl(),
4456                                                mkU32(0x0000003F))));
4457                     }
4458
4459                     if ((rddsp_mask & 0x2) == 0x2) {
4460                        /* Read scount field (bits 12-7) of DSPControl
4461                           register. */
4462                        putIReg(rd, binop(Iop_Or32,
4463                                          getIReg(rd),
4464                                          binop(Iop_And32,
4465                                                getDSPControl(),
4466                                                mkU32(0x00001F80))));
4467                     }
4468
4469                     if ((rddsp_mask & 0x4) == 0x4) {
4470                        /* Read C field (bit 13) of DSPControl register. */
4471                        putIReg(rd, binop(Iop_Or32,
4472                                          getIReg(rd),
4473                                          binop(Iop_And32,
4474                                                getDSPControl(),
4475                                                mkU32(0x00002000))));
4476                     }
4477
4478                     if ((rddsp_mask & 0x8) == 0x8) {
4479                        /* Read outflag field (bit s 23-16) of DSPControl
4480                           register. */
4481                        putIReg(rd, binop(Iop_Or32,
4482                                          getIReg(rd),
4483                                          binop(Iop_And32,
4484                                                getDSPControl(),
4485                                                mkU32(0x00FF0000))));
4486                     }
4487
4488                     if ((rddsp_mask & 0x10) == 0x10) {
4489                        /* Read ccond field (bits 31-24) of DSPControl
4490                           register. */
4491                        putIReg(rd, binop(Iop_Or32,
4492                                          getIReg(rd),
4493                                          binop(Iop_And32,
4494                                                getDSPControl(),
4495                                                mkU32(0xFF000000))));
4496                     }
4497
4498                     if ((rddsp_mask & 0x20) == 0x20) {
4499                        /* Read EFI field (bit 14) of DSPControl register. */
4500                        putIReg(rd, binop(Iop_Or32,
4501                                          getIReg(rd),
4502                                          binop(Iop_And32,
4503                                                getDSPControl(),
4504                                                mkU32(0x00004000))));
4505                     }
4506
4507                     if ((rddsp_mask & 0x3f) == 0x3f) {
4508                        /* Read all fields of DSPControl register. */
4509                        putIReg(rd, getDSPControl());
4510                     }
4511                     break;
4512                  }
4513                  case 0x13: {  /* WRDSP */
4514                     DIP("wrdsp r%d, mask 0x%x", rs, wrdsp_mask);
4515                     vassert(!mode64);
4516
4517                     if ((wrdsp_mask & 0x3f) == 0x3f) {
4518                        /* If mips64 put all fields of rs, except bit 15 and bit
4519                           6, to DSPControl register, otherwise put all except
4520                           bits 15, 6 and bits 31..28. */
4521                        putDSPControl(mode64 ?
4522                                      binop(Iop_And32,
4523                                            getIReg(rs),
4524                                            mkU32(0xffff7fbf)) :
4525                                      binop(Iop_And32,
4526                                            getIReg(rs),
4527                                            mkU32(0x0fff7fbf)));
4528                     } else {
4529                        if ((wrdsp_mask & 0x1) == 0x1) {
4530                           /* Put bits 5-0 of rs to DSPControl register pos
4531                              field. */
4532                           putDSPControl(binop(Iop_Or32,
4533                                               binop(Iop_And32,
4534                                                     getDSPControl(),
4535                                                     mkU32(0xFFFF7F40)),
4536                                               binop(Iop_And32,
4537                                                     getIReg(rs),
4538                                                     mkU32(0x0000003F))));
4539                        }
4540
4541                        if ((wrdsp_mask & 0x2) == 0x2) {
4542                           /* Put bits 12-7 of rs to DSPControl scount field. */
4543                           putDSPControl(binop(Iop_Or32,
4544                                               binop(Iop_And32,
4545                                                     getDSPControl(),
4546                                                     mkU32(0xFFFFE03F)),
4547                                               binop(Iop_And32,
4548                                                     getIReg(rs),
4549                                                     mkU32(0x00001F80))));
4550                        }
4551
4552                        if ((wrdsp_mask & 0x4) == 0x4) {
4553                           /* Put bit 13 of rs to DSPControl register C
4554                              field. */
4555                           putDSPControl(binop(Iop_Or32,
4556                                               binop(Iop_And32,
4557                                                     getDSPControl(),
4558                                                     mkU32(0xFFFF5FBF)),
4559                                               binop(Iop_And32,
4560                                                     getIReg(rs),
4561                                                     mkU32(0x00002000))));
4562                        }
4563
4564                        if ((wrdsp_mask & 0x8) == 0x8) {
4565                           /* Put bits 23-16 of rs to DSPControl reg outflag
4566                              field. */
4567                           putDSPControl(binop(Iop_Or32,
4568                                               binop(Iop_And32,
4569                                                     getDSPControl(),
4570                                                     mkU32(0xFF007FBF)),
4571                                               binop(Iop_And32,
4572                                                     getIReg(rs),
4573                                                     mkU32(0x00FF0000))));
4574                        }
4575
4576                        if ((wrdsp_mask & 0x10) == 0x10) {
4577                           /* Put bits 31-24 of rs to DSPControl reg ccond
4578                              field. */
4579                           putDSPControl(binop(Iop_Or32,
4580                                               binop(Iop_And32,
4581                                                     getDSPControl(),
4582                                                     mkU32(0x00FF7FBF)),
4583                                               binop(Iop_And32,
4584                                                     getIReg(rs),
4585                                                     mode64 ? mkU32(0xFF000000)
4586                                                            : mkU32(0x0F000000))
4587                                               )
4588                                        );
4589                        }
4590
4591                        if ((wrdsp_mask & 0x20) == 0x20) {
4592                           /* Put bit 14 of rs to DSPControl register EFI
4593                              field. */
4594                           putDSPControl(binop(Iop_Or32,
4595                                               binop(Iop_And32,
4596                                                     getDSPControl(),
4597                                                     mkU32(0xFFFF3FBF)),
4598                                               binop(Iop_And32,
4599                                                     getIReg(rs),
4600                                                     mkU32(0x00004000))));
4601                        }
4602                     }
4603                     break;
4604                  }
4605                  case 0x1A: {  /* SHILO */
4606                     DIP("shilo ac%d, %d", ac, shift);
4607                     vassert(!mode64);
4608                     t0 = newTemp(Ity_I64);
4609                     t1 = newTemp(Ity_I64);
4610
4611                     assign(t0, getAcc(ac));
4612
4613                     putAcc(ac, mkexpr(t0));
4614
4615                     if (0x20 == (shift & 0x3f)) {
4616                        putAcc(ac, binop(Iop_32HLto64,
4617                                         unop(Iop_64to32, mkexpr(t0)),
4618                                         mkU32(0x0)));
4619                     } else if (0x20 == (shift & 0x20)) {
4620                        assign(t1, binop(Iop_Shl64,
4621                                         mkexpr(t0),
4622                                         unop(Iop_32to8,
4623                                              binop(Iop_Add32,
4624                                                    unop(Iop_Not32,
4625                                                         mkU32(shift)),
4626                                                    mkU32(0x1)))));
4627
4628                        putAcc(ac, mkexpr(t1));
4629                     } else {
4630                        assign(t1, binop(Iop_Shr64, mkexpr(t0), mkU8(shift)));
4631
4632                        putAcc(ac, mkexpr(t1));
4633                     }
4634                     break;
4635                  }
4636                  case 0x1B: {  /* SHILOV */
4637                     DIP("shilov ac%d, r%d", ac, rs);
4638                     vassert(!mode64);
4639                     t0 = newTemp(Ity_I64);
4640                     t1 = newTemp(Ity_I32);
4641                     t2 = newTemp(Ity_I1);
4642                     t3 = newTemp(Ity_I64);
4643                     t4 = newTemp(Ity_I64);
4644
4645                     assign(t0, getAcc(ac));
4646                     assign(t1, binop(Iop_And32, getIReg(rs), mkU32(0x3f)));
4647                     assign(t2, binop(Iop_CmpEQ32, mkexpr(t1), mkU32(0x20)));
4648                     assign(t3, binop(Iop_Shl64,
4649                                      mkexpr(t0),
4650                                      unop(Iop_32to8,
4651                                           binop(Iop_Add32,
4652                                                 unop(Iop_Not32,
4653                                                      mkexpr(t1)),
4654                                                 mkU32(0x1)))));
4655                     assign(t4, binop(Iop_Shr64,
4656                                      mkexpr(t0),
4657                                      unop(Iop_32to8,
4658                                           mkexpr(t1))));
4659
4660                     putAcc(ac,
4661                            IRExpr_ITE(mkexpr(t2),
4662                                       binop(Iop_32HLto64,
4663                                             unop(Iop_64to32, mkexpr(t0)),
4664                                             mkU32(0x0)),
4665                                       IRExpr_ITE(binop(Iop_CmpEQ32,
4666                                                        binop(Iop_And32,
4667                                                              mkexpr(t1),
4668                                                              mkU32(0x20)),
4669                                                        mkU32(0x20)),
4670                                                  mkexpr(t3),
4671                                                  mkexpr(t4))));
4672                     break;
4673                  }
4674                  case 0x1F: {  /* MTHLIP */
4675                     DIP("mthlip r%d, ac%d", rs, ac);
4676                     vassert(!mode64);
4677                     t0 = newTemp(Ity_I64);
4678                     t1 = newTemp(Ity_I32);
4679                     t2 = newTemp(Ity_I32);
4680                     t3 = newTemp(Ity_I1);
4681
4682                     assign(t0, getAcc(ac));
4683                     putAcc(ac, binop(Iop_32HLto64,
4684                                      unop(Iop_64to32, mkexpr(t0)),
4685                                      getIReg(rs)));
4686                     assign(t1, binop(Iop_And32, getDSPControl(), mkU32(0x3f)));
4687                     putDSPControl(IRExpr_ITE(binop(Iop_CmpLE32U,
4688                                                    mkU32(32),
4689                                                    mkexpr(t1)),
4690                                              binop(Iop_Or32,
4691                                                    binop(Iop_Sub32,
4692                                                          mkexpr(t1),
4693                                                          mkU32(32)),
4694                                                   binop(Iop_And32,
4695                                                         getDSPControl(),
4696                                                         mkU32(0xffffffc0))),
4697                                              binop(Iop_Or32,
4698                                                    binop(Iop_Add32,
4699                                                          mkexpr(t1),
4700                                                          mkU32(32)),
4701                                                    binop(Iop_And32,
4702                                                          getDSPControl(),
4703                                                          mkU32(0xffffffc0)))));
4704                     break;
4705                  }
4706                  default:
4707                     return -1;
4708               }
4709               break;  /* end of EXTR.W */
4710            }
4711            case 0xA: {  /* LX */
4712               switch(sa) {
4713                  case 0x0: {  /* LWX */
4714                     DIP("lwx r%d, r%d(r%d)", rd, rt, rs);
4715                     vassert(!mode64);
4716                     t0 = newTemp(Ity_I32);
4717
4718                     assign(t0, binop(Iop_Add32, getIReg(rt), getIReg(rs)));
4719
4720                     putIReg(rd, load(Ity_I32, mkexpr(t0)));
4721                     break;
4722                  }
4723                  case 0x4: {  /* LHX */
4724                     DIP("lhx r%d, r%d(r%d)", rd, rt, rs);
4725                     vassert(!mode64);
4726                     t0 = newTemp(Ity_I32);
4727
4728                     assign(t0, binop(Iop_Add32, getIReg(rt), getIReg(rs)));
4729
4730                     putIReg(rd, unop(Iop_16Sto32, load(Ity_I16, mkexpr(t0))));
4731                     break;
4732                  }
4733                  case 0x6: {  /* LBUX */
4734                     DIP("lbux r%d, r%d(r%d)", rd, rt, rs);
4735                     vassert(!mode64);
4736                     t0 = newTemp(Ity_I32);
4737
4738                     assign(t0, binop(Iop_Add32, getIReg(rt), getIReg(rs)));
4739
4740                     putIReg(rd, unop(Iop_8Uto32, load(Ity_I8, mkexpr(t0))));
4741                     break;
4742                  }
4743                  default:
4744                     return -1;
4745               }
4746               break;  /* end of LX */
4747            }
4748            case 0xC: {  /* INSV */
4749               switch(sa) {
4750                  case 0x0: {  /* INSV */
4751                     DIP("insv r%d, r%d", rt, rs);
4752                     vassert(!mode64);
4753
4754                     t0 = newTemp(Ity_I32);
4755                     t1 = newTemp(Ity_I32);
4756                     t2 = newTemp(Ity_I8);
4757                     t3 = newTemp(Ity_I8);
4758                     t4 = newTemp(Ity_I32);
4759                     t5 = newTemp(Ity_I1);
4760                     t6 = newTemp(Ity_I32);
4761                     t7 = newTemp(Ity_I32);
4762                     t8 = newTemp(Ity_I32);
4763                     t9 = newTemp(Ity_I32);
4764
4765                     /* t0 <- pos field of DSPControl register. */
4766                     assign(t0, binop(Iop_And32, getDSPControl(), mkU32(0x3f)));
4767                     /* t1 <- scount field of DSPControl register. */
4768                     assign(t1, binop(Iop_Shr32,
4769                                      binop(Iop_And32,
4770                                            getDSPControl(),
4771                                            mkU32(0x1f80)),
4772                                      mkU8(7)));
4773
4774                     assign(t2, unop(Iop_32to8,
4775                                     binop(Iop_Add32,
4776                                           mkexpr(t1),
4777                                           mkexpr(t0))));
4778
4779                     /* 32-(pos+size) most significant bits of rt. */
4780                     assign(t6, binop(Iop_Shl32,
4781                                      binop(Iop_Shr32,
4782                                            getIReg(rt),
4783                                            mkexpr(t2)),
4784                                      mkexpr(t2)));
4785
4786                     assign(t3, unop(Iop_32to8,
4787                                     binop(Iop_Sub32,
4788                                           mkU32(32),
4789                                           mkexpr(t0))));
4790                     /* Pos least significant bits of rt. */
4791                     assign(t7, binop(Iop_Shr32,
4792                                      binop(Iop_Shl32,
4793                                            getIReg(rt),
4794                                            mkexpr(t3)),
4795                                      mkexpr(t3)));
4796
4797                     /* Size least significant bits of rs,
4798                        shifted to appropriate position. */
4799                     assign(t8, binop(Iop_Shl32,
4800                                      binop(Iop_And32,
4801                                            getIReg(rs),
4802                                            unop(Iop_Not32,
4803                                                 binop(Iop_Shl32,
4804                                                       mkU32(0xffffffff),
4805                                                       unop(Iop_32to8,
4806                                                            mkexpr(t1))))),
4807                                      unop(Iop_32to8,
4808                                           mkexpr(t0))));
4809
4810                     putIReg(rt, IRExpr_ITE(binop(Iop_CmpEQ32,
4811                                                  mkexpr(t0),
4812                                                  mkU32(0)),
4813                                            IRExpr_ITE(binop(Iop_CmpEQ32,
4814                                                             mkexpr(t1),
4815                                                             mkU32(32)),
4816                                                       getIReg(rs),
4817                                                       binop(Iop_Or32,
4818                                                             mkexpr(t6),
4819                                                             mkexpr(t8))),
4820                                            IRExpr_ITE(binop(Iop_CmpEQ32,
4821                                                             unop(Iop_8Uto32,
4822                                                                  mkexpr(t2)),
4823                                                             mkU32(32)),
4824                                                       binop(Iop_Or32,
4825                                                             mkexpr(t7),
4826                                                             mkexpr(t8)),
4827                                                       binop(Iop_Or32,
4828                                                             binop(Iop_Or32,
4829                                                                   mkexpr(t6),
4830                                                                   mkexpr(t7)),
4831                                                             mkexpr(t8)))));
4832                     break;
4833                  }
4834                  default:
4835                     return -1;
4836               }
4837               break;  /* enf of INSV */
4838            }
4839            case 0x10: {  /* ADDU.QB */
4840               switch(sa) {
4841                  case 0x00: {  /* ADDU.QB */
4842                     DIP("addu.qb r%d, r%d, r%d", rd, rs, rt);
4843                     vassert(!mode64);
4844                     t0 = newTemp(Ity_I32);
4845                     t1 = newTemp(Ity_I1);
4846                     t2 = newTemp(Ity_I32);
4847                     t3 = newTemp(Ity_I1);
4848                     t4 = newTemp(Ity_I32);
4849                     t5 = newTemp(Ity_I1);
4850                     t6 = newTemp(Ity_I32);
4851                     t7 = newTemp(Ity_I1);
4852                     t8 = newTemp(Ity_I32);
4853
4854                     /* Add rightmost bytes of rs and rt. */
4855                     assign(t0,
4856                            binop(Iop_Add32,
4857                                  unop(Iop_8Uto32,
4858                                       unop(Iop_16to8,
4859                                            unop(Iop_32to16, getIReg(rs)))),
4860                                  unop(Iop_8Uto32,
4861                                       unop(Iop_16to8,
4862                                            unop(Iop_32to16, getIReg(rt))))));
4863                     /* t1 will be 1 if there is overflow, 0 otherwise. */
4864                     assign(t1, binop(Iop_CmpEQ32,
4865                                      binop(Iop_And32,
4866                                            mkexpr(t0),
4867                                            mkU32(0x00000100)),
4868                                      mkU32(0x00000100)));
4869
4870                     /* Add bits 15-8 of rs and rt. */
4871                     assign(t2,
4872                            binop(Iop_Add32,
4873                                  unop(Iop_8Uto32,
4874                                       unop(Iop_16HIto8,
4875                                            unop(Iop_32to16, getIReg(rs)))),
4876                                  unop(Iop_8Uto32,
4877                                       unop(Iop_16HIto8,
4878                                            unop(Iop_32to16, getIReg(rt))))));
4879                     /* t3 will be 1 if there is overflow, 0 otherwise. */
4880                     assign(t3, binop(Iop_CmpEQ32,
4881                                      binop(Iop_And32,
4882                                            mkexpr(t2),
4883                                            mkU32(0x00000100)),
4884                                      mkU32(0x00000100)));
4885
4886                     /* Add bits 15-8 of rs and rt. */
4887                     assign(t4,
4888                            binop(Iop_Add32,
4889                                  unop(Iop_8Uto32,
4890                                       unop(Iop_16to8,
4891                                            unop(Iop_32HIto16, getIReg(rs)))),
4892                                  unop(Iop_8Uto32,
4893                                       unop(Iop_16to8,
4894                                            unop(Iop_32HIto16, getIReg(rt))))));
4895                     /* t5 will be 1 if there is overflow, 0 otherwise. */
4896                     assign(t5, binop(Iop_CmpEQ32,
4897                                      binop(Iop_And32,
4898                                            mkexpr(t4),
4899                                            mkU32(0x00000100)),
4900                                      mkU32(0x00000100)));
4901
4902                     /* Add bits 15-8 of rs and rt. */
4903                     assign(t6,
4904                            binop(Iop_Add32,
4905                                  unop(Iop_8Uto32,
4906                                       unop(Iop_16HIto8,
4907                                            unop(Iop_32HIto16, getIReg(rs)))),
4908                                  unop(Iop_8Uto32,
4909                                       unop(Iop_16HIto8,
4910                                            unop(Iop_32HIto16, getIReg(rt))))));
4911                     /* t7 will be 1 if there is overflow, 0 otherwise. */
4912                     assign(t7, binop(Iop_CmpEQ32,
4913                                      binop(Iop_And32,
4914                                            mkexpr(t6),
4915                                            mkU32(0x00000100)),
4916                                      mkU32(0x00000100)));
4917
4918                     assign(t8,
4919                            binop(Iop_Or32,
4920                                  binop(Iop_Or32,
4921                                        binop(Iop_Or32,
4922                                              unop(Iop_1Sto32, mkexpr(t7)),
4923                                              unop(Iop_1Sto32,  mkexpr(t5))),
4924                                        unop(Iop_1Sto32, mkexpr(t3))),
4925                                  unop(Iop_1Sto32, mkexpr(t1))));
4926
4927                     putDSPControl(IRExpr_ITE(binop(Iop_CmpEQ32,
4928                                                    mkexpr(t8),
4929                                                    mkU32(0x0)),
4930                                              getDSPControl(),
4931                                              binop(Iop_Or32,
4932                                                    getDSPControl(),
4933                                                    mkU32(0x00100000))));
4934
4935                     putIReg(rd, binop(Iop_16HLto32,
4936                                       binop(Iop_8HLto16,
4937                                             unop(Iop_32to8, mkexpr(t6)),
4938                                             unop(Iop_32to8, mkexpr(t4))),
4939                                       binop(Iop_8HLto16,
4940                                             unop(Iop_32to8, mkexpr(t2)),
4941                                             unop(Iop_32to8, mkexpr(t0)))));
4942                     break;
4943                  }
4944                  case 0x1: {  /* SUBU.QB */
4945                     DIP("subu.qb r%d, r%d, r%d", rd, rs, rt);
4946                     vassert(!mode64);
4947                     t0 = newTemp(Ity_I32);
4948                     t1 = newTemp(Ity_I1);
4949                     t2 = newTemp(Ity_I32);
4950                     t3 = newTemp(Ity_I1);
4951                     t4 = newTemp(Ity_I32);
4952                     t5 = newTemp(Ity_I1);
4953                     t6 = newTemp(Ity_I32);
4954                     t7 = newTemp(Ity_I1);
4955                     t8 = newTemp(Ity_I32);
4956
4957                     /* Subtract rightmost bytes of rs and rt. */
4958                     assign(t0,
4959                            binop(Iop_Sub32,
4960                                  unop(Iop_8Uto32,
4961                                       unop(Iop_16to8,
4962                                            unop(Iop_32to16, getIReg(rs)))),
4963                                  unop(Iop_8Uto32,
4964                                       unop(Iop_16to8,
4965                                            unop(Iop_32to16, getIReg(rt))))));
4966                     /* t1 will be 1 if there is overflow, 0 otherwise. */
4967                     assign(t1, binop(Iop_CmpEQ32,
4968                                      binop(Iop_And32,
4969                                            mkexpr(t0),
4970                                            mkU32(0x00000100)),
4971                                      mkU32(0x00000100)));
4972
4973                     /* Subtract bits 15-8 of rs and rt. */
4974                     assign(t2,
4975                            binop(Iop_Sub32,
4976                                  unop(Iop_8Uto32,
4977                                       unop(Iop_16HIto8,
4978                                            unop(Iop_32to16, getIReg(rs)))),
4979                                  unop(Iop_8Uto32,
4980                                       unop(Iop_16HIto8,
4981                                            unop(Iop_32to16, getIReg(rt))))));
4982                     /* t3 will be 1 if there is overflow, 0 otherwise. */
4983                     assign(t3, binop(Iop_CmpEQ32,
4984                                      binop(Iop_And32,
4985                                            mkexpr(t2),
4986                                            mkU32(0x00000100)),
4987                                      mkU32(0x00000100)));
4988
4989                     /* Subtract bits 15-8 of rs and rt. */
4990                     assign(t4,
4991                            binop(Iop_Sub32,
4992                                  unop(Iop_8Uto32,
4993                                       unop(Iop_16to8,
4994                                            unop(Iop_32HIto16, getIReg(rs)))),
4995                                  unop(Iop_8Uto32,
4996                                       unop(Iop_16to8,
4997                                            unop(Iop_32HIto16, getIReg(rt))))));
4998                     /* t5 will be 1 if there is overflow, 0 otherwise. */
4999                     assign(t5, binop(Iop_CmpEQ32,
5000                                      binop(Iop_And32,
5001                                            mkexpr(t4),
5002                                            mkU32(0x00000100)),
5003                                      mkU32(0x00000100)));
5004
5005                     /* Subtract bits 15-8 of rs and rt. */
5006                     assign(t6,
5007                            binop(Iop_Sub32,
5008                                  unop(Iop_8Uto32,
5009                                       unop(Iop_16HIto8,
5010                                            unop(Iop_32HIto16, getIReg(rs)))),
5011                                  unop(Iop_8Uto32,
5012                                       unop(Iop_16HIto8,
5013                                            unop(Iop_32HIto16, getIReg(rt))))));
5014                     /* t7 will be 1 if there is overflow, 0 otherwise. */
5015                     assign(t7, binop(Iop_CmpEQ32,
5016                                      binop(Iop_And32,
5017                                            mkexpr(t6),
5018                                            mkU32(0x00000100)),
5019                                      mkU32(0x00000100)));
5020
5021                     assign(t8, binop(Iop_Or32,
5022                                      binop(Iop_Or32,
5023                                            binop(Iop_Or32,
5024                                                  unop(Iop_1Sto32, mkexpr(t7)),
5025                                                  unop(Iop_1Sto32, mkexpr(t5))),
5026                                            unop(Iop_1Sto32, mkexpr(t3))),
5027                                      unop(Iop_1Sto32, mkexpr(t1))));
5028
5029                     putDSPControl(IRExpr_ITE(binop(Iop_CmpEQ32,
5030                                                     mkexpr(t8),
5031                                                     mkU32(0x0)),
5032                                              getDSPControl(),
5033                                              binop(Iop_Or32,
5034                                                    getDSPControl(),
5035                                                    mkU32(0x00100000))));
5036
5037                     putIReg(rd, binop(Iop_16HLto32,
5038                                       binop(Iop_8HLto16,
5039                                             unop(Iop_32to8, mkexpr(t6)),
5040                                             unop(Iop_32to8, mkexpr(t4))),
5041                                       binop(Iop_8HLto16,
5042                                             unop(Iop_32to8, mkexpr(t2)),
5043                                             unop(Iop_32to8, mkexpr(t0)))));
5044                     break;
5045                  }
5046                  case 0x04: {  /* ADDU_S.QB */
5047                     DIP("addu_s.qb r%d, r%d, r%d", rd, rs, rt);
5048                     vassert(!mode64);
5049                     t0 = newTemp(Ity_I32);
5050                     t1 = newTemp(Ity_I1);
5051                     t2 = newTemp(Ity_I8);
5052                     t3 = newTemp(Ity_I32);
5053                     t4 = newTemp(Ity_I1);
5054                     t5 = newTemp(Ity_I8);
5055                     t6 = newTemp(Ity_I32);
5056                     t7 = newTemp(Ity_I1);
5057                     t8 = newTemp(Ity_I8);
5058                     t9 = newTemp(Ity_I32);
5059                     t10 = newTemp(Ity_I1);
5060                     t11 = newTemp(Ity_I8);
5061                     t12 = newTemp(Ity_I32);
5062
5063                     /* Add rightmost bytes of rs and rt. */
5064                     assign(t0,
5065                            binop(Iop_Add32,
5066                                  unop(Iop_8Uto32,
5067                                       unop(Iop_16to8,
5068                                            unop(Iop_32to16, getIReg(rs)))),
5069                                  unop(Iop_8Uto32,
5070                                       unop(Iop_16to8,
5071                                            unop(Iop_32to16, getIReg(rt))))));
5072                     /* t1 will be 1 if there is overflow, 0 otherwise. */
5073                     assign(t1, binop(Iop_CmpEQ32,
5074                                      binop(Iop_And32,
5075                                            mkexpr(t0),
5076                                            mkU32(0x00000100)),
5077                                      mkU32(0x00000100)));
5078                     /* Saturate if necessary. */
5079                     assign(t2, IRExpr_ITE(mkexpr(t1),
5080                                           mkU8(0xff),
5081                                           unop(Iop_32to8, mkexpr(t0))));
5082
5083                     /* Add bits 15-8 of rs and rt. */
5084                     assign(t3,
5085                            binop(Iop_Add32,
5086                                  unop(Iop_8Uto32,
5087                                       unop(Iop_16HIto8,
5088                                            unop(Iop_32to16, getIReg(rs)))),
5089                                  unop(Iop_8Uto32,
5090                                       unop(Iop_16HIto8,
5091                                            unop(Iop_32to16, getIReg(rt))))));
5092                     /* t4 will be 1 if there is overflow, 0 otherwise. */
5093                     assign(t4, binop(Iop_CmpEQ32,
5094                                      binop(Iop_And32,
5095                                            mkexpr(t3),
5096                                            mkU32(0x00000100)),
5097                                      mkU32(0x00000100)));
5098                     /* Saturate if necessary. */
5099                     assign(t5, IRExpr_ITE(mkexpr(t4),
5100                                           mkU8(0xff),
5101                                           unop(Iop_32to8, mkexpr(t3))));
5102
5103                     /* Add bits 15-8 of rs and rt. */
5104                     assign(t6,
5105                            binop(Iop_Add32,
5106                                  unop(Iop_8Uto32,
5107                                       unop(Iop_16to8,
5108                                            unop(Iop_32HIto16, getIReg(rs)))),
5109                                  unop(Iop_8Uto32,
5110                                       unop(Iop_16to8,
5111                                            unop(Iop_32HIto16, getIReg(rt))))));
5112                     /* t7 will be 1 if there is overflow, 0 otherwise. */
5113                     assign(t7, binop(Iop_CmpEQ32,
5114                                      binop(Iop_And32,
5115                                            mkexpr(t6),
5116                                            mkU32(0x00000100)),
5117                                      mkU32(0x00000100)));
5118                     /* Saturate if necessary. */
5119                     assign(t8, IRExpr_ITE(mkexpr(t7),
5120                                           mkU8(0xff),
5121                                           unop(Iop_32to8, mkexpr(t6))));
5122
5123                     /* Add bits 15-8 of rs and rt. */
5124                     assign(t9,
5125                            binop(Iop_Add32,
5126                                  unop(Iop_8Uto32,
5127                                       unop(Iop_16HIto8,
5128                                            unop(Iop_32HIto16, getIReg(rs)))),
5129                                  unop(Iop_8Uto32,
5130                                       unop(Iop_16HIto8,
5131                                            unop(Iop_32HIto16, getIReg(rt))))));
5132                     /* t10 will be 1 if there is overflow, 0 otherwise. */
5133                     assign(t10, binop(Iop_CmpEQ32,
5134                                       binop(Iop_And32,
5135                                             mkexpr(t9),
5136                                             mkU32(0x00000100)),
5137                                       mkU32(0x00000100)));
5138                     /* Saturate if necessary. */
5139                     assign(t11, IRExpr_ITE(mkexpr(t10),
5140                                            mkU8(0xff),
5141                                            unop(Iop_32to8, mkexpr(t9))));
5142
5143                     assign(t12,
5144                            binop(Iop_Or32,
5145                                  binop(Iop_Or32,
5146                                        binop(Iop_Or32,
5147                                              unop(Iop_1Sto32, mkexpr(t10)),
5148                                              unop(Iop_1Sto32, mkexpr(t7))),
5149                                        unop(Iop_1Sto32, mkexpr(t4))),
5150                                  unop(Iop_1Sto32, mkexpr(t1))));
5151
5152                     putDSPControl(IRExpr_ITE(binop(Iop_CmpEQ32,
5153                                                    mkexpr(t12),
5154                                                    mkU32(0x0)),
5155                                              getDSPControl(),
5156                                              binop(Iop_Or32,
5157                                                    getDSPControl(),
5158                                                    mkU32(0x00100000))));
5159
5160                     putIReg(rd,
5161                             binop(Iop_16HLto32,
5162                                   binop(Iop_8HLto16, mkexpr(t11), mkexpr(t8)),
5163                                   binop(Iop_8HLto16, mkexpr(t5), mkexpr(t2))));
5164                     break;
5165                  }
5166                  case 0x05: {  /* SUBU_S.QB */
5167                     DIP("subu_s.qb r%d, r%d, r%d", rd, rs, rt);
5168                     vassert(!mode64);
5169                     t1 = newTemp(Ity_I32);
5170                     t2 = newTemp(Ity_I1);
5171                     t3 = newTemp(Ity_I1);
5172                     t4 = newTemp(Ity_I1);
5173                     t5 = newTemp(Ity_I1);
5174                     t6 = newTemp(Ity_I32);
5175                     t7 = newTemp(Ity_I32);
5176                     t8 = newTemp(Ity_I32);
5177                     t9 = newTemp(Ity_I32);
5178
5179                     /* Use C function to easily calculate the result
5180                        and write it in the register more conveniently
5181                        Underflow is checked using step by step subtraction. */
5182                     assign(t1, binop(Iop_QSub8Ux4, getIReg(rs), getIReg(rt)));
5183
5184                     /* Subtract each byte of rs and rt. */
5185                     assign(t6,
5186                            binop(Iop_Sub32,
5187                                  unop(Iop_8Uto32,
5188                                       unop(Iop_16to8,
5189                                            unop(Iop_32to16, getIReg(rs)))),
5190                                  unop(Iop_8Uto32,
5191                                       unop(Iop_16to8,
5192                                            unop(Iop_32to16, getIReg(rt))))));
5193                     assign(t7,
5194                            binop(Iop_Sub32,
5195                                  unop(Iop_8Uto32,
5196                                       unop(Iop_16HIto8,
5197                                            unop(Iop_32to16, getIReg(rs)))),
5198                                  unop(Iop_8Uto32,
5199                                       unop(Iop_16HIto8,
5200                                            unop(Iop_32to16, getIReg(rt))))));
5201                     assign(t8,
5202                            binop(Iop_Sub32,
5203                                  unop(Iop_8Uto32,
5204                                       unop(Iop_16to8,
5205                                            unop(Iop_32HIto16, getIReg(rs)))),
5206                                  unop(Iop_8Uto32,
5207                                       unop(Iop_16to8,
5208                                            unop(Iop_32HIto16, getIReg(rt))))));
5209                     assign(t9,
5210                            binop(Iop_Sub32,
5211                                  unop(Iop_8Uto32,
5212                                       unop(Iop_16HIto8,
5213                                            unop(Iop_32HIto16, getIReg(rs)))),
5214                                  unop(Iop_8Uto32,
5215                                       unop(Iop_16HIto8,
5216                                            unop(Iop_32HIto16, getIReg(rt))))));
5217
5218                     /* Put 1 to bit 20 in DSPControl if there is underflow
5219                        in either byte. */
5220                     assign(t2, binop(Iop_CmpEQ32,
5221                                      binop(Iop_And32,
5222                                            mkexpr(t6),
5223                                            mkU32(0x00000100)),
5224                                      mkU32(0x00000100)));
5225                     putDSPControl(IRExpr_ITE(mkexpr(t2),
5226                                              binop(Iop_Or32,
5227                                                    getDSPControl(),
5228                                                    mkU32(0x00100000)),
5229                                              getDSPControl()));
5230                     assign(t3, binop(Iop_CmpEQ32,
5231                                      binop(Iop_And32,
5232                                            mkexpr(t7),
5233                                            mkU32(0x00000100)),
5234                                      mkU32(0x00000100)));
5235                     putDSPControl(IRExpr_ITE(mkexpr(t3),
5236                                              binop(Iop_Or32,
5237                                                    getDSPControl(),
5238                                                    mkU32(0x00100000)),
5239                                              getDSPControl()));
5240                     assign(t4, binop(Iop_CmpEQ32,
5241                                      binop(Iop_And32,
5242                                            mkexpr(t8),
5243                                            mkU32(0x00000100)),
5244                                      mkU32(0x00000100)));
5245                     putDSPControl(IRExpr_ITE(mkexpr(t4),
5246                                              binop(Iop_Or32,
5247                                                    getDSPControl(),
5248                                                    mkU32(0x00100000)),
5249                                              getDSPControl()));
5250                     assign(t5, binop(Iop_CmpEQ32,
5251                                      binop(Iop_And32,
5252                                            mkexpr(t9),
5253                                            mkU32(0x00000100)),
5254                                      mkU32(0x00000100)));
5255                     putDSPControl(IRExpr_ITE(mkexpr(t5),
5256                                              binop(Iop_Or32,
5257                                                    getDSPControl(),
5258                                                    mkU32(0x00100000)),
5259                                              getDSPControl()));
5260                     putIReg(rd, mkexpr(t1));
5261                     break;
5262                  }
5263                  case 0x6: {  /* MULEU_S.PH.QBL */
5264                     DIP("muleu_s.ph.qbl r%d, r%d, r%d", rd, rs, rt);
5265                     vassert(!mode64);
5266                     t0 = newTemp(Ity_I32);
5267                     t1 = newTemp(Ity_I32);
5268                     t2 = newTemp(Ity_I1);
5269                     t3 = newTemp(Ity_I1);
5270
5271                     assign(t0,
5272                            unop(Iop_64to32,
5273                                 binop(Iop_MullU32,
5274                                       unop(Iop_8Uto32,
5275                                            unop(Iop_16HIto8,
5276                                                 unop(Iop_32HIto16,
5277                                                      getIReg(rs)))),
5278                                       unop(Iop_16Uto32,
5279                                            unop(Iop_32HIto16, getIReg(rt))))));
5280                     assign(t1,
5281                            unop(Iop_64to32,
5282                                 binop(Iop_MullU32,
5283                                       unop(Iop_8Uto32,
5284                                            unop(Iop_16to8,
5285                                                 unop(Iop_32HIto16,
5286                                                      getIReg(rs)))),
5287                                       unop(Iop_16Uto32,
5288                                            unop(Iop_32to16, getIReg(rt))))));
5289
5290                     assign(t2, binop(Iop_CmpNE32,
5291                                      mkU32(0x0),
5292                                      binop(Iop_And32,
5293                                            mkexpr(t0),
5294                                            mkU32(0x03ff0000))));
5295                     assign(t3, binop(Iop_CmpNE32,
5296                                      mkU32(0x0),
5297                                      binop(Iop_And32,
5298                                            mkexpr(t1),
5299                                            mkU32(0x03ff0000))));
5300                     putDSPControl(IRExpr_ITE(mkexpr(t2),
5301                                              binop(Iop_Or32,
5302                                                    getDSPControl(),
5303                                                    mkU32(0x200000)),
5304                                              IRExpr_ITE(mkexpr(t3),
5305                                                         binop(Iop_Or32,
5306                                                               getDSPControl(),
5307                                                               mkU32(0x200000)),
5308                                                         getDSPControl())));
5309                     putIReg(rd,
5310                             binop(Iop_16HLto32,
5311                                   IRExpr_ITE(mkexpr(t2),
5312                                              mkU16(0xffff),
5313                                              unop(Iop_32to16, mkexpr(t0))),
5314                                   IRExpr_ITE(mkexpr(t3),
5315                                              mkU16(0xffff),
5316                                              unop(Iop_32to16, mkexpr(t1)))));
5317                     break;
5318                  }
5319                  case 0x7: {  /* MULEU_S.PH.QBR */
5320                     DIP("muleu_s.ph.qbr r%d, r%d, r%d", rd, rs, rt);
5321                     vassert(!mode64);
5322                     t0 = newTemp(Ity_I32);
5323                     t1 = newTemp(Ity_I32);
5324                     t2 = newTemp(Ity_I1);
5325                     t3 = newTemp(Ity_I1);
5326
5327                     assign(t0, unop(Iop_64to32,
5328                                     binop(Iop_MullU32,
5329                                           unop(Iop_8Uto32,
5330                                                unop(Iop_16HIto8,
5331                                                     unop(Iop_32to16,
5332                                                          getIReg(rs)))),
5333                                           unop(Iop_16Uto32,
5334                                                unop(Iop_32HIto16,
5335                                                     getIReg(rt))))));
5336                     assign(t1, unop(Iop_64to32,
5337                                     binop(Iop_MullU32,
5338                                           unop(Iop_8Uto32,
5339                                                unop(Iop_16to8,
5340                                                     unop(Iop_32to16,
5341                                                          getIReg(rs)))),
5342                                           unop(Iop_16Uto32,
5343                                                unop(Iop_32to16,
5344                                                     getIReg(rt))))));
5345
5346                     assign(t2, binop(Iop_CmpNE32,
5347                                      mkU32(0x0),
5348                                      binop(Iop_And32,
5349                                            mkexpr(t0),
5350                                            mkU32(0x03ff0000))));
5351                     assign(t3, binop(Iop_CmpNE32,
5352                                      mkU32(0x0),
5353                                      binop(Iop_And32,
5354                                            mkexpr(t1),
5355                                            mkU32(0x03ff0000))));
5356                     putDSPControl(IRExpr_ITE(mkexpr(t2),
5357                                              binop(Iop_Or32,
5358                                                    getDSPControl(),
5359                                                    mkU32(0x200000)),
5360                                              IRExpr_ITE(mkexpr(t3),
5361                                                         binop(Iop_Or32,
5362                                                               getDSPControl(),
5363                                                               mkU32(0x200000)),
5364                                                         getDSPControl())));
5365                     putIReg(rd, binop(Iop_16HLto32,
5366                                       IRExpr_ITE(mkexpr(t2),
5367                                                  mkU16(0xffff),
5368                                                  unop(Iop_32to16,
5369                                                       mkexpr(t0))),
5370                                       IRExpr_ITE(mkexpr(t3),
5371                                                  mkU16(0xffff),
5372                                                  unop(Iop_32to16,
5373                                                       mkexpr(t1)))));
5374                     break;
5375                  }
5376                  case 0x08: {  /* ADDU.PH */
5377                     DIP("addu.ph r%d, r%d, r%d", rd, rs, rt);
5378                     vassert(!mode64);
5379                     t0 = newTemp(Ity_I32);
5380                     t1 = newTemp(Ity_I1);
5381                     t2 = newTemp(Ity_I32);
5382                     t3 = newTemp(Ity_I1);
5383
5384                     /* Add lower halves. */
5385                     assign(t0, binop(Iop_Add32,
5386                                      unop(Iop_16Uto32,
5387                                           unop(Iop_32to16, getIReg(rs))),
5388                                      unop(Iop_16Uto32,
5389                                           unop(Iop_32to16, getIReg(rt)))));
5390
5391                     /* Detect overflow. */
5392                     assign(t1, binop(Iop_CmpLT32U,
5393                                      unop(Iop_16Uto32,
5394                                           unop(Iop_32to16, mkexpr(t0))),
5395                                      unop(Iop_16Uto32,
5396                                           unop(Iop_32to16, getIReg(rs)))));
5397
5398                     putDSPControl(IRExpr_ITE(mkexpr(t1),
5399                                              binop(Iop_Or32,
5400                                                    getDSPControl(),
5401                                                    mkU32(0x00100000)),
5402                                              getDSPControl()));
5403
5404                     /* Add higher halves. */
5405                     assign(t2, binop(Iop_Add32,
5406                                      unop(Iop_16Uto32,
5407                                           unop(Iop_32HIto16, getIReg(rs))),
5408                                      unop(Iop_16Uto32,
5409                                           unop(Iop_32HIto16, getIReg(rt)))));
5410
5411                     /* Detect overflow. */
5412                     assign(t3, binop(Iop_CmpLT32U,
5413                                      unop(Iop_16Uto32,
5414                                           unop(Iop_32to16, mkexpr(t2))),
5415                                      unop(Iop_16Uto32,
5416                                           unop(Iop_32HIto16,
5417                                                getIReg(rs)))));
5418
5419                     putDSPControl(IRExpr_ITE(mkexpr(t3),
5420                                              binop(Iop_Or32,
5421                                                    getDSPControl(),
5422                                                    mkU32(0x00100000)),
5423                                              getDSPControl()));
5424
5425                     putIReg(rd, binop(Iop_16HLto32,
5426                                       unop(Iop_32to16, mkexpr(t2)),
5427                                       unop(Iop_32to16, mkexpr(t0))));
5428                     break;
5429                  }
5430                  case 0x9: {  /* SUBU.PH */
5431                     DIP("subu.ph r%d, r%d, r%d", rd, rs, rt);
5432                     vassert(!mode64);
5433                     t0 = newTemp(Ity_I32);
5434                     t1 = newTemp(Ity_I1);
5435                     t2 = newTemp(Ity_I32);
5436                     t3 = newTemp(Ity_I1);
5437
5438                     /* Substract lower halves. */
5439                     assign(t0, binop(Iop_Sub32,
5440                                      unop(Iop_16Uto32,
5441                                           unop(Iop_32to16, getIReg(rs))),
5442                                      unop(Iop_16Uto32,
5443                                           unop(Iop_32to16, getIReg(rt)))));
5444
5445                     /* Detect underflow. */
5446                     assign(t1, binop(Iop_CmpNE32,
5447                                      binop(Iop_And32,
5448                                            mkexpr(t0),
5449                                            mkU32(0x00010000)),
5450                                      mkU32(0x0)));
5451
5452                     putDSPControl(IRExpr_ITE(mkexpr(t1),
5453                                              binop(Iop_Or32,
5454                                                    getDSPControl(),
5455                                                    mkU32(0x00100000)),
5456                                              getDSPControl()));
5457
5458                     /* Subtract higher halves. */
5459                     assign(t2, binop(Iop_Sub32,
5460                                      unop(Iop_16Uto32,
5461                                           unop(Iop_32HIto16, getIReg(rs))),
5462                                      unop(Iop_16Uto32,
5463                                           unop(Iop_32HIto16, getIReg(rt)))));
5464
5465                     /* Detect underflow. */
5466                     assign(t3, binop(Iop_CmpNE32,
5467                                      binop(Iop_And32,
5468                                            mkexpr(t2),
5469                                            mkU32(0x00010000)),
5470                                      mkU32(0x0)));
5471
5472                     putDSPControl(IRExpr_ITE(mkexpr(t3),
5473                                              binop(Iop_Or32,
5474                                                    getDSPControl(),
5475                                                    mkU32(0x00100000)),
5476                                              getDSPControl()));
5477
5478                     putIReg(rd, binop(Iop_16HLto32,
5479                                       unop(Iop_32to16, mkexpr(t2)),
5480                                       unop(Iop_32to16, mkexpr(t0))));
5481                     break;
5482                  }
5483                  case 0xA: {  /* ADDQ.PH */
5484                     DIP("addq.ph r%d, r%d, r%d", rd, rs, rt);
5485                     vassert(!mode64);
5486                     t0 = newTemp(Ity_I32);
5487                     t1 = newTemp(Ity_I1);
5488                     t2 = newTemp(Ity_I32);
5489                     t3 = newTemp(Ity_I1);
5490                     t6 = newTemp(Ity_I32);
5491                     t7 = newTemp(Ity_I32);
5492
5493                     /* Add lower halves. */
5494                     assign(t0, binop(Iop_Add32,
5495                                      unop(Iop_16Sto32,
5496                                           unop(Iop_32to16, getIReg(rs))),
5497                                      unop(Iop_16Sto32,
5498                                           unop(Iop_32to16, getIReg(rt)))));
5499
5500                     /* Bit 16 of the result. */
5501                     assign(t6, binop(Iop_And32,
5502                                      unop(Iop_16Uto32,
5503                                           unop(Iop_32HIto16, mkexpr(t0))),
5504                                      mkU32(0x1)));
5505                     /* Detect overflow. */
5506                     assign(t1, binop(Iop_CmpNE32,
5507                                      binop(Iop_Shr32,
5508                                            binop(Iop_And32,
5509                                                  mkexpr(t0),
5510                                                  mkU32(0x8000)),
5511                                            mkU8(15)),
5512                                      mkexpr(t6)));
5513
5514                     putDSPControl(IRExpr_ITE(mkexpr(t1),
5515                                              binop(Iop_Or32,
5516                                                    getDSPControl(),
5517                                                    mkU32(0x00100000)),
5518                                              getDSPControl()));
5519
5520                     /* Add higher halves. */
5521                     assign(t2, binop(Iop_Add32,
5522                                      unop(Iop_16Sto32,
5523                                           unop(Iop_32HIto16, getIReg(rs))),
5524                                      unop(Iop_16Sto32,
5525                                           unop(Iop_32HIto16, getIReg(rt)))));
5526
5527                     /* Bit 16 of the result. */
5528                     assign(t7, binop(Iop_And32,
5529                                      unop(Iop_16Uto32,
5530                                           unop(Iop_32HIto16, mkexpr(t2))),
5531                                      mkU32(0x1)));
5532                     /* Detect overflow. */
5533                     assign(t3, binop(Iop_CmpNE32,
5534                                      binop(Iop_Shr32,
5535                                            binop(Iop_And32,
5536                                                  mkexpr(t2),
5537                                                  mkU32(0x00008000)),
5538                                            mkU8(15)),
5539                                      mkexpr(t7)));
5540
5541                     putDSPControl(IRExpr_ITE(mkexpr(t3),
5542                                              binop(Iop_Or32,
5543                                                    getDSPControl(),
5544                                                    mkU32(0x00100000)),
5545                                              getDSPControl()));
5546
5547                     putIReg(rd, binop(Iop_16HLto32,
5548                                       unop(Iop_32to16, mkexpr(t2)),
5549                                       unop(Iop_32to16, mkexpr(t0))));
5550                     break;
5551                  }
5552                  case 0xB: {  /* SUBQ.PH */
5553                     DIP("subq.ph r%d, r%d, r%d", rd, rs, rt);
5554                     vassert(!mode64);
5555                     t0 = newTemp(Ity_I32);
5556                     t1 = newTemp(Ity_I1);
5557                     t2 = newTemp(Ity_I32);
5558                     t3 = newTemp(Ity_I1);
5559                     t6 = newTemp(Ity_I32);
5560                     t7 = newTemp(Ity_I32);
5561
5562                     /* Subtract lower halves. */
5563                     assign(t0, binop(Iop_Sub32,
5564                                      unop(Iop_16Sto32,
5565                                           unop(Iop_32to16, getIReg(rs))),
5566                                      unop(Iop_16Sto32,
5567                                           unop(Iop_32to16, getIReg(rt)))));
5568
5569                     /* Bit 16 of the result. */
5570                     assign(t6, binop(Iop_And32,
5571                                      unop(Iop_16Uto32,
5572                                           unop(Iop_32HIto16, mkexpr(t0))),
5573                                      mkU32(0x1)));
5574                     /* Compare the signs of input value and the result. */
5575                     assign(t1, binop(Iop_CmpNE32,
5576                                      binop(Iop_Shr32,
5577                                            binop(Iop_And32,
5578                                                  mkexpr(t0),
5579                                                  mkU32(0x8000)),
5580                                            mkU8(15)),
5581                                      mkexpr(t6)));
5582
5583                     putDSPControl(IRExpr_ITE(mkexpr(t1),
5584                                              binop(Iop_Or32,
5585                                                    getDSPControl(),
5586                                                    mkU32(0x00100000)),
5587                                              getDSPControl()));
5588
5589                     /* Subtract higher halves. */
5590                     assign(t2, binop(Iop_Sub32,
5591                                      unop(Iop_16Sto32,
5592                                           unop(Iop_32HIto16, getIReg(rs))),
5593                                      unop(Iop_16Sto32,
5594                                           unop(Iop_32HIto16, getIReg(rt)))));
5595
5596                     /* Bit 16 of the result. */
5597                     assign(t7, binop(Iop_And32,
5598                                      unop(Iop_16Uto32,
5599                                           unop(Iop_32HIto16, mkexpr(t2))),
5600                                      mkU32(0x1)));
5601                     /* Compare the signs of input value and the result. */
5602                     assign(t3, binop(Iop_CmpNE32,
5603                                      binop(Iop_Shr32,
5604                                            binop(Iop_And32,
5605                                                  mkexpr(t2),
5606                                                  mkU32(0x00008000)),
5607                                            mkU8(15)),
5608                                      mkexpr(t7)));
5609
5610                     putDSPControl(IRExpr_ITE(mkexpr(t3),
5611                                              binop(Iop_Or32,
5612                                                    getDSPControl(),
5613                                                    mkU32(0x00100000)),
5614                                              getDSPControl()));
5615
5616                     putIReg(rd, binop(Iop_16HLto32,
5617                                       unop(Iop_32to16, mkexpr(t2)),
5618                                       unop(Iop_32to16, mkexpr(t0))));
5619                     break;
5620                  }
5621                  case 0xC: {  /* ADDU_S.PH */
5622                     DIP("addu_s.ph r%d, r%d, r%d", rd, rs, rt);
5623                     vassert(!mode64);
5624                     t0 = newTemp(Ity_I32);
5625                     t1 = newTemp(Ity_I1);
5626                     t2 = newTemp(Ity_I32);
5627                     t3 = newTemp(Ity_I1);
5628
5629                     /* Add lower halves. */
5630                     assign(t0, binop(Iop_Add32,
5631                                      unop(Iop_16Uto32,
5632                                           unop(Iop_32to16, getIReg(rs))),
5633                                      unop(Iop_16Uto32,
5634                                           unop(Iop_32to16, getIReg(rt)))));
5635
5636                     /* Detect overflow. */
5637                     assign(t1, binop(Iop_CmpLT32U,
5638                                      unop(Iop_16Uto32,
5639                                           unop(Iop_32to16, mkexpr(t0))),
5640                                      unop(Iop_16Uto32,
5641                                           unop(Iop_32to16, getIReg(rs)))));
5642
5643                     putDSPControl(IRExpr_ITE(mkexpr(t1),
5644                                              binop(Iop_Or32,
5645                                                    getDSPControl(),
5646                                                    mkU32(0x00100000)),
5647                                              getDSPControl()));
5648
5649                     /* Add higher halves. */
5650                     assign(t2, binop(Iop_Add32,
5651                                      unop(Iop_16Uto32,
5652                                           unop(Iop_32HIto16, getIReg(rs))),
5653                                      unop(Iop_16Uto32,
5654                                           unop(Iop_32HIto16, getIReg(rt)))));
5655
5656                     /* Detect overflow. */
5657                     assign(t3, binop(Iop_CmpLT32U,
5658                                      unop(Iop_16Uto32,
5659                                           unop(Iop_32to16, mkexpr(t2))),
5660                                      unop(Iop_16Uto32,
5661                                           unop(Iop_32HIto16, getIReg(rs)))));
5662
5663                     putDSPControl(IRExpr_ITE(mkexpr(t3),
5664                                              binop(Iop_Or32,
5665                                                    getDSPControl(),
5666                                                    mkU32(0x00100000)),
5667                                              getDSPControl()));
5668
5669                     putIReg(rd, binop(Iop_16HLto32,
5670                                       IRExpr_ITE(mkexpr(t3),
5671                                                  mkU16(0xffff),
5672                                                  unop(Iop_32to16,
5673                                                       mkexpr(t2))),
5674                                       IRExpr_ITE(mkexpr(t1),
5675                                                  mkU16(0xffff),
5676                                                  unop(Iop_32to16,
5677                                                       mkexpr(t0)))));
5678                     break;
5679                  }
5680                  case 0xD: {  /* SUBU_S.PH */
5681                     DIP("subu_s.ph r%d, r%d, r%d", rd, rs, rt);
5682                     vassert(!mode64);
5683                     t0 = newTemp(Ity_I32);
5684                     t1 = newTemp(Ity_I1);
5685                     t2 = newTemp(Ity_I32);
5686                     t3 = newTemp(Ity_I1);
5687
5688                     /* Subtract lower halves. */
5689                     assign(t0, binop(Iop_Sub32,
5690                                      unop(Iop_16Uto32,
5691                                           unop(Iop_32to16, getIReg(rs))),
5692                                      unop(Iop_16Uto32,
5693                                           unop(Iop_32to16, getIReg(rt)))));
5694
5695                     /* Detect underflow. */
5696                     assign(t1, binop(Iop_CmpNE32,
5697                                      binop(Iop_And32,
5698                                            mkexpr(t0), mkU32(0x00010000)),
5699                                      mkU32(0x0)));
5700
5701                     putDSPControl(IRExpr_ITE(mkexpr(t1),
5702                                              binop(Iop_Or32,
5703                                                    getDSPControl(),
5704                                                    mkU32(0x00100000)),
5705                                              getDSPControl()));
5706
5707                     /* Subtract higher halves. */
5708                     assign(t2, binop(Iop_Sub32,
5709                                      unop(Iop_16Uto32,
5710                                           unop(Iop_32HIto16, getIReg(rs))),
5711                                      unop(Iop_16Uto32,
5712                                           unop(Iop_32HIto16, getIReg(rt)))));
5713
5714                     /* Detect underflow. */
5715                     assign(t3, binop(Iop_CmpNE32,
5716                                      binop(Iop_And32,
5717                                            mkexpr(t2), mkU32(0x00010000)),
5718                                      mkU32(0x0)));
5719
5720                     putDSPControl(IRExpr_ITE(mkexpr(t3),
5721                                              binop(Iop_Or32,
5722                                                    getDSPControl(),
5723                                                    mkU32(0x00100000)),
5724                                              getDSPControl()));
5725
5726                     putIReg(rd,
5727                             binop(Iop_16HLto32,
5728                                   IRExpr_ITE(mkexpr(t3),
5729                                              mkU16(0x0000),
5730                                              unop(Iop_32to16, mkexpr(t2))),
5731                                   IRExpr_ITE(mkexpr(t1),
5732                                              mkU16(0x0000),
5733                                              unop(Iop_32to16, mkexpr(t0)))));
5734                     break;
5735                  }
5736                  case 0xE: {  /* ADDQ_S.PH */
5737                     DIP("addq_s.ph r%d r%d, r%d", rd, rs, rt);
5738                     vassert(!mode64);
5739                     t0 = newTemp(Ity_I32);
5740                     t1 = newTemp(Ity_I1);
5741                     t2 = newTemp(Ity_I32);
5742                     t3 = newTemp(Ity_I1);
5743                     t4 = newTemp(Ity_I16);
5744                     t5 = newTemp(Ity_I16);
5745                     t6 = newTemp(Ity_I32);
5746                     t7 = newTemp(Ity_I32);
5747
5748                     /* Add lower halves. */
5749                     assign(t0, binop(Iop_Add32,
5750                                      unop(Iop_16Sto32,
5751                                           unop(Iop_32to16, getIReg(rs))),
5752                                      unop(Iop_16Sto32,
5753                                           unop(Iop_32to16, getIReg(rt)))));
5754
5755                     /* Bit 16 of the result. */
5756                     assign(t6, binop(Iop_And32,
5757                                      unop(Iop_16Uto32,
5758                                           unop(Iop_32HIto16, mkexpr(t0))),
5759                                      mkU32(0x1)));
5760                     /* Detect overflow. */
5761                     assign(t1, binop(Iop_CmpNE32,
5762                                      binop(Iop_Shr32,
5763                                            binop(Iop_And32,
5764                                                  mkexpr(t0),
5765                                                  mkU32(0x8000)),
5766                                            mkU8(15)),
5767                                      mkexpr(t6)));
5768
5769                     putDSPControl(IRExpr_ITE(mkexpr(t1),
5770                                              binop(Iop_Or32,
5771                                                    getDSPControl(),
5772                                                    mkU32(0x00100000)),
5773                                              getDSPControl()));
5774                     /* Saturate if needed. */
5775                     assign(t4, IRExpr_ITE(mkexpr(t1),
5776                                           IRExpr_ITE(binop(Iop_CmpEQ32,
5777                                                            mkexpr(t6),
5778                                                            mkU32(0x0)),
5779                                                      mkU16(0x7fff),
5780                                                      mkU16(0x8000)),
5781                                           unop(Iop_32to16, mkexpr(t0))));
5782
5783                     /* Add higher halves. */
5784                     assign(t2, binop(Iop_Add32,
5785                                      unop(Iop_16Sto32,
5786                                           unop(Iop_32HIto16, getIReg(rs))),
5787                                      unop(Iop_16Sto32,
5788                                           unop(Iop_32HIto16, getIReg(rt)))));
5789
5790                     /* Bit 16 of the result. */
5791                     assign(t7, binop(Iop_And32,
5792                                      unop(Iop_16Uto32,
5793                                           unop(Iop_32HIto16, mkexpr(t2))),
5794                                      mkU32(0x1)));
5795                     /* Detect overflow. */
5796                     assign(t3, binop(Iop_CmpNE32,
5797                                      binop(Iop_Shr32,
5798                                            binop(Iop_And32,
5799                                                  mkexpr(t2),
5800                                                  mkU32(0x00008000)),
5801                                            mkU8(15)),
5802                                      mkexpr(t7)));
5803
5804                     putDSPControl(IRExpr_ITE(mkexpr(t3),
5805                                              binop(Iop_Or32,
5806                                                    getDSPControl(),
5807                                                    mkU32(0x00100000)),
5808                                              getDSPControl()));
5809                     /* Saturate if needed. */
5810                     assign(t5, IRExpr_ITE(mkexpr(t3),
5811                                           IRExpr_ITE(binop(Iop_CmpEQ32,
5812                                                            mkexpr(t7),
5813                                                            mkU32(0x0)),
5814                                                      mkU16(0x7fff),
5815                                                      mkU16(0x8000)),
5816                                           unop(Iop_32to16, mkexpr(t2))));
5817
5818                     putIReg(rd, binop(Iop_16HLto32, mkexpr(t5), mkexpr(t4)));
5819                     break;
5820                  }
5821                  case 0xF: {  /* SUBQ_S.PH */
5822                     DIP("subq_s.ph r%d r%d, r%d", rd, rs, rt);
5823                     vassert(!mode64);
5824                     t0 = newTemp(Ity_I32);
5825                     t1 = newTemp(Ity_I1);
5826                     t2 = newTemp(Ity_I32);
5827                     t3 = newTemp(Ity_I1);
5828                     t4 = newTemp(Ity_I16);
5829                     t5 = newTemp(Ity_I16);
5830                     t6 = newTemp(Ity_I32);
5831                     t7 = newTemp(Ity_I32);
5832
5833                     /* Subtract lower halves. */
5834                     assign(t0, binop(Iop_Sub32,
5835                                      unop(Iop_16Sto32,
5836                                           unop(Iop_32to16, getIReg(rs))),
5837                                      unop(Iop_16Sto32,
5838                                           unop(Iop_32to16, getIReg(rt)))));
5839
5840                     /* Bit 16 of the result. */
5841                     assign(t6, binop(Iop_And32,
5842                                      unop(Iop_16Uto32,
5843                                           unop(Iop_32HIto16, mkexpr(t0))),
5844                                      mkU32(0x1)));
5845                     /* Detect overflow or underflow. */
5846                     assign(t1, binop(Iop_CmpNE32,
5847                                      binop(Iop_Shr32,
5848                                            binop(Iop_And32,
5849                                                  mkexpr(t0),
5850                                                  mkU32(0x8000)),
5851                                            mkU8(15)),
5852                                      mkexpr(t6)));
5853
5854                     putDSPControl(IRExpr_ITE(mkexpr(t1),
5855                                              binop(Iop_Or32,
5856                                                    getDSPControl(),
5857                                                    mkU32(0x00100000)),
5858                                              getDSPControl()));
5859                     /* Saturate if needed. */
5860                     assign(t4, IRExpr_ITE(mkexpr(t1),
5861                                           IRExpr_ITE(binop(Iop_CmpEQ32,
5862                                                            mkexpr(t6),
5863                                                            mkU32(0x0)),
5864                                                      mkU16(0x7fff),
5865                                                      mkU16(0x8000)),
5866                                           unop(Iop_32to16, mkexpr(t0))));
5867
5868                     /* Subtract higher halves. */
5869                     assign(t2, binop(Iop_Sub32,
5870                                      unop(Iop_16Sto32,
5871                                           unop(Iop_32HIto16, getIReg(rs))),
5872                                      unop(Iop_16Sto32,
5873                                           unop(Iop_32HIto16, getIReg(rt)))));
5874
5875                     /* Bit 16 of the result. */
5876                     assign(t7, binop(Iop_And32,
5877                                      unop(Iop_16Uto32,
5878                                           unop(Iop_32HIto16, mkexpr(t2))),
5879                                      mkU32(0x1)));
5880                     /* Detect overflow or underflow. */
5881                     assign(t3, binop(Iop_CmpNE32,
5882                                      binop(Iop_Shr32,
5883                                            binop(Iop_And32,
5884                                                  mkexpr(t2),
5885                                                  mkU32(0x00008000)),
5886                                            mkU8(15)),
5887                                      mkexpr(t7)));
5888
5889                     putDSPControl(IRExpr_ITE(mkexpr(t3),
5890                                              binop(Iop_Or32,
5891                                                    getDSPControl(),
5892                                                    mkU32(0x00100000)),
5893                                              getDSPControl()));
5894                     /* Saturate if needed. */
5895                     assign(t5, IRExpr_ITE(mkexpr(t3),
5896                                           IRExpr_ITE(binop(Iop_CmpEQ32,
5897                                                            mkexpr(t7),
5898                                                            mkU32(0x0)),
5899                                                      mkU16(0x7fff),
5900                                                      mkU16(0x8000)),
5901                                           unop(Iop_32to16, mkexpr(t2))));
5902
5903                     putIReg(rd, binop(Iop_16HLto32, mkexpr(t5), mkexpr(t4)));
5904                     break;
5905                  }
5906                  case 0x10: {  /* ADDSC */
5907                     DIP("addsc r%d, r%d, r%d", rd, rs, rt);
5908                     vassert(!mode64);
5909                     t0 = newTemp(Ity_I64);
5910                     t1 = newTemp(Ity_I1);
5911
5912                     /* The carry bit result out of the addition operation is
5913                        written to bit 13(the c field) of the DSPControl reg. */
5914                     assign(t0, binop(Iop_Add64,
5915                                      unop(Iop_32Uto64, getIReg(rs)),
5916                                      unop(Iop_32Uto64, getIReg(rt))));
5917
5918                     assign(t1, binop(Iop_CmpEQ32,
5919                                      binop(Iop_And32,
5920                                            unop(Iop_64HIto32, mkexpr(t0)),
5921                                            mkU32(0x1)),
5922                                      mkU32(0x1)));
5923                     putDSPControl(IRExpr_ITE(mkexpr(t1),
5924                                              binop(Iop_Or32,
5925                                                    getDSPControl(),
5926                                                    mkU32(0x2000)),
5927                                              binop(Iop_And32,
5928                                                    getDSPControl(),
5929                                                    mkU32(0xffffdfff))));
5930
5931                     putIReg(rd, unop(Iop_64to32, mkexpr(t0)));
5932                     break;
5933                  }
5934                  case 0x11: {  /* ADDWC */
5935                     DIP("addwc r%d, r%d, r%d", rd, rs, rt);
5936                     vassert(!mode64);
5937                     t0 = newTemp(Ity_I32);
5938                     t1 = newTemp(Ity_I64);
5939                     t2 = newTemp(Ity_I32);
5940                     t3 = newTemp(Ity_I32);
5941                     t4 = newTemp(Ity_I1);
5942
5943                     /* Get carry bit from DSPControl register. */
5944                     assign(t0, binop(Iop_Shr32,
5945                                       binop(Iop_And32,
5946                                             getDSPControl(),
5947                                             mkU32(0x2000)),
5948                                       mkU8(0xd)));
5949                     assign(t1, binop(Iop_Add64,
5950                                      unop(Iop_32Sto64, getIReg(rs)),
5951                                      unop(Iop_32Sto64,
5952                                           binop(Iop_Add32,
5953                                                 getIReg(rt),
5954                                                 mkexpr(t0)))));
5955
5956                     /* Extract bits 32 and 31. */
5957                     assign(t2, binop(Iop_And32,
5958                                      unop(Iop_64HIto32, mkexpr(t1)),
5959                                      mkU32(0x1)));
5960                     assign(t3, binop(Iop_Shr32,
5961                                      binop(Iop_And32,
5962                                            unop(Iop_64to32, mkexpr(t1)),
5963                                            mkU32(0x80000000)),
5964                                      mkU8(31)));
5965                     assign(t4, binop(Iop_CmpNE32, mkexpr(t2), mkexpr(t3)));
5966
5967                     putDSPControl(IRExpr_ITE(mkexpr(t4),
5968                                              binop(Iop_Or32,
5969                                                    getDSPControl(),
5970                                                    mkU32(0x00100000)),
5971                                              getDSPControl()));
5972                     putIReg(rd, unop(Iop_64to32, mkexpr(t1)));
5973                     break;
5974                  }
5975                  case 0x12: {  /* MODSUB */
5976                     DIP("modsub r%d, r%d, r%d", rd, rs, rt);
5977                     vassert(!mode64);
5978                     t0 = newTemp(Ity_I32);
5979                     t1 = newTemp(Ity_I32);
5980                     t2 = newTemp(Ity_I32);
5981
5982                     /* decr_7..0 */
5983                     assign(t0,
5984                            unop(Iop_8Uto32,
5985                                 unop(Iop_16to8,
5986                                      unop(Iop_32to16, getIReg(rt)))));
5987
5988                     /* lastindex_15..0 */
5989                     assign(t1,
5990                            unop(Iop_16Uto32,
5991                                 binop(Iop_8HLto16,
5992                                       unop(Iop_16to8,
5993                                            unop(Iop_32HIto16, getIReg(rt))),
5994                                       unop(Iop_16HIto8,
5995                                            unop(Iop_32to16, getIReg(rt))))));
5996                     /* temp_15..0 */
5997                     assign(t2,
5998                            IRExpr_ITE(binop(Iop_CmpEQ32,
5999                                             getIReg(rs),
6000                                             mkU32(0x00000000)),
6001                                       mkexpr(t1),
6002                                       binop(Iop_Sub32,
6003                                             getIReg(rs), mkexpr(t0))));
6004                     putIReg(rd, mkexpr(t2));
6005                     break;
6006                  }
6007                  case 0x14: {  /* RADDU.W.QB */
6008                     DIP("raddu.w.qb r%d, r%d", rd, rs);
6009                     vassert(!mode64);
6010                     putIReg(rd, binop(Iop_Add32,
6011                                       binop(Iop_Add32,
6012                                             unop(Iop_8Uto32,
6013                                                  unop(Iop_16to8,
6014                                                       unop(Iop_32to16,
6015                                                            getIReg(rs)))),
6016                                             unop(Iop_8Uto32,
6017                                                  unop(Iop_16HIto8,
6018                                                       unop(Iop_32to16,
6019                                                            getIReg(rs))))),
6020                                       binop(Iop_Add32,
6021                                             unop(Iop_8Uto32,
6022                                                  unop(Iop_16to8,
6023                                                       unop(Iop_32HIto16,
6024                                                            getIReg(rs)))),
6025                                             unop(Iop_8Uto32,
6026                                                  unop(Iop_16HIto8,
6027                                                       unop(Iop_32HIto16,
6028                                                            getIReg(rs)))))));
6029                     break;
6030                  }
6031                  case 0x16: {  /* ADDQ_S.W */
6032                     DIP("addq_s.w r%d, r%d, r%d", rd, rs, rt);
6033                     vassert(!mode64);
6034                     t0 = newTemp(Ity_I64);
6035                     t1 = newTemp(Ity_I1);
6036                     t2 = newTemp(Ity_I32);
6037                     t3 = newTemp(Ity_I32);
6038
6039                     assign(t0, binop(Iop_Add64,
6040                                      unop(Iop_32Sto64, getIReg(rs)),
6041                                      unop(Iop_32Sto64, getIReg(rt))));
6042
6043                     assign(t3, binop(Iop_And32,
6044                                      unop(Iop_64HIto32, mkexpr(t0)),
6045                                      mkU32(0x1)));
6046                     assign(t1, binop(Iop_CmpNE32,
6047                                      binop(Iop_Shr32,
6048                                            binop(Iop_And32,
6049                                                  unop(Iop_64to32, mkexpr(t0)),
6050                                                  mkU32(0x80000000)),
6051                                            mkU8(31)),
6052                                      mkexpr(t3)));
6053
6054                     putDSPControl(IRExpr_ITE(mkexpr(t1),
6055                                              binop(Iop_Or32,
6056                                                    getDSPControl(),
6057                                                    mkU32(0x00100000)),
6058                                              getDSPControl()));
6059
6060                     putIReg(rd, IRExpr_ITE(mkexpr(t1),
6061                                            IRExpr_ITE(binop(Iop_CmpEQ32,
6062                                                             mkexpr(t3),
6063                                                             mkU32(0x0)),
6064                                                       mkU32(0x7fffffff),
6065                                                       mkU32(0x80000000)),
6066                                            unop(Iop_64to32, mkexpr(t0))));
6067                     break;
6068                  }
6069                  case 0x17: {  /* SUBQ_S.W */
6070                     DIP("subq_s.w r%d, r%d, r%d", rd, rs, rt);
6071                     vassert(!mode64);
6072                     t0 = newTemp(Ity_I64);
6073                     t1 = newTemp(Ity_I1);
6074                     t2 = newTemp(Ity_I32);
6075                     t3 = newTemp(Ity_I32);
6076
6077                     assign(t0, binop(Iop_Sub64,
6078                                      unop(Iop_32Sto64, getIReg(rs)),
6079                                      unop(Iop_32Sto64, getIReg(rt))));
6080
6081                     assign(t3, binop(Iop_And32,
6082                                      unop(Iop_64HIto32, mkexpr(t0)),
6083                                      mkU32(0x1)));
6084                     assign(t1, binop(Iop_CmpNE32,
6085                                      binop(Iop_Shr32,
6086                                            binop(Iop_And32,
6087                                                  unop(Iop_64to32, mkexpr(t0)),
6088                                                  mkU32(0x80000000)),
6089                                            mkU8(31)),
6090                                      mkexpr(t3)));
6091
6092                     putDSPControl(IRExpr_ITE(mkexpr(t1),
6093                                              binop(Iop_Or32,
6094                                                    getDSPControl(),
6095                                                    mkU32(0x00100000)),
6096                                              getDSPControl()));
6097
6098                     putIReg(rd, IRExpr_ITE(mkexpr(t1),
6099                                            IRExpr_ITE(binop(Iop_CmpEQ32,
6100                                                             mkexpr(t3),
6101                                                             mkU32(0x0)),
6102                                                       mkU32(0x7fffffff),
6103                                                       mkU32(0x80000000)),
6104                                            unop(Iop_64to32, mkexpr(t0))));
6105                     break;
6106                  }
6107                  case 0x1C: {  /* MULEQ_S.W.PHL */
6108                     DIP("muleq_s.w.phl r%d, r%d, r%d", rd, rs, rt);
6109                     vassert(!mode64);
6110                     t0 = newTemp(Ity_I32);
6111                     t1 = newTemp(Ity_I1);
6112                     t2 = newTemp(Ity_I1);
6113                     t3 = newTemp(Ity_I32);
6114
6115                     assign(t0,
6116                            binop(Iop_Shl32,
6117                                  binop(Iop_Mul32,
6118                                        unop(Iop_16Sto32,
6119                                             unop(Iop_32HIto16, getIReg(rt))),
6120                                        unop(Iop_16Sto32,
6121                                             unop(Iop_32HIto16, getIReg(rs)))),
6122                                  mkU8(0x1)));
6123                     assign(t1, binop(Iop_CmpEQ32,
6124                                      binop(Iop_And32,
6125                                            getIReg(rt),
6126                                            mkU32(0xffff0000)),
6127                                      mkU32(0x80000000)));
6128                     assign(t2, binop(Iop_CmpEQ32,
6129                                      binop(Iop_And32,
6130                                            getIReg(rs),
6131                                            mkU32(0xffff0000)),
6132                                      mkU32(0x80000000)));
6133                     assign(t3, IRExpr_ITE(mkexpr(t1),
6134                                           IRExpr_ITE(mkexpr(t2),
6135                                                      binop(Iop_Or32,
6136                                                            getDSPControl(),
6137                                                            mkU32(0x00200000)),
6138                                                      getDSPControl()),
6139                                           getDSPControl()));
6140                     putDSPControl(mkexpr(t3));
6141
6142                     putIReg(rd, IRExpr_ITE(mkexpr(t1),
6143                                            IRExpr_ITE(mkexpr(t2),
6144                                                       mkU32(0x7fffffff),
6145                                                       mkexpr(t0)),
6146                                            mkexpr(t0)));
6147                     break;
6148                  }
6149                  case 0x1D: {  /* MULEQ_S.W.PHR */
6150                     DIP("muleq_s.w.phr r%d, r%d, r%d", rd, rs, rt);
6151                     vassert(!mode64);
6152                     t0 = newTemp(Ity_I32);
6153                     t1 = newTemp(Ity_I1);
6154                     t2 = newTemp(Ity_I1);
6155
6156                     assign(t0,
6157                            binop(Iop_Shl32,
6158                                  binop(Iop_Mul32,
6159                                        unop(Iop_16Sto32,
6160                                             unop(Iop_32to16, getIReg(rt))),
6161                                        unop(Iop_16Sto32,
6162                                             unop(Iop_32to16, getIReg(rs)))),
6163                                  mkU8(0x1)));
6164                     assign(t1, binop(Iop_CmpEQ32,
6165                                      binop(Iop_And32,
6166                                            getIReg(rt),
6167                                            mkU32(0xffff)),
6168                                      mkU32(0x8000)));
6169                     assign(t2, binop(Iop_CmpEQ32,
6170                                      binop(Iop_And32,
6171                                            getIReg(rs),
6172                                            mkU32(0xffff)),
6173                                      mkU32(0x8000)));
6174                     putDSPControl(IRExpr_ITE(mkexpr(t1),
6175                                              IRExpr_ITE(mkexpr(t2),
6176                                                         binop(Iop_Or32,
6177                                                               getDSPControl(),
6178                                                               mkU32(0x00200000)
6179                                                              ),
6180                                                         getDSPControl()),
6181                                              getDSPControl()));
6182                     putIReg(rd, IRExpr_ITE(mkexpr(t1),
6183                                            IRExpr_ITE(mkexpr(t2),
6184                                                       mkU32(0x7fffffff),
6185                                                       mkexpr(t0)),
6186                                            mkexpr(t0)));
6187                     break;
6188                  }
6189                  case 0x1E: {  /* MULQ_S.PH */
6190                     DIP("mulq_s.ph r%d, r%d, r%d", rd, rs, rt);
6191                     vassert(!mode64);
6192                     t0 = newTemp(Ity_I32);
6193                     t1 = newTemp(Ity_I32);
6194                     t2 = newTemp(Ity_I16);
6195                     t3 = newTemp(Ity_I16);
6196                     t5 = newTemp(Ity_I32);
6197                     t6 = newTemp(Ity_I32);
6198                     t7 = newTemp(Ity_I32);
6199                     t8 = newTemp(Ity_I32);
6200
6201                     assign(t5,
6202                            unop(Iop_16Sto32, unop(Iop_32to16, getIReg(rs))));
6203                     assign(t6,
6204                            unop(Iop_16Sto32, unop(Iop_32to16, getIReg(rt))));
6205
6206                     assign(t7,
6207                            unop(Iop_16Sto32, unop(Iop_32HIto16, getIReg(rs))));
6208                     assign(t8,
6209                            unop(Iop_16Sto32, unop(Iop_32HIto16, getIReg(rt))));
6210
6211                     assign(t0, binop(Iop_And32,
6212                                      unop(Iop_1Sto32,
6213                                           binop(Iop_CmpEQ32,
6214                                                 binop(Iop_And32,
6215                                                       mkexpr(t5),
6216                                                       mkU32(0xffff)),
6217                                                 mkU32(0x8000))),
6218                                      unop(Iop_1Sto32,
6219                                           binop(Iop_CmpEQ32,
6220                                                 binop(Iop_And32,
6221                                                       mkexpr(t6),
6222                                                       mkU32(0xffff)),
6223                                                 mkU32(0x8000)))));
6224                     assign(t1, binop(Iop_And32,
6225                                      unop(Iop_1Sto32,
6226                                           binop(Iop_CmpEQ32,
6227                                                 binop(Iop_And32,
6228                                                       mkexpr(t7),
6229                                                       mkU32(0xffff)),
6230                                                 mkU32(0x8000))),
6231                                      unop(Iop_1Sto32,
6232                                           binop(Iop_CmpEQ32,
6233                                                 binop(Iop_And32,
6234                                                       mkexpr(t8),
6235                                                       mkU32(0xffff)),
6236                                                 mkU32(0x8000)))));
6237
6238                     putDSPControl(IRExpr_ITE(binop(Iop_CmpEQ32,
6239                                                    binop(Iop_Or32,
6240                                                          mkexpr(t0),
6241                                                          mkexpr(t1)),
6242                                                    mkU32(0x0)),
6243                                              getDSPControl(),
6244                                              binop(Iop_Or32,
6245                                                    getDSPControl(),
6246                                                    mkU32(0x200000))));
6247
6248                     assign(t2, unop(Iop_32HIto16,
6249                                     binop(Iop_Shl32,
6250                                           unop(Iop_64to32,
6251                                                binop(Iop_MullS32,
6252                                                      mkexpr(t7),
6253                                                      mkexpr(t8))),
6254                                           mkU8(0x1))));
6255                     assign(t3, unop(Iop_32HIto16,
6256                                     binop(Iop_Shl32,
6257                                           unop(Iop_64to32,
6258                                                binop(Iop_MullS32,
6259                                                      mkexpr(t5),
6260                                                      mkexpr(t6))),
6261                                           mkU8(0x1))));
6262                     putIReg(rd, binop(Iop_16HLto32,
6263                                       IRExpr_ITE(binop(Iop_CmpEQ32,
6264                                                        mkexpr(t1),
6265                                                        mkU32(0x0)),
6266                                                  mkexpr(t2),
6267                                                  mkU16(0x7fff)),
6268                                       IRExpr_ITE(binop(Iop_CmpEQ32,
6269                                                        mkexpr(t0),
6270                                                        mkU32(0x0)),
6271                                                  mkexpr(t3),
6272                                                  mkU16(0x7fff))));
6273                     break;
6274                  }
6275                  case 0x1F: {  /* MULQ_RS.PH */
6276                     DIP("mulq_rs.ph r%d, r%d, r%d", rd, rs, rt);
6277                     vassert(!mode64);
6278                     t0 = newTemp(Ity_I32);
6279                     t1 = newTemp(Ity_I1);
6280                     t2 = newTemp(Ity_I1);
6281                     t3 = newTemp(Ity_I16);
6282                     t4 = newTemp(Ity_I32);
6283                     t5 = newTemp(Ity_I1);
6284                     t6 = newTemp(Ity_I1);
6285                     t7 = newTemp(Ity_I16);
6286
6287                     /* Multiply and round lower halfwords. */
6288                     assign(t0, binop(Iop_Add32,
6289                                      binop(Iop_Shl32,
6290                                            binop(Iop_Mul32,
6291                                                  unop(Iop_16Sto32,
6292                                                       unop(Iop_32to16,
6293                                                            getIReg(rt))),
6294                                                  unop(Iop_16Sto32,
6295                                                       unop(Iop_32to16,
6296                                                            getIReg(rs)))),
6297                                            mkU8(0x1)),
6298                                      mkU32(0x00008000)));
6299                     assign(t1, binop(Iop_CmpEQ32,
6300                                      binop(Iop_And32,
6301                                            getIReg(rt), mkU32(0xffff)),
6302                                      mkU32(0x8000)));
6303                     assign(t2, binop(Iop_CmpEQ32,
6304                                      binop(Iop_And32,
6305                                            getIReg(rs), mkU32(0xffff)),
6306                                      mkU32(0x8000)));
6307                     putDSPControl(IRExpr_ITE(mkexpr(t1),
6308                                              IRExpr_ITE(mkexpr(t2),
6309                                                         binop(Iop_Or32,
6310                                                               getDSPControl(),
6311                                                               mkU32(0x00200000)
6312                                                              ),
6313                                                         getDSPControl()),
6314                                              getDSPControl()));
6315                     assign(t3, IRExpr_ITE(mkexpr(t1),
6316                                           IRExpr_ITE(mkexpr(t2),
6317                                                      mkU16(0x7fff),
6318                                                      unop(Iop_32HIto16,
6319                                                           mkexpr(t0))),
6320                                           unop(Iop_32HIto16, mkexpr(t0))));
6321
6322                     /* Multiply and round higher halfwords. */
6323                     assign(t4, binop(Iop_Add32,
6324                                      binop(Iop_Shl32,
6325                                            binop(Iop_Mul32,
6326                                                  unop(Iop_16Sto32,
6327                                                       unop(Iop_32HIto16,
6328                                                            getIReg(rt))),
6329                                                  unop(Iop_16Sto32,
6330                                                       unop(Iop_32HIto16,
6331                                                            getIReg(rs)))),
6332                                            mkU8(0x1)),
6333                                      mkU32(0x00008000)));
6334                     assign(t5, binop(Iop_CmpEQ32,
6335                                      binop(Iop_And32,
6336                                            getIReg(rt),
6337                                            mkU32(0xffff0000)),
6338                                      mkU32(0x80000000)));
6339                     assign(t6, binop(Iop_CmpEQ32,
6340                                      binop(Iop_And32,
6341                                            getIReg(rs),
6342                                            mkU32(0xffff0000)),
6343                                      mkU32(0x80000000)));
6344                     putDSPControl(IRExpr_ITE(mkexpr(t5),
6345                                             IRExpr_ITE(mkexpr(t6),
6346                                                        binop(Iop_Or32,
6347                                                             getDSPControl(),
6348                                                             mkU32(0x00200000)),
6349                                                        getDSPControl()),
6350                                             getDSPControl()));
6351                     assign(t7, IRExpr_ITE(mkexpr(t5),
6352                                           IRExpr_ITE(mkexpr(t6),
6353                                                      mkU16(0x7fff),
6354                                                      unop(Iop_32HIto16,
6355                                                           mkexpr(t4))),
6356                                           unop(Iop_32HIto16, mkexpr(t4))));
6357
6358                     putIReg(rd, binop(Iop_16HLto32, mkexpr(t7), mkexpr(t3)));
6359                     break;
6360                  }
6361                  default:
6362                     return -1;
6363               }
6364               break;  /* end of ADDU.QB */
6365            }
6366            case 0x11: {  /* CMPU.EQ.QB */
6367               switch(sa) {
6368                  case 0x0: {  /* CMPU.EQ.QB */
6369                     DIP("cmpu.eq.qb r%d, r%d", rs, rt);
6370                     vassert(!mode64);
6371                     t1 = newTemp(Ity_I1);
6372                     t2 = newTemp(Ity_I1);
6373                     t3 = newTemp(Ity_I1);
6374                     t4 = newTemp(Ity_I1);
6375
6376                     assign(t1,
6377                            binop(Iop_CmpEQ32,
6378                                  binop(Iop_And32, getIReg(rs), mkU32(0xff)),
6379                                  binop(Iop_And32, getIReg(rt), mkU32(0xff))));
6380                     putDSPControl(IRExpr_ITE(mkexpr(t1),
6381                                              binop(Iop_Or32,
6382                                                    getDSPControl(),
6383                                                    mkU32(0x01000000)),
6384                                              binop(Iop_And32,
6385                                                    getDSPControl(),
6386                                                    mkU32(0xfeffffff))));
6387
6388                     assign(t2, binop(Iop_CmpEQ32,
6389                                      unop(Iop_8Uto32,
6390                                           unop(Iop_16HIto8,
6391                                                unop(Iop_32to16,
6392                                                     getIReg(rs)))),
6393                                      unop(Iop_8Uto32,
6394                                           unop(Iop_16HIto8,
6395                                                unop(Iop_32to16,
6396                                                     getIReg(rt))))));
6397                     putDSPControl(IRExpr_ITE(mkexpr(t2),
6398                                              binop(Iop_Or32,
6399                                                    getDSPControl(),
6400                                                    mkU32(0x02000000)),
6401                                              binop(Iop_And32,
6402                                                    getDSPControl(),
6403                                                    mkU32(0xfdffffff))));
6404
6405                     assign(t3, binop(Iop_CmpEQ32,
6406                                      unop(Iop_8Uto32,
6407                                           unop(Iop_16to8,
6408                                                unop(Iop_32HIto16,
6409                                                     getIReg(rs)))),
6410                                      unop(Iop_8Uto32,
6411                                           unop(Iop_16to8,
6412                                                unop(Iop_32HIto16,
6413                                                     getIReg(rt))))));
6414                     putDSPControl(IRExpr_ITE(mkexpr(t3),
6415                                              binop(Iop_Or32,
6416                                                    getDSPControl(),
6417                                                    mkU32(0x04000000)),
6418                                              binop(Iop_And32,
6419                                                    getDSPControl(),
6420                                                    mkU32(0xfbffffff))));
6421
6422                     assign(t4, binop(Iop_CmpEQ32,
6423                                      unop(Iop_8Uto32,
6424                                           unop(Iop_16HIto8,
6425                                                unop(Iop_32HIto16,
6426                                                     getIReg(rs)))),
6427                                      unop(Iop_8Uto32,
6428                                           unop(Iop_16HIto8,
6429                                                unop(Iop_32HIto16,
6430                                                     getIReg(rt))))));
6431                     putDSPControl(IRExpr_ITE(mkexpr(t4),
6432                                              binop(Iop_Or32,
6433                                                    getDSPControl(),
6434                                                    mkU32(0x08000000)),
6435                                              binop(Iop_And32,
6436                                                    getDSPControl(),
6437                                                    mkU32(0xf7ffffff))));
6438                     break;
6439                  }
6440                  case 0x1: {  /* CMPU.LT.QB */
6441                     DIP("cmpu.lt.qb r%d, r%d", rs, rt);
6442                     vassert(!mode64);
6443                     t1 = newTemp(Ity_I1);
6444                     t2 = newTemp(Ity_I1);
6445                     t3 = newTemp(Ity_I1);
6446                     t4 = newTemp(Ity_I1);
6447
6448                     assign(t1, binop(Iop_CmpLT32U,
6449                                      unop(Iop_8Uto32,
6450                                           unop(Iop_16to8,
6451                                                unop(Iop_32to16,
6452                                                     getIReg(rs)))),
6453                                      unop(Iop_8Uto32,
6454                                           unop(Iop_16to8,
6455                                                unop(Iop_32to16,
6456                                                     getIReg(rt))))));
6457                     putDSPControl(IRExpr_ITE(mkexpr(t1),
6458                                              binop(Iop_Or32,
6459                                                    getDSPControl(),
6460                                                    mkU32(0x01000000)),
6461                                              binop(Iop_And32,
6462                                                    getDSPControl(),
6463                                                    mkU32(0xfeffffff))));
6464
6465                     assign(t2, binop(Iop_CmpLT32U,
6466                                      unop(Iop_8Uto32,
6467                                           unop(Iop_16HIto8,
6468                                                unop(Iop_32to16,
6469                                                     getIReg(rs)))),
6470                                      unop(Iop_8Uto32,
6471                                           unop(Iop_16HIto8,
6472                                                unop(Iop_32to16,
6473                                                     getIReg(rt))))));
6474                     putDSPControl(IRExpr_ITE(mkexpr(t2),
6475                                              binop(Iop_Or32,
6476                                                    getDSPControl(),
6477                                                    mkU32(0x02000000)),
6478                                              binop(Iop_And32,
6479                                                    getDSPControl(),
6480                                                    mkU32(0xfdffffff))));
6481
6482                     assign(t3, binop(Iop_CmpLT32U,
6483                                      unop(Iop_8Uto32,
6484                                           unop(Iop_16to8,
6485                                                unop(Iop_32HIto16,
6486                                                     getIReg(rs)))),
6487                                      unop(Iop_8Uto32,
6488                                           unop(Iop_16to8,
6489                                                unop(Iop_32HIto16,
6490                                                     getIReg(rt))))));
6491                     putDSPControl(IRExpr_ITE(mkexpr(t3),
6492                                              binop(Iop_Or32,
6493                                                    getDSPControl(),
6494                                                    mkU32(0x04000000)),
6495                                              binop(Iop_And32,
6496                                                    getDSPControl(),
6497                                                    mkU32(0xfbffffff))));
6498
6499                     assign(t4, binop(Iop_CmpLT32U,
6500                                      unop(Iop_8Uto32,
6501                                           unop(Iop_16HIto8,
6502                                                unop(Iop_32HIto16,
6503                                                     getIReg(rs)))),
6504                                      unop(Iop_8Uto32,
6505                                           unop(Iop_16HIto8,
6506                                                unop(Iop_32HIto16,
6507                                                     getIReg(rt))))));
6508                     putDSPControl(IRExpr_ITE(mkexpr(t4),
6509                                              binop(Iop_Or32,
6510                                                    getDSPControl(),
6511                                                    mkU32(0x08000000)),
6512                                              binop(Iop_And32,
6513                                                    getDSPControl(),
6514                                                    mkU32(0xf7ffffff))));
6515                     break;
6516                  }
6517                  case 0x2: {  /* CMPU.LE.QB */
6518                     DIP("cmpu.le.qb r%d, r%d", rs, rt);
6519                     vassert(!mode64);
6520                     t1 = newTemp(Ity_I1);
6521                     t2 = newTemp(Ity_I1);
6522                     t3 = newTemp(Ity_I1);
6523                     t4 = newTemp(Ity_I1);
6524
6525                     assign(t1, binop(Iop_CmpLE32U,
6526                                      unop(Iop_8Uto32,
6527                                           unop(Iop_16to8,
6528                                                unop(Iop_32to16,
6529                                                     getIReg(rs)))),
6530                                      unop(Iop_8Uto32,
6531                                           unop(Iop_16to8,
6532                                                unop(Iop_32to16,
6533                                                     getIReg(rt))))));
6534                     putDSPControl(IRExpr_ITE(mkexpr(t1),
6535                                              binop(Iop_Or32,
6536                                                    getDSPControl(),
6537                                                    mkU32(0x01000000)),
6538                                              binop(Iop_And32,
6539                                                    getDSPControl(),
6540                                                    mkU32(0xfeffffff))));
6541
6542                     assign(t2, binop(Iop_CmpLE32U,
6543                                      unop(Iop_8Uto32,
6544                                           unop(Iop_16HIto8,
6545                                                unop(Iop_32to16,
6546                                                     getIReg(rs)))),
6547                                      unop(Iop_8Uto32,
6548                                           unop(Iop_16HIto8,
6549                                                unop(Iop_32to16,
6550                                                     getIReg(rt))))));
6551                     putDSPControl(IRExpr_ITE(mkexpr(t2),
6552                                              binop(Iop_Or32,
6553                                                    getDSPControl(),
6554                                                    mkU32(0x02000000)),
6555                                              binop(Iop_And32,
6556                                                    getDSPControl(),
6557                                                    mkU32(0xfdffffff))));
6558
6559                     assign(t3, binop(Iop_CmpLE32U,
6560                                      unop(Iop_8Uto32,
6561                                           unop(Iop_16to8,
6562                                                unop(Iop_32HIto16,
6563                                                     getIReg(rs)))),
6564                                      unop(Iop_8Uto32,
6565                                           unop(Iop_16to8,
6566                                                unop(Iop_32HIto16,
6567                                                     getIReg(rt))))));
6568                     putDSPControl(IRExpr_ITE(mkexpr(t3),
6569                                              binop(Iop_Or32,
6570                                                    getDSPControl(),
6571                                                    mkU32(0x04000000)),
6572                                              binop(Iop_And32,
6573                                                    getDSPControl(),
6574                                                    mkU32(0xfbffffff))));
6575
6576                     assign(t4, binop(Iop_CmpLE32U,
6577                                      unop(Iop_8Uto32,
6578                                           unop(Iop_16HIto8,
6579                                                unop(Iop_32HIto16,
6580                                                     getIReg(rs)))),
6581                                      unop(Iop_8Uto32,
6582                                           unop(Iop_16HIto8,
6583                                                unop(Iop_32HIto16,
6584                                                     getIReg(rt))))));
6585                     putDSPControl(IRExpr_ITE(mkexpr(t4),
6586                                              binop(Iop_Or32,
6587                                                    getDSPControl(),
6588                                                    mkU32(0x08000000)),
6589                                              binop(Iop_And32,
6590                                                    getDSPControl(),
6591                                                    mkU32(0xf7ffffff))));
6592                     break;
6593                  }
6594                  case 0x3: {  /* PICK.QB */
6595                     DIP("pick.qb r%d, r%d, r%d", rd, rs, rt);
6596                     vassert(!mode64);
6597                     t0 = newTemp(Ity_I32);
6598                     t1 = newTemp(Ity_I8);
6599                     t2 = newTemp(Ity_I8);
6600                     t3 = newTemp(Ity_I8);
6601                     t4 = newTemp(Ity_I8);
6602
6603                     assign(t0, getDSPControl());
6604                     assign(t1, IRExpr_ITE(binop(Iop_CmpNE32,
6605                                                 binop(Iop_And32,
6606                                                       mkexpr(t0),
6607                                                       mkU32(0x01000000)),
6608                                                 mkU32(0x0)),
6609                                           unop(Iop_16to8,
6610                                                 unop(Iop_32to16,
6611                                                      getIReg(rs))),
6612                                           unop(Iop_16to8,
6613                                                unop(Iop_32to16,
6614                                                     getIReg(rt)))));
6615                     assign(t2, IRExpr_ITE(binop(Iop_CmpNE32,
6616                                                 binop(Iop_And32,
6617                                                       mkexpr(t0),
6618                                                       mkU32(0x02000000)),
6619                                                 mkU32(0x0)),
6620                                           unop(Iop_16HIto8,
6621                                                unop(Iop_32to16, getIReg(rs))),
6622                                           unop(Iop_16HIto8,
6623                                                unop(Iop_32to16,
6624                                                     getIReg(rt)))));
6625                     assign(t3, IRExpr_ITE(binop(Iop_CmpNE32,
6626                                                 binop(Iop_And32,
6627                                                       mkexpr(t0),
6628                                                       mkU32(0x04000000)),
6629                                                 mkU32(0x0)),
6630                                           unop(Iop_16to8,
6631                                                unop(Iop_32HIto16,
6632                                                     getIReg(rs))),
6633                                           unop(Iop_16to8,
6634                                                unop(Iop_32HIto16,
6635                                                     getIReg(rt)))));
6636                     assign(t4, IRExpr_ITE(binop(Iop_CmpNE32,
6637                                                 binop(Iop_And32,
6638                                                       mkexpr(t0),
6639                                                       mkU32(0x08000000)),
6640                                                 mkU32(0x0)),
6641                                           unop(Iop_16HIto8,
6642                                                unop(Iop_32HIto16,
6643                                                     getIReg(rs))),
6644                                           unop(Iop_16HIto8,
6645                                                unop(Iop_32HIto16,
6646                                                     getIReg(rt)))));
6647                     putIReg(rd,
6648                             binop(Iop_16HLto32,
6649                                   binop(Iop_8HLto16, mkexpr(t4), mkexpr(t3)),
6650                                   binop(Iop_8HLto16, mkexpr(t2), mkexpr(t1))));
6651                     break;
6652                  }
6653                  case 0x4: {  /* CMPGU.EQ.QB */
6654                     DIP("cmpgu.eq.qb r%d, r%d, r%d", rd, rs, rt);
6655                     vassert(!mode64);
6656                     t1 = newTemp(Ity_I1);
6657                     t2 = newTemp(Ity_I1);
6658                     t3 = newTemp(Ity_I1);
6659                     t4 = newTemp(Ity_I1);
6660                     t5 = newTemp(Ity_I32);
6661                     t6 = newTemp(Ity_I32);
6662                     t7 = newTemp(Ity_I32);
6663                     t8 = newTemp(Ity_I32);
6664
6665                     assign(t1, binop(Iop_CmpEQ32,
6666                                      unop(Iop_8Uto32,
6667                                           unop(Iop_16to8,
6668                                                unop(Iop_32to16, getIReg(rs)))),
6669                                      unop(Iop_8Uto32,
6670                                           unop(Iop_16to8,
6671                                                unop(Iop_32to16,
6672                                                     getIReg(rt))))));
6673                     assign(t5, IRExpr_ITE(mkexpr(t1),
6674                                           mkU32(0x00000001), mkU32(0)));
6675
6676                     assign(t2, binop(Iop_CmpEQ32,
6677                                      unop(Iop_8Uto32,
6678                                           unop(Iop_16HIto8,
6679                                                unop(Iop_32to16, getIReg(rs)))),
6680                                      unop(Iop_8Uto32,
6681                                           unop(Iop_16HIto8,
6682                                                unop(Iop_32to16,
6683                                                     getIReg(rt))))));
6684                     assign(t6, IRExpr_ITE(mkexpr(t2),
6685                                           mkU32(0x00000002), mkU32(0)));
6686
6687                     assign(t3, binop(Iop_CmpEQ32,
6688                                      unop(Iop_8Uto32,
6689                                           unop(Iop_16to8,
6690                                                unop(Iop_32HIto16,
6691                                                     getIReg(rs)))),
6692                                      unop(Iop_8Uto32,
6693                                           unop(Iop_16to8,
6694                                                unop(Iop_32HIto16,
6695                                                     getIReg(rt))))));
6696                     assign(t7, IRExpr_ITE(mkexpr(t3),
6697                                           mkU32(0x00000004), mkU32(0)));
6698
6699                     assign(t4, binop(Iop_CmpEQ32,
6700                                      unop(Iop_8Uto32,
6701                                           unop(Iop_16HIto8,
6702                                                unop(Iop_32HIto16,
6703                                                     getIReg(rs)))),
6704                                      unop(Iop_8Uto32,
6705                                           unop(Iop_16HIto8,
6706                                                unop(Iop_32HIto16,
6707                                                     getIReg(rt))))));
6708                     assign(t8, IRExpr_ITE(mkexpr(t4),
6709                                           mkU32(0x00000008), mkU32(0)));
6710
6711                     putIReg(rd, binop(Iop_Or32,
6712                                       binop(Iop_Or32,
6713                                             binop(Iop_Or32,
6714                                                   mkexpr(t5), mkexpr(t6)),
6715                                             mkexpr(t7)),
6716                                       mkexpr(t8)));
6717                     break;
6718                  }
6719                  case 0x5: {  /* CMPGU.LT.QB */
6720                     DIP("cmpgu.lt.qb r%d, r%d, r%d", rd, rs, rt);
6721                     vassert(!mode64);
6722                     t1 = newTemp(Ity_I1);
6723                     t2 = newTemp(Ity_I1);
6724                     t3 = newTemp(Ity_I1);
6725                     t4 = newTemp(Ity_I1);
6726                     t5 = newTemp(Ity_I32);
6727                     t6 = newTemp(Ity_I32);
6728                     t7 = newTemp(Ity_I32);
6729                     t8 = newTemp(Ity_I32);
6730
6731                     assign(t1, binop(Iop_CmpLT32U,
6732                                      unop(Iop_8Uto32,
6733                                           unop(Iop_16to8,
6734                                                unop(Iop_32to16, getIReg(rs)))),
6735                                      unop(Iop_8Uto32,
6736                                           unop(Iop_16to8,
6737                                                unop(Iop_32to16,
6738                                                     getIReg(rt))))));
6739                     assign(t5, IRExpr_ITE(mkexpr(t1),
6740                                           mkU32(0x00000001), mkU32(0)));
6741
6742                     assign(t2, binop(Iop_CmpLT32U,
6743                                      unop(Iop_8Uto32,
6744                                           unop(Iop_16HIto8,
6745                                                unop(Iop_32to16, getIReg(rs)))),
6746                                      unop(Iop_8Uto32,
6747                                           unop(Iop_16HIto8,
6748                                                unop(Iop_32to16,
6749                                                     getIReg(rt))))));
6750                     assign(t6, IRExpr_ITE(mkexpr(t2),
6751                                           mkU32(0x00000002), mkU32(0)));
6752
6753                     assign(t3, binop(Iop_CmpLT32U,
6754                                      unop(Iop_8Uto32,
6755                                           unop(Iop_16to8,
6756                                                unop(Iop_32HIto16,
6757                                                     getIReg(rs)))),
6758                                      unop(Iop_8Uto32,
6759                                           unop(Iop_16to8,
6760                                                unop(Iop_32HIto16,
6761                                                     getIReg(rt))))));
6762                     assign(t7, IRExpr_ITE(mkexpr(t3),
6763                                           mkU32(0x00000004), mkU32(0)));
6764
6765                     assign(t4, binop(Iop_CmpLT32U,
6766                                      unop(Iop_8Uto32,
6767                                           unop(Iop_16HIto8,
6768                                                unop(Iop_32HIto16,
6769                                                     getIReg(rs)))),
6770                                      unop(Iop_8Uto32,
6771                                           unop(Iop_16HIto8,
6772                                                unop(Iop_32HIto16,
6773                                                     getIReg(rt))))));
6774                     assign(t8, IRExpr_ITE(mkexpr(t4),
6775                                           mkU32(0x00000008), mkU32(0)));
6776                     putIReg(rd, binop(Iop_Or32,
6777                                       binop(Iop_Or32,
6778                                             binop(Iop_Or32,
6779                                                   mkexpr(t5), mkexpr(t6)),
6780                                             mkexpr(t7)),
6781                                       mkexpr(t8)));
6782                     break;
6783                  }
6784                  case 0x6: {  /* CMPGU.LE.QB */
6785                     DIP("cmpgu.le.qb r%d, r%d, r%d", rd, rs, rt);
6786                     vassert(!mode64);
6787                     t1 = newTemp(Ity_I1);
6788                     t2 = newTemp(Ity_I1);
6789                     t3 = newTemp(Ity_I1);
6790                     t4 = newTemp(Ity_I1);
6791                     t5 = newTemp(Ity_I32);
6792                     t6 = newTemp(Ity_I32);
6793                     t7 = newTemp(Ity_I32);
6794                     t8 = newTemp(Ity_I32);
6795
6796                     assign(t1, binop(Iop_CmpLE32U,
6797                                      unop(Iop_8Uto32,
6798                                           unop(Iop_16to8,
6799                                                unop(Iop_32to16, getIReg(rs)))),
6800                                      unop(Iop_8Uto32,
6801                                           unop(Iop_16to8,
6802                                                unop(Iop_32to16,
6803                                                     getIReg(rt))))));
6804                     assign(t5, IRExpr_ITE(mkexpr(t1),
6805                                           mkU32(0x00000001), mkU32(0)));
6806
6807                     assign(t2, binop(Iop_CmpLE32U,
6808                                      unop(Iop_8Uto32,
6809                                           unop(Iop_16HIto8,
6810                                                unop(Iop_32to16, getIReg(rs)))),
6811                                      unop(Iop_8Uto32,
6812                                           unop(Iop_16HIto8,
6813                                                unop(Iop_32to16,
6814                                                     getIReg(rt))))));
6815                     assign(t6, IRExpr_ITE(mkexpr(t2),
6816                                           mkU32(0x00000002), mkU32(0)));
6817
6818                     assign(t3, binop(Iop_CmpLE32U,
6819                                      unop(Iop_8Uto32,
6820                                           unop(Iop_16to8,
6821                                                unop(Iop_32HIto16,
6822                                                     getIReg(rs)))),
6823                                      unop(Iop_8Uto32,
6824                                           unop(Iop_16to8,
6825                                                unop(Iop_32HIto16,
6826                                                     getIReg(rt))))));
6827                     assign(t7, IRExpr_ITE(mkexpr(t3),
6828                                           mkU32(0x00000004), mkU32(0)));
6829
6830                     assign(t4, binop(Iop_CmpLE32U,
6831                                      unop(Iop_8Uto32,
6832                                           unop(Iop_16HIto8,
6833                                                unop(Iop_32HIto16,
6834                                                     getIReg(rs)))),
6835                                      unop(Iop_8Uto32,
6836                                           unop(Iop_16HIto8,
6837                                                unop(Iop_32HIto16,
6838                                                     getIReg(rt))))));
6839                     assign(t8, IRExpr_ITE(mkexpr(t4),
6840                                           mkU32(0x00000008), mkU32(0)));
6841                     putIReg(rd, binop(Iop_Or32,
6842                                       binop(Iop_Or32,
6843                                             binop(Iop_Or32,
6844                                                   mkexpr(t5), mkexpr(t6)),
6845                                             mkexpr(t7)),
6846                                       mkexpr(t8)));
6847                     break;
6848                  }
6849                  case 0x8: {  /* CMP.EQ.PH */
6850                     DIP("cmp.eq.ph r%d, r%d", rs, rt);
6851                     vassert(!mode64);
6852                     t1 = newTemp(Ity_I1);
6853                     t2 = newTemp(Ity_I1);
6854
6855                     assign(t1, binop(Iop_CmpEQ16,
6856                                      unop(Iop_32to16, getIReg(rs)),
6857                                      unop(Iop_32to16, getIReg(rt))));
6858                     putDSPControl(IRExpr_ITE(mkexpr(t1),
6859                                              binop(Iop_Or32,
6860                                                    getDSPControl(),
6861                                                    mkU32(0x01000000)),
6862                                              binop(Iop_And32,
6863                                                    getDSPControl(),
6864                                                    mkU32(0xfeffffff))));
6865                     assign(t2, binop(Iop_CmpEQ16,
6866                                      unop(Iop_32HIto16, getIReg(rs)),
6867                                      unop(Iop_32HIto16, getIReg(rt))));
6868                     putDSPControl(IRExpr_ITE(mkexpr(t2),
6869                                              binop(Iop_Or32,
6870                                                    getDSPControl(),
6871                                                    mkU32(0x02000000)),
6872                                              binop(Iop_And32,
6873                                                    getDSPControl(),
6874                                                    mkU32(0xfdffffff))));
6875                     break;
6876                  }
6877                  case 0x9: {  /* CMP.LT.PH */
6878                     DIP("cmp.lt.ph r%d, r%d", rs, rt);
6879                     vassert(!mode64);
6880                     t1 = newTemp(Ity_I1);
6881                     t2 = newTemp(Ity_I1);
6882
6883                     assign(t1, binop(Iop_CmpLT32S,
6884                                      unop(Iop_16Sto32,
6885                                           unop(Iop_32to16, getIReg(rs))),
6886                                      unop(Iop_16Sto32,
6887                                           unop(Iop_32to16, getIReg(rt)))));
6888                     putDSPControl(IRExpr_ITE(mkexpr(t1),
6889                                              binop(Iop_Or32,
6890                                                    getDSPControl(),
6891                                                    mkU32(0x01000000)),
6892                                              binop(Iop_And32,
6893                                                    getDSPControl(),
6894                                                    mkU32(0xfeffffff))));
6895
6896                     assign(t2, binop(Iop_CmpLT32S,
6897                                      unop(Iop_16Sto32,
6898                                           unop(Iop_32HIto16, getIReg(rs))),
6899                                      unop(Iop_16Sto32,
6900                                           unop(Iop_32HIto16, getIReg(rt)))));
6901                     putDSPControl(IRExpr_ITE(mkexpr(t2),
6902                                              binop(Iop_Or32,
6903                                                    getDSPControl(),
6904                                                    mkU32(0x02000000)),
6905                                              binop(Iop_And32,
6906                                                    getDSPControl(),
6907                                                    mkU32(0xfdffffff))));
6908                     break;
6909                  }
6910                  case 0xA: {  /* CMP.LE.PH */
6911                     DIP("cmp.le.ph r%d, r%d", rs, rt);
6912                     vassert(!mode64);
6913                     t1 = newTemp(Ity_I1);
6914                     t2 = newTemp(Ity_I1);
6915
6916                     assign(t1, binop(Iop_CmpLE32S,
6917                                      unop(Iop_16Sto32,
6918                                           unop(Iop_32to16, getIReg(rs))),
6919                                      unop(Iop_16Sto32,
6920                                           unop(Iop_32to16, getIReg(rt)))));
6921                     putDSPControl(IRExpr_ITE(mkexpr(t1),
6922                                              binop(Iop_Or32,
6923                                                    getDSPControl(),
6924                                                    mkU32(0x01000000)),
6925                                              binop(Iop_And32,
6926                                                    getDSPControl(),
6927                                                    mkU32(0xfeffffff))));
6928
6929                     assign(t2, binop(Iop_CmpLE32S,
6930                                      unop(Iop_16Sto32,
6931                                           unop(Iop_32HIto16, getIReg(rs))),
6932                                      unop(Iop_16Sto32,
6933                                           unop(Iop_32HIto16, getIReg(rt)))));
6934                     putDSPControl(IRExpr_ITE(mkexpr(t2),
6935                                              binop(Iop_Or32,
6936                                                    getDSPControl(),
6937                                                    mkU32(0x02000000)),
6938                                              binop(Iop_And32,
6939                                                    getDSPControl(),
6940                                                    mkU32(0xfdffffff))));
6941                     break;
6942                  }
6943                  case 0xB: {  /* PICK.PH */
6944                     DIP("pick.qb r%d, r%d, r%d", rd, rs, rt);
6945                     vassert(!mode64);
6946                     t0 = newTemp(Ity_I32);
6947                     t1 = newTemp(Ity_I16);
6948                     t2 = newTemp(Ity_I16);
6949
6950                     assign(t0, getDSPControl());
6951
6952                     assign(t1, IRExpr_ITE(binop(Iop_CmpNE32,
6953                                                 binop(Iop_And32,
6954                                                       mkexpr(t0),
6955                                                       mkU32(0x01000000)),
6956                                                 mkU32(0x0)),
6957                                           unop(Iop_32to16, getIReg(rs)),
6958                                           unop(Iop_32to16, getIReg(rt))));
6959
6960                     assign(t2, IRExpr_ITE(binop(Iop_CmpNE32,
6961                                                 binop(Iop_And32,
6962                                                       mkexpr(t0),
6963                                                       mkU32(0x02000000)),
6964                                                 mkU32(0x0)),
6965                                           unop(Iop_32HIto16, getIReg(rs)),
6966                                           unop(Iop_32HIto16, getIReg(rt))));
6967
6968                     putIReg(rd, binop(Iop_16HLto32, mkexpr(t2), mkexpr(t1)));
6969                     break;
6970                  }
6971                  case 0xC: {  /* PRECRQ.QB.PH */
6972                     DIP("precrq.qb.ph r%d, r%d, %d", rd, rs, rt);
6973                     vassert(!mode64);
6974                     putIReg(rd,
6975                             binop(Iop_16HLto32,
6976                                   binop(Iop_8HLto16,
6977                                         unop(Iop_16HIto8,
6978                                              unop(Iop_32HIto16, getIReg(rs))),
6979                                         unop(Iop_16HIto8,
6980                                              unop(Iop_32to16, getIReg(rs)))),
6981                                   binop(Iop_8HLto16,
6982                                         unop(Iop_16HIto8,
6983                                              unop(Iop_32HIto16, getIReg(rt))),
6984                                         unop(Iop_16HIto8,
6985                                              unop(Iop_32to16, getIReg(rt))))));
6986                     break;
6987                  }
6988                  case 0xD: {  /* PRECR.QB.PH */
6989                     DIP("precr.qb.ph r%d, r%d, r%d", rd, rs, rt);
6990                     vassert(!mode64);
6991
6992                     putIReg(rd,
6993                             binop(Iop_16HLto32,
6994                                   binop(Iop_8HLto16,
6995                                         unop(Iop_16to8,
6996                                              unop(Iop_32HIto16, getIReg(rs))),
6997                                         unop(Iop_16to8,
6998                                              unop(Iop_32to16, getIReg(rs)))),
6999                                   binop(Iop_8HLto16,
7000                                         unop(Iop_16to8,
7001                                              unop(Iop_32HIto16, getIReg(rt))),
7002                                         unop(Iop_16to8,
7003                                              unop(Iop_32to16, getIReg(rt))))));
7004                     break;
7005                  }
7006                  case 0xF: {  /* PRECRQU_S.QB.PH */
7007                     DIP("precrqu_s.qb.ph r%d, r%d, %d", rd, rs, rt);
7008                     vassert(!mode64);
7009                     t0 = newTemp(Ity_I8);
7010                     t1 = newTemp(Ity_I8);
7011                     t2 = newTemp(Ity_I8);
7012                     t3 = newTemp(Ity_I8);
7013                     t4 = newTemp(Ity_I8);
7014                     t5 = newTemp(Ity_I32);
7015                     t6 = newTemp(Ity_I1);
7016                     t7 = newTemp(Ity_I8);
7017                     t8 = newTemp(Ity_I1);
7018                     t9 = newTemp(Ity_I32);
7019                     t10 = newTemp(Ity_I8);
7020                     t11 = newTemp(Ity_I1);
7021                     t12 = newTemp(Ity_I32);
7022                     t13 = newTemp(Ity_I8);
7023                     t14 = newTemp(Ity_I1);
7024                     t15 = newTemp(Ity_I32);
7025
7026                     assign(t4, IRExpr_ITE(binop(Iop_CmpLT32U,
7027                                                 mkU32(0x7f80),
7028                                                 binop(Iop_And32,
7029                                                       unop(Iop_16Uto32,
7030                                                            unop(Iop_32to16,
7031                                                            getIReg(rs))),
7032                                                       mkU32(0x7fff))),
7033                                           mkU8(0xff),
7034                                           unop(Iop_16HIto8,
7035                                                unop(Iop_32to16,
7036                                                     binop(Iop_Shl32,
7037                                                           getIReg(rs),
7038                                                           mkU8(1))))));
7039                     assign(t0, IRExpr_ITE(binop(Iop_CmpEQ32,
7040                                                 binop(Iop_And32,
7041                                                       unop(Iop_16Uto32,
7042                                                            unop(Iop_32to16,
7043                                                                 getIReg(rs))),
7044                                                       mkU32(0x00008000)),
7045                                                 mkU32(0x0)),
7046                                           mkexpr(t4),
7047                                           mkU8(0x0)));
7048                     assign(t5, binop(Iop_And32,
7049                                      unop(Iop_16Uto32,
7050                                            unop(Iop_32to16,
7051                                                 getIReg(rs))),
7052                                      mkU32(0x00008000)));
7053                     assign(t6, binop(Iop_CmpLT32U,
7054                                      mkU32(0x7f80),
7055                                      binop(Iop_And32,
7056                                            unop(Iop_16Uto32,
7057                                                 unop(Iop_32to16,
7058                                                 getIReg(rs))),
7059                                            mkU32(0x7fff))));
7060                     putDSPControl(IRExpr_ITE(binop(Iop_CmpEQ32,
7061                                                    mkexpr(t5),
7062                                                    mkU32(0x0)),
7063                                              IRExpr_ITE(mkexpr(t6),
7064                                                         binop(Iop_Or32,
7065                                                               getDSPControl(),
7066                                                               mkU32(0x00400000)
7067                                                              ),
7068                                                         getDSPControl()),
7069                                              binop(Iop_Or32,
7070                                                    getDSPControl(),
7071                                                    mkU32(0x00400000))));
7072
7073                     assign(t7, IRExpr_ITE(binop(Iop_CmpLT32U,
7074                                                 mkU32(0x7f80),
7075                                                 binop(Iop_And32,
7076                                                       unop(Iop_16Uto32,
7077                                                            unop(Iop_32HIto16,
7078                                                                 getIReg(rs))),
7079                                                       mkU32(0x7fff))),
7080                                           mkU8(0xff),
7081                                           unop(Iop_16HIto8,
7082                                                unop(Iop_32HIto16,
7083                                                     binop(Iop_Shl32,
7084                                                           getIReg(rs),
7085                                                           mkU8(1))))));
7086                     assign(t1, IRExpr_ITE(binop(Iop_CmpEQ32,
7087                                                 binop(Iop_And32,
7088                                                       unop(Iop_16Uto32,
7089                                                            unop(Iop_32HIto16,
7090                                                                 getIReg(rs))),
7091                                                       mkU32(0x00008000)),
7092                                                 mkU32(0x0)),
7093                                           mkexpr(t7),
7094                                           mkU8(0x0)));
7095                     assign(t8, binop(Iop_CmpEQ32,
7096                                      binop(Iop_And32,
7097                                            unop(Iop_16Uto32,
7098                                                 unop(Iop_32HIto16,
7099                                                      getIReg(rs))),
7100                                            mkU32(0x00008000)),
7101                                      mkU32(0x0)));
7102                     assign(t9, IRExpr_ITE(binop(Iop_CmpLT32U,
7103                                                 mkU32(0x7f80),
7104                                                 binop(Iop_And32,
7105                                                       unop(Iop_16Uto32,
7106                                                            unop(Iop_32HIto16,
7107                                                                 getIReg(rs))),
7108                                                       mkU32(0x7fff))),
7109                                           binop(Iop_Or32,
7110                                                 getDSPControl(),
7111                                                 mkU32(0x00400000)),
7112                                           getDSPControl()));
7113                     putDSPControl(IRExpr_ITE(mkexpr(t8),
7114                                              mkexpr(t9),
7115                                              binop(Iop_Or32,
7116                                                    getDSPControl(),
7117                                                    mkU32(0x00400000))));
7118
7119                     assign(t10, IRExpr_ITE(binop(Iop_CmpLT32U,
7120                                                  mkU32(0x7f80),
7121                                                  binop(Iop_And32,
7122                                                        unop(Iop_16Uto32,
7123                                                             unop(Iop_32to16,
7124                                                             getIReg(rt))),
7125                                                        mkU32(0x7fff))),
7126                                            mkU8(0xff),
7127                                            unop(Iop_16HIto8,
7128                                                 unop(Iop_32to16,
7129                                                      binop(Iop_Shl32,
7130                                                            getIReg(rt),
7131                                                            mkU8(1))))));
7132                     assign(t2, IRExpr_ITE(binop(Iop_CmpEQ32,
7133                                                 binop(Iop_And32,
7134                                                       unop(Iop_16Uto32,
7135                                                            unop(Iop_32to16,
7136                                                                 getIReg(rt))),
7137                                                       mkU32(0x00008000)),
7138                                                 mkU32(0x0)),
7139                                           mkexpr(t10),
7140                                           mkU8(0x0)));
7141                     assign(t11, binop(Iop_CmpEQ32,
7142                                       binop(Iop_And32,
7143                                             unop(Iop_16Uto32,
7144                                                  unop(Iop_32to16,
7145                                                       getIReg(rt))),
7146                                             mkU32(0x00008000)),
7147                                       mkU32(0x0)));
7148                     assign(t12, IRExpr_ITE(binop(Iop_CmpLT32U,
7149                                                  mkU32(0x7f80),
7150                                                  binop(Iop_And32,
7151                                                        unop(Iop_16Uto32,
7152                                                             unop(Iop_32to16,
7153                                                             getIReg(rt))),
7154                                                        mkU32(0x7fff))),
7155                                            binop(Iop_Or32,
7156                                                  getDSPControl(),
7157                                                  mkU32(0x00400000)),
7158                                            getDSPControl()));
7159                     putDSPControl(IRExpr_ITE(mkexpr(t11),
7160                                              mkexpr(t12),
7161                                              binop(Iop_Or32,
7162                                                    getDSPControl(),
7163                                                    mkU32(0x00400000))));
7164
7165                     assign(t13, IRExpr_ITE(binop(Iop_CmpLT32U,
7166                                                  mkU32(0x7f80),
7167                                                  binop(Iop_And32,
7168                                                        unop(Iop_16Uto32,
7169                                                             unop(Iop_32HIto16,
7170                                                                  getIReg(rt))),
7171                                                        mkU32(0x7fff))),
7172                                            mkU8(0xff),
7173                                            unop(Iop_16HIto8,
7174                                                 unop(Iop_32HIto16,
7175                                                      binop(Iop_Shl32,
7176                                                            getIReg(rt),
7177                                                            mkU8(1))))));
7178                     assign(t3, IRExpr_ITE(binop(Iop_CmpEQ32,
7179                                                 binop(Iop_And32,
7180                                                       unop(Iop_16Uto32,
7181                                                            unop(Iop_32HIto16,
7182                                                                 getIReg(rt))),
7183                                                       mkU32(0x00008000)),
7184                                                 mkU32(0x0)),
7185                                           mkexpr(t13),
7186                                           mkU8(0x0)));
7187                     assign(t14, binop(Iop_CmpEQ32,
7188                                       binop(Iop_And32,
7189                                             unop(Iop_16Uto32,
7190                                                  unop(Iop_32HIto16,
7191                                                       getIReg(rt))),
7192                                             mkU32(0x00008000)),
7193                                       mkU32(0x0)));
7194                     assign(t15, IRExpr_ITE(binop(Iop_CmpLT32U,
7195                                                  mkU32(0x7f80),
7196                                                  binop(Iop_And32,
7197                                                        unop(Iop_16Uto32,
7198                                                             unop(Iop_32HIto16,
7199                                                                  getIReg(rt))),
7200                                                        mkU32(0x7fff))),
7201                                            binop(Iop_Or32,
7202                                                  getDSPControl(),
7203                                                  mkU32(0x00400000)),
7204                                            getDSPControl()));
7205                     putDSPControl(IRExpr_ITE(mkexpr(t14),
7206                                              mkexpr(t15),
7207                                              binop(Iop_Or32,
7208                                                    getDSPControl(),
7209                                                    mkU32(0x00400000))));
7210
7211                     putIReg(rd, binop(Iop_16HLto32,
7212                                       binop(Iop_8HLto16,
7213                                             mkexpr(t1), mkexpr(t0)),
7214                                       binop(Iop_8HLto16,
7215                                             mkexpr(t3), mkexpr(t2))));
7216                     break;
7217                  }
7218                  case 0x14: {  /* PRECRQ.PH.W */
7219                     DIP("precrq.ph.w r%d, r%d, %d", rd, rs, rt);
7220                     vassert(!mode64);
7221                     putIReg(rd, binop(Iop_16HLto32,
7222                                       unop(Iop_32HIto16, getIReg(rs)),
7223                                       unop(Iop_32HIto16, getIReg(rt))));
7224                     break;
7225                  }
7226                  case 0x15: {  /* PRECRQ_RS.PH.W */
7227                     DIP("precrq_rs.ph.w r%d, r%d, %d", rd, rs, rt);
7228                     vassert(!mode64);
7229                     t0 = newTemp(Ity_I64);
7230                     t1 = newTemp(Ity_I1);
7231                     t2 = newTemp(Ity_I32);
7232                     t3 = newTemp(Ity_I64);
7233                     t4 = newTemp(Ity_I1);
7234                     t5 = newTemp(Ity_I32);
7235
7236                     assign(t0, binop(Iop_Add64,
7237                                      binop(Iop_32HLto64,
7238                                            binop(Iop_Shr32,
7239                                                  binop(Iop_And32,
7240                                                        getIReg(rs),
7241                                                        mkU32(0x80000000)),
7242                                                  mkU8(31)),
7243                                            getIReg(rs)),
7244                                      mkU64(0x0000000000008000ULL)));
7245                     assign(t1, binop(Iop_CmpNE32,
7246                                      binop(Iop_And32,
7247                                            unop(Iop_64HIto32, mkexpr(t0)),
7248                                            mkU32(0x1)),
7249                                      binop(Iop_And32,
7250                                            binop(Iop_Shr32,
7251                                                  unop(Iop_64to32, mkexpr(t0)),
7252                                                  mkU8(31)),
7253                                            mkU32(0x1))));
7254                     assign(t2, IRExpr_ITE(mkexpr(t1),
7255                                           mkU32(0x7fffffff),
7256                                           unop(Iop_64to32, mkexpr(t0))));
7257                     putDSPControl(IRExpr_ITE(mkexpr(t1),
7258                                              binop(Iop_Or32,
7259                                                    getDSPControl(),
7260                                                    mkU32(0x400000)),
7261                                              getDSPControl()));
7262                     assign(t3, binop(Iop_Add64,
7263                                      binop(Iop_32HLto64,
7264                                            binop(Iop_Shr32,
7265                                                  binop(Iop_And32,
7266                                                        getIReg(rt),
7267                                                        mkU32(0x80000000)),
7268                                                  mkU8(31)),
7269                                            getIReg(rt)),
7270                                      mkU64(0x0000000000008000ULL)));
7271                     assign(t4, binop(Iop_CmpNE32,
7272                                      binop(Iop_And32,
7273                                            unop(Iop_64HIto32, mkexpr(t3)),
7274                                            mkU32(0x1)),
7275                                      binop(Iop_And32,
7276                                            binop(Iop_Shr32,
7277                                                  unop(Iop_64to32, mkexpr(t3)),
7278                                                  mkU8(31)),
7279                                            mkU32(0x1))));
7280                     assign(t5, IRExpr_ITE(mkexpr(t4),
7281                                           mkU32(0x7fffffff),
7282                                           unop(Iop_64to32, mkexpr(t3))));
7283                     putDSPControl(IRExpr_ITE(mkexpr(t4),
7284                                              binop(Iop_Or32,
7285                                                    getDSPControl(),
7286                                                    mkU32(0x400000)),
7287                                              getDSPControl()));
7288                     putIReg(rd, binop(Iop_16HLto32,
7289                                       unop(Iop_32HIto16, mkexpr(t2)),
7290                                       unop(Iop_32HIto16, mkexpr(t5))));
7291                     break;
7292                  }
7293                  case 0x1E: {  /* PRECR_SRA.PH.W */
7294                     DIP("precr_sra.ph.w r%d, r%d, %d", rt, rs, rd);
7295                     vassert(!mode64);
7296
7297                     if (0 == rd) {
7298                        putIReg(rt, binop(Iop_16HLto32,
7299                                          unop(Iop_32to16, getIReg(rt)),
7300                                          unop(Iop_32to16, getIReg(rs))));
7301                     } else {
7302                        putIReg(rt, binop(Iop_16HLto32,
7303                                          unop(Iop_32to16, binop(Iop_Sar32,
7304                                                                 getIReg(rt),
7305                                                                 mkU8(rd))),
7306                                          unop(Iop_32to16, binop(Iop_Sar32,
7307                                                                 getIReg(rs),
7308                                                                 mkU8(rd)))));
7309                     }
7310                     break;
7311                  }
7312                  case 0x1F: {  /* PRECR_SRA_R.PH.W */
7313                     DIP("precr_sra_r.ph.w r%d, r%d, %d", rt, rs, rd);
7314                     vassert(!mode64);
7315
7316                     t0 = newTemp(Ity_I32);
7317                     t1 = newTemp(Ity_I32);
7318
7319                     if (0 == rd) {
7320                        putIReg(rt, binop(Iop_16HLto32,
7321                                          unop(Iop_32to16, getIReg(rt)),
7322                                          unop(Iop_32to16, getIReg(rs))));
7323                     } else {
7324                        assign(t0, binop(Iop_Shr32,
7325                                         binop(Iop_Add32,
7326                                               binop(Iop_Sar32,
7327                                                     getIReg(rt),
7328                                                     mkU8(rd-1)),
7329                                               mkU32(0x1)),
7330                                         mkU8(0x1)));
7331                        assign(t1, binop(Iop_Shr32,
7332                                         binop(Iop_Add32,
7333                                               binop(Iop_Sar32,
7334                                                     getIReg(rs),
7335                                                     mkU8(rd-1)),
7336                                               mkU32(0x1)),
7337                                         mkU8(0x1)));
7338                        putIReg(rt, binop(Iop_16HLto32,
7339                                          unop(Iop_32to16, mkexpr(t0)),
7340                                          unop(Iop_32to16, mkexpr(t1))));
7341                     };
7342                     break;
7343                  }
7344                  case 0xE: {  /* PACKRL.PH */
7345                     DIP("packrl.ph r%d, r%d, r%d", rd, rs, rt);
7346                     vassert(!mode64);
7347
7348                     putIReg(rd, binop(Iop_16HLto32,
7349                                       unop(Iop_32to16, getIReg(rs)),
7350                                       unop(Iop_32HIto16, getIReg(rt))));
7351                     break;
7352                  }
7353                  case 0x18: {  /* CMPGDU.EQ.QB */
7354                     DIP("cmpgdu.eq.qb r%d, r%d, r%d", rd, rs, rt);
7355                     vassert(!mode64);
7356                     t1 = newTemp(Ity_I1);
7357                     t2 = newTemp(Ity_I1);
7358                     t3 = newTemp(Ity_I1);
7359                     t4 = newTemp(Ity_I1);
7360                     t5 = newTemp(Ity_I32);
7361                     t6 = newTemp(Ity_I32);
7362                     t7 = newTemp(Ity_I32);
7363                     t8 = newTemp(Ity_I32);
7364
7365                     assign(t1,
7366                            binop(Iop_CmpEQ32,
7367                                  unop(Iop_8Uto32,
7368                                       unop(Iop_16to8,
7369                                            unop(Iop_32to16, getIReg(rs)))),
7370                                  unop(Iop_8Uto32,
7371                                       unop(Iop_16to8,
7372                                            unop(Iop_32to16, getIReg(rt))))));
7373                     assign(t5, IRExpr_ITE(mkexpr(t1),
7374                                           mkU32(0x00000001), mkU32(0)));
7375                     putDSPControl(IRExpr_ITE(mkexpr(t1),
7376                                              binop(Iop_Or32,
7377                                                    getDSPControl(),
7378                                                    mkU32(0x01000000)),
7379                                              binop(Iop_And32,
7380                                                    getDSPControl(),
7381                                                    mkU32(0xfeffffff))));
7382
7383                     assign(t2, binop(Iop_CmpEQ32,
7384                                      unop(Iop_8Uto32,
7385                                           unop(Iop_16HIto8,
7386                                                unop(Iop_32to16, getIReg(rs)))),
7387                                      unop(Iop_8Uto32,
7388                                           unop(Iop_16HIto8,
7389                                                unop(Iop_32to16,
7390                                                     getIReg(rt))))));
7391                     assign(t6, IRExpr_ITE(mkexpr(t2),
7392                                           mkU32(0x00000002), mkU32(0)));
7393                     putDSPControl(IRExpr_ITE(mkexpr(t2),
7394                                              binop(Iop_Or32,
7395                                                    getDSPControl(),
7396                                                    mkU32(0x02000000)),
7397                                              binop(Iop_And32,
7398                                                    getDSPControl(),
7399                                                    mkU32(0xfdffffff))));
7400
7401                     assign(t3, binop(Iop_CmpEQ32,
7402                                      unop(Iop_8Uto32,
7403                                           unop(Iop_16to8,
7404                                                unop(Iop_32HIto16,
7405                                                     getIReg(rs)))),
7406                                      unop(Iop_8Uto32,
7407                                           unop(Iop_16to8,
7408                                                unop(Iop_32HIto16,
7409                                                     getIReg(rt))))));
7410                     assign(t7, IRExpr_ITE(mkexpr(t3),
7411                                           mkU32(0x00000004), mkU32(0)));
7412                     putDSPControl(IRExpr_ITE(mkexpr(t3),
7413                                              binop(Iop_Or32,
7414                                                    getDSPControl(),
7415                                                    mkU32(0x04000000)),
7416                                              binop(Iop_And32,
7417                                                    getDSPControl(),
7418                                                    mkU32(0xfbffffff))));
7419
7420                     assign(t4, binop(Iop_CmpEQ32,
7421                                      unop(Iop_8Uto32,
7422                                           unop(Iop_16HIto8,
7423                                                unop(Iop_32HIto16,
7424                                                     getIReg(rs)))),
7425                                      unop(Iop_8Uto32,
7426                                           unop(Iop_16HIto8,
7427                                                unop(Iop_32HIto16,
7428                                                     getIReg(rt))))));
7429                     assign(t8, IRExpr_ITE(mkexpr(t4),
7430                                           mkU32(0x00000008), mkU32(0)));
7431                     putDSPControl(IRExpr_ITE(mkexpr(t4),
7432                                              binop(Iop_Or32,
7433                                                    getDSPControl(),
7434                                                    mkU32(0x08000000)),
7435                                              binop(Iop_And32,
7436                                                    getDSPControl(),
7437                                                    mkU32(0xf7ffffff))));
7438
7439                     putIReg(rd, binop(Iop_Or32,
7440                                       binop(Iop_Or32,
7441                                             binop(Iop_Or32,
7442                                                   mkexpr(t5), mkexpr(t6)),
7443                                             mkexpr(t7)),
7444                                       mkexpr(t8)));
7445                     break;
7446                  }
7447                  case 0x19: {  /* CMPGDU.LT.QB */
7448                     DIP("cmpgdu.lt.qb r%d, r%d, r%d", rd, rs, rt);
7449                     vassert(!mode64);
7450                     t1 = newTemp(Ity_I1);
7451                     t2 = newTemp(Ity_I1);
7452                     t3 = newTemp(Ity_I1);
7453                     t4 = newTemp(Ity_I1);
7454                     t5 = newTemp(Ity_I32);
7455                     t6 = newTemp(Ity_I32);
7456                     t7 = newTemp(Ity_I32);
7457                     t8 = newTemp(Ity_I32);
7458
7459                     assign(t1, binop(Iop_CmpLT32U,
7460                                      unop(Iop_8Uto32,
7461                                           unop(Iop_16to8,
7462                                                unop(Iop_32to16, getIReg(rs)))),
7463                                      unop(Iop_8Uto32,
7464                                           unop(Iop_16to8,
7465                                                unop(Iop_32to16,
7466                                                     getIReg(rt))))));
7467                     assign(t5, IRExpr_ITE(mkexpr(t1),
7468                                           mkU32(0x00000001), mkU32(0)));
7469                     putDSPControl(IRExpr_ITE(mkexpr(t1),
7470                                              binop(Iop_Or32,
7471                                                    getDSPControl(),
7472                                                    mkU32(0x01000000)),
7473                                              binop(Iop_And32,
7474                                                    getDSPControl(),
7475                                                    mkU32(0xfeffffff))));
7476
7477                     assign(t2, binop(Iop_CmpLT32U,
7478                                      unop(Iop_8Uto32,
7479                                           unop(Iop_16HIto8,
7480                                                unop(Iop_32to16, getIReg(rs)))),
7481                                      unop(Iop_8Uto32,
7482                                           unop(Iop_16HIto8,
7483                                                unop(Iop_32to16,
7484                                                     getIReg(rt))))));
7485                     assign(t6, IRExpr_ITE(mkexpr(t2),
7486                                           mkU32(0x00000002), mkU32(0)));
7487                     putDSPControl(IRExpr_ITE(mkexpr(t2),
7488                                              binop(Iop_Or32,
7489                                                    getDSPControl(),
7490                                                    mkU32(0x02000000)),
7491                                              binop(Iop_And32,
7492                                                    getDSPControl(),
7493                                                    mkU32(0xfdffffff))));
7494
7495                     assign(t3, binop(Iop_CmpLT32U,
7496                                      unop(Iop_8Uto32,
7497                                           unop(Iop_16to8,
7498                                                unop(Iop_32HIto16,
7499                                                     getIReg(rs)))),
7500                                      unop(Iop_8Uto32,
7501                                           unop(Iop_16to8,
7502                                                unop(Iop_32HIto16,
7503                                                     getIReg(rt))))));
7504                     assign(t7, IRExpr_ITE(mkexpr(t3),
7505                                           mkU32(0x00000004), mkU32(0)));
7506                     putDSPControl(IRExpr_ITE(mkexpr(t3),
7507                                              binop(Iop_Or32,
7508                                                    getDSPControl(),
7509                                                    mkU32(0x04000000)),
7510                                              binop(Iop_And32,
7511                                                    getDSPControl(),
7512                                                    mkU32(0xfbffffff))));
7513
7514                     assign(t4, binop(Iop_CmpLT32U,
7515                                      unop(Iop_8Uto32,
7516                                           unop(Iop_16HIto8,
7517                                                unop(Iop_32HIto16,
7518                                                     getIReg(rs)))),
7519                                      unop(Iop_8Uto32,
7520                                           unop(Iop_16HIto8,
7521                                                unop(Iop_32HIto16,
7522                                                     getIReg(rt))))));
7523                     assign(t8, IRExpr_ITE(mkexpr(t4),
7524                                           mkU32(0x00000008), mkU32(0)));
7525                     putDSPControl(IRExpr_ITE(mkexpr(t4),
7526                                              binop(Iop_Or32,
7527                                                    getDSPControl(),
7528                                                    mkU32(0x08000000)),
7529                                              binop(Iop_And32,
7530                                                    getDSPControl(),
7531                                                    mkU32(0xf7ffffff))));
7532
7533                     putIReg(rd, binop(Iop_Or32,
7534                                       binop(Iop_Or32,
7535                                             binop(Iop_Or32,
7536                                                   mkexpr(t5), mkexpr(t6)),
7537                                             mkexpr(t7)),
7538                                       mkexpr(t8)));
7539                     break;
7540                  }
7541                  case 0x1A: {  /* CMPGDU.LE.QB */
7542                     DIP("cmpgdu.le.qb r%d, r%d, r%d", rd, rs, rt);
7543                     vassert(!mode64);
7544                     t1 = newTemp(Ity_I1);
7545                     t2 = newTemp(Ity_I1);
7546                     t3 = newTemp(Ity_I1);
7547                     t4 = newTemp(Ity_I1);
7548                     t5 = newTemp(Ity_I32);
7549                     t6 = newTemp(Ity_I32);
7550                     t7 = newTemp(Ity_I32);
7551                     t8 = newTemp(Ity_I32);
7552
7553                     assign(t1, binop(Iop_CmpLE32U,
7554                                      unop(Iop_8Uto32,
7555                                           unop(Iop_16to8,
7556                                                unop(Iop_32to16, getIReg(rs)))),
7557                                      unop(Iop_8Uto32,
7558                                           unop(Iop_16to8,
7559                                                unop(Iop_32to16,
7560                                                     getIReg(rt))))));
7561                     assign(t5, IRExpr_ITE(mkexpr(t1),
7562                                           mkU32(0x00000001),
7563                                           mkU32(0)));
7564                     putDSPControl(IRExpr_ITE(mkexpr(t1),
7565                                              binop(Iop_Or32,
7566                                                    getDSPControl(),
7567                                                    mkU32(0x01000000)),
7568                                              binop(Iop_And32,
7569                                                    getDSPControl(),
7570                                                    mkU32(0xfeffffff))));
7571
7572                     assign(t2, binop(Iop_CmpLE32U,
7573                                      unop(Iop_8Uto32,
7574                                           unop(Iop_16HIto8,
7575                                                unop(Iop_32to16, getIReg(rs)))),
7576                                      unop(Iop_8Uto32,
7577                                           unop(Iop_16HIto8,
7578                                                unop(Iop_32to16,
7579                                                     getIReg(rt))))));
7580                     assign(t6, IRExpr_ITE(mkexpr(t2),
7581                                           mkU32(0x00000002), mkU32(0)));
7582                     putDSPControl(IRExpr_ITE(mkexpr(t2),
7583                                              binop(Iop_Or32,
7584                                                    getDSPControl(),
7585                                                    mkU32(0x02000000)),
7586                                              binop(Iop_And32,
7587                                                    getDSPControl(),
7588                                                    mkU32(0xfdffffff))));
7589
7590                     assign(t3, binop(Iop_CmpLE32U,
7591                                      unop(Iop_8Uto32,
7592                                           unop(Iop_16to8,
7593                                                unop(Iop_32HIto16,
7594                                                     getIReg(rs)))),
7595                                      unop(Iop_8Uto32,
7596                                           unop(Iop_16to8,
7597                                                unop(Iop_32HIto16,
7598                                                     getIReg(rt))))));
7599                     assign(t7, IRExpr_ITE(mkexpr(t3),
7600                                           mkU32(0x00000004), mkU32(0)));
7601                     putDSPControl(IRExpr_ITE(mkexpr(t3),
7602                                              binop(Iop_Or32,
7603                                                    getDSPControl(),
7604                                                    mkU32(0x04000000)),
7605                                              binop(Iop_And32,
7606                                                    getDSPControl(),
7607                                                    mkU32(0xfbffffff))));
7608
7609                     assign(t4, binop(Iop_CmpLE32U,
7610                                      unop(Iop_8Uto32,
7611                                           unop(Iop_16HIto8,
7612                                                unop(Iop_32HIto16,
7613                                                     getIReg(rs)))),
7614                                      unop(Iop_8Uto32,
7615                                           unop(Iop_16HIto8,
7616                                                unop(Iop_32HIto16,
7617                                                     getIReg(rt))))));
7618                     assign(t8, IRExpr_ITE(mkexpr(t4),
7619                                           mkU32(0x00000008), mkU32(0)));
7620                     putDSPControl(IRExpr_ITE(mkexpr(t4),
7621                                              binop(Iop_Or32,
7622                                                    getDSPControl(),
7623                                                    mkU32(0x08000000)),
7624                                              binop(Iop_And32,
7625                                                    getDSPControl(),
7626                                                    mkU32(0xf7ffffff))));
7627
7628                     putIReg(rd, binop(Iop_Or32,
7629                                       binop(Iop_Or32,
7630                                             binop(Iop_Or32,
7631                                                   mkexpr(t5), mkexpr(t6)),
7632                                             mkexpr(t7)),
7633                                       mkexpr(t8)));
7634                     break;
7635                  }
7636                  default:
7637                     return -1;
7638               }
7639               break;  /* end of CMPU.EQ.QB */
7640            }
7641            case 0x13: {  /* SHLL.QB */
7642               switch(sa) {
7643                  case 0x0: {  /* SHLL.QB */
7644                     DIP("shll.qb r%d, r%d, %d", rd, rt, rs);
7645                     vassert(!mode64);
7646                     t0 = newTemp(Ity_I32);
7647                     t1 = newTemp(Ity_I1);
7648                     t2 = newTemp(Ity_I1);
7649                     t3 = newTemp(Ity_I32);
7650                     t4 = newTemp(Ity_I1);
7651                     t5 = newTemp(Ity_I1);
7652                     t6 = newTemp(Ity_I32);
7653                     t7 = newTemp(Ity_I1);
7654                     t8 = newTemp(Ity_I1);
7655                     t9 = newTemp(Ity_I1);
7656                     t10 = newTemp(Ity_I1);
7657
7658                     if (0 == rs) {
7659                        putIReg(rd, getIReg(rt));
7660                     } else {
7661                        /* Shift bits 7..0 and 23..16. */
7662                        assign(t0, binop(Iop_Shl32,
7663                                         binop(Iop_And32,
7664                                               getIReg(rt),
7665                                               mkU32(0x00ff00ff)),
7666                                         mkU8(rs)));
7667                        assign(t1, binop(Iop_CmpNE32,
7668                                        binop(Iop_And32,
7669                                              mkexpr(t0),
7670                                              mkU32(0xff000000)),
7671                                        mkU32(0x00000000)));
7672                        assign(t2, binop(Iop_CmpNE32,
7673                                        binop(Iop_And32,
7674                                              mkexpr(t0),
7675                                              mkU32(0xff000000)),
7676                                        mkU32(0xff000000)));
7677                        assign(t7, binop(Iop_CmpNE32,
7678                                        binop(Iop_And32,
7679                                              mkexpr(t0),
7680                                              mkU32(0x0000ff00)),
7681                                        mkU32(0x00000000)));
7682                        assign(t8, binop(Iop_CmpNE32,
7683                                        binop(Iop_And32,
7684                                              mkexpr(t0),
7685                                              mkU32(0x0000ff00)),
7686                                        mkU32(0x000ff00)));
7687                        /* Shift bits 15..8 and 31..24. */
7688                        assign(t3, binop(Iop_Shl32,
7689                                         binop(Iop_Shr32,
7690                                               binop(Iop_And32,
7691                                                     getIReg(rt),
7692                                                     mkU32(0xff00ff00)),
7693                                               mkU8(8)),
7694                                         mkU8(rs)));
7695                        assign(t4, binop(Iop_CmpNE32,
7696                                        binop(Iop_And32,
7697                                              mkexpr(t3),
7698                                              mkU32(0xff000000)),
7699                                        mkU32(0x00000000)));
7700                        assign(t5, binop(Iop_CmpNE32,
7701                                        binop(Iop_And32,
7702                                              mkexpr(t3),
7703                                              mkU32(0xff000000)),
7704                                        mkU32(0xff000000)));
7705                        assign(t9, binop(Iop_CmpNE32,
7706                                        binop(Iop_And32,
7707                                              mkexpr(t3),
7708                                              mkU32(0x0000ff00)),
7709                                        mkU32(0x00000000)));
7710                        assign(t10, binop(Iop_CmpNE32,
7711                                        binop(Iop_And32,
7712                                              mkexpr(t3),
7713                                              mkU32(0x0000ff00)),
7714                                        mkU32(0x0000ff00)));
7715
7716                        assign(t6, binop(Iop_Or32,
7717                                         binop(Iop_Or32,
7718                                               binop(Iop_And32,
7719                                                     unop(Iop_1Uto32,
7720                                                          mkexpr(t1)),
7721                                                     unop(Iop_1Uto32,
7722                                                          mkexpr(t2))),
7723                                               binop(Iop_And32,
7724                                                     unop(Iop_1Uto32,
7725                                                          mkexpr(t7)),
7726                                                     unop(Iop_1Uto32,
7727                                                          mkexpr(t8)))),
7728                                         binop(Iop_Or32,
7729                                               binop(Iop_And32,
7730                                                     unop(Iop_1Uto32,
7731                                                          mkexpr(t4)),
7732                                                     unop(Iop_1Uto32,
7733                                                          mkexpr(t5))),
7734                                               binop(Iop_And32,
7735                                                     unop(Iop_1Uto32,
7736                                                          mkexpr(t9)),
7737                                                     unop(Iop_1Uto32,
7738                                                          mkexpr(t10))))));
7739
7740                        putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32,
7741                                                       mkexpr(t6),
7742                                                       mkU32(0x0)),
7743                                                 binop(Iop_Or32,
7744                                                       getDSPControl(),
7745                                                       mkU32(0x400000)),
7746                                                 getDSPControl()));
7747                        putIReg(rd, binop(Iop_Or32,
7748                                          binop(Iop_Shl32,
7749                                                binop(Iop_And32,
7750                                                      mkexpr(t3),
7751                                                      mkU32(0x00ff00ff)),
7752                                                mkU8(8)),
7753                                          binop(Iop_And32,
7754                                                mkexpr(t0),
7755                                                mkU32(0x00ff00ff))));
7756                     }
7757                     break;
7758                  }
7759                  case 0x3: {  /* SHRL.QB */
7760                     DIP("shrl.qb r%d, r%d, %d", rd, rt, rs);
7761                     vassert(!mode64);
7762                     t0 = newTemp(Ity_I32);
7763                     t1 = newTemp(Ity_I8);
7764                     t2 = newTemp(Ity_I32);
7765                     t3 = newTemp(Ity_I8);
7766                     t4 = newTemp(Ity_I32);
7767                     t5 = newTemp(Ity_I8);
7768                     t6 = newTemp(Ity_I32);
7769                     t7 = newTemp(Ity_I8);
7770                     t9 = newTemp(Ity_I32);
7771
7772                     assign(t9, binop(Iop_And32, getIReg(rs), mkU32(0x7)));
7773                     assign(t0, unop(Iop_8Uto32,
7774                                     unop(Iop_16to8,
7775                                          unop(Iop_32to16, getIReg(rt)))));
7776                     assign(t1, unop(Iop_32to8,
7777                                     binop(Iop_Shr32,
7778                                           mkexpr(t0),
7779                                           unop(Iop_32to8, mkexpr(t9)))));
7780
7781                     assign(t2, unop(Iop_8Uto32,
7782                                     unop(Iop_16HIto8,
7783                                          unop(Iop_32to16, getIReg(rt)))));
7784                     assign(t3, unop(Iop_32to8,
7785                                     binop(Iop_Shr32,
7786                                           mkexpr(t2),
7787                                           unop(Iop_32to8, mkexpr(t9)))));
7788
7789                     assign(t4, unop(Iop_8Uto32,
7790                                     unop(Iop_16to8,
7791                                          unop(Iop_32HIto16, getIReg(rt)))));
7792                     assign(t5, unop(Iop_32to8,
7793                                     binop(Iop_Shr32,
7794                                           mkexpr(t4),
7795                                           unop(Iop_32to8, mkexpr(t9)))));
7796
7797                     assign(t6, unop(Iop_8Uto32,
7798                                     unop(Iop_16HIto8,
7799                                          unop(Iop_32HIto16, getIReg(rt)))));
7800                     assign(t7, unop(Iop_32to8,
7801                                     binop(Iop_Shr32,
7802                                           mkexpr(t6),
7803                                           unop(Iop_32to8, mkexpr(t9)))));
7804                     putIReg(rd, IRExpr_ITE(binop(Iop_CmpEQ32,
7805                                                  mkexpr(t9),
7806                                                  mkU32(0x0)),
7807                                            getIReg(rt),
7808                                            binop(Iop_16HLto32,
7809                                                  binop(Iop_8HLto16,
7810                                                        mkexpr(t7),
7811                                                        mkexpr(t5)),
7812                                                  binop(Iop_8HLto16,
7813                                                        mkexpr(t3),
7814                                                        mkexpr(t1)))));
7815                     break;
7816                  }
7817                  case 0x2: {  /* SHLLV.QB */
7818                     DIP("shllv.qb r%d, r%d, r%d", rd, rt, rs);
7819                     vassert(!mode64);
7820                     t0 = newTemp(Ity_I32);
7821                     t1 = newTemp(Ity_I1);
7822                     t2 = newTemp(Ity_I1);
7823                     t3 = newTemp(Ity_I32);
7824                     t4 = newTemp(Ity_I1);
7825                     t5 = newTemp(Ity_I1);
7826                     t6 = newTemp(Ity_I32);
7827                     t7 = newTemp(Ity_I1);
7828                     t8 = newTemp(Ity_I1);
7829                     t9 = newTemp(Ity_I1);
7830                     t10 = newTemp(Ity_I1);
7831                     t11 = newTemp(Ity_I8);
7832
7833                     assign(t11, unop(Iop_32to8,
7834                                      binop(Iop_And32,
7835                                            getIReg(rs),
7836                                            mkU32(0x7))));
7837                     /* Shift bits 7..0 and 23..16. */
7838                     assign(t0, binop(Iop_Shl32,
7839                                      binop(Iop_And32,
7840                                            getIReg(rt),
7841                                            mkU32(0x00ff00ff)),
7842                                      mkexpr(t11)));
7843                     assign(t1, binop(Iop_CmpNE32,
7844                                     binop(Iop_And32,
7845                                           mkexpr(t0),
7846                                           mkU32(0xff000000)),
7847                                     mkU32(0x00000000)));
7848                     assign(t2, binop(Iop_CmpNE32,
7849                                     binop(Iop_And32,
7850                                           mkexpr(t0),
7851                                           mkU32(0xff000000)),
7852                                     mkU32(0xff000000)));
7853                     assign(t7, binop(Iop_CmpNE32,
7854                                     binop(Iop_And32,
7855                                           mkexpr(t0),
7856                                           mkU32(0x0000ff00)),
7857                                     mkU32(0x00000000)));
7858                     assign(t8, binop(Iop_CmpNE32,
7859                                     binop(Iop_And32,
7860                                           mkexpr(t0),
7861                                           mkU32(0x0000ff00)),
7862                                     mkU32(0x000ff00)));
7863                     /* Shift bits 15..8 and 31..24. */
7864                     assign(t3, binop(Iop_Shl32,
7865                                      binop(Iop_Shr32,
7866                                            binop(Iop_And32,
7867                                                  getIReg(rt),
7868                                                  mkU32(0xff00ff00)),
7869                                            mkU8(8)),
7870                                      mkexpr(t11)));
7871                     assign(t4, binop(Iop_CmpNE32,
7872                                     binop(Iop_And32,
7873                                           mkexpr(t3),
7874                                           mkU32(0xff000000)),
7875                                     mkU32(0x00000000)));
7876                     assign(t5, binop(Iop_CmpNE32,
7877                                     binop(Iop_And32,
7878                                           mkexpr(t3),
7879                                           mkU32(0xff000000)),
7880                                     mkU32(0xff000000)));
7881                     assign(t9, binop(Iop_CmpNE32,
7882                                     binop(Iop_And32,
7883                                           mkexpr(t3),
7884                                           mkU32(0x0000ff00)),
7885                                     mkU32(0x00000000)));
7886                     assign(t10, binop(Iop_CmpNE32,
7887                                     binop(Iop_And32,
7888                                           mkexpr(t3),
7889                                           mkU32(0x0000ff00)),
7890                                     mkU32(0x0000ff00)));
7891
7892                     assign(t6, binop(Iop_Or32,
7893                                      binop(Iop_Or32,
7894                                            binop(Iop_And32,
7895                                                  unop(Iop_1Uto32,
7896                                                       mkexpr(t1)),
7897                                                  unop(Iop_1Uto32,
7898                                                       mkexpr(t2))),
7899                                            binop(Iop_And32,
7900                                                  unop(Iop_1Uto32,
7901                                                       mkexpr(t7)),
7902                                                  unop(Iop_1Uto32,
7903                                                       mkexpr(t8)))),
7904                                      binop(Iop_Or32,
7905                                            binop(Iop_And32,
7906                                                  unop(Iop_1Uto32,
7907                                                       mkexpr(t4)),
7908                                                  unop(Iop_1Uto32,
7909                                                       mkexpr(t5))),
7910                                            binop(Iop_And32,
7911                                                  unop(Iop_1Uto32,
7912                                                       mkexpr(t9)),
7913                                                  unop(Iop_1Uto32,
7914                                                       mkexpr(t10))))));
7915
7916                     putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32,
7917                                                    mkexpr(t6),
7918                                                    mkU32(0x0)),
7919                                              binop(Iop_Or32,
7920                                                    getDSPControl(),
7921                                                    mkU32(0x400000)),
7922                                              getDSPControl()));
7923                     putIReg(rd, IRExpr_ITE(binop(Iop_CmpEQ32,
7924                                                  unop(Iop_8Uto32, mkexpr(t11)),
7925                                                  mkU32(0)),
7926                                            getIReg(rt),
7927                                            binop(Iop_Or32,
7928                                                  binop(Iop_Shl32,
7929                                                        binop(Iop_And32,
7930                                                              mkexpr(t3),
7931                                                              mkU32(0xff00ff)),
7932                                                        mkU8(8)),
7933                                                  binop(Iop_And32,
7934                                                        mkexpr(t0),
7935                                                        mkU32(0x00ff00ff)))));
7936                     break;
7937                  }
7938                  case 0x1: {  /* SHRLV.QB */
7939                     DIP("shrlv.qb r%d, r%d, r%d", rd, rt, rs);
7940                     vassert(!mode64);
7941                     t0 = newTemp(Ity_I8);
7942                     t1 = newTemp(Ity_I8);
7943                     t2 = newTemp(Ity_I8);
7944                     t3 = newTemp(Ity_I8);
7945
7946                     assign(t0, unop(Iop_32to8,
7947                                     binop(Iop_Shr32,
7948                                           unop(Iop_8Uto32,
7949                                                unop(Iop_32to8, getIReg(rt))),
7950                                           mkU8(rs))));
7951                     assign(t1, unop(Iop_32to8,
7952                                     binop(Iop_Shr32,
7953                                           unop(Iop_8Uto32,
7954                                                unop(Iop_16HIto8,
7955                                                     unop(Iop_32to16,
7956                                                          getIReg(rt)))),
7957                                           mkU8(rs))));
7958                     assign(t2, unop(Iop_32to8,
7959                                      binop(Iop_Shr32,
7960                                            unop(Iop_8Uto32,
7961                                                 unop(Iop_16to8,
7962                                                      unop(Iop_32HIto16,
7963                                                           getIReg(rt)))),
7964                                            mkU8(rs))));
7965                     assign(t3, unop(Iop_32to8,
7966                                     binop(Iop_Shr32,
7967                                           unop(Iop_8Uto32,
7968                                                unop(Iop_16HIto8,
7969                                                     unop(Iop_32HIto16,
7970                                                          getIReg(rt)))),
7971                                           mkU8(rs))));
7972                     putIReg(rd,
7973                             binop(Iop_16HLto32,
7974                                   binop(Iop_8HLto16, mkexpr(t3), mkexpr(t2)),
7975                                   binop(Iop_8HLto16, mkexpr(t1), mkexpr(t0))));
7976                     break;
7977                  }
7978                  case 0x4: {  /* SHRA.QB */
7979                     DIP("shra.qb r%d, r%d, %d", rd, rt, rs);
7980                     vassert(!mode64);
7981                     t0 = newTemp(Ity_I32);
7982                     t1 = newTemp(Ity_I32);
7983                     t2 = newTemp(Ity_I32);
7984                     t3 = newTemp(Ity_I32);
7985                     t4 = newTemp(Ity_I32);
7986                     t5 = newTemp(Ity_I32);
7987                     t6 = newTemp(Ity_I32);
7988                     t7 = newTemp(Ity_I32);
7989                     t8 = newTemp(Ity_I32);
7990                     t9 = newTemp(Ity_I32);
7991                     t10 = newTemp(Ity_I32);
7992                     t11 = newTemp(Ity_I32);
7993
7994                     /* ========== GPR[rt]_31..24 ========== */
7995                     assign(t1,
7996                            unop(Iop_8Uto32,
7997                                 unop(Iop_16HIto8,
7998                                      unop(Iop_32HIto16, getIReg(rt)))));
7999                     assign(t2,
8000                            binop(Iop_Shr32, mkexpr(t1), mkU8(rs)));
8001                     /* tempD_7..0 */
8002                     assign(t0,
8003                            binop(Iop_Or32,
8004                                  mkexpr(t2),
8005                                  binop(Iop_Shl32,
8006                                        IRExpr_ITE(binop(Iop_CmpEQ32,
8007                                                         binop(Iop_And32,
8008                                                               mkexpr(t1),
8009                                                               mkU32(0x00000080)
8010                                                              ),
8011                                                         mkU32(0x00000080)),
8012                                                   mkU32(0xFFFFFFFF),
8013                                                   mkU32(0x00000000)),
8014                                        binop(Iop_Sub8, mkU8(0x8), mkU8(rs)))));
8015
8016                     /* ========== GPR[rt]_23..16 ========== */
8017                     assign(t4,
8018                            unop(Iop_8Uto32,
8019                                 unop(Iop_16to8,
8020                                      unop(Iop_32HIto16, getIReg(rt)))));
8021                     assign(t5, binop(Iop_Shr32, mkexpr(t4), mkU8(rs)));
8022                     /* tempC_7..0 */
8023                     assign(t3,
8024                            binop(Iop_Or32,
8025                                  mkexpr(t5),
8026                                  binop(Iop_Shl32,
8027                                        IRExpr_ITE(binop(Iop_CmpEQ32,
8028                                                         binop(Iop_And32,
8029                                                               mkexpr(t4),
8030                                                               mkU32(0x00000080)
8031                                                              ),
8032                                                         mkU32(0x00000080)),
8033                                                   mkU32(0xFFFFFFFF),
8034                                                   mkU32(0x00000000)),
8035                                        binop(Iop_Sub8, mkU8(0x8), mkU8(rs)))));
8036
8037                     /* ========== GPR[rt]_15..8 ========== */
8038                     assign(t7,
8039                            unop(Iop_8Uto32,
8040                                 unop(Iop_16HIto8,
8041                                      unop(Iop_32to16, getIReg(rt)))));
8042                     assign(t8, binop(Iop_Shr32, mkexpr(t7), mkU8(rs)));
8043                     /* tempB_7..0 */
8044                     assign(t6,
8045                            binop(Iop_Or32,
8046                                  mkexpr(t8),
8047                                  binop(Iop_Shl32,
8048                                        IRExpr_ITE(binop(Iop_CmpEQ32,
8049                                                         binop(Iop_And32,
8050                                                               mkexpr(t7),
8051                                                               mkU32(0x00000080)
8052                                                              ),
8053                                                         mkU32(0x00000080)),
8054                                                   mkU32(0xFFFFFFFF),
8055                                                   mkU32(0x00000000)),
8056                                        binop(Iop_Sub8, mkU8(0x8), mkU8(rs)))));
8057
8058                     /* ========== GPR[rt]_7..0 ========== */
8059                     assign(t10,
8060                            unop(Iop_8Uto32,
8061                                 unop(Iop_16to8,
8062                                      unop(Iop_32to16, getIReg(rt)))));
8063                     assign(t11, binop(Iop_Shr32, mkexpr(t10), mkU8(rs)));
8064                     /* tempB_7..0 */
8065                     assign(t9,
8066                            binop(Iop_Or32,
8067                                  mkexpr(t11),
8068                                  binop(Iop_Shl32,
8069                                        IRExpr_ITE(binop(Iop_CmpEQ32,
8070                                                         binop(Iop_And32,
8071                                                               mkexpr(t10),
8072                                                               mkU32(0x00000080)
8073                                                              ),
8074                                                         mkU32(0x00000080)),
8075                                                   mkU32(0xFFFFFFFF),
8076                                                   mkU32(0x00000000)),
8077                                        binop(Iop_Sub8, mkU8(0x8), mkU8(rs)))));
8078
8079                     putIReg(rd,
8080                             binop(Iop_16HLto32,
8081                                   binop(Iop_8HLto16,
8082                                         unop(Iop_32to8, mkexpr(t0)),
8083                                         unop(Iop_32to8, mkexpr(t3))),
8084                                   binop(Iop_8HLto16,
8085                                         unop(Iop_32to8, mkexpr(t6)),
8086                                         unop(Iop_32to8, mkexpr(t9)))));
8087                     break;
8088                  }
8089                  case 0x5: {  /* SHRA_R.QB */
8090                     DIP("shra_r.qb r%d, r%d, %d", rd, rt, rs);
8091                     vassert(!mode64);
8092                     t0 = newTemp(Ity_I32);
8093                     t1 = newTemp(Ity_I8);
8094                     t2 = newTemp(Ity_I32);
8095                     t3 = newTemp(Ity_I8);
8096                     t4 = newTemp(Ity_I32);
8097                     t5 = newTemp(Ity_I8);
8098                     t6 = newTemp(Ity_I32);
8099                     t7 = newTemp(Ity_I8);
8100
8101                     if (0 == rs) {
8102                        putIReg(rd, getIReg(rt));
8103                     } else {
8104                        assign(t0, unop(Iop_8Sto32,
8105                                        unop(Iop_16to8,
8106                                             unop(Iop_32to16, getIReg(rt)))));
8107                        assign(t1, unop(Iop_32to8,
8108                                        binop(Iop_Sar32,
8109                                              binop(Iop_Add32,
8110                                                    mkexpr(t0),
8111                                                    binop(Iop_Shl32,
8112                                                          mkU32(0x1),
8113                                                          mkU8(rs-1))),
8114                                              mkU8(rs))));
8115
8116                        assign(t2, unop(Iop_8Sto32,
8117                                        unop(Iop_16HIto8,
8118                                             unop(Iop_32to16, getIReg(rt)))));
8119                        assign(t3, unop(Iop_32to8,
8120                                        binop(Iop_Sar32,
8121                                              binop(Iop_Add32,
8122                                                    mkexpr(t2),
8123                                                    binop(Iop_Shl32,
8124                                                          mkU32(0x1),
8125                                                          mkU8(rs-1))),
8126                                              mkU8(rs))));
8127
8128                        assign(t4, unop(Iop_8Sto32,
8129                                        unop(Iop_16to8,
8130                                             unop(Iop_32HIto16, getIReg(rt)))));
8131                        assign(t5, unop(Iop_32to8,
8132                                        binop(Iop_Sar32,
8133                                              binop(Iop_Add32,
8134                                                    mkexpr(t4),
8135                                                    binop(Iop_Shl32,
8136                                                          mkU32(0x1),
8137                                                          mkU8(rs-1))),
8138                                              mkU8(rs))));
8139
8140                        assign(t6, unop(Iop_8Sto32,
8141                                        unop(Iop_16HIto8,
8142                                             unop(Iop_32HIto16, getIReg(rt)))));
8143                        assign(t7, unop(Iop_32to8,
8144                                        binop(Iop_Sar32,
8145                                              binop(Iop_Add32,
8146                                                    mkexpr(t6),
8147                                                    binop(Iop_Shl32,
8148                                                          mkU32(0x1),
8149                                                          mkU8(rs-1))),
8150                                              mkU8(rs))));
8151                        putIReg(rd, binop(Iop_16HLto32,
8152                                         binop(Iop_8HLto16,
8153                                               mkexpr(t7), mkexpr(t5)),
8154                                         binop(Iop_8HLto16,
8155                                               mkexpr(t3), mkexpr(t1))));
8156                     }
8157                     break;
8158                  }
8159                  case 0x6: {  /* SHRAV.QB */
8160                     DIP("shrav.qb r%d, r%d, %d", rd, rt, rs);
8161                     vassert(!mode64);
8162
8163                     t0 = newTemp(Ity_I32);
8164                     t1 = newTemp(Ity_I32);
8165                     t2 = newTemp(Ity_I32);
8166
8167                     t3 = newTemp(Ity_I32);
8168                     t4 = newTemp(Ity_I32);
8169                     t5 = newTemp(Ity_I32);
8170
8171                     t6 = newTemp(Ity_I32);
8172                     t7 = newTemp(Ity_I32);
8173                     t8 = newTemp(Ity_I32);
8174
8175                     t9 = newTemp(Ity_I32);
8176                     t10 = newTemp(Ity_I32);
8177                     t11 = newTemp(Ity_I32);
8178
8179                     /* ========== GPR[rt]_31..24 ========== */
8180                     assign(t1,
8181                            unop(Iop_8Uto32,
8182                                 unop(Iop_16HIto8,
8183                                      unop(Iop_32HIto16, getIReg(rt)))));
8184                     assign(t2,
8185                            binop(Iop_Shr32,
8186                                  mkexpr(t1),
8187                                  unop(Iop_32to8, binop(Iop_And32,
8188                                                        getIReg(rs),
8189                                                        mkU32(0x7)))));
8190                     /* tempD_7..0 */
8191                     assign(t0,
8192                            binop(Iop_Or32,
8193                                  mkexpr(t2),
8194                                  binop(Iop_Shl32,
8195                                        IRExpr_ITE(binop(Iop_CmpEQ32,
8196                                                         binop(Iop_And32,
8197                                                               mkexpr(t1),
8198                                                               mkU32(0x00000080)
8199                                                              ),
8200                                                         mkU32(0x00000080)),
8201                                                   mkU32(0xFFFFFFFF),
8202                                                   mkU32(0x00000000)),
8203                                        binop(Iop_Sub8,
8204                                              mkU8(0x8),
8205                                              unop(Iop_32to8, binop(Iop_And32,
8206                                                                    getIReg(rs),
8207                                                                    mkU32(0x7)))
8208                                              ))));
8209
8210                     /* ========== GPR[rt]_23..16 ========== */
8211                     assign(t4,
8212                            unop(Iop_8Uto32,
8213                                 unop(Iop_16to8,
8214                                      unop(Iop_32HIto16, getIReg(rt)))));
8215                     assign(t5,
8216                            binop(Iop_Shr32,
8217                                  mkexpr(t4),
8218                                  unop(Iop_32to8, binop(Iop_And32,
8219                                                        getIReg(rs),
8220                                                        mkU32(0x7)))));
8221                     /* tempC_7..0 */
8222                     assign(t3,
8223                            binop(Iop_Or32,
8224                                  mkexpr(t5),
8225                                  binop(Iop_Shl32,
8226                                        IRExpr_ITE(binop(Iop_CmpEQ32,
8227                                                         binop(Iop_And32,
8228                                                               mkexpr(t4),
8229                                                               mkU32(0x00000080)
8230                                                              ),
8231                                                         mkU32(0x00000080)),
8232                                                   mkU32(0xFFFFFFFF),
8233                                                   mkU32(0x00000000)),
8234                                        binop(Iop_Sub8,
8235                                              mkU8(0x8),
8236                                              unop(Iop_32to8, binop(Iop_And32,
8237                                                                    getIReg(rs),
8238                                                                    mkU32(0x7)))
8239                                              ))));
8240
8241                     /* ========== GPR[rt]_15..8 ========== */
8242                     assign(t7,
8243                            unop(Iop_8Uto32,
8244                                 unop(Iop_16HIto8,
8245                                      unop(Iop_32to16, getIReg(rt)))));
8246                     assign(t8,
8247                            binop(Iop_Shr32,
8248                                  mkexpr(t7),
8249                                  unop(Iop_32to8, binop(Iop_And32,
8250                                                        getIReg(rs),
8251                                                        mkU32(0x7)))));
8252                     /* tempB_7..0 */
8253                     assign(t6,
8254                            binop(Iop_Or32,
8255                                  mkexpr(t8),
8256                                  binop(Iop_Shl32,
8257                                        IRExpr_ITE(binop(Iop_CmpEQ32,
8258                                                         binop(Iop_And32,
8259                                                               mkexpr(t7),
8260                                                               mkU32(0x00000080)
8261                                                              ),
8262                                                         mkU32(0x00000080)),
8263                                                   mkU32(0xFFFFFFFF),
8264                                                   mkU32(0x00000000)),
8265                                        binop(Iop_Sub8,
8266                                              mkU8(0x8),
8267                                              unop(Iop_32to8, binop(Iop_And32,
8268                                                                    getIReg(rs),
8269                                                                    mkU32(0x7)))
8270                                              ))));
8271
8272                     /* ========== GPR[rt]_7..0 ========== */
8273                     assign(t10,
8274                            unop(Iop_8Uto32,
8275                                 unop(Iop_16to8,
8276                                      unop(Iop_32to16, getIReg(rt)))));
8277                     assign(t11,
8278                            binop(Iop_Shr32,
8279                                  mkexpr(t10),
8280                                  unop(Iop_32to8, binop(Iop_And32,
8281                                                        getIReg(rs),
8282                                                        mkU32(0x7)))));
8283                     /* tempB_7..0 */
8284                     assign(t9,
8285                            binop(Iop_Or32,
8286                                  mkexpr(t11),
8287                                  binop(Iop_Shl32,
8288                                        IRExpr_ITE(binop(Iop_CmpEQ32,
8289                                                         binop(Iop_And32,
8290                                                               mkexpr(t10),
8291                                                               mkU32(0x00000080)
8292                                                              ),
8293                                                         mkU32(0x00000080)),
8294                                                   mkU32(0xFFFFFFFF),
8295                                                   mkU32(0x00000000)),
8296                                        binop(Iop_Sub8,
8297                                              mkU8(0x8),
8298                                              unop(Iop_32to8, binop(Iop_And32,
8299                                                                    getIReg(rs),
8300                                                                    mkU32(0x7)))
8301                                              ))));
8302
8303                     putIReg(rd,
8304                             binop(Iop_16HLto32,
8305                                   binop(Iop_8HLto16,
8306                                         unop(Iop_32to8,
8307                                              IRExpr_ITE(binop(Iop_CmpEQ32,
8308                                                               binop(Iop_And32,
8309                                                                     mkU32(rs),
8310                                                                     mkU32(0x7)
8311                                                                    ),
8312                                                               mkU32(0x0)),
8313                                                         mkexpr(t1),
8314                                                         mkexpr(t0))),
8315                                         unop(Iop_32to8,
8316                                              IRExpr_ITE(binop(Iop_CmpEQ32,
8317                                                               binop(Iop_And32,
8318                                                                     mkU32(rs),
8319                                                                     mkU32(0x7)
8320                                                                    ),
8321                                                               mkU32(0x0)),
8322                                                         mkexpr(t2),
8323                                                         mkexpr(t3)))),
8324                                   binop(Iop_8HLto16,
8325                                         unop(Iop_32to8,
8326                                              IRExpr_ITE(binop(Iop_CmpEQ32,
8327                                                               binop(Iop_And32,
8328                                                                     mkU32(rs),
8329                                                                     mkU32(0x7)
8330                                                                    ),
8331                                                               mkU32(0x0)),
8332                                                         mkexpr(t5),
8333                                                         mkexpr(t6))),
8334                                         unop(Iop_32to8,
8335                                              IRExpr_ITE(binop(Iop_CmpEQ32,
8336                                                               binop(Iop_And32,
8337                                                                     mkU32(rs),
8338                                                                     mkU32(0x7)
8339                                                                    ),
8340                                                               mkU32(0x0)),
8341                                                         mkexpr(t8),
8342                                                         mkexpr(t9))))));
8343                     break;
8344                  }
8345                  case 0x7: {  /* SHRAV_R.QB */
8346                     DIP("shrav_r.qb r%d, r%d, r%d", rd, rt, rs);
8347                     vassert(!mode64);
8348                     t0 = newTemp(Ity_I32);
8349                     t1 = newTemp(Ity_I8);
8350                     t2 = newTemp(Ity_I32);
8351                     t3 = newTemp(Ity_I8);
8352                     t4 = newTemp(Ity_I32);
8353                     t5 = newTemp(Ity_I8);
8354                     t6 = newTemp(Ity_I32);
8355                     t7 = newTemp(Ity_I8);
8356                     t8 = newTemp(Ity_I8);
8357                     t9 = newTemp(Ity_I32);
8358
8359                     assign(t9, binop(Iop_And32, getIReg(rs), mkU32(0x7)));
8360                     assign(t8, unop(Iop_32to8,
8361                                     binop(Iop_Sub32, mkexpr(t9), mkU32(0x1))));
8362                     assign(t0, unop(Iop_8Sto32,
8363                                     unop(Iop_16to8,
8364                                          unop(Iop_32to16, getIReg(rt)))));
8365                     assign(t1, unop(Iop_32to8,
8366                                     binop(Iop_Sar32,
8367                                           binop(Iop_Add32,
8368                                                 mkexpr(t0),
8369                                                 binop(Iop_Shl32,
8370                                                       mkU32(0x1),
8371                                                       mkexpr(t8))),
8372                                           unop(Iop_32to8,
8373                                                mkexpr(t9)))));
8374
8375                     assign(t2, unop(Iop_8Sto32,
8376                                     unop(Iop_16HIto8,
8377                                          unop(Iop_32to16, getIReg(rt)))));
8378                     assign(t3, unop(Iop_32to8,
8379                                     binop(Iop_Sar32,
8380                                           binop(Iop_Add32,
8381                                                 mkexpr(t2),
8382                                                 binop(Iop_Shl32,
8383                                                       mkU32(0x1),
8384                                                       mkexpr(t8))),
8385                                           unop(Iop_32to8, mkexpr(t9)))));
8386
8387                     assign(t4, unop(Iop_8Sto32,
8388                                     unop(Iop_16to8,
8389                                          unop(Iop_32HIto16, getIReg(rt)))));
8390                     assign(t5, unop(Iop_32to8,
8391                                     binop(Iop_Sar32,
8392                                           binop(Iop_Add32,
8393                                                 mkexpr(t4),
8394                                                 binop(Iop_Shl32,
8395                                                       mkU32(0x1),
8396                                                       mkexpr(t8))),
8397                                           unop(Iop_32to8, mkexpr(t9)))));
8398
8399                     assign(t6, unop(Iop_8Sto32,
8400                                     unop(Iop_16HIto8,
8401                                          unop(Iop_32HIto16, getIReg(rt)))));
8402                     assign(t7, unop(Iop_32to8,
8403                                     binop(Iop_Sar32,
8404                                           binop(Iop_Add32,
8405                                                 mkexpr(t6),
8406                                                 binop(Iop_Shl32,
8407                                                       mkU32(0x1),
8408                                                       mkexpr(t8))),
8409                                           unop(Iop_32to8, mkexpr(t9)))));
8410                     putIReg(rd, IRExpr_ITE(binop(Iop_CmpEQ32,
8411                                                  mkexpr(t9),
8412                                                  mkU32(0x0)),
8413                                            getIReg(rt),
8414                                            binop(Iop_16HLto32,
8415                                                  binop(Iop_8HLto16,
8416                                                        mkexpr(t7),
8417                                                        mkexpr(t5)),
8418                                                  binop(Iop_8HLto16,
8419                                                        mkexpr(t3),
8420                                                        mkexpr(t1)))));
8421                     break;
8422                  }
8423                  case 0x8: {  /* SHLL.PH */
8424                     DIP("shll.ph r%d, r%d, %d", rd, rt, rs);
8425                     vassert(!mode64);
8426                     t0 = newTemp(Ity_I32);
8427                     t1 = newTemp(Ity_I32);
8428                     t2 = newTemp(Ity_I32);
8429                     t3 = newTemp(Ity_I32);
8430                     t4 = newTemp(Ity_I32);
8431                     t5 = newTemp(Ity_I32);
8432                     t6 = newTemp(Ity_I32);
8433                     t7 = newTemp(Ity_I32);
8434
8435                     if (0 == rs) {
8436                        putIReg(rd, getIReg(rt));
8437                     } else {
8438                        /* Shift lower 16 bits. */
8439                        assign(t0, binop(Iop_Shl32,
8440                                         unop(Iop_16Sto32,
8441                                              unop(Iop_32to16, getIReg(rt))),
8442                                         mkU8(rs)));
8443
8444                        assign(t1, unop(Iop_1Uto32,
8445                                        binop(Iop_CmpNE32,
8446                                               binop(Iop_Sar32,
8447                                                     mkexpr(t0),
8448                                                     mkU8(16)),
8449                                               mkU32(0))));
8450                        assign(t2, unop(Iop_1Uto32,
8451                                        binop(Iop_CmpNE32,
8452                                              binop(Iop_Sar32,
8453                                                    mkexpr(t0),
8454                                                    mkU8(16)),
8455                                              mkU32(0xffffffff))));
8456                        assign(t3, binop(Iop_And32,
8457                                         mkexpr(t1),
8458                                         mkexpr(t2)));
8459                        putDSPControl(IRExpr_ITE(binop(Iop_CmpEQ32,
8460                                                       mkexpr(t3),
8461                                                       mkU32(0x1)),
8462                                                 binop(Iop_Or32,
8463                                                       getDSPControl(),
8464                                                       mkU32(0x400000)),
8465                                                 getDSPControl()));
8466                        putDSPControl(IRExpr_ITE(binop(Iop_CmpEQ32,
8467                                                       binop(Iop_And32,
8468                                                             getIReg(rt),
8469                                                             mkU32(0x00008000)),
8470                                                       binop(Iop_And32,
8471                                                             mkexpr(t0),
8472                                                             mkU32(0x00008000))
8473                                                      ),
8474                                                 getDSPControl(),
8475                                                 binop(Iop_Or32,
8476                                                       getDSPControl(),
8477                                                       mkU32(0x400000))));
8478                        /* Shift higher 16 bits. */
8479                        assign(t4, binop(Iop_Shl32,
8480                                         unop(Iop_16Sto32,
8481                                              unop(Iop_32HIto16, getIReg(rt))),
8482                                         mkU8(rs)));
8483
8484                        assign(t5, unop(Iop_1Uto32,
8485                                        binop(Iop_CmpNE32,
8486                                               binop(Iop_Sar32,
8487                                                     mkexpr(t4),
8488                                                     mkU8(16)),
8489                                               mkU32(0))));
8490                        assign(t6, unop(Iop_1Uto32,
8491                                        binop(Iop_CmpNE32,
8492                                              binop(Iop_Sar32,
8493                                                    mkexpr(t4),
8494                                                    mkU8(16)),
8495                                              mkU32(0xffffffff))));
8496                        assign(t7, binop(Iop_And32,
8497                                         mkexpr(t5),
8498                                         mkexpr(t6)));
8499                        putDSPControl(IRExpr_ITE(binop(Iop_CmpEQ32,
8500                                                       mkexpr(t7),
8501                                                       mkU32(0x1)),
8502                                                 binop(Iop_Or32,
8503                                                       getDSPControl(),
8504                                                       mkU32(0x400000)),
8505                                                 getDSPControl()));
8506                        putDSPControl(IRExpr_ITE(binop(Iop_CmpEQ32,
8507                                                       mkexpr(t7),
8508                                                       mkU32(0x1)),
8509                                                 binop(Iop_Or32,
8510                                                       getDSPControl(),
8511                                                       mkU32(0x400000)),
8512                                                 getDSPControl()));
8513                        putDSPControl(IRExpr_ITE(binop(Iop_CmpEQ32,
8514                                                       binop(Iop_And32,
8515                                                             getIReg(rt),
8516                                                             mkU32(0x80000000)),
8517                                                       binop(Iop_Shl32,
8518                                                             binop(Iop_And32,
8519                                                                   mkexpr(t4),
8520                                                                   mkU32(0x00008000)),
8521                                                             mkU8(16))
8522                                                      ),
8523                                                 getDSPControl(),
8524                                                 binop(Iop_Or32,
8525                                                       getDSPControl(),
8526                                                       mkU32(0x400000))));
8527                        putIReg(rd, binop(Iop_16HLto32,
8528                                          unop(Iop_32to16, mkexpr(t4)),
8529                                          unop(Iop_32to16, mkexpr(t0))));
8530                     }
8531                     break;
8532                  }
8533                  case 0x9: {  /* SHRA.PH */
8534                     DIP("shra.ph r%d, r%d, %d", rd, rt, rs);
8535                     vassert(!mode64);
8536                     t0 = newTemp(Ity_I32);
8537                     t1 = newTemp(Ity_I32);
8538                     if (0 == rs) {
8539                        putIReg(rd, getIReg(rt));
8540                     } else {
8541                        assign(t0, binop(Iop_Sar32,
8542                                         unop(Iop_16Sto32,
8543                                              unop(Iop_32to16, getIReg(rt))),
8544                                         mkU8(rs)));
8545                        assign(t1, binop(Iop_Sar32,
8546                                         unop(Iop_16Sto32,
8547                                              unop(Iop_32HIto16, getIReg(rt))),
8548                                         mkU8(rs)));
8549                        putIReg(rd, binop(Iop_16HLto32,
8550                                          unop(Iop_32to16, mkexpr(t1)),
8551                                          unop(Iop_32to16, mkexpr(t0))));
8552                     }
8553                     break;
8554                  }
8555                  case 0xA: {  /* SHLLV.PH */
8556                     DIP("shllv.ph r%d, r%d, r%d", rd, rt, rs);
8557                     vassert(!mode64);
8558                     t0 = newTemp(Ity_I32);
8559                     t2 = newTemp(Ity_I32);
8560                     t3 = newTemp(Ity_I1);
8561                     t4 = newTemp(Ity_I1);
8562                     t5 = newTemp(Ity_I32);
8563                     t6 = newTemp(Ity_I32);
8564                     t7 = newTemp(Ity_I1);
8565                     t8 = newTemp(Ity_I1);
8566                     t9 = newTemp(Ity_I32);
8567                     t10 = newTemp(Ity_I32);
8568                     t11 = newTemp(Ity_I32);
8569                     t12 = newTemp(Ity_I1);
8570                     t13 = newTemp(Ity_I1);
8571
8572                     assign(t0, binop(Iop_And32, getIReg(rs), mkU32(0x0f)));
8573
8574                     /* Shift lower 16 bits. */
8575                     assign(t2, binop(Iop_Shl32,
8576                                      unop(Iop_16Sto32,
8577                                           unop(Iop_32to16, getIReg(rt))),
8578                                      unop(Iop_32to8, mkexpr(t0))));
8579
8580                     assign(t3, binop(Iop_CmpNE32,
8581                                      unop(Iop_16Sto32,
8582                                           unop(Iop_32HIto16, mkexpr(t2))),
8583                                      mkU32(0x00000000)));
8584                     assign(t4, binop(Iop_CmpNE32,
8585                                      unop(Iop_16Sto32,
8586                                           unop(Iop_32HIto16, mkexpr(t2))),
8587                                      mkU32(0xffffffff)));
8588                     assign(t10, binop(Iop_And32,
8589                                       unop(Iop_1Sto32, mkexpr(t3)),
8590                                       unop(Iop_1Sto32, mkexpr(t4))));
8591                     assign(t5, binop(Iop_Shr32,
8592                                      binop(Iop_And32,
8593                                            getIReg(rt),
8594                                            mkU32(0x00008000)),
8595                                      mkU8(15)));
8596                     assign(t12, binop(Iop_CmpEQ32,
8597                                       mkexpr(t5),
8598                                       binop(Iop_Shr32,
8599                                             binop(Iop_And32,
8600                                                   mkexpr(t2),
8601                                                   mkU32(0x00008000)),
8602                                             mkU8(15))));
8603
8604                     putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32,
8605                                                    mkexpr(t10),
8606                                                    mkU32(0x0)),
8607                                              binop(Iop_Or32,
8608                                                    getDSPControl(),
8609                                                    mkU32(0x400000)),
8610                                              IRExpr_ITE(mkexpr(t12),
8611                                                         getDSPControl(),
8612                                                         binop(Iop_Or32,
8613                                                               getDSPControl(),
8614                                                               mkU32(0x400000)))
8615                                             ));
8616                     /* Shift higher 16 bits. */
8617                     assign(t6, binop(Iop_Shl32,
8618                                      unop(Iop_16Sto32,
8619                                           unop(Iop_32HIto16, getIReg(rt))),
8620                                      unop(Iop_32to8, mkexpr(t0))));
8621
8622                     assign(t7, binop(Iop_CmpNE32,
8623                                      unop(Iop_16Sto32,
8624                                           unop(Iop_32HIto16, mkexpr(t6))),
8625                                      mkU32(0x00000000)));
8626                     assign(t8, binop(Iop_CmpNE32,
8627                                      unop(Iop_16Sto32,
8628                                           unop(Iop_32HIto16, mkexpr(t6))),
8629                                      mkU32(0xffffffff)));
8630                     assign(t11, binop(Iop_And32,
8631                                       unop(Iop_1Sto32, mkexpr(t7)),
8632                                       unop(Iop_1Sto32, mkexpr(t8))));
8633
8634                     assign(t9, binop(Iop_Shr32,
8635                                      binop(Iop_And32,
8636                                            getIReg(rt),
8637                                            mkU32(0x80000000)),
8638                                      mkU8(31)));
8639                     assign(t13, binop(Iop_CmpEQ32,
8640                                       mkexpr(t9),
8641                                       binop(Iop_Shr32,
8642                                             binop(Iop_And32,
8643                                                   mkexpr(t6),
8644                                                   mkU32(0x00008000)),
8645                                             mkU8(15))));
8646
8647                     putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32,
8648                                                    mkexpr(t11),
8649                                                    mkU32(0x0)),
8650                                              binop(Iop_Or32,
8651                                                    getDSPControl(),
8652                                                    mkU32(0x400000)),
8653                                              IRExpr_ITE(mkexpr(t13),
8654                                                         getDSPControl(),
8655                                                         binop(Iop_Or32,
8656                                                               getDSPControl(),
8657                                                               mkU32(0x400000)))
8658                                             ));
8659
8660                     putIReg(rd, binop(Iop_16HLto32,
8661                                       unop(Iop_32to16, mkexpr(t6)),
8662                                       unop(Iop_32to16, mkexpr(t2))));
8663                     break;
8664                  }
8665                  case 0xB: {  /* SHRAV.PH */
8666                     DIP("shrav.ph r%d, r%d, r%d", rd, rt, rs);
8667                     vassert(!mode64);
8668                     t0 = newTemp(Ity_I32);
8669                     t1 = newTemp(Ity_I1);
8670                     t2 = newTemp(Ity_I32);
8671                     t3 = newTemp(Ity_I32);
8672
8673                     assign(t0, binop(Iop_And32, getIReg(rs), mkU32(0x0f)));
8674                     assign(t1, binop(Iop_CmpEQ32, mkexpr(t0), mkU32(0x0)));
8675                     assign(t2, binop(Iop_Sar32,
8676                                      unop(Iop_16Sto32,
8677                                           unop(Iop_32to16, getIReg(rt))),
8678                                      unop(Iop_32to8, mkexpr(t0))));
8679                     assign(t3, binop(Iop_Sar32,
8680                                      unop(Iop_16Sto32,
8681                                           unop(Iop_32HIto16, getIReg(rt))),
8682                                      unop(Iop_32to8, mkexpr(t0))));
8683                     putIReg(rd,
8684                             binop(Iop_16HLto32,
8685                                   IRExpr_ITE(mkexpr(t1),
8686                                              unop(Iop_32HIto16, getIReg(rt)),
8687                                              unop(Iop_32to16, mkexpr(t3))),
8688                                   IRExpr_ITE(mkexpr(t1),
8689                                              unop(Iop_32to16, getIReg(rt)),
8690                                              unop(Iop_32to16, mkexpr(t2)))));
8691                     break;
8692                  }
8693                  case 0xC: {  /* SHLL_S.PH */
8694                     DIP("shll_s.ph r%d, r%d, %d", rd, rt, rs);
8695                     vassert(!mode64);
8696                     t0 = newTemp(Ity_I32);
8697                     t1 = newTemp(Ity_I32);
8698                     t2 = newTemp(Ity_I32);
8699                     t3 = newTemp(Ity_I32);
8700                     t4 = newTemp(Ity_I32);
8701                     t5 = newTemp(Ity_I32);
8702                     t6 = newTemp(Ity_I32);
8703                     t7 = newTemp(Ity_I32);
8704                     t8 = newTemp(Ity_I32);
8705                     t9 = newTemp(Ity_I32);
8706                     t10 = newTemp(Ity_I32);
8707                     t11 = newTemp(Ity_I32);
8708                     t12 = newTemp(Ity_I32);
8709                     t13 = newTemp(Ity_I32);
8710                     t14 = newTemp(Ity_I32);
8711
8712                     if (0 == rs) {
8713                        putIReg(rd, getIReg(rt));
8714                     } else {
8715                        /* Shift lower 16 bits. */
8716                        assign(t0, binop(Iop_Shl32,
8717                                         unop(Iop_16Sto32,
8718                                              unop(Iop_32to16, getIReg(rt))),
8719                                         mkU8(rs)));
8720
8721                        assign(t1, unop(Iop_1Uto32,
8722                                        binop(Iop_CmpNE32,
8723                                               binop(Iop_Sar32,
8724                                                     mkexpr(t0),
8725                                                     mkU8(16)),
8726                                               mkU32(0))));
8727                        assign(t2, unop(Iop_1Uto32,
8728                                        binop(Iop_CmpNE32,
8729                                              binop(Iop_Sar32,
8730                                                    mkexpr(t0),
8731                                                    mkU8(16)),
8732                                              mkU32(0xffffffff))));
8733                        assign(t3, binop(Iop_And32,
8734                                         mkexpr(t1),
8735                                         mkexpr(t2)));
8736                        putDSPControl(IRExpr_ITE(binop(Iop_CmpEQ32,
8737                                                       mkexpr(t3),
8738                                                       mkU32(0x1)),
8739                                                 binop(Iop_Or32,
8740                                                       getDSPControl(),
8741                                                       mkU32(0x400000)),
8742                                                 getDSPControl()));
8743                        putDSPControl(IRExpr_ITE(binop(Iop_CmpEQ32,
8744                                                       binop(Iop_And32,
8745                                                             getIReg(rt),
8746                                                             mkU32(0x00008000)),
8747                                                       binop(Iop_And32,
8748                                                             mkexpr(t0),
8749                                                             mkU32(0x00008000))
8750                                                      ),
8751                                                 getDSPControl(),
8752                                                 binop(Iop_Or32,
8753                                                       getDSPControl(),
8754                                                       mkU32(0x400000))));
8755                        assign(t8,
8756                               IRExpr_ITE(binop(Iop_CmpEQ32,
8757                                                mkexpr(t3),
8758                                                mkU32(0x1)),
8759                                          IRExpr_ITE(binop(Iop_CmpEQ32,
8760                                                           binop(Iop_And32,
8761                                                                 getIReg(rt),
8762                                                                 mkU32(0x8000)),
8763                                                           mkU32(0)),
8764                                                     mkU32(0x00007fff),
8765                                                     mkU32(0x00008000)),
8766                                          binop(Iop_And32,
8767                                                mkexpr(t0),
8768                                                mkU32(0x0000ffff))));
8769                        assign(t10,
8770                               IRExpr_ITE(binop(Iop_CmpEQ32,
8771                                                binop(Iop_And32,
8772                                                      getIReg(rt),
8773                                                      mkU32(0x00008000)),
8774                                                binop(Iop_And32,
8775                                                      mkexpr(t0),
8776                                                      mkU32(0x00008000))),
8777                                          mkexpr(t8),
8778                                          IRExpr_ITE(binop(Iop_CmpEQ32,
8779                                                           binop(Iop_And32,
8780                                                                 getIReg(rt),
8781                                                                 mkU32(0x8000)),
8782                                                           mkU32(0)),
8783                                                     mkU32(0x00007fff),
8784                                                     mkU32(0x00008000))));
8785                        /* Shift higher 16 bits. */
8786                        assign(t4, binop(Iop_Shl32,
8787                                         unop(Iop_16Sto32,
8788                                              unop(Iop_32HIto16, getIReg(rt))),
8789                                         mkU8(rs)));
8790
8791                        assign(t5, unop(Iop_1Uto32,
8792                                        binop(Iop_CmpNE32,
8793                                               binop(Iop_Sar32,
8794                                                     mkexpr(t4),
8795                                                     mkU8(16)),
8796                                               mkU32(0))));
8797                        assign(t6, unop(Iop_1Uto32,
8798                                        binop(Iop_CmpNE32,
8799                                              binop(Iop_Sar32,
8800                                                    mkexpr(t4),
8801                                                    mkU8(16)),
8802                                              mkU32(0xffffffff))));
8803                        assign(t7, binop(Iop_And32,
8804                                         mkexpr(t5),
8805                                         mkexpr(t6)));
8806                        putDSPControl(IRExpr_ITE(binop(Iop_CmpEQ32,
8807                                                       mkexpr(t7),
8808                                                       mkU32(0x1)),
8809                                                 binop(Iop_Or32,
8810                                                       getDSPControl(),
8811                                                       mkU32(0x400000)),
8812                                                 getDSPControl()));
8813                        putDSPControl(IRExpr_ITE(binop(Iop_CmpEQ32,
8814                                                       mkexpr(t7),
8815                                                       mkU32(0x1)),
8816                                                 binop(Iop_Or32,
8817                                                       getDSPControl(),
8818                                                       mkU32(0x400000)),
8819                                                 getDSPControl()));
8820                        assign(t12, binop(Iop_Shl32,
8821                                          binop(Iop_And32,
8822                                                mkexpr(t4),
8823                                                mkU32(0x8000)),
8824                                          mkU8(16)));
8825                        putDSPControl(IRExpr_ITE(binop(Iop_CmpEQ32,
8826                                                       binop(Iop_And32,
8827                                                             getIReg(rt),
8828                                                             mkU32(0x80000000)),
8829                                                       mkexpr(t12)),
8830                                                 getDSPControl(),
8831                                                 binop(Iop_Or32,
8832                                                       getDSPControl(),
8833                                                       mkU32(0x400000))));
8834                        assign(t13, IRExpr_ITE(binop(Iop_CmpEQ32,
8835                                                     binop(Iop_And32,
8836                                                           getIReg(rt),
8837                                                           mkU32(0x80000000)),
8838                                                     mkU32(0)),
8839                                               mkU32(0x7fff0000),
8840                                               mkU32(0x80000000)));
8841                        assign(t9,
8842                               IRExpr_ITE(binop(Iop_CmpEQ32,
8843                                                mkexpr(t7),
8844                                                mkU32(0x1)),
8845                                          mkexpr(t13),
8846                                          binop(Iop_Shl32,
8847                                                binop(Iop_And32,
8848                                                      mkexpr(t4),
8849                                                      mkU32(0x0000ffff)),
8850                                                mkU8(16))));
8851                        assign(t14, IRExpr_ITE(binop(Iop_CmpEQ32,
8852                                                     binop(Iop_And32,
8853                                                           getIReg(rt),
8854                                                           mkU32(0x80000000)),
8855                                                     mkU32(0)),
8856                                               mkU32(0x7fff0000),
8857                                               mkU32(0x80000000)));
8858                        assign(t11,
8859                               IRExpr_ITE(binop(Iop_CmpEQ32,
8860                                                binop(Iop_And32,
8861                                                      getIReg(rt),
8862                                                      mkU32(0x80000000)),
8863                                                binop(Iop_Shl32,
8864                                                      binop(Iop_And32,
8865                                                            mkexpr(t4),
8866                                                            mkU32(0x00008000)),
8867                                                      mkU8(16))),
8868                                          mkexpr(t9),
8869                                          mkexpr(t14)));
8870                        putIReg(rd, binop(Iop_Or32,
8871                                          mkexpr(t10),
8872                                          mkexpr(t11)));
8873                     }
8874                     break;
8875                  }
8876                  case 0xD: {  /* SHRA_R.PH */
8877                     DIP("shra.ph r%d, r%d, %d", rd, rt, rs);
8878                     vassert(!mode64);
8879                     t0 = newTemp(Ity_I32);
8880                     t1 = newTemp(Ity_I32);
8881                     if (0 == rs) {
8882                        putIReg(rd, getIReg(rt));
8883                     } else {
8884                        assign(t0, binop(Iop_Sar32,
8885                                         binop(Iop_Add32,
8886                                               unop(Iop_16Sto32,
8887                                                    unop(Iop_32to16,
8888                                                         getIReg(rt))),
8889                                               binop(Iop_Shl32,
8890                                                     mkU32(0x1),
8891                                                     mkU8(rs-1))),
8892                                         mkU8(rs)));
8893                        assign(t1, binop(Iop_Sar32,
8894                                         binop(Iop_Add32,
8895                                               unop(Iop_16Sto32,
8896                                                    unop(Iop_32HIto16,
8897                                                         getIReg(rt))),
8898                                               binop(Iop_Shl32,
8899                                                     mkU32(0x1),
8900                                                     mkU8(rs-1))),
8901                                         mkU8(rs)));
8902                        putIReg(rd, binop(Iop_16HLto32,
8903                                          unop(Iop_32to16, mkexpr(t1)),
8904                                          unop(Iop_32to16, mkexpr(t0))));
8905                     }
8906                     break;
8907                  }
8908                  case 0xE: {  /* SHLLV_S.PH */
8909                     DIP("shllv_s.ph r%d, r%d, r%d", rd, rt, rs);
8910                     vassert(!mode64);
8911                     t0 = newTemp(Ity_I32);
8912                     t2 = newTemp(Ity_I32);
8913                     t3 = newTemp(Ity_I1);
8914                     t4 = newTemp(Ity_I1);
8915                     t5 = newTemp(Ity_I32);
8916                     t6 = newTemp(Ity_I32);
8917                     t7 = newTemp(Ity_I1);
8918                     t8 = newTemp(Ity_I1);
8919                     t9 = newTemp(Ity_I32);
8920                     t10 = newTemp(Ity_I32);
8921                     t11 = newTemp(Ity_I32);
8922                     t12 = newTemp(Ity_I1);
8923                     t13 = newTemp(Ity_I1);
8924                     t14 = newTemp(Ity_I16);
8925                     t15 = newTemp(Ity_I16);
8926                     t16 = newTemp(Ity_I16);
8927                     t17 = newTemp(Ity_I16);
8928
8929                     assign(t0, binop(Iop_And32, getIReg(rs), mkU32(0x0f)));
8930
8931                     /* Shift lower 16 bits. */
8932                     assign(t2, binop(Iop_Shl32,
8933                                      unop(Iop_16Sto32,
8934                                           unop(Iop_32to16, getIReg(rt))),
8935                                      unop(Iop_32to8, mkexpr(t0))));
8936
8937                     assign(t3, binop(Iop_CmpNE32,
8938                                      unop(Iop_16Sto32,
8939                                           unop(Iop_32HIto16, mkexpr(t2))),
8940                                      mkU32(0x00000000)));
8941                     assign(t4, binop(Iop_CmpNE32,
8942                                      unop(Iop_16Sto32,
8943                                           unop(Iop_32HIto16, mkexpr(t2))),
8944                                      mkU32(0xffffffff)));
8945                     assign(t10, binop(Iop_And32,
8946                                       unop(Iop_1Sto32, mkexpr(t3)),
8947                                       unop(Iop_1Sto32, mkexpr(t4))));
8948                     assign(t5, binop(Iop_Shr32,
8949                                       binop(Iop_And32,
8950                                             getIReg(rt),
8951                                             mkU32(0x00008000)),
8952                                       mkU8(15)));
8953                     assign(t12, binop(Iop_CmpEQ32,
8954                                       mkexpr(t5),
8955                                       binop(Iop_Shr32,
8956                                             binop(Iop_And32,
8957                                                   mkexpr(t2),
8958                                                   mkU32(0x00008000)),
8959                                             mkU8(15))));
8960
8961                     putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32,
8962                                                    mkexpr(t10),
8963                                                    mkU32(0x0)),
8964                                              binop(Iop_Or32,
8965                                                    getDSPControl(),
8966                                                    mkU32(0x400000)),
8967                                              IRExpr_ITE(mkexpr(t12),
8968                                                         getDSPControl(),
8969                                                         binop(Iop_Or32,
8970                                                               getDSPControl(),
8971                                                               mkU32(0x400000)))
8972                                             ));
8973                     assign(t14, IRExpr_ITE(binop(Iop_CmpNE32,
8974                                                  mkexpr(t5),
8975                                                  mkU32(0x0)),
8976                                            mkU16(0x8000),
8977                                            mkU16(0x7fff)));
8978                     assign(t15, IRExpr_ITE(binop(Iop_CmpNE32,
8979                                                  mkexpr(t10),
8980                                                  mkU32(0x0)),
8981                                            mkexpr(t14),
8982                                            IRExpr_ITE(mkexpr(t12),
8983                                                       unop(Iop_32to16,
8984                                                            mkexpr(t2)),
8985                                                       mkexpr(t14))));
8986                     /* Shift higher 16 bits. */
8987                     assign(t6, binop(Iop_Shl32,
8988                                      unop(Iop_16Sto32,
8989                                           unop(Iop_32HIto16, getIReg(rt))),
8990                                      unop(Iop_32to8, mkexpr(t0))));
8991
8992                     assign(t7, binop(Iop_CmpNE32,
8993                                      unop(Iop_16Sto32,
8994                                           unop(Iop_32HIto16, mkexpr(t6))),
8995                                      mkU32(0x00000000)));
8996                     assign(t8, binop(Iop_CmpNE32,
8997                                      unop(Iop_16Sto32,
8998                                           unop(Iop_32HIto16, mkexpr(t6))),
8999                                      mkU32(0xffffffff)));
9000                     assign(t11, binop(Iop_And32,
9001                                       unop(Iop_1Sto32, mkexpr(t7)),
9002                                       unop(Iop_1Sto32, mkexpr(t8))));
9003
9004                     assign(t9, binop(Iop_Shr32,
9005                                      binop(Iop_And32,
9006                                            getIReg(rt),
9007                                            mkU32(0x80000000)),
9008                                      mkU8(31)));
9009                     assign(t13, binop(Iop_CmpEQ32,
9010                                       mkexpr(t9),
9011                                       binop(Iop_Shr32,
9012                                             binop(Iop_And32,
9013                                                   mkexpr(t6),
9014                                                   mkU32(0x00008000)),
9015                                             mkU8(15))));
9016
9017                     putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32,
9018                                                    mkexpr(t11),
9019                                                    mkU32(0x0)),
9020                                              binop(Iop_Or32,
9021                                                    getDSPControl(),
9022                                                    mkU32(0x400000)),
9023                                              IRExpr_ITE(mkexpr(t13),
9024                                                         getDSPControl(),
9025                                                         binop(Iop_Or32,
9026                                                               getDSPControl(),
9027                                                               mkU32(0x400000)))
9028                                             ));
9029
9030                     assign(t16, IRExpr_ITE(binop(Iop_CmpNE32,
9031                                                  mkexpr(t9),
9032                                                  mkU32(0x0)),
9033                                            mkU16(0x8000),
9034                                            mkU16(0x7fff)));
9035                     assign(t17, IRExpr_ITE(binop(Iop_CmpNE32,
9036                                                  mkexpr(t11),
9037                                                  mkU32(0x0)),
9038                                            mkexpr(t16),
9039                                            IRExpr_ITE(mkexpr(t13),
9040                                                       unop(Iop_32to16,
9041                                                            mkexpr(t6)),
9042                                                       mkexpr(t16))));
9043
9044                     putIReg(rd, binop(Iop_16HLto32, mkexpr(t17), mkexpr(t15)));
9045                     break;
9046                  }
9047                  case 0xF: {  /* SHRAV_R.PH */
9048                     DIP("shrav_r.ph r%d, r%d, r%d", rd, rt, rs);
9049                     vassert(!mode64);
9050                     t0 = newTemp(Ity_I32);
9051                     t1 = newTemp(Ity_I1);
9052                     t2 = newTemp(Ity_I8);
9053                     t3 = newTemp(Ity_I32);
9054                     t4 = newTemp(Ity_I32);
9055
9056                     assign(t0, binop(Iop_And32, getIReg(rs), mkU32(0x0f)));
9057                     assign(t1, binop(Iop_CmpEQ32, mkexpr(t0), mkU32(0x0)));
9058                     assign(t2, unop(Iop_32to8,
9059                                     binop(Iop_Sub32, mkexpr(t0), mkU32(1))));
9060
9061                     assign(t3, binop(Iop_Sar32,
9062                                      binop(Iop_Add32,
9063                                            unop(Iop_16Sto32,
9064                                                 unop(Iop_32to16, getIReg(rt))),
9065                                            binop(Iop_Shl32,
9066                                                  mkU32(0x1),
9067                                                  mkexpr(t2))),
9068                                      unop(Iop_32to8, mkexpr(t0))));
9069                     assign(t4, binop(Iop_Sar32,
9070                                      binop(Iop_Add32,
9071                                            unop(Iop_16Sto32,
9072                                                 unop(Iop_32HIto16,
9073                                                      getIReg(rt))),
9074                                            binop(Iop_Shl32,
9075                                                  mkU32(0x1),
9076                                                  mkexpr(t2))),
9077                                      unop(Iop_32to8, mkexpr(t0))));
9078
9079                     putIReg(rd, binop(Iop_16HLto32,
9080                                       IRExpr_ITE(mkexpr(t1),
9081                                                  unop(Iop_32HIto16,
9082                                                       getIReg(rt)),
9083                                                  unop(Iop_32to16,
9084                                                       mkexpr(t4))),
9085                                       IRExpr_ITE(mkexpr(t1),
9086                                                  unop(Iop_32to16, getIReg(rt)),
9087                                                  unop(Iop_32to16,
9088                                                       mkexpr(t3)))));
9089                     break;
9090                  }
9091                  case 0x14: {  /* SHLL_S.W */
9092                     DIP("shll_s.w r%d, r%d, %d", rd, rt, rs);
9093                     vassert(!mode64);
9094                     t0 = newTemp(Ity_I32);
9095                     t1 = newTemp(Ity_I32);
9096                     t2 = newTemp(Ity_I32);
9097                     t3 = newTemp(Ity_I32);
9098                     t4 = newTemp(Ity_I32);
9099                     t5 = newTemp(Ity_I32);
9100
9101                     if (0 == rs) {
9102                        putIReg(rd, getIReg(rt));
9103                     } else {
9104                        /* t0-bits that will be discarded, sign extended to
9105                           32bits. */
9106                        assign(t0, binop(Iop_Sar32,
9107                                         binop(Iop_And32,
9108                                               getIReg(rt),
9109                                               binop(Iop_Sar32,
9110                                                     mkU32(0x80000000),
9111                                                     mkU8(rs-1))),
9112                                         mkU8(32-rs)));
9113
9114                        assign(t1, IRExpr_ITE(binop(Iop_CmpEQ32,
9115                                                    binop(Iop_And32,
9116                                                          getIReg(rt),
9117                                                          mkU32(0x80000000)),
9118                                                    mkU32(0x0)),
9119                                              mkU32(0x7fffffff),
9120                                              mkU32(0x80000000)));
9121
9122                        assign(t2, binop(Iop_Shl32, getIReg(rt), mkU8(rs)));
9123                        assign(t3, IRExpr_ITE(binop(Iop_CmpEQ32,
9124                                                    binop(Iop_And32,
9125                                                          getIReg(rt),
9126                                                          mkU32(0x80000000)),
9127                                                    binop(Iop_And32,
9128                                                          mkexpr(t2),
9129                                                          mkU32(0x80000000))),
9130                                              mkexpr(t2),
9131                                              mkexpr(t1)));
9132
9133                        assign(t4, IRExpr_ITE(binop(Iop_CmpNE32,
9134                                                    mkexpr(t0),
9135                                                    mkU32(0x0)),
9136                                              IRExpr_ITE(binop(Iop_CmpNE32,
9137                                                               mkexpr(t0),
9138                                                               mkU32(0xffffffff)
9139                                                              ),
9140                                                         mkexpr(t1),
9141                                                         mkexpr(t3)),
9142                                              mkexpr(t3)));
9143                        assign(t5, IRExpr_ITE(binop(Iop_CmpNE32,
9144                                                    mkexpr(t0),
9145                                                    mkU32(0xffffffff)),
9146                                              binop(Iop_Or32,
9147                                                    getDSPControl(),
9148                                                    mkU32(0x400000)),
9149                                              getDSPControl()));
9150                        putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32,
9151                                                       mkexpr(t0),
9152                                                       mkU32(0x0)),
9153                                                 mkexpr(t5),
9154                                                 getDSPControl()));
9155                        putDSPControl(IRExpr_ITE(binop(Iop_CmpEQ32,
9156                                                       binop(Iop_And32,
9157                                                             getIReg(rt),
9158                                                             mkU32(0x80000000)),
9159                                                       binop(Iop_And32,
9160                                                             mkexpr(t2),
9161                                                             mkU32(0x80000000))
9162                                                            ),
9163                                                 getDSPControl(),
9164                                                 binop(Iop_Or32,
9165                                                       getDSPControl(),
9166                                                       mkU32(0x400000))));
9167                        putIReg(rd, mkexpr(t4));
9168                     }
9169                     break;
9170                  }
9171                  case 0x15: {  /* SHRA_R.W */
9172                     DIP("shra_r.w r%d, r%d, %d", rd, rt, rs);
9173                     vassert(!mode64);
9174                     if (0 == rs) {
9175                        putIReg(rd, getIReg(rt));
9176                     } else {
9177                        putIReg(rd, binop(Iop_Add32,
9178                                          binop(Iop_Sar32,
9179                                                getIReg(rt), mkU8(rs)),
9180                                          binop(Iop_Shr32,
9181                                                binop(Iop_And32,
9182                                                      getIReg(rt),
9183                                                      binop(Iop_Shl32,
9184                                                            mkU32(0x1),
9185                                                            mkU8(rs-1))),
9186                                                mkU8(rs-1))));
9187                     }
9188                     break;
9189                  }
9190                  case 0x16: {  /* SHLLV_S.W */
9191                     DIP("shllv_s.w r%d, r%d, r%d", rd, rt, rs);
9192                     vassert(!mode64);
9193                     t0 = newTemp(Ity_I32);
9194                     t1 = newTemp(Ity_I1);
9195                     t2 = newTemp(Ity_I32);
9196                     t3 = newTemp(Ity_I64);
9197                     t4 = newTemp(Ity_I1);
9198                     t5 = newTemp(Ity_I1);
9199                     t6 = newTemp(Ity_I32);
9200                     t7 = newTemp(Ity_I1);
9201                     t8 = newTemp(Ity_I32);
9202
9203                     /* Check if shift amount is zero. */
9204                     assign(t0, binop(Iop_And32, getIReg(rs), mkU32(0x1f)));
9205                     assign(t1, binop(Iop_CmpEQ32, mkexpr(t0), mkU32(0x0)));
9206
9207                     /* t2 = sign of the input value. */
9208                     assign(t2, binop(Iop_Shr32,
9209                                      binop(Iop_And32,
9210                                            getIReg(rt),
9211                                            mkU32(0x80000000)),
9212                                      mkU8(31)));
9213                     /* Shift left input value and check for overflow. */
9214                     assign(t3, binop(Iop_Shl64,
9215                                      unop(Iop_32Sto64, getIReg(rt)),
9216                                      unop(Iop_32to8, mkexpr(t0))));
9217                     assign(t4, binop(Iop_CmpNE32,
9218                                      unop(Iop_64HIto32, mkexpr(t3)),
9219                                      mkU32(0x00000000)));
9220                     assign(t5, binop(Iop_CmpNE32,
9221                                      unop(Iop_64HIto32, mkexpr(t3)),
9222                                      mkU32(0xffffffff)));
9223                     assign(t6, binop(Iop_And32,
9224                                      unop(Iop_1Uto32, mkexpr(t4)),
9225                                      unop(Iop_1Uto32, mkexpr(t5))));
9226                     assign(t7, binop(Iop_CmpEQ32,
9227                                      binop(Iop_Shr32,
9228                                            binop(Iop_And32,
9229                                                  getIReg(rt),
9230                                                  mkU32(0x80000000)),
9231                                            mkU8(31)),
9232                                      binop(Iop_Shr32,
9233                                            binop(Iop_And32,
9234                                                  unop(Iop_64to32, mkexpr(t3)),
9235                                                  mkU32(0x80000000)),
9236                                            mkU8(31))));
9237
9238                     putDSPControl(IRExpr_ITE(unop(Iop_32to1, mkexpr(t6)),
9239                                                   binop(Iop_Or32,
9240                                                         getDSPControl(),
9241                                                         mkU32(0x400000)),
9242                                              IRExpr_ITE(mkexpr(t7),
9243                                                         getDSPControl(),
9244                                                         binop(Iop_Or32,
9245                                                               getDSPControl(),
9246                                                               mkU32(0x400000)))
9247                                             ));
9248
9249                     assign(t8, IRExpr_ITE(unop(Iop_32to1,
9250                                                mkexpr(t2)),
9251                                           mkU32(0x80000000),
9252                                           mkU32(0x7fffffff)));
9253                     putIReg(rd, IRExpr_ITE(unop(Iop_32to1, mkexpr(t6)),
9254                                            IRExpr_ITE(unop(Iop_32to1,
9255                                                            mkexpr(t2)),
9256                                                       mkU32(0x80000000),
9257                                                       mkU32(0x7fffffff)),
9258                                            IRExpr_ITE(mkexpr(t7),
9259                                                       unop(Iop_64to32,
9260                                                            mkexpr(t3)),
9261                                                       mkexpr(t8))));
9262                     break;
9263                  }
9264                  case 0x17: {  /* SHRAV_R.W */
9265                     DIP("shrav_r.w r%d, r%d, r%d", rd, rt, rs);
9266                     vassert(!mode64);
9267                     t0 = newTemp(Ity_I32);
9268                     t1 = newTemp(Ity_I1);
9269                     t2 = newTemp(Ity_I8);
9270                     t3 = newTemp(Ity_I32);
9271
9272                     assign(t0, binop(Iop_And32, getIReg(rs), mkU32(0x1f)));
9273                     assign(t1, binop(Iop_CmpEQ32, mkexpr(t0), mkU32(0x0)));
9274                     assign(t2, unop(Iop_32to8,
9275                                     binop(Iop_Sub32, mkexpr(t0), mkU32(1))));
9276
9277                     putIReg(rd, IRExpr_ITE(mkexpr(t1),
9278                                            getIReg(rt),
9279                                            binop(Iop_Sar32,
9280                                                  binop(Iop_Add32,
9281                                                        binop(Iop_Sar32,
9282                                                              getIReg(rt),
9283                                                              mkexpr(t2)),
9284                                                        mkU32(0x1)),
9285                                                  mkU8(1))));
9286                     break;
9287                  }
9288                  case 0x19: {  /* SHRL.PH */
9289                     DIP("shrl.ph r%d, r%d, %d", rd, rt, rs);
9290                     vassert(!mode64);
9291                     t0 = newTemp(Ity_I32);
9292                     t1 = newTemp(Ity_I32);
9293                     assign(t0, binop(Iop_Shr32,
9294                                      unop(Iop_16Uto32,
9295                                           unop(Iop_32to16, getIReg(rt))),
9296                                      mkU8(rs)));
9297                     assign(t1, binop(Iop_Shr32,
9298                                      unop(Iop_16Uto32,
9299                                           unop(Iop_32HIto16, getIReg(rt))),
9300                                      mkU8(rs)));
9301                     putIReg(rd, binop(Iop_16HLto32,
9302                                       unop(Iop_32to16, mkexpr(t1)),
9303                                       unop(Iop_32to16, mkexpr(t0))));
9304                     break;
9305                  }
9306                  case 0x1B: {  /* SHRLV.PH */
9307                     DIP("shrlv.ph r%d, r%d, r%d", rd, rt, rs);
9308                     vassert(!mode64);
9309                     t0 = newTemp(Ity_I32);
9310                     t1 = newTemp(Ity_I1);
9311                     t2 = newTemp(Ity_I32);
9312                     t3 = newTemp(Ity_I32);
9313                     t4 = newTemp(Ity_I16);
9314                     t5 = newTemp(Ity_I16);
9315
9316                     /* Get shift amount from lower 5 bits of rs
9317                        and check if it is zero. */
9318                     assign(t0, binop(Iop_And32, getIReg(rs), mkU32(0x0f)));
9319                     assign(t1, binop(Iop_CmpEQ32, mkexpr(t0), mkU32(0x0)));
9320
9321                     assign(t2, binop(Iop_Shr32,
9322                                      unop(Iop_16Uto32,
9323                                           unop(Iop_32to16, getIReg(rt))),
9324                                      unop(Iop_32to8, mkexpr(t0))));
9325                     assign(t3, binop(Iop_Shr32,
9326                                      unop(Iop_16Uto32,
9327                                           unop(Iop_32HIto16, getIReg(rt))),
9328                                      unop(Iop_32to8, mkexpr(t0))));
9329
9330                     assign(t4, IRExpr_ITE(mkexpr(t1),
9331                                           unop(Iop_32HIto16, getIReg(rt)),
9332                                           unop(Iop_32to16, mkexpr(t3))));
9333                     assign(t5, IRExpr_ITE(mkexpr(t1),
9334                                           unop(Iop_32to16, getIReg(rt)),
9335                                           unop(Iop_32to16, mkexpr(t2))));
9336                     putIReg(rd, binop(Iop_16HLto32, mkexpr(t4), mkexpr(t5)));
9337                     break;
9338                  }
9339                  default:
9340                     return -1;
9341               }
9342               break;  /* end of SHLL.QB */
9343            }
9344            case 0x18: {  /* ADDUH.QB/MUL.PH */
9345               switch(sa) {
9346                  case 0x00: {  /* ADDUH.QB */
9347                     DIP("adduh.qb r%d, r%d, r%d", rd, rs, rt);
9348                     vassert(!mode64);
9349                     t0 = newTemp(Ity_I32);
9350
9351                     assign(t0, binop(Iop_HAdd8Ux4, getIReg(rs), getIReg(rt)));
9352
9353                     putIReg(rd, mkexpr(t0));
9354                     break;
9355                  }
9356                  case 0x1: {  /* SUBUH.QB */
9357                     DIP("subuh.qb r%d, r%d, r%d", rd, rs, rt);
9358                     vassert(!mode64);
9359                     t0 = newTemp(Ity_I32);
9360
9361                     assign(t0, binop(Iop_HSub8Ux4, getIReg(rs), getIReg(rt)));
9362
9363                     putIReg(rd, mkexpr(t0));
9364                     break;
9365                  }
9366                  case 0x02: {  /* ADDUH_R.QB */
9367                     DIP("adduh_r.qb r%d, r%d, r%d", rd, rs, rt);
9368                     vassert(!mode64);
9369                     t0 = newTemp(Ity_I32);
9370                     t1 = newTemp(Ity_I32);
9371                     t2 = newTemp(Ity_I8);
9372                     t3 = newTemp(Ity_I32);
9373                     t4 = newTemp(Ity_I32);
9374                     t5 = newTemp(Ity_I8);
9375                     t6 = newTemp(Ity_I32);
9376                     t7 = newTemp(Ity_I32);
9377                     t8 = newTemp(Ity_I8);
9378                     t9 = newTemp(Ity_I32);
9379                     t10 = newTemp(Ity_I32);
9380                     t11 = newTemp(Ity_I8);
9381
9382                     /* Extract input bytes, add values, add 1 and half the
9383                        result. */
9384                     assign(t0, unop(Iop_8Uto32,
9385                                     unop(Iop_16to8,
9386                                          unop(Iop_32to16, getIReg(rs)))));
9387                     assign(t1, unop(Iop_8Uto32,
9388                                     unop(Iop_16to8,
9389                                          unop(Iop_32to16, getIReg(rt)))));
9390                     assign(t2, unop(Iop_16to8,
9391                                     unop(Iop_32to16,
9392                                          binop(Iop_Shr32,
9393                                                binop(Iop_Add32,
9394                                                      binop(Iop_Add32,
9395                                                            mkexpr(t0),
9396                                                            mkexpr(t1)),
9397                                                      mkU32(0x00000001)),
9398                                                mkU8(0x01)))));
9399
9400                     assign(t3, unop(Iop_8Uto32,
9401                                     unop(Iop_16HIto8,
9402                                          unop(Iop_32to16, getIReg(rs)))));
9403                     assign(t4, unop(Iop_8Uto32,
9404                                     unop(Iop_16HIto8,
9405                                          unop(Iop_32to16, getIReg(rt)))));
9406                     assign(t5, unop(Iop_16to8,
9407                                     unop(Iop_32to16,
9408                                          binop(Iop_Shr32,
9409                                                binop(Iop_Add32,
9410                                                      binop(Iop_Add32,
9411                                                            mkexpr(t3),
9412                                                            mkexpr(t4)),
9413                                                      mkU32(0x00000001)),
9414                                                mkU8(0x01)))));
9415
9416                     assign(t6, unop(Iop_8Uto32,
9417                                     unop(Iop_16to8,
9418                                          unop(Iop_32HIto16, getIReg(rs)))));
9419                     assign(t7, unop(Iop_8Uto32,
9420                                     unop(Iop_16to8,
9421                                          unop(Iop_32HIto16, getIReg(rt)))));
9422                     assign(t8, unop(Iop_16to8,
9423                                     unop(Iop_32to16,
9424                                          binop(Iop_Shr32,
9425                                                binop(Iop_Add32,
9426                                                      binop(Iop_Add32,
9427                                                            mkexpr(t7),
9428                                                            mkexpr(t6)),
9429                                                      mkU32(0x00000001)),
9430                                                mkU8(0x01)))));
9431
9432                     assign(t9, unop(Iop_8Uto32,
9433                                     unop(Iop_16HIto8,
9434                                          unop(Iop_32HIto16, getIReg(rs)))));
9435                     assign(t10, unop(Iop_8Uto32,
9436                                      unop(Iop_16HIto8,
9437                                           unop(Iop_32HIto16, getIReg(rt)))));
9438                     assign(t11, unop(Iop_16to8,
9439                                      unop(Iop_32to16,
9440                                           binop(Iop_Shr32,
9441                                                 binop(Iop_Add32,
9442                                                       binop(Iop_Add32,
9443                                                             mkexpr(t9),
9444                                                             mkexpr(t10)),
9445                                                       mkU32(0x00000001)),
9446                                                 mkU8(0x01)))));
9447
9448                     putIReg(rd, binop(Iop_16HLto32,
9449                                       binop(Iop_8HLto16,
9450                                             mkexpr(t11), mkexpr(t8)),
9451                                       binop(Iop_8HLto16,
9452                                             mkexpr(t5), mkexpr(t2))));
9453                     break;
9454                  }
9455                  case 0x3: {  /* SUBUH_R.QB */
9456                     DIP("subuh_r.qb r%d, r%d, r%d", rd, rs, rt);
9457                     vassert(!mode64);
9458                     t1 = newTemp(Ity_I32);
9459                     t2 = newTemp(Ity_I32);
9460                     t3 = newTemp(Ity_I32);
9461                     t4 = newTemp(Ity_I32);
9462                     t5 = newTemp(Ity_I32);
9463                     t6 = newTemp(Ity_I32);
9464                     t7 = newTemp(Ity_I32);
9465                     t8 = newTemp(Ity_I32);
9466                     t9 = newTemp(Ity_I8);
9467                     t10 = newTemp(Ity_I8);
9468                     t11 = newTemp(Ity_I8);
9469                     t12 = newTemp(Ity_I8);
9470
9471                     /* Extract each byte of rs and rt. */
9472                     assign(t1, unop(Iop_8Uto32,
9473                                     unop(Iop_16to8,
9474                                          unop(Iop_32to16, getIReg(rs)))));
9475                     assign(t2, unop(Iop_8Uto32,
9476                                     unop(Iop_16HIto8,
9477                                          unop(Iop_32to16, getIReg(rs)))));
9478                     assign(t3, unop(Iop_8Uto32,
9479                                     unop(Iop_16to8,
9480                                          unop(Iop_32HIto16, getIReg(rs)))));
9481                     assign(t4, unop(Iop_8Uto32,
9482                                     unop(Iop_16HIto8,
9483                                          unop(Iop_32HIto16, getIReg(rs)))));
9484
9485                     assign(t5, unop(Iop_8Uto32,
9486                                     unop(Iop_16to8,
9487                                          unop(Iop_32to16, getIReg(rt)))));
9488                     assign(t6, unop(Iop_8Uto32,
9489                                     unop(Iop_16HIto8,
9490                                          unop(Iop_32to16, getIReg(rt)))));
9491                     assign(t7, unop(Iop_8Uto32,
9492                                     unop(Iop_16to8,
9493                                          unop(Iop_32HIto16, getIReg(rt)))));
9494                     assign(t8, unop(Iop_8Uto32,
9495                                     unop(Iop_16HIto8,
9496                                          unop(Iop_32HIto16, getIReg(rt)))));
9497
9498                     /* Add 1 to each resulting byte and half the results. */
9499                     assign(t9, unop(Iop_16to8,
9500                                     unop(Iop_32to16,
9501                                          binop(Iop_Shr32,
9502                                                binop(Iop_Add32,
9503                                                      binop(Iop_Sub32,
9504                                                            mkexpr(t1),
9505                                                            mkexpr(t5)),
9506                                                      mkU32(0x00000001)),
9507                                                mkU8(0x01)))));
9508                     assign(t10, unop(Iop_16to8,
9509                                      unop(Iop_32to16,
9510                                           binop(Iop_Shr32,
9511                                                 binop(Iop_Add32,
9512                                                       binop(Iop_Sub32,
9513                                                             mkexpr(t2),
9514                                                             mkexpr(t6)),
9515                                                       mkU32(0x00000001)),
9516                                                 mkU8(0x01)))));
9517                     assign(t11, unop(Iop_16to8,
9518                                      unop(Iop_32to16,
9519                                            binop(Iop_Shr32,
9520                                                  binop(Iop_Add32,
9521                                                        binop(Iop_Sub32,
9522                                                              mkexpr(t3),
9523                                                              mkexpr(t7)),
9524                                                        mkU32(0x00000001)),
9525                                                  mkU8(0x01)))));
9526                     assign(t12, unop(Iop_16to8,
9527                                      unop(Iop_32to16,
9528                                           binop(Iop_Shr32,
9529                                                 binop(Iop_Add32,
9530                                                       binop(Iop_Sub32,
9531                                                             mkexpr(t4),
9532                                                             mkexpr(t8)),
9533                                                       mkU32(0x00000001)),
9534                                                 mkU8(0x01)))));
9535
9536                     putIReg(rd, binop(Iop_16HLto32,
9537                                       binop(Iop_8HLto16,
9538                                             mkexpr(t12), mkexpr(t11)),
9539                                       binop(Iop_8HLto16,
9540                                             mkexpr(t10), mkexpr(t9))));
9541                     break;
9542                  }
9543                  case 0x8: {  /* ADDQH.PH */
9544                     DIP("addqh.ph r%d, r%d, r%d", rd, rs, rt);
9545                     vassert(!mode64);
9546                     t0 = newTemp(Ity_I32);
9547                     t1 = newTemp(Ity_I16);
9548                     t2 = newTemp(Ity_I32);
9549                     t3 = newTemp(Ity_I16);
9550
9551                     /* Add lower halfs of rs and rt
9552                        and right shift the result by 1. */
9553                     assign(t0, binop(Iop_Add32,
9554                                      unop(Iop_16Sto32,
9555                                           unop(Iop_32to16, getIReg(rs))),
9556                                      unop(Iop_16Sto32,
9557                                           unop(Iop_32to16, getIReg(rt)))));
9558                     assign(t1, unop(Iop_32to16,
9559                                     binop(Iop_Shr32,
9560                                           binop(Iop_And32,
9561                                                 mkexpr(t0),
9562                                                 mkU32(0x0001fffe)),
9563                                           mkU8(0x1))));
9564                     /* Add higher halfs of rs and rt
9565                        and right shift the result by 1. */
9566                     assign(t2, binop(Iop_Add32,
9567                                      unop(Iop_16Sto32,
9568                                           unop(Iop_32HIto16, getIReg(rs))),
9569                                      unop(Iop_16Sto32,
9570                                           unop(Iop_32HIto16, getIReg(rt)))));
9571                     assign(t3, unop(Iop_32to16,
9572                                     binop(Iop_Shr32,
9573                                           binop(Iop_And32,
9574                                                 mkexpr(t2),
9575                                                 mkU32(0x0001fffe)),
9576                                           mkU8(0x1))));
9577                     putIReg(rd, binop(Iop_16HLto32, mkexpr(t3), mkexpr(t1)));
9578                     break;
9579                  }
9580                  case 0x9: {  /* SUBQH.PH */
9581                     DIP("subqh.ph r%d, r%d, r%d", rd, rs, rt);
9582                     vassert(!mode64);
9583
9584                     putIReg(rd, binop(Iop_HSub16Sx2,
9585                                       getIReg(rs), getIReg(rt)));
9586                     break;
9587                  }
9588                  case 0xA: {/* ADDQH_R.PH */
9589                     DIP("addqh_r.ph r%d, r%d, r%d", rd, rs, rt);
9590                     vassert(!mode64);
9591                     t0 = newTemp(Ity_I32);
9592                     t1 = newTemp(Ity_I16);
9593                     t2 = newTemp(Ity_I32);
9594                     t3 = newTemp(Ity_I16);
9595
9596                     /* Add lower halfs of rs and rt, add 1
9597                        and right shift the result by 1. */
9598                     assign(t0, binop(Iop_Add32,
9599                                      unop(Iop_16Sto32,
9600                                           unop(Iop_32to16, getIReg(rs))),
9601                                      unop(Iop_16Sto32,
9602                                           unop(Iop_32to16, getIReg(rt)))));
9603                     assign(t1, unop(Iop_32to16,
9604                                     binop(Iop_Shr32,
9605                                           binop(Iop_And32,
9606                                                 binop(Iop_Add32,
9607                                                       mkexpr(t0),
9608                                                       mkU32(0x1)),
9609                                                 mkU32(0x0001fffe)),
9610                                           mkU8(0x1))));
9611                     /* Add higher halfs of rs and rt, add 1
9612                        and right shift the result by 1. */
9613                     assign(t2, binop(Iop_Add32,
9614                                      unop(Iop_16Sto32,
9615                                           unop(Iop_32HIto16, getIReg(rs))),
9616                                      unop(Iop_16Sto32,
9617                                           unop(Iop_32HIto16, getIReg(rt)))));
9618                     assign(t3, unop(Iop_32to16,
9619                                     binop(Iop_Shr32,
9620                                           binop(Iop_And32,
9621                                                 binop(Iop_Add32,
9622                                                       mkexpr(t2),
9623                                                       mkU32(0x1)),
9624                                                 mkU32(0x0001fffe)),
9625                                           mkU8(0x1))));
9626
9627                     putIReg(rd, binop(Iop_16HLto32, mkexpr(t3), mkexpr(t1)));
9628                     break;
9629                  }
9630                  case 0xB: {  /* SUBQH_R.PH */
9631                     DIP("subqh_r.ph r%d, r%d, r%d", rd, rs, rt);
9632                     vassert(!mode64);
9633                     t0 = newTemp(Ity_I32);
9634                     t1 = newTemp(Ity_I16);
9635                     t2 = newTemp(Ity_I32);
9636                     t3 = newTemp(Ity_I16);
9637
9638                     /* Sub lower halfs of rs and rt, add 1
9639                        and right shift the result by 1. */
9640                     assign(t0, binop(Iop_Sub32,
9641                                      unop(Iop_16Sto32,
9642                                           unop(Iop_32to16, getIReg(rs))),
9643                                      unop(Iop_16Sto32,
9644                                           unop(Iop_32to16, getIReg(rt)))));
9645                     assign(t1, unop(Iop_32to16,
9646                                     binop(Iop_Shr32,
9647                                           binop(Iop_And32,
9648                                                 binop(Iop_Add32,
9649                                                       mkexpr(t0),
9650                                                       mkU32(0x1)),
9651                                                 mkU32(0x0001fffe)),
9652                                           mkU8(0x1))));
9653                     /* Sub higher halfs of rs and rt, add 1
9654                        and right shift the result by 1. */
9655                     assign(t2, binop(Iop_Sub32,
9656                                      unop(Iop_16Sto32,
9657                                           unop(Iop_32HIto16, getIReg(rs))),
9658                                      unop(Iop_16Sto32,
9659                                           unop(Iop_32HIto16, getIReg(rt)))));
9660                     assign(t3, unop(Iop_32to16,
9661                                     binop(Iop_Shr32,
9662                                           binop(Iop_And32,
9663                                                 binop(Iop_Add32,
9664                                                       mkexpr(t2),
9665                                                       mkU32(0x1)),
9666                                                 mkU32(0x0001fffe)),
9667                                           mkU8(0x1))));
9668
9669                     putIReg(rd, binop(Iop_16HLto32, mkexpr(t3), mkexpr(t1)));
9670                     break;
9671                  }
9672                  case 0xC: {  /* MUL.PH */
9673                     DIP("mul.ph r%d, r%d, r%d", rd, rs, rt);
9674                     vassert(!mode64);
9675                     t0 = newTemp(Ity_I32);
9676                     t1 = newTemp(Ity_I32);
9677                     t2 = newTemp(Ity_I32);
9678
9679                     assign(t0,
9680                            binop(Iop_Mul32,
9681                                  unop(Iop_16Sto32,
9682                                       unop(Iop_32HIto16, getIReg(rs))),
9683                                  unop(Iop_16Sto32,
9684                                       unop(Iop_32HIto16, getIReg(rt)))));
9685                     /* DSP Control flag. */
9686                     putDSPControl(IRExpr_ITE(unop(Iop_Not1,
9687                                                   binop(Iop_CmpLE32S,
9688                                                         mkexpr(t0),
9689                                                         mkU32(0x7FFF))),
9690                                              binop(Iop_Or32,
9691                                                    getDSPControl(),
9692                                                    mkU32(0x00200000)),
9693                                              IRExpr_ITE(binop(Iop_CmpLT32S,
9694                                                               mkexpr(t0),
9695                                                               mkU32(0xFFFF8000)
9696                                                             ),
9697                                                         binop(Iop_Or32,
9698                                                               getDSPControl(),
9699                                                               mkU32(0x00200000)
9700                                                              ),
9701                                                         getDSPControl())));
9702
9703                     assign(t1,
9704                            binop(Iop_Mul32,
9705                                  unop(Iop_16Sto32,
9706                                       unop(Iop_32to16, getIReg(rs))),
9707                                  unop(Iop_16Sto32,
9708                                       unop(Iop_32to16, getIReg(rt)))));
9709                     /* DSP Control flag. */
9710                     putDSPControl(IRExpr_ITE(unop(Iop_Not1,
9711                                                   binop(Iop_CmpLE32S,
9712                                                         mkexpr(t1),
9713                                                         mkU32(0x7FFF))),
9714                                              binop(Iop_Or32,
9715                                                    getDSPControl(),
9716                                                    mkU32(0x00200000)),
9717                                              IRExpr_ITE(binop(Iop_CmpLT32S,
9718                                                               mkexpr(t1),
9719                                                               mkU32(0xFFFF8000)
9720                                                              ),
9721                                                         binop(Iop_Or32,
9722                                                               getDSPControl(),
9723                                                               mkU32(0x00200000)
9724                                                              ),
9725                                                         getDSPControl())));
9726
9727                     assign(t2, binop(Iop_16HLto32,
9728                                      unop(Iop_32to16, mkexpr(t0)),
9729                                      unop(Iop_32to16, mkexpr(t1))));
9730                     putIReg(rd, mkexpr(t2));
9731                     break;
9732                  }
9733                  case 0xE: {  /* MUL_S.PH */
9734                     DIP("mul_s.ph r%d r%d, r%d", rd, rs, rt);
9735                     vassert(!mode64);
9736
9737                     t0 = newTemp(Ity_I32);
9738                     t1 = newTemp(Ity_I32);
9739                     t2 = newTemp(Ity_I32);
9740                     t3 = newTemp(Ity_I32);
9741                     t4 = newTemp(Ity_I32);
9742
9743                     /* t0 - signed intermediate result. */
9744                     assign(t0,
9745                           binop(Iop_Mul32,
9746                                 unop(Iop_16Sto32,
9747                                      unop(Iop_32HIto16, getIReg(rs))),
9748                                 unop(Iop_16Sto32,
9749                                      unop(Iop_32HIto16, getIReg(rt)))));
9750
9751                     assign(t1,
9752                            IRExpr_ITE(unop(Iop_Not1,
9753                                            binop(Iop_CmpLE32S,
9754                                                  mkexpr(t0),
9755                                                  mkU32(0x7FFF))),
9756                                       mkU32(0x00007FFF),
9757                                       IRExpr_ITE(binop(Iop_CmpLT32S,
9758                                                        mkexpr(t0),
9759                                                        mkU32(0xFFFF8000)),
9760                                                  mkU32(0xFFFF8000),
9761                                                  mkexpr(t0))));
9762
9763                     /* DSP Control flag. */
9764                     putDSPControl(IRExpr_ITE(unop(Iop_Not1,
9765                                                   binop(Iop_CmpLE32S,
9766                                                         mkexpr(t0),
9767                                                         mkU32(0x7FFF))),
9768                                              binop(Iop_Or32,
9769                                                    getDSPControl(),
9770                                                    mkU32(0x00200000)),
9771                                              IRExpr_ITE(binop(Iop_CmpLT32S,
9772                                                               mkexpr(t0),
9773                                                               mkU32(0xFFFF8000)
9774                                                              ),
9775                                                         binop(Iop_Or32,
9776                                                               getDSPControl(),
9777                                                               mkU32(0x00200000)
9778                                                              ),
9779                                                         getDSPControl())));
9780
9781                     /* t2 - signed intermediate result. */
9782                     assign(t2, binop(Iop_Mul32,
9783                                      unop(Iop_16Sto32,
9784                                           unop(Iop_32to16, getIReg(rs))),
9785                                      unop(Iop_16Sto32,
9786                                           unop(Iop_32to16, getIReg(rt)))));
9787
9788                     assign(t3, IRExpr_ITE(unop(Iop_Not1,
9789                                                binop(Iop_CmpLE32S,
9790                                                      mkexpr(t2),
9791                                                      mkU32(0x7FFF))),
9792                                           mkU32(0x00007FFF),
9793                                           IRExpr_ITE(binop(Iop_CmpLT32S,
9794                                                            mkexpr(t2),
9795                                                            mkU32(0xFFFF8000)),
9796                                                      mkU32(0xFFFF8000),
9797                                                      mkexpr(t2))));
9798
9799                     /* DSP Control flag. */
9800                     putDSPControl(IRExpr_ITE(unop(Iop_Not1,
9801                                                   binop(Iop_CmpLE32S,
9802                                                         mkexpr(t2),
9803                                                         mkU32(0x7FFF))),
9804                                              binop(Iop_Or32,
9805                                                    getDSPControl(),
9806                                                    mkU32(0x00200000)),
9807                                              IRExpr_ITE(binop(Iop_CmpLT32S,
9808                                                               mkexpr(t2),
9809                                                               mkU32(0xFFFF8000)
9810                                                              ),
9811                                                         binop(Iop_Or32,
9812                                                               getDSPControl(),
9813                                                               mkU32(0x00200000)
9814                                                              ),
9815                                                         getDSPControl())));
9816
9817                     assign(t4, binop(Iop_16HLto32,
9818                                      unop(Iop_32to16, mkexpr(t1)),
9819                                      unop(Iop_32to16, mkexpr(t3))));
9820                     putIReg(rd, mkexpr(t4));
9821                     break;
9822                  }
9823                  case 0x10: {  /* ADDQH.W */
9824                     DIP("addqh.w r%d, r%d, r%d", rd, rs, rt);
9825                     vassert(!mode64);
9826                     t0 = newTemp(Ity_I64);
9827                     t1 = newTemp(Ity_I64);
9828
9829                     assign(t0, binop(Iop_Add64,
9830                                      unop(Iop_32Sto64, getIReg(rs)),
9831                                      unop(Iop_32Sto64, getIReg(rt))));
9832                     assign(t1, binop(Iop_And64,
9833                                      mkexpr(t0),
9834                                      mkU64(0x00000001fffffffeULL)));
9835                     putIReg(rd, unop(Iop_64to32,
9836                                      binop(Iop_Shr64, mkexpr(t1), mkU8(0x1))));
9837                     break;
9838                  }
9839                  case 0x11: {  /* SUBQH.W */
9840                     DIP("subqh.w r%d, r%d, r%d", rd, rs, rt);
9841                     vassert(!mode64);
9842                     t0 = newTemp(Ity_I64);
9843                     t1 = newTemp(Ity_I64);
9844
9845                     assign(t0, binop(Iop_Sub64,
9846                                      unop(Iop_32Sto64, getIReg(rs)),
9847                                      unop(Iop_32Sto64, getIReg(rt))));
9848                     assign(t1, binop(Iop_And64,
9849                                      mkexpr(t0),
9850                                      mkU64(0x00000001fffffffeULL)));
9851                     putIReg(rd, unop(Iop_64to32,
9852                                      binop(Iop_Shr64, mkexpr(t1), mkU8(0x1))));
9853                     break;
9854                  }
9855                  case 0x12: {  /* ADDQH_R.W */
9856                     DIP("addqh_r.w r%d, r%d, r%d", rd, rs, rt);
9857                     vassert(!mode64);
9858                     t0 = newTemp(Ity_I64);
9859                     t1 = newTemp(Ity_I64);
9860                     t2 = newTemp(Ity_I64);
9861
9862                     assign(t0, binop(Iop_Add64,
9863                                      unop(Iop_32Sto64, getIReg(rs)),
9864                                      unop(Iop_32Sto64, getIReg(rt))));
9865                     assign(t1, binop(Iop_Add64,
9866                                      mkexpr(t0),
9867                                      mkU64(0x0000000000000001ULL)));
9868                     assign(t2, binop(Iop_And64,
9869                                      mkexpr(t1),
9870                                      mkU64(0x00000001fffffffeULL)));
9871                     putIReg(rd, unop(Iop_64to32,
9872                                      binop(Iop_Shr64, mkexpr(t2), mkU8(0x1))));
9873                     break;
9874                  }
9875                  case 0x13: {  /* SUBQH_R.W */
9876                     DIP("subqh_r.w r%d, r%d, r%d", rd, rs, rt);
9877                     vassert(!mode64);
9878                     t0 = newTemp(Ity_I64);
9879                     t1 = newTemp(Ity_I64);
9880                     t2 = newTemp(Ity_I64);
9881
9882                     assign(t0, binop(Iop_Sub64,
9883                                      unop(Iop_32Sto64, getIReg(rs)),
9884                                      unop(Iop_32Sto64, getIReg(rt))));
9885                     assign(t1, binop(Iop_Add64,
9886                                      mkexpr(t0),
9887                                      mkU64(0x0000000000000001ULL)));
9888                     assign(t2, binop(Iop_And64,
9889                                      mkexpr(t1),
9890                                      mkU64(0x00000001fffffffeULL)));
9891                     putIReg(rd, unop(Iop_64to32,
9892                                      binop(Iop_Shr64, mkexpr(t2), mkU8(0x1))));
9893                     break;
9894                  }
9895                  case 0x16: {  /* MULQ_S.W */
9896                     DIP("mulq_s.w r%d, r%d, r%d", rd, rs, rt);
9897                     vassert(!mode64);
9898                     t0 = newTemp(Ity_I64);
9899                     t1 = newTemp(Ity_I1);
9900                     t2 = newTemp(Ity_I1);
9901
9902                     assign(t0, binop(Iop_Shl64,
9903                                      binop(Iop_MullS32,
9904                                            getIReg(rt), getIReg(rs)),
9905                                      mkU8(0x1)));
9906                     assign(t1, binop(Iop_CmpEQ32,
9907                                      getIReg(rt), mkU32(0x80000000)));
9908                     assign(t2, binop(Iop_CmpEQ32,
9909                                      getIReg(rs), mkU32(0x80000000)));
9910
9911                     putDSPControl(IRExpr_ITE(mkexpr(t1),
9912                                              IRExpr_ITE(mkexpr(t2),
9913                                                         binop(Iop_Or32,
9914                                                               getDSPControl(),
9915                                                               mkU32(0x00200000)
9916                                                              ),
9917                                                         getDSPControl()),
9918                                              getDSPControl()));
9919                     putIReg(rd, IRExpr_ITE(mkexpr(t1),
9920                                            IRExpr_ITE(mkexpr(t2),
9921                                                       mkU32(0x7fffffff),
9922                                                       unop(Iop_64HIto32,
9923                                                            mkexpr(t0))),
9924                                            unop(Iop_64HIto32, mkexpr(t0))));
9925                     break;
9926                  }
9927                  case 0x17: {  /* MULQ_RS.W */
9928                     DIP("mulq_rs.w r%d, r%d, r%d", rd, rs, rt);
9929                     vassert(!mode64);
9930                     t0 = newTemp(Ity_I64);
9931                     t1 = newTemp(Ity_I1);
9932                     t2 = newTemp(Ity_I1);
9933
9934                     assign(t0, binop(Iop_Add64,
9935                                      binop(Iop_Shl64,
9936                                            binop(Iop_MullS32,
9937                                                  getIReg(rt),
9938                                                  getIReg(rs)),
9939                                            mkU8(0x1)),
9940                                      mkU64(0x0000000080000000ULL)));
9941                     assign(t1,
9942                            binop(Iop_CmpEQ32, getIReg(rt), mkU32(0x80000000)));
9943                     assign(t2,
9944                            binop(Iop_CmpEQ32, getIReg(rs), mkU32(0x80000000)));
9945                     putDSPControl(IRExpr_ITE(mkexpr(t1),
9946                                              IRExpr_ITE(mkexpr(t2),
9947                                                         binop(Iop_Or32,
9948                                                               getDSPControl(),
9949                                                               mkU32(0x00200000)
9950                                                              ),
9951                                                         getDSPControl()),
9952                                              getDSPControl()));
9953                     putIReg(rd, IRExpr_ITE(mkexpr(t1),
9954                                            IRExpr_ITE(mkexpr(t2),
9955                                                       mkU32(0x7fffffff),
9956                                                       unop(Iop_64HIto32,
9957                                                            mkexpr(t0))),
9958                                            unop(Iop_64HIto32, mkexpr(t0))));
9959                     break;
9960                  }
9961                  default:
9962                     return -1;
9963               }
9964               break;  /* end of ADDUH.QB/MUL.PH */
9965            }
9966            case 0x30: {  /* DPAQ.W.PH */
9967               switch(sa) {
9968                  case 0x0: {  /* DPA.W.PH */
9969                     DIP("dpa.w.ph ac%d, r%d, r%d", ac, rs, rt);
9970                     vassert(!mode64);
9971
9972                     t0 = newTemp(Ity_I64);
9973                     t1 = newTemp(Ity_I64);
9974                     t2 = newTemp(Ity_I64);
9975
9976                     assign(t0,
9977                            unop(Iop_32Sto64,
9978                                 binop(Iop_Mul32,
9979                                       unop(Iop_16Sto32,
9980                                            unop(Iop_32HIto16, getIReg(rs))),
9981                                       unop(Iop_16Sto32,
9982                                            unop(Iop_32HIto16, getIReg(rt))))));
9983                     assign(t1,
9984                            unop(Iop_32Sto64,
9985                                 binop(Iop_Mul32,
9986                                       unop(Iop_16Sto32,
9987                                            unop(Iop_32to16, getIReg(rs))),
9988                                       unop(Iop_16Sto32,
9989                                            unop(Iop_32to16, getIReg(rt))))));
9990                     assign(t2,
9991                            binop(Iop_Add64,
9992                                  getAcc(ac),
9993                                  binop(Iop_Add64, mkexpr(t0), mkexpr(t1))));
9994                     putAcc(ac, mkexpr(t2));
9995                     break;
9996                  }
9997                  case 0x1: {  /* DPS.W.PH */
9998                     DIP("dps.w.ph ac%d, r%d, r%d", ac, rs, rt);
9999                     vassert(!mode64);
10000
10001                     t0 = newTemp(Ity_I64);
10002                     t1 = newTemp(Ity_I64);
10003                     t2 = newTemp(Ity_I64);
10004
10005                     assign(t0,
10006                            unop(Iop_32Sto64,
10007                                 binop(Iop_Mul32,
10008                                       unop(Iop_16Sto32,
10009                                            unop(Iop_32HIto16, getIReg(rs))),
10010                                       unop(Iop_16Sto32,
10011                                            unop(Iop_32HIto16, getIReg(rt))))));
10012                     assign(t1,
10013                            unop(Iop_32Sto64,
10014                                 binop(Iop_Mul32,
10015                                       unop(Iop_16Sto32,
10016                                            unop(Iop_32to16, getIReg(rs))),
10017                                       unop(Iop_16Sto32,
10018                                            unop(Iop_32to16, getIReg(rt))))));
10019                     assign(t2,
10020                            binop(Iop_Sub64,
10021                                  getAcc(ac),
10022                                  binop(Iop_Add64, mkexpr(t0), mkexpr(t1))));
10023                     putAcc(ac, mkexpr(t2));
10024                     break;
10025                  }
10026                  case 0x2: {  /* MULSA.W.PH */
10027                     DIP("mulsa.w.ph ac%d, r%d, r%d", ac, rs, rt);
10028                     vassert(!mode64);
10029                     t0 = newTemp(Ity_I32);
10030                     t1 = newTemp(Ity_I32);
10031                     t2 = newTemp(Ity_I32);
10032                     t3 = newTemp(Ity_I1);
10033                     t4 = newTemp(Ity_I64);
10034
10035                     assign(t4, getAcc(ac));
10036                     assign(t0, binop(Iop_Mul32,
10037                                      unop(Iop_16Sto32,
10038                                           unop(Iop_32to16, getIReg(rt))),
10039                                      unop(Iop_16Sto32,
10040                                           unop(Iop_32to16, getIReg(rs)))));
10041                     assign(t1, binop(Iop_Mul32,
10042                                      unop(Iop_16Sto32,
10043                                           unop(Iop_32HIto16, getIReg(rt))),
10044                                      unop(Iop_16Sto32,
10045                                           unop(Iop_32HIto16, getIReg(rs)))));
10046                     assign(t2, binop(Iop_Sub32, mkexpr(t1), mkexpr(t0)));
10047                     putAcc(ac, binop(Iop_Add64,
10048                                      mkexpr(t4),
10049                                      unop(Iop_32Sto64, mkexpr(t2))));
10050                     break;
10051                  }
10052                  case 0x3: {  /* DPAU.H.QBL */
10053                     DIP("dpau.h.qbl ac%d, r%d, r%d", ac, rs, rt);
10054                     vassert(!mode64);
10055                     t0 = newTemp(Ity_I32);
10056                     t1 = newTemp(Ity_I32);
10057                     t2 = newTemp(Ity_I64);
10058                     t3 = newTemp(Ity_I64);
10059
10060                     assign(t0,
10061                            binop(Iop_Mul32,
10062                                  unop(Iop_8Uto32,
10063                                       unop(Iop_16HIto8,
10064                                            unop(Iop_32HIto16, getIReg(rs)))),
10065                                  unop(Iop_8Uto32,
10066                                       unop(Iop_16HIto8,
10067                                            unop(Iop_32HIto16, getIReg(rt))))));
10068                     assign(t1,
10069                            binop(Iop_Mul32,
10070                                  unop(Iop_8Uto32,
10071                                       unop(Iop_16to8,
10072                                            unop(Iop_32HIto16, getIReg(rs)))),
10073                                  unop(Iop_8Uto32,
10074                                       unop(Iop_16to8,
10075                                            unop(Iop_32HIto16, getIReg(rt))))));
10076                     assign(t2,
10077                            unop(Iop_32Uto64,
10078                                 binop(Iop_Add32,
10079                                       mkexpr(t0),
10080                                       mkexpr(t1))));
10081                     assign(t3,
10082                            binop(Iop_Add64, getAcc(ac), mkexpr(t2)));
10083                     putAcc(ac, mkexpr(t3));
10084                     break;
10085                  }
10086                  case 0x4: {  /* DPAQ_S.W.PH */
10087                     DIP("dpaq_s.w.ph ac%d, r%d, r%d", ac, rs, rt);
10088                     vassert(!mode64);
10089                     t0 = newTemp(Ity_I64);
10090                     t1 = newTemp(Ity_I64);
10091                     t2 = newTemp(Ity_I1);
10092                     t3 = newTemp(Ity_I1);
10093                     t4 = newTemp(Ity_I64);
10094                     t5 = newTemp(Ity_I64);
10095                     t6 = newTemp(Ity_I1);
10096                     t7 = newTemp(Ity_I1);
10097                     t8 = newTemp(Ity_I64);
10098                     t9 = newTemp(Ity_I64);
10099
10100                     assign(t0, getAcc(ac));
10101
10102                     assign(t1, binop(Iop_Shl64,
10103                                      binop(Iop_MullS32,
10104                                            unop(Iop_16Sto32,
10105                                                 unop(Iop_32HIto16,
10106                                                      getIReg(rs))),
10107                                            unop(Iop_16Sto32,
10108                                                 unop(Iop_32HIto16,
10109                                                      getIReg(rt)))),
10110                                      mkU8(0x1)));
10111                     assign(t2, binop(Iop_CmpEQ32,
10112                                      unop(Iop_16Uto32,
10113                                           unop(Iop_32HIto16, getIReg(rs))),
10114                                      mkU32(0x00008000)));
10115                     assign(t3, binop(Iop_CmpEQ32,
10116                                      unop(Iop_16Uto32,
10117                                           unop(Iop_32HIto16, getIReg(rt))),
10118                                      mkU32(0x00008000)));
10119                     assign(t4,
10120                            IRExpr_ITE(mkexpr(t2),
10121                                       IRExpr_ITE(mkexpr(t3),
10122                                                  mkU64(0x000000007fffffffULL),
10123                                                  mkexpr(t1)),
10124                                       mkexpr(t1)));
10125
10126                     putDSPControl(IRExpr_ITE(mkexpr(t2),
10127                                              IRExpr_ITE(mkexpr(t3),
10128                                                         binop(Iop_Or32,
10129                                                               getDSPControl(),
10130                                                               binop(Iop_Shl32,
10131                                                                     mkU32(0x1),
10132                                                                     mkU8(ac+16)
10133                                                                    )
10134                                                              ),
10135                                                         getDSPControl()),
10136                                              getDSPControl()));
10137
10138                     assign(t5, binop(Iop_Shl64,
10139                                      binop(Iop_MullS32,
10140                                            unop(Iop_16Sto32,
10141                                                 unop(Iop_32to16, getIReg(rs))),
10142                                            unop(Iop_16Sto32,
10143                                                 unop(Iop_32to16, getIReg(rt)))
10144                                           ),
10145                                      mkU8(0x1)));
10146                     assign(t6, binop(Iop_CmpEQ32,
10147                                      unop(Iop_16Uto32,
10148                                           unop(Iop_32to16, getIReg(rs))),
10149                                      mkU32(0x00008000)));
10150                     assign(t7, binop(Iop_CmpEQ32,
10151                                      unop(Iop_16Uto32,
10152                                           unop(Iop_32to16, getIReg(rt))),
10153                                      mkU32(0x00008000)));
10154                     assign(t8,
10155                            IRExpr_ITE(mkexpr(t6),
10156                                       IRExpr_ITE(mkexpr(t7),
10157                                                  mkU64(0x000000007fffffffULL),
10158                                                  mkexpr(t5)),
10159                                       mkexpr(t5)));
10160
10161                     putDSPControl(IRExpr_ITE(mkexpr(t6),
10162                                              IRExpr_ITE(mkexpr(t7),
10163                                                         binop(Iop_Or32,
10164                                                               getDSPControl(),
10165                                                               binop(Iop_Shl32,
10166                                                                     mkU32(0x1),
10167                                                                     mkU8(ac+16)
10168                                                                    )
10169                                                              ),
10170                                                         getDSPControl()),
10171                                              getDSPControl()));
10172
10173                     assign(t9, binop(Iop_Add64,
10174                                      binop(Iop_Add64, mkexpr(t4), mkexpr(t8)),
10175                                      mkexpr(t0)));
10176                     putAcc(ac, mkexpr(t9));
10177                     break;
10178                  }
10179                  case 0x5: {  /* DPSQ_S.W.PH */
10180                     DIP("dpsq_s.w.ph ac%d r%d, r%d", ac, rs, rt);
10181                     vassert(!mode64);
10182                     t0 = newTemp(Ity_I64);
10183                     t1 = newTemp(Ity_I64);
10184                     t2 = newTemp(Ity_I1);
10185                     t3 = newTemp(Ity_I1);
10186                     t4 = newTemp(Ity_I64);
10187                     t5 = newTemp(Ity_I64);
10188                     t6 = newTemp(Ity_I1);
10189                     t7 = newTemp(Ity_I1);
10190                     t8 = newTemp(Ity_I64);
10191                     t9 = newTemp(Ity_I64);
10192
10193                     assign(t0, getAcc(ac));
10194
10195                     assign(t1, binop(Iop_Shl64,
10196                                      binop(Iop_MullS32,
10197                                            unop(Iop_16Sto32,
10198                                                 unop(Iop_32HIto16,
10199                                                      getIReg(rs))),
10200                                            unop(Iop_16Sto32,
10201                                                 unop(Iop_32HIto16,
10202                                                      getIReg(rt)))),
10203                                      mkU8(0x1)));
10204                     assign(t2, binop(Iop_CmpEQ32,
10205                                      unop(Iop_16Uto32,
10206                                           unop(Iop_32HIto16, getIReg(rs))),
10207                                      mkU32(0x00008000)));
10208                     assign(t3, binop(Iop_CmpEQ32,
10209                                      unop(Iop_16Uto32,
10210                                           unop(Iop_32HIto16, getIReg(rt))),
10211                                      mkU32(0x00008000)));
10212                     assign(t4,
10213                            IRExpr_ITE(mkexpr(t2),
10214                                       IRExpr_ITE(mkexpr(t3),
10215                                                  mkU64(0x000000007fffffffULL),
10216                                                  mkexpr(t1)),
10217                                       mkexpr(t1)));
10218
10219                     putDSPControl(IRExpr_ITE(mkexpr(t2),
10220                                              IRExpr_ITE(mkexpr(t3),
10221                                                         binop(Iop_Or32,
10222                                                               getDSPControl(),
10223                                                               binop(Iop_Shl32,
10224                                                                     mkU32(0x1),
10225                                                                     mkU8(ac+16)
10226                                                                    )
10227                                                              ),
10228                                                         getDSPControl()),
10229                                              getDSPControl()));
10230
10231                     assign(t5,
10232                            binop(Iop_Shl64,
10233                                  binop(Iop_MullS32,
10234                                        unop(Iop_16Sto32,
10235                                             unop(Iop_32to16, getIReg(rs))),
10236                                        unop(Iop_16Sto32,
10237                                             unop(Iop_32to16, getIReg(rt)))),
10238                                  mkU8(0x1)));
10239                     assign(t6, binop(Iop_CmpEQ32,
10240                                      unop(Iop_16Uto32,
10241                                           unop(Iop_32to16, getIReg(rs))),
10242                                      mkU32(0x00008000)));
10243                     assign(t7, binop(Iop_CmpEQ32,
10244                                      unop(Iop_16Uto32,
10245                                           unop(Iop_32to16, getIReg(rt))),
10246                                      mkU32(0x00008000)));
10247                     assign(t8,
10248                            IRExpr_ITE(mkexpr(t6),
10249                                       IRExpr_ITE(mkexpr(t7),
10250                                                  mkU64(0x000000007fffffffULL),
10251                                                  mkexpr(t5)),
10252                                       mkexpr(t5)));
10253
10254                     putDSPControl(IRExpr_ITE(mkexpr(t6),
10255                                              IRExpr_ITE(mkexpr(t7),
10256                                                         binop(Iop_Or32,
10257                                                               getDSPControl(),
10258                                                               binop(Iop_Shl32,
10259                                                                     mkU32(0x1),
10260                                                                     mkU8(ac+16)
10261                                                                    )
10262                                                              ),
10263                                                         getDSPControl()),
10264                                              getDSPControl()));
10265
10266                     assign(t9,
10267                            binop(Iop_Sub64,
10268                                  mkexpr(t0),
10269                                  binop(Iop_Add64, mkexpr(t4), mkexpr(t8))));
10270                     putAcc(ac, mkexpr(t9));
10271                     break;
10272                  }
10273                  case 0x6: {  /* MULSAQ_S.W.PH */
10274                     DIP("mulsaq_s.w.ph ac%d r%d, r%d", ac, rs, rt);
10275                     vassert(!mode64);
10276
10277                     t0 = newTemp(Ity_I32);
10278                     t1 = newTemp(Ity_I32);
10279                     t2 = newTemp(Ity_I32);
10280                     t3 = newTemp(Ity_I32);
10281                     t4 = newTemp(Ity_I32);
10282                     t5 = newTemp(Ity_I32);
10283                     t6 = newTemp(Ity_I64);
10284                     t7 = newTemp(Ity_I64);
10285                     t8 = newTemp(Ity_I32);
10286                     t9 = newTemp(Ity_I32);
10287
10288                     assign(t0, unop(Iop_16Sto32,
10289                                     unop(Iop_32HIto16, getIReg(rs))));
10290                     assign(t1, unop(Iop_16Sto32,
10291                                     unop(Iop_32HIto16, getIReg(rt))));
10292
10293                     assign(t8, binop(Iop_And32,
10294                                      unop(Iop_1Sto32,
10295                                           binop(Iop_CmpEQ32,
10296                                                 unop(Iop_16Uto32,
10297                                                      unop(Iop_32HIto16,
10298                                                           getIReg(rs))),
10299                                                 mkU32(0x8000))),
10300                                    unop(Iop_1Sto32,
10301                                         binop(Iop_CmpEQ32,
10302                                               unop(Iop_16Uto32,
10303                                                    unop(Iop_32HIto16,
10304                                                         getIReg(rt))),
10305                                               mkU32(0x8000)))));
10306                     /* DSPControl_outflag:16+acc <- 1 */
10307                     putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32,
10308                                                    mkexpr(t8),
10309                                                    mkU32(0x0)),
10310                                              binop(Iop_Or32,
10311                                                    getDSPControl(),
10312                                                    binop(Iop_Shl32,
10313                                                          mkU32(0x00010000),
10314                                                          mkU8(ac))),
10315                                              getDSPControl()));
10316
10317                     /* tempB_31..0 */
10318                     assign(t2,
10319                            IRExpr_ITE(binop(Iop_CmpNE32,
10320                                             mkexpr(t8), mkU32(0x0)),
10321                                       mkU32(0x7FFFFFFF),
10322                                       binop(Iop_Shl32,
10323                                             binop(Iop_Mul32,
10324                                                   mkexpr(t0), mkexpr(t1)),
10325                                             mkU8(1))));
10326
10327                     assign(t3, unop(Iop_16Sto32,
10328                                     unop(Iop_32to16, getIReg(rs))));
10329                     assign(t4, unop(Iop_16Sto32,
10330                                     unop(Iop_32to16, getIReg(rt))));
10331
10332                     assign(t9, binop(Iop_And32,
10333                                      unop(Iop_1Sto32,
10334                                           binop(Iop_CmpEQ32,
10335                                                 unop(Iop_16Uto32,
10336                                                      unop(Iop_32to16,
10337                                                           getIReg(rs))),
10338                                                 mkU32(0x8000))),
10339                                      unop(Iop_1Sto32,
10340                                           binop(Iop_CmpEQ32,
10341                                                 unop(Iop_16Uto32,
10342                                                      unop(Iop_32to16,
10343                                                           getIReg(rt))),
10344                                                 mkU32(0x8000)))));
10345                     /* DSPControl_outflag:16+acc <- 1 */
10346                     putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32,
10347                                                    mkexpr(t9),
10348                                                    mkU32(0x0)),
10349                                              binop(Iop_Or32,
10350                                                    getDSPControl(),
10351                                                    binop(Iop_Shl32,
10352                                                          mkU32(0x00010000),
10353                                                          mkU8(ac))),
10354                                              getDSPControl()));
10355                     /* tempA_31..0 */
10356                     assign(t5,
10357                            IRExpr_ITE(binop(Iop_CmpNE32,
10358                                             mkexpr(t9),
10359                                             mkU32(0x0)),
10360                                       mkU32(0x7FFFFFFF),
10361                                       binop(Iop_Shl32,
10362                                             binop(Iop_Mul32,
10363                                                   mkexpr(t3),
10364                                                   mkexpr(t4)),
10365                                             mkU8(1))));
10366                     /* dotp_63..0 */
10367                     assign(t6,
10368                            binop(Iop_Sub64,
10369                                  unop(Iop_32Sto64, mkexpr(t2)),
10370                                  unop(Iop_32Sto64, mkexpr(t5))));
10371                     /* tempC_63..0 */
10372                     assign(t7, binop(Iop_Add64, getAcc(ac), mkexpr(t6)));
10373
10374                     putAcc(ac, mkexpr(t7));
10375                     break;
10376                  }
10377                  case 0x7: {  /* DPAU.H.QBR */
10378                     DIP("dpau.h.qbr ac%d, r%d, r%d", ac, rs, rt);
10379                     vassert(!mode64);
10380                     t0 = newTemp(Ity_I32);
10381                     t1 = newTemp(Ity_I32);
10382                     t2 = newTemp(Ity_I64);
10383                     t3 = newTemp(Ity_I64);
10384
10385                     assign(t0,
10386                            binop(Iop_Mul32,
10387                                  unop(Iop_8Uto32,
10388                                       unop(Iop_16HIto8,
10389                                            unop(Iop_32to16, getIReg(rs)))),
10390                                  unop(Iop_8Uto32,
10391                                       unop(Iop_16HIto8,
10392                                            unop(Iop_32to16, getIReg(rt))))));
10393                     assign(t1,
10394                            binop(Iop_Mul32,
10395                                  unop(Iop_8Uto32,
10396                                       unop(Iop_16to8,
10397                                            unop(Iop_32to16, getIReg(rs)))),
10398                                  unop(Iop_8Uto32,
10399                                       unop(Iop_16to8,
10400                                            unop(Iop_32to16, getIReg(rt))))));
10401                     assign(t2, unop(Iop_32Uto64,
10402                                     binop(Iop_Add32, mkexpr(t0), mkexpr(t1))));
10403                     assign(t3, binop(Iop_Add64, getAcc(ac), mkexpr(t2)));
10404                     putAcc(ac, mkexpr(t3));
10405                     break;
10406                  }
10407                  case 0x8: {  /* DPAX.W.PH */
10408                     DIP("dpax.w.ph ac%d, r%d, r%d", ac, rs, rt);
10409                     vassert(!mode64);
10410                     t0 = newTemp(Ity_I64);
10411                     t1 = newTemp(Ity_I64);
10412                     t2 = newTemp(Ity_I64);
10413
10414                     assign(t0,
10415                            unop(Iop_32Sto64,
10416                                 binop(Iop_Mul32,
10417                                       unop(Iop_16Sto32,
10418                                            unop(Iop_32HIto16, getIReg(rs))),
10419                                       unop(Iop_16Sto32,
10420                                            unop(Iop_32to16, getIReg(rt))))));
10421                     assign(t1,
10422                            unop(Iop_32Sto64,
10423                                 binop(Iop_Mul32,
10424                                       unop(Iop_16Sto32,
10425                                            unop(Iop_32to16, getIReg(rs))),
10426                                       unop(Iop_16Sto32,
10427                                            unop(Iop_32HIto16, getIReg(rt))))));
10428                     assign(t2,
10429                            binop(Iop_Add64,
10430                                  getAcc(ac),
10431                                  binop(Iop_Add64, mkexpr(t0), mkexpr(t1))));
10432                     putAcc(ac, mkexpr(t2));
10433                     break;
10434                  }
10435                  case 0x9: {  /* DPSX.W.PH */
10436                     DIP("dpsx.w.ph ac%d r%d, r%d", ac, rs, rt);
10437                     vassert(!mode64);
10438
10439                     t0 = newTemp(Ity_I64);
10440                     t1 = newTemp(Ity_I64);
10441                     t2 = newTemp(Ity_I64);
10442
10443                     assign(t0,
10444                            unop(Iop_32Sto64,
10445                                 binop(Iop_Mul32,
10446                                       unop(Iop_16Sto32,
10447                                            unop(Iop_32HIto16, getIReg(rs))),
10448                                       unop(Iop_16Sto32,
10449                                            unop(Iop_32to16, getIReg(rt))))));
10450                     assign(t1,
10451                            unop(Iop_32Sto64,
10452                                 binop(Iop_Mul32,
10453                                       unop(Iop_16Sto32,
10454                                            unop(Iop_32to16, getIReg(rs))),
10455                                       unop(Iop_16Sto32,
10456                                            unop(Iop_32HIto16, getIReg(rt))))));
10457                     assign(t2,
10458                            binop(Iop_Sub64,
10459                                  getAcc(ac),
10460                                  binop(Iop_Add64, mkexpr(t0), mkexpr(t1))));
10461                     putAcc(ac, mkexpr(t2));
10462                     break;
10463                  }
10464                  case 0xB: {  /* DPSU.H.QBL */
10465                     DIP("dpsu.h.qbl ac%d, r%d, r%d", ac, rs, rt);
10466                     vassert(!mode64);
10467
10468                     t0 = newTemp(Ity_I32);
10469                     t1 = newTemp(Ity_I32);
10470                     t2 = newTemp(Ity_I64);
10471                     t3 = newTemp(Ity_I64);
10472
10473                     assign(t0,
10474                            binop(Iop_Mul32,
10475                                  unop(Iop_8Uto32,
10476                                       unop(Iop_16HIto8,
10477                                            unop(Iop_32HIto16, getIReg(rs)))),
10478                                  unop(Iop_8Uto32,
10479                                       unop(Iop_16HIto8,
10480                                            unop(Iop_32HIto16, getIReg(rt))))));
10481                     assign(t1,
10482                            binop(Iop_Mul32,
10483                                  unop(Iop_8Uto32,
10484                                       unop(Iop_16to8,
10485                                            unop(Iop_32HIto16, getIReg(rs)))),
10486                                  unop(Iop_8Uto32,
10487                                       unop(Iop_16to8,
10488                                            unop(Iop_32HIto16, getIReg(rt))))));
10489                     assign(t2,
10490                            unop(Iop_32Uto64,
10491                                 binop(Iop_Add32, mkexpr(t0), mkexpr(t1))));
10492                     assign(t3,
10493                            binop(Iop_Sub64, getAcc(ac), mkexpr(t2)));
10494                     putAcc(ac, mkexpr(t3));
10495                     break;
10496                  }
10497                  case 0xC: {  /* DPAQ_SA.L.W */
10498                     DIP("dpaq_sa.l.w ac%d, r%d, r%d", ac, rs, rt);
10499                     vassert(!mode64);
10500                     t0 = newTemp(Ity_I64);
10501                     t1 = newTemp(Ity_I64);
10502                     t2 = newTemp(Ity_I1);
10503                     t3 = newTemp(Ity_I1);
10504                     t4 = newTemp(Ity_I64);
10505                     t5 = newTemp(Ity_I64);
10506                     t6 = newTemp(Ity_I64);
10507                     t7 = newTemp(Ity_I64);
10508                     t8 = newTemp(Ity_I1);
10509                     t9 = newTemp(Ity_I1);
10510
10511                     assign(t0, getAcc(ac));
10512
10513                     assign(t1, binop(Iop_Shl64,
10514                                      binop(Iop_MullS32,
10515                                            getIReg(rs), getIReg(rt)),
10516                                      mkU8(0x1)));
10517
10518                     assign(t2, binop(Iop_CmpEQ32,
10519                                      getIReg(rs),
10520                                      mkU32(0x80000000)));
10521                     assign(t3, binop(Iop_CmpEQ32,
10522                                      getIReg(rt),
10523                                      mkU32(0x80000000)));
10524
10525                     assign(t4,
10526                            IRExpr_ITE(mkexpr(t2),
10527                                       IRExpr_ITE(mkexpr(t3),
10528                                                  mkU64(0x7fffffffffffffffULL),
10529                                                  mkexpr(t1)),
10530                                       mkexpr(t1)));
10531
10532                     putDSPControl(IRExpr_ITE(mkexpr(t2),
10533                                              IRExpr_ITE(mkexpr(t3),
10534                                                         binop(Iop_Or32,
10535                                                               getDSPControl(),
10536                                                               binop(Iop_Shl32,
10537                                                                     mkU32(0x1),
10538                                                                     mkU8(ac+16)
10539                                                                    )
10540                                                              ),
10541                                                         getDSPControl()),
10542                                              getDSPControl()));
10543
10544                     assign(t5, binop(Iop_Add64,
10545                                      unop(Iop_32Uto64,
10546                                           unop(Iop_64to32, mkexpr(t0))),
10547                                      unop(Iop_32Uto64,
10548                                           unop(Iop_64to32, mkexpr(t4)))));
10549                     assign(t6,
10550                            binop(Iop_Add64,
10551                                  binop(Iop_Add64,
10552                                        unop(Iop_32Sto64,
10553                                             unop(Iop_64HIto32, mkexpr(t0))),
10554                                        unop(Iop_32Sto64,
10555                                             unop(Iop_64HIto32, mkexpr(t4)))),
10556                                  unop(Iop_32Uto64,
10557                                       binop(Iop_And32,
10558                                             unop(Iop_64HIto32, mkexpr(t5)),
10559                                             mkU32(0x1)))));
10560                     assign(t7, binop(Iop_32HLto64,
10561                                      unop(Iop_64to32, mkexpr(t6)),
10562                                      unop(Iop_64to32, mkexpr(t5))));
10563                     assign(t8, binop(Iop_CmpEQ32,
10564                                      binop(Iop_Shr32,
10565                                            binop(Iop_And32,
10566                                                  unop(Iop_64to32, mkexpr(t6)),
10567                                                  mkU32(0x80000000)),
10568                                            mkU8(31)),
10569                                      binop(Iop_And32,
10570                                            unop(Iop_64HIto32, mkexpr(t6)),
10571                                            mkU32(0x00000001))));
10572                     assign(t9, binop(Iop_CmpEQ32,
10573                                      binop(Iop_And32,
10574                                            unop(Iop_64HIto32,
10575                                                 mkexpr(t6)),
10576                                            mkU32(0x00000001)),
10577                                      mkU32(0x1)));
10578                     putDSPControl(IRExpr_ITE(mkexpr(t8),
10579                                              getDSPControl(),
10580                                              binop(Iop_Or32,
10581                                                    getDSPControl(),
10582                                                    binop(Iop_Shl32,
10583                                                          mkU32(0x1),
10584                                                          mkU8(ac+16)))));
10585                     putAcc(ac,
10586                            IRExpr_ITE(mkexpr(t8),
10587                                       mkexpr(t7),
10588                                       IRExpr_ITE(mkexpr(t9),
10589                                                  mkU64(0x8000000000000000ULL),
10590                                                  mkU64(0x7fffffffffffffffULL)))
10591                           );
10592                     break;
10593                  }
10594                  case 0xD: {  /* DPSQ_SA.L.W */
10595                     DIP("dpsq_sa.l.w ac%d, r%d, r%d", ac, rs, rt);
10596                     vassert(!mode64);
10597                     t0 = newTemp(Ity_I64);
10598                     t1 = newTemp(Ity_I64);
10599                     t2 = newTemp(Ity_I1);
10600                     t3 = newTemp(Ity_I1);
10601                     t4 = newTemp(Ity_I64);
10602                     t5 = newTemp(Ity_I64);
10603                     t6 = newTemp(Ity_I64);
10604                     t7 = newTemp(Ity_I64);
10605                     t8 = newTemp(Ity_I1);
10606                     t9 = newTemp(Ity_I1);
10607
10608                     assign(t0, getAcc(ac));
10609
10610                     assign(t1, binop(Iop_Shl64,
10611                                      binop(Iop_MullS32,
10612                                            getIReg(rs), getIReg(rt)),
10613                                      mkU8(0x1)));
10614
10615                     assign(t2, binop(Iop_CmpEQ32,
10616                                      getIReg(rs),
10617                                      mkU32(0x80000000)));
10618                     assign(t3, binop(Iop_CmpEQ32,
10619                                      getIReg(rt),
10620                                      mkU32(0x80000000)));
10621
10622                     assign(t4,
10623                            IRExpr_ITE(mkexpr(t2),
10624                                       IRExpr_ITE(mkexpr(t3),
10625                                                  mkU64(0x7fffffffffffffffULL),
10626                                                  mkexpr(t1)),
10627                                       mkexpr(t1)));
10628
10629                     putDSPControl(IRExpr_ITE(mkexpr(t2),
10630                                              IRExpr_ITE(mkexpr(t3),
10631                                                         binop(Iop_Or32,
10632                                                               getDSPControl(),
10633                                                               binop(Iop_Shl32,
10634                                                                     mkU32(0x1),
10635                                                                     mkU8(ac+16)
10636                                                                    )
10637                                                              ),
10638                                                         getDSPControl()),
10639                                              getDSPControl()));
10640
10641                     assign(t5, binop(Iop_Sub64,
10642                                      unop(Iop_32Uto64,
10643                                           unop(Iop_64to32, mkexpr(t0))),
10644                                      unop(Iop_32Uto64,
10645                                           unop(Iop_64to32, mkexpr(t4)))));
10646                     assign(t6, binop(Iop_Sub64,
10647                                      binop(Iop_Add64,
10648                                            unop(Iop_32Sto64,
10649                                                 unop(Iop_64HIto32, mkexpr(t0))
10650                                                ),
10651                                            unop(Iop_32Sto64,
10652                                                 unop(Iop_1Sto32,
10653                                                      binop(Iop_CmpLT32U,
10654                                                            unop(Iop_64to32,
10655                                                                 mkexpr(t0)),
10656                                                            unop(Iop_64to32,
10657                                                                mkexpr(t4)))))),
10658                                      unop(Iop_32Sto64,
10659                                           unop(Iop_64HIto32, mkexpr(t4)))));
10660                     assign(t7, binop(Iop_32HLto64,
10661                                      unop(Iop_64to32, mkexpr(t6)),
10662                                      unop(Iop_64to32, mkexpr(t5))));
10663                     assign(t8, binop(Iop_CmpEQ32,
10664                                      binop(Iop_Shr32,
10665                                            binop(Iop_And32,
10666                                                  unop(Iop_64to32, mkexpr(t6)),
10667                                                  mkU32(0x80000000)),
10668                                            mkU8(31)),
10669                                      binop(Iop_And32,
10670                                            unop(Iop_64HIto32, mkexpr(t6)),
10671                                            mkU32(0x00000001))));
10672                     assign(t9, binop(Iop_CmpEQ32,
10673                                      binop(Iop_And32,
10674                                            unop(Iop_64HIto32, mkexpr(t6)),
10675                                            mkU32(0x00000001)),
10676                                      mkU32(0x1)));
10677                     putDSPControl(IRExpr_ITE(mkexpr(t8),
10678                                              getDSPControl(),
10679                                              binop(Iop_Or32,
10680                                                    getDSPControl(),
10681                                                    binop(Iop_Shl32,
10682                                                          mkU32(0x1),
10683                                                          mkU8(ac+16)))));
10684                     putAcc(ac,
10685                            IRExpr_ITE(mkexpr(t8),
10686                                       mkexpr(t7),
10687                                       IRExpr_ITE(mkexpr(t9),
10688                                                  mkU64(0x8000000000000000ULL),
10689                                                  mkU64(0x7fffffffffffffffULL)))
10690                           );
10691                     break;
10692                  }
10693                  case 0xF: {  /* DPSU.H.QBR */
10694                     DIP("dpsu.h.qbr ac%d r%d, r%d", ac, rs, rt);
10695                     vassert(!mode64);
10696
10697                     t0 = newTemp(Ity_I32);
10698                     t1 = newTemp(Ity_I32);
10699                     t2 = newTemp(Ity_I64);
10700                     t3 = newTemp(Ity_I64);
10701
10702                     assign(t0,
10703                            binop(Iop_Mul32,
10704                                  unop(Iop_8Uto32,
10705                                       unop(Iop_16HIto8,
10706                                            unop(Iop_32to16, getIReg(rs)))),
10707                                  unop(Iop_8Uto32,
10708                                       unop(Iop_16HIto8,
10709                                            unop(Iop_32to16, getIReg(rt))))));
10710                     assign(t1,
10711                            binop(Iop_Mul32,
10712                                  unop(Iop_8Uto32,
10713                                       unop(Iop_16to8,
10714                                            unop(Iop_32to16, getIReg(rs)))),
10715                                  unop(Iop_8Uto32,
10716                                       unop(Iop_16to8,
10717                                            unop(Iop_32to16, getIReg(rt))))));
10718                     assign(t2, unop(Iop_32Uto64,
10719                                     binop(Iop_Add32, mkexpr(t0), mkexpr(t1))));
10720                     assign(t3, binop(Iop_Sub64, getAcc(ac), mkexpr(t2)));
10721                     putAcc(ac, mkexpr(t3));
10722
10723                     break;
10724                  }
10725                  case 0x10: {  /* MAQ_SA.W.PHL */
10726                     DIP("maq_sa.w.phl ac%d, r%d, r%d", ac, rs, rt);
10727                     vassert(!mode64);
10728                     t0 = newTemp(Ity_I64);
10729                     t1 = newTemp(Ity_I64);
10730                     t2 = newTemp(Ity_I1);
10731                     t3 = newTemp(Ity_I1);
10732                     t4 = newTemp(Ity_I64);
10733                     t5 = newTemp(Ity_I64);
10734                     t6 = newTemp(Ity_I1);
10735                     t7 = newTemp(Ity_I64);
10736
10737                     assign(t0, getAcc(ac));
10738                     assign(t1, unop(Iop_32Sto64,
10739                                     binop(Iop_Shl32,
10740                                           binop(Iop_Mul32,
10741                                                 unop(Iop_16Sto32,
10742                                                      unop(Iop_32HIto16,
10743                                                           getIReg(rs))),
10744                                                 unop(Iop_16Sto32,
10745                                                      unop(Iop_32HIto16,
10746                                                           getIReg(rt)))),
10747                                           mkU8(0x1))));
10748
10749                     /* If both input arguments are equal 0x8000, saturate
10750                        intermediate product and write to DSPControl register.
10751                     */
10752                     assign(t2, binop(Iop_CmpEQ32,
10753                                      unop(Iop_16Uto32,
10754                                           unop(Iop_32HIto16, getIReg(rs))),
10755                                      mkU32(0x00008000)));
10756                     assign(t3, binop(Iop_CmpEQ32,
10757                                      unop(Iop_16Uto32,
10758                                           unop(Iop_32HIto16, getIReg(rt))),
10759                                      mkU32(0x00008000)));
10760
10761                     assign(t4,
10762                            IRExpr_ITE(mkexpr(t2),
10763                                       IRExpr_ITE(mkexpr(t3),
10764                                                  mkU64(0x000000007fffffffULL),
10765                                                  mkexpr(t1)),
10766                                       mkexpr(t1)));
10767
10768                     putDSPControl(IRExpr_ITE(mkexpr(t2),
10769                                              IRExpr_ITE(mkexpr(t3),
10770                                                         binop(Iop_Or32,
10771                                                               getDSPControl(),
10772                                                               binop(Iop_Shl32,
10773                                                                     mkU32(0x1),
10774                                                                     mkU8(ac+16)
10775                                                                    )
10776                                                              ),
10777                                                         getDSPControl()),
10778                                              getDSPControl()));
10779                     /* Add intermediate product and value in the
10780                        accumulator. */
10781                     assign(t5, binop(Iop_Add64, mkexpr(t0), mkexpr(t4)));
10782
10783                     /* Compare bits 31 and 32 of the value in t5. */
10784                     assign(t6, binop(Iop_CmpEQ32,
10785                                      binop(Iop_Shr32,
10786                                            binop(Iop_And32,
10787                                                  unop(Iop_64to32, mkexpr(t5)),
10788                                                  mkU32(0x80000000)),
10789                                            mkU8(31)),
10790                                      binop(Iop_And32,
10791                                            unop(Iop_64HIto32, mkexpr(t5)),
10792                                            mkU32(1))));
10793                     putDSPControl(IRExpr_ITE(mkexpr(t6),
10794                                              getDSPControl(),
10795                                              binop(Iop_Or32,
10796                                                    getDSPControl(),
10797                                                    binop(Iop_Shl32,
10798                                                          mkU32(0x1),
10799                                                          mkU8(ac+16)))));
10800                     assign(t7,
10801                            IRExpr_ITE(mkexpr(t6),
10802                                       mkexpr(t5),
10803                                       IRExpr_ITE(binop(Iop_CmpEQ32,
10804                                                        binop(Iop_And32,
10805                                                              unop(Iop_64HIto32,
10806                                                                   mkexpr(t5)),
10807                                                              mkU32(1)),
10808                                                        mkU32(0x0)),
10809                                                  mkU64(0x000000007fffffffULL),
10810                                                  mkU64(0xffffffff80000000ULL)))
10811                           );
10812                     putAcc(ac, mkexpr(t7));
10813                     break;
10814                  }
10815                  case 0x12: {  /* MAQ_SA.W.PHR */
10816                     DIP("maq_sa.w.phr ac%d, r%d, r%d", ac, rs, rt);
10817                     vassert(!mode64);
10818                     t0 = newTemp(Ity_I64);
10819                     t1 = newTemp(Ity_I64);
10820                     t2 = newTemp(Ity_I1);
10821                     t3 = newTemp(Ity_I1);
10822                     t4 = newTemp(Ity_I64);
10823                     t5 = newTemp(Ity_I64);
10824                     t6 = newTemp(Ity_I1);
10825                     t7 = newTemp(Ity_I64);
10826
10827                     assign(t0, getAcc(ac));
10828                     assign(t1, unop(Iop_32Sto64,
10829                                     binop(Iop_Shl32,
10830                                           binop(Iop_Mul32,
10831                                                 unop(Iop_16Sto32,
10832                                                      unop(Iop_32to16,
10833                                                           getIReg(rs))),
10834                                                 unop(Iop_16Sto32,
10835                                                      unop(Iop_32to16,
10836                                                           getIReg(rt)))),
10837                                           mkU8(0x1))));
10838
10839                     /* If both input arguments are equal 0x8000, saturate
10840                        intermediate product and write to DSPControl
10841                        register. */
10842                     assign(t2, binop(Iop_CmpEQ32,
10843                                      unop(Iop_16Uto32,
10844                                           unop(Iop_32to16, getIReg(rs))),
10845                                      mkU32(0x00008000)));
10846                     assign(t3, binop(Iop_CmpEQ32,
10847                                      unop(Iop_16Uto32,
10848                                           unop(Iop_32to16, getIReg(rt))),
10849                                      mkU32(0x00008000)));
10850
10851                     assign(t4,
10852                            IRExpr_ITE(mkexpr(t2),
10853                                       IRExpr_ITE(mkexpr(t3),
10854                                                  mkU64(0x000000007fffffffULL),
10855                                                  mkexpr(t1)),
10856                                       mkexpr(t1)));
10857
10858                     putDSPControl(IRExpr_ITE(mkexpr(t2),
10859                                              IRExpr_ITE(mkexpr(t3),
10860                                                         binop(Iop_Or32,
10861                                                               getDSPControl(),
10862                                                               binop(Iop_Shl32,
10863                                                                     mkU32(0x1),
10864                                                                     mkU8(ac+16)
10865                                                                    )
10866                                                              ),
10867                                                         getDSPControl()),
10868                                              getDSPControl()));
10869                     /* Add intermediate product and value in the
10870                        accumulator. */
10871                     assign(t5, binop(Iop_Add64, mkexpr(t0), mkexpr(t4)));
10872
10873                     /* Compare bits 31 and 32 of the value in t5. */
10874                     assign(t6, binop(Iop_CmpEQ32,
10875                                      binop(Iop_Shr32,
10876                                            binop(Iop_And32,
10877                                                  unop(Iop_64to32, mkexpr(t5)),
10878                                                  mkU32(0x80000000)),
10879                                            mkU8(31)),
10880                                      binop(Iop_And32,
10881                                            unop(Iop_64HIto32, mkexpr(t5)),
10882                                            mkU32(1))));
10883                     putDSPControl(IRExpr_ITE(mkexpr(t6),
10884                                              getDSPControl(),
10885                                              binop(Iop_Or32,
10886                                                    getDSPControl(),
10887                                                    binop(Iop_Shl32,
10888                                                          mkU32(0x1),
10889                                                          mkU8(ac+16)))));
10890                     assign(t7,
10891                            IRExpr_ITE(mkexpr(t6),
10892                                       mkexpr(t5),
10893                                       IRExpr_ITE(binop(Iop_CmpEQ32,
10894                                                        binop(Iop_And32,
10895                                                              unop(Iop_64HIto32,
10896                                                                   mkexpr(t5)),
10897                                                              mkU32(1)),
10898                                                        mkU32(0x0)),
10899                                                  mkU64(0x000000007fffffffULL),
10900                                                  mkU64(0xffffffff80000000ULL)))
10901                           );
10902                     putAcc(ac, mkexpr(t7));
10903                     break;
10904                  }
10905                  case 0x14: {  /* MAQ_S.W.PHL */
10906                     DIP("maq_s.w.phl ac%d, r%d, r%d", ac, rs, rt);
10907                     vassert(!mode64);
10908                     t0 = newTemp(Ity_I32);
10909                     t1 = newTemp(Ity_I32);
10910                     t2 = newTemp(Ity_I32);
10911                     t3 = newTemp(Ity_I1);
10912                     t4 = newTemp(Ity_I32);
10913                     t5 = newTemp(Ity_I64);
10914
10915                     assign(t5, getAcc(ac));
10916
10917                     assign(t0, unop(Iop_16Sto32,
10918                                     unop(Iop_32HIto16, getIReg(rs))));
10919                     assign(t1, unop(Iop_16Sto32,
10920                                     unop(Iop_32HIto16, getIReg(rt))));
10921
10922                     assign(t2, binop(Iop_And32,
10923                                      unop(Iop_1Sto32,
10924                                           binop(Iop_CmpEQ32,
10925                                                 binop(Iop_And32,
10926                                                       mkexpr(t0),
10927                                                       mkU32(0xffff)),
10928                                                 mkU32(0x8000))),
10929                                      unop(Iop_1Sto32,
10930                                           binop(Iop_CmpEQ32,
10931                                                 binop(Iop_And32,
10932                                                       mkexpr(t1),
10933                                                       mkU32(0xffff)),
10934                                                 mkU32(0x8000)))));
10935
10936                     assign(t3, binop(Iop_CmpEQ32, mkexpr(t2), mkU32(0x0)));
10937
10938                     putDSPControl(IRExpr_ITE(mkexpr(t3),
10939                                              getDSPControl(),
10940                                              binop(Iop_Or32,
10941                                                    getDSPControl(),
10942                                                    binop(Iop_Shl32,
10943                                                          mkU32(0x1),
10944                                                          mkU8(ac+16)))));
10945
10946                     assign(t4, unop(Iop_64to32,
10947                                     binop(Iop_MullS32,
10948                                           mkexpr(t0), mkexpr(t1))));
10949                     putAcc(ac, IRExpr_ITE(mkexpr(t3),
10950                                           binop(Iop_Add64,
10951                                                 unop(Iop_32Sto64,
10952                                                      binop(Iop_Shl32,
10953                                                            mkexpr(t4),
10954                                                            mkU8(0x1))),
10955                                                 mkexpr(t5)),
10956                                           binop(Iop_Add64,
10957                                                 mkexpr(t5),
10958                                                 unop(Iop_32Sto64,
10959                                                      mkU32(0x7fffffff)))));
10960                     break;
10961                  }
10962                  case 0x16: {  /* MAQ_S.W.PHR */
10963                     DIP("maq_s.w.phr ac%d, r%d, r%d", ac, rs, rt);
10964                     vassert(!mode64);
10965                     t0 = newTemp(Ity_I32);
10966                     t1 = newTemp(Ity_I32);
10967                     t2 = newTemp(Ity_I32);
10968                     t3 = newTemp(Ity_I1);
10969                     t4 = newTemp(Ity_I32);
10970                     t5 = newTemp(Ity_I64);
10971
10972                     assign(t5, getAcc(ac));
10973
10974                     assign(t0, unop(Iop_16Sto32,
10975                                     unop(Iop_32to16, getIReg(rs))));
10976                     assign(t1, unop(Iop_16Sto32,
10977                                     unop(Iop_32to16, getIReg(rt))));
10978
10979                     assign(t2, binop(Iop_And32,
10980                                      unop(Iop_1Sto32,
10981                                           binop(Iop_CmpEQ32,
10982                                                 binop(Iop_And32,
10983                                                       mkexpr(t0),
10984                                                       mkU32(0xffff)),
10985                                                 mkU32(0x8000))),
10986                                      unop(Iop_1Sto32,
10987                                           binop(Iop_CmpEQ32,
10988                                                 binop(Iop_And32,
10989                                                       mkexpr(t1),
10990                                                       mkU32(0xffff)),
10991                                                 mkU32(0x8000)))));
10992
10993                     assign(t3, binop(Iop_CmpEQ32, mkexpr(t2), mkU32(0x0)));
10994
10995                     putDSPControl(IRExpr_ITE(mkexpr(t3),
10996                                              getDSPControl(),
10997                                              binop(Iop_Or32,
10998                                                    getDSPControl(),
10999                                                    binop(Iop_Shl32,
11000                                                          mkU32(0x1),
11001                                                          mkU8(ac+16)))));
11002
11003                     assign(t4, unop(Iop_64to32,
11004                                     binop(Iop_MullS32,
11005                                           mkexpr(t0), mkexpr(t1))));
11006                     putAcc(ac, IRExpr_ITE(mkexpr(t3),
11007                                           binop(Iop_Add64,
11008                                                 unop(Iop_32Sto64,
11009                                                      binop(Iop_Shl32,
11010                                                            mkexpr(t4),
11011                                                            mkU8(0x1))),
11012                                                 mkexpr(t5)),
11013                                           binop(Iop_Add64,
11014                                                 mkexpr(t5),
11015                                                 unop(Iop_32Sto64,
11016                                                      mkU32(0x7fffffff)))));
11017                     break;
11018                  }
11019                  case 0x18: {  /* DPAQX_S.W.PH */
11020                     DIP("dpaqx_s.w.ph ac%d, r%d, r%d", ac, rs, rt);
11021                     vassert(!mode64);
11022                     t0 = newTemp(Ity_I64);
11023                     t1 = newTemp(Ity_I64);
11024                     t2 = newTemp(Ity_I1);
11025                     t3 = newTemp(Ity_I1);
11026                     t4 = newTemp(Ity_I64);
11027                     t5 = newTemp(Ity_I64);
11028                     t6 = newTemp(Ity_I1);
11029                     t7 = newTemp(Ity_I1);
11030                     t8 = newTemp(Ity_I64);
11031                     t9 = newTemp(Ity_I64);
11032
11033                     assign(t0, getAcc(ac));
11034
11035                     assign(t1, binop(Iop_Shl64,
11036                                      binop(Iop_MullS32,
11037                                            unop(Iop_16Sto32,
11038                                                 unop(Iop_32HIto16,
11039                                                      getIReg(rs))),
11040                                            unop(Iop_16Sto32,
11041                                                 unop(Iop_32to16,
11042                                                      getIReg(rt)))),
11043                                      mkU8(0x1)));
11044                     assign(t2, binop(Iop_CmpEQ32,
11045                                      unop(Iop_16Uto32,
11046                                           unop(Iop_32HIto16, getIReg(rs))),
11047                                      mkU32(0x00008000)));
11048                     assign(t3, binop(Iop_CmpEQ32,
11049                                      unop(Iop_16Uto32,
11050                                           unop(Iop_32to16, getIReg(rt))),
11051                                      mkU32(0x00008000)));
11052                     assign(t4,
11053                            IRExpr_ITE(mkexpr(t2),
11054                                       IRExpr_ITE(mkexpr(t3),
11055                                                  mkU64(0x000000007fffffffULL),
11056                                                  mkexpr(t1)),
11057                                       mkexpr(t1)));
11058
11059                     putDSPControl(IRExpr_ITE(mkexpr(t2),
11060                                              IRExpr_ITE(mkexpr(t3),
11061                                                         binop(Iop_Or32,
11062                                                               getDSPControl(),
11063                                                               binop(Iop_Shl32,
11064                                                                  mkU32(0x1),
11065                                                                  mkU8(ac+16))),
11066                                                         getDSPControl()),
11067                                              getDSPControl()));
11068
11069                     assign(t5, binop(Iop_Shl64,
11070                                      binop(Iop_MullS32,
11071                                            unop(Iop_16Sto32,
11072                                                 unop(Iop_32to16,
11073                                                      getIReg(rs))),
11074                                            unop(Iop_16Sto32,
11075                                                 unop(Iop_32HIto16,
11076                                                      getIReg(rt)))),
11077                                      mkU8(0x1)));
11078                     assign(t6, binop(Iop_CmpEQ32,
11079                                      unop(Iop_16Uto32,
11080                                           unop(Iop_32to16, getIReg(rs))),
11081                                      mkU32(0x00008000)));
11082                     assign(t7, binop(Iop_CmpEQ32,
11083                                      unop(Iop_16Uto32,
11084                                           unop(Iop_32HIto16, getIReg(rt))),
11085                                      mkU32(0x00008000)));
11086                     assign(t8,
11087                            IRExpr_ITE(mkexpr(t6),
11088                                       IRExpr_ITE(mkexpr(t7),
11089                                                  mkU64(0x000000007fffffffULL),
11090                                                  mkexpr(t5)),
11091                                       mkexpr(t5)));
11092
11093                     putDSPControl(IRExpr_ITE(mkexpr(t6),
11094                                              IRExpr_ITE(mkexpr(t7),
11095                                                         binop(Iop_Or32,
11096                                                               getDSPControl(),
11097                                                               binop(Iop_Shl32,
11098                                                                     mkU32(0x1),
11099                                                                     mkU8(ac+16)
11100                                                                    )
11101                                                              ),
11102                                                         getDSPControl()),
11103                                              getDSPControl()));
11104
11105                     assign(t9, binop(Iop_Add64,
11106                                      binop(Iop_Add64, mkexpr(t4), mkexpr(t8)),
11107                                      mkexpr(t0)));
11108                     putAcc(ac, mkexpr(t9));
11109                     break;
11110                  }
11111                  case 0x19: {  /* DPSQX_S.W.PH */
11112                     DIP("dpsqx_s.w.ph ac%d, r%d, r%d", ac, rs, rt);
11113                     vassert(!mode64);
11114                     t0 = newTemp(Ity_I64);
11115                     t1 = newTemp(Ity_I64);
11116                     t2 = newTemp(Ity_I1);
11117                     t3 = newTemp(Ity_I1);
11118                     t4 = newTemp(Ity_I64);
11119                     t5 = newTemp(Ity_I64);
11120                     t6 = newTemp(Ity_I1);
11121                     t7 = newTemp(Ity_I1);
11122                     t8 = newTemp(Ity_I64);
11123                     t9 = newTemp(Ity_I64);
11124
11125                     assign(t0, getAcc(ac));
11126
11127                     assign(t1, binop(Iop_Shl64,
11128                                      binop(Iop_MullS32,
11129                                            unop(Iop_16Sto32,
11130                                                 unop(Iop_32HIto16,
11131                                                      getIReg(rs))),
11132                                            unop(Iop_16Sto32,
11133                                                 unop(Iop_32to16,
11134                                                      getIReg(rt)))),
11135                                      mkU8(0x1)));
11136                     assign(t2, binop(Iop_CmpEQ32,
11137                                      unop(Iop_16Uto32,
11138                                           unop(Iop_32HIto16, getIReg(rs))),
11139                                      mkU32(0x00008000)));
11140                     assign(t3, binop(Iop_CmpEQ32,
11141                                      unop(Iop_16Uto32,
11142                                           unop(Iop_32to16, getIReg(rt))),
11143                                      mkU32(0x00008000)));
11144                     assign(t4,
11145                            IRExpr_ITE(mkexpr(t2),
11146                                       IRExpr_ITE(mkexpr(t3),
11147                                                  mkU64(0x000000007fffffffULL),
11148                                                  mkexpr(t1)),
11149                                       mkexpr(t1)));
11150
11151                     putDSPControl(IRExpr_ITE(mkexpr(t2),
11152                                              IRExpr_ITE(mkexpr(t3),
11153                                                         binop(Iop_Or32,
11154                                                               getDSPControl(),
11155                                                               binop(Iop_Shl32,
11156                                                                     mkU32(0x1),
11157                                                                     mkU8(ac+16)
11158                                                                    )
11159                                                              ),
11160                                                         getDSPControl()),
11161                                              getDSPControl()));
11162
11163                     assign(t5, binop(Iop_Shl64,
11164                                      binop(Iop_MullS32,
11165                                            unop(Iop_16Sto32,
11166                                                 unop(Iop_32to16,
11167                                                      getIReg(rs))),
11168                                            unop(Iop_16Sto32,
11169                                                 unop(Iop_32HIto16,
11170                                                      getIReg(rt)))),
11171                                      mkU8(0x1)));
11172                     assign(t6, binop(Iop_CmpEQ32,
11173                                      unop(Iop_16Uto32,
11174                                           unop(Iop_32to16, getIReg(rs))),
11175                                      mkU32(0x00008000)));
11176                     assign(t7, binop(Iop_CmpEQ32,
11177                                      unop(Iop_16Uto32,
11178                                           unop(Iop_32HIto16, getIReg(rt))),
11179                                      mkU32(0x00008000)));
11180                     assign(t8,
11181                            IRExpr_ITE(mkexpr(t6),
11182                                       IRExpr_ITE(mkexpr(t7),
11183                                                  mkU64(0x000000007fffffffULL),
11184                                                  mkexpr(t5)),
11185                                       mkexpr(t5)));
11186
11187                     putDSPControl(IRExpr_ITE(mkexpr(t6),
11188                                              IRExpr_ITE(mkexpr(t7),
11189                                                         binop(Iop_Or32,
11190                                                               getDSPControl(),
11191                                                               binop(Iop_Shl32,
11192                                                                     mkU32(0x1),
11193                                                                     mkU8(ac+16)
11194                                                                    )
11195                                                              ),
11196                                                         getDSPControl()),
11197                                              getDSPControl()));
11198
11199                     assign(t9, binop(Iop_Sub64,
11200                                     mkexpr(t0),
11201                                     binop(Iop_Add64, mkexpr(t4), mkexpr(t8))));
11202                     putAcc(ac, mkexpr(t9));
11203                     break;
11204                  }
11205                  case 0x1A: {  /* DPAQX_SA.W.PH */
11206                     DIP("dpaqx_sa.w.ph ac%d, r%d, r%d", ac, rs, rt);
11207                     vassert(!mode64);
11208                     t0 = newTemp(Ity_I64);
11209                     t1 = newTemp(Ity_I64);
11210                     t2 = newTemp(Ity_I1);
11211                     t3 = newTemp(Ity_I1);
11212                     t4 = newTemp(Ity_I64);
11213                     t5 = newTemp(Ity_I64);
11214                     t6 = newTemp(Ity_I1);
11215                     t7 = newTemp(Ity_I1);
11216                     t8 = newTemp(Ity_I64);
11217                     t9 = newTemp(Ity_I64);
11218                     t10 = newTemp(Ity_I32);
11219
11220                     assign(t0, getAcc(ac));
11221                     /* Calculate the first cross dot product and saturate if
11222                        needed. */
11223                     assign(t1, unop(Iop_32Sto64,
11224                                     binop(Iop_Shl32,
11225                                           binop(Iop_Mul32,
11226                                                 unop(Iop_16Sto32,
11227                                                      unop(Iop_32HIto16,
11228                                                           getIReg(rs))),
11229                                                 unop(Iop_16Sto32,
11230                                                      unop(Iop_32to16,
11231                                                           getIReg(rt)))),
11232                                           mkU8(0x1))));
11233
11234                     /* If both input arguments are equal 0x8000, saturate
11235                        intermediate product and write to DSPControl
11236                        register. */
11237                     assign(t2, binop(Iop_CmpEQ32,
11238                                      unop(Iop_16Uto32,
11239                                           unop(Iop_32HIto16, getIReg(rs))),
11240                                      mkU32(0x00008000)));
11241                     assign(t3, binop(Iop_CmpEQ32,
11242                                      unop(Iop_16Uto32,
11243                                           unop(Iop_32to16, getIReg(rt))),
11244                                      mkU32(0x00008000)));
11245
11246                     assign(t4, IRExpr_ITE(binop(Iop_CmpNE32,
11247                                                 binop(Iop_And32,
11248                                                       unop(Iop_1Sto32,
11249                                                            mkexpr(t2)),
11250                                                       unop(Iop_1Sto32,
11251                                                            mkexpr(t3))),
11252                                                 mkU32(0)),
11253                                           mkU64(0x000000007fffffffULL),
11254                                           mkexpr(t1)));
11255
11256                     putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32,
11257                                                    binop(Iop_And32,
11258                                                          unop(Iop_1Sto32,
11259                                                               mkexpr(t2)),
11260                                                          unop(Iop_1Sto32,
11261                                                               mkexpr(t3))),
11262                                                    mkU32(0)),
11263                                              binop(Iop_Or32,
11264                                                    getDSPControl(),
11265                                                    binop(Iop_Shl32,
11266                                                          mkU32(0x1),
11267                                                          mkU8(ac+16))),
11268                                              getDSPControl()));
11269                     /* Calculate second cross dot product and saturate if
11270                        needed. */
11271                     assign(t5, unop(Iop_32Sto64,
11272                                     binop(Iop_Shl32,
11273                                           binop(Iop_Mul32,
11274                                                 unop(Iop_16Sto32,
11275                                                      unop(Iop_32to16,
11276                                                           getIReg(rs))),
11277                                                 unop(Iop_16Sto32,
11278                                                      unop(Iop_32HIto16,
11279                                                           getIReg(rt)))),
11280                                           mkU8(0x1))));
11281
11282                     /* If both input arguments are equal 0x8000, saturate
11283                        intermediate product and write to DSPControl
11284                        register. */
11285                     assign(t6, binop(Iop_CmpEQ32,
11286                                      unop(Iop_16Uto32,
11287                                           unop(Iop_32to16, getIReg(rs))),
11288                                      mkU32(0x00008000)));
11289                     assign(t7, binop(Iop_CmpEQ32,
11290                                      unop(Iop_16Uto32,
11291                                           unop(Iop_32HIto16, getIReg(rt))),
11292                                      mkU32(0x00008000)));
11293
11294                     assign(t8, IRExpr_ITE(binop(Iop_CmpNE32,
11295                                                 binop(Iop_And32,
11296                                                       unop(Iop_1Sto32,
11297                                                            mkexpr(t6)),
11298                                                       unop(Iop_1Sto32,
11299                                                            mkexpr(t7))),
11300                                                 mkU32(0)),
11301                                           mkU64(0x000000007fffffffULL),
11302                                           mkexpr(t5)));
11303
11304                     putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32,
11305                                                    binop(Iop_And32,
11306                                                          unop(Iop_1Sto32,
11307                                                               mkexpr(t6)),
11308                                                          unop(Iop_1Sto32,
11309                                                               mkexpr(t7))),
11310                                                    mkU32(0)),
11311                                              binop(Iop_Or32,
11312                                                    getDSPControl(),
11313                                                    binop(Iop_Shl32,
11314                                                          mkU32(0x1),
11315                                                          mkU8(ac+16))),
11316                                              getDSPControl()));
11317                     /* Subtract intermediate products from value in the
11318                        accumulator. */
11319                     assign(t9,
11320                            binop(Iop_Add64,
11321                                  mkexpr(t0),
11322                                  binop(Iop_Add64, mkexpr(t8), mkexpr(t4))));
11323
11324                     putAcc(ac,
11325                            IRExpr_ITE(binop(Iop_CmpEQ32,
11326                                             binop(Iop_And32,
11327                                                   unop(Iop_64HIto32,
11328                                                        mkexpr(t9)),
11329                                                   mkU32(0x80000000)),
11330                                             mkU32(0x0)),
11331                                       IRExpr_ITE(binop(Iop_CmpNE32,
11332                                                        unop(Iop_64HIto32,
11333                                                             binop(Iop_Shl64,
11334                                                                   mkexpr(t9),
11335                                                                   mkU8(1))),
11336                                                        mkU32(0x0)),
11337                                                  mkU64(0x000000007fffffffULL),
11338                                                  mkexpr(t9)),
11339                                       IRExpr_ITE(binop(Iop_CmpNE32,
11340                                                        unop(Iop_64HIto32,
11341                                                             binop(Iop_Shl64,
11342                                                                   mkexpr(t9),
11343                                                                   mkU8(1))),
11344                                                        mkU32(0xffffffff)),
11345                                                  mkU64(0xffffffff80000000ULL),
11346                                                  mkexpr(t9))));
11347                     assign(t10, IRExpr_ITE(binop(Iop_CmpEQ32,
11348                                                  unop(Iop_64to32,
11349                                                       mkexpr(t9)),
11350                                                  unop(Iop_64to32,
11351                                                       getAcc(ac))),
11352                                           getDSPControl(),
11353                                           binop(Iop_Or32,
11354                                                 getDSPControl(),
11355                                                 binop(Iop_Shl32,
11356                                                       mkU32(0x1),
11357                                                       mkU8(ac+16)))));
11358                     putDSPControl(IRExpr_ITE(binop(Iop_CmpEQ32,
11359                                                    unop(Iop_64HIto32,
11360                                                         mkexpr(t9)),
11361                                                    unop(Iop_64HIto32,
11362                                                         getAcc(ac))),
11363                                              mkexpr(t10),
11364                                              binop(Iop_Or32,
11365                                                    getDSPControl(),
11366                                                    binop(Iop_Shl32,
11367                                                          mkU32(0x1),
11368                                                          mkU8(ac+16)))));
11369                     break;
11370                  }
11371                  case 0x1B: {  /* DPSQX_SA.W.PH */
11372                     DIP("dpsqx_sa.w.ph ac%d, r%d, r%d", ac, rs, rt);
11373                     vassert(!mode64);
11374                     t0 = newTemp(Ity_I64);
11375                     t1 = newTemp(Ity_I64);
11376                     t2 = newTemp(Ity_I1);
11377                     t3 = newTemp(Ity_I1);
11378                     t4 = newTemp(Ity_I64);
11379                     t5 = newTemp(Ity_I64);
11380                     t6 = newTemp(Ity_I1);
11381                     t7 = newTemp(Ity_I1);
11382                     t8 = newTemp(Ity_I64);
11383                     t9 = newTemp(Ity_I64);
11384                     t10 = newTemp(Ity_I32);
11385
11386                     assign(t0, getAcc(ac));
11387                     /* Calculate the first cross dot product and saturate if
11388                        needed. */
11389                     assign(t1, unop(Iop_32Sto64,
11390                                     binop(Iop_Shl32,
11391                                           binop(Iop_Mul32,
11392                                                 unop(Iop_16Sto32,
11393                                                      unop(Iop_32HIto16,
11394                                                           getIReg(rs))),
11395                                                 unop(Iop_16Sto32,
11396                                                      unop(Iop_32to16,
11397                                                           getIReg(rt)))),
11398                                           mkU8(0x1))));
11399
11400                     /* If both input arguments are equal 0x8000, saturate
11401                        intermediate product and write to DSPControl
11402                        register. */
11403                     assign(t2, binop(Iop_CmpEQ32,
11404                                      unop(Iop_16Uto32,
11405                                           unop(Iop_32HIto16, getIReg(rs))),
11406                                      mkU32(0x00008000)));
11407                     assign(t3, binop(Iop_CmpEQ32,
11408                                      unop(Iop_16Uto32,
11409                                           unop(Iop_32to16, getIReg(rt))),
11410                                      mkU32(0x00008000)));
11411
11412                     assign(t4, IRExpr_ITE(binop(Iop_CmpNE32,
11413                                                 binop(Iop_And32,
11414                                                       unop(Iop_1Sto32,
11415                                                            mkexpr(t2)),
11416                                                       unop(Iop_1Sto32,
11417                                                            mkexpr(t3))),
11418                                                 mkU32(0)),
11419                                           mkU64(0x000000007fffffffULL),
11420                                           mkexpr(t1)));
11421
11422                     putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32,
11423                                                    binop(Iop_And32,
11424                                                          unop(Iop_1Sto32,
11425                                                               mkexpr(t2)),
11426                                                          unop(Iop_1Sto32,
11427                                                               mkexpr(t3))),
11428                                                    mkU32(0)),
11429                                              binop(Iop_Or32,
11430                                                    getDSPControl(),
11431                                                    binop(Iop_Shl32,
11432                                                          mkU32(0x1),
11433                                                          mkU8(ac+16))),
11434                                              getDSPControl()));
11435                     /* Calculate second cross dot product and saturate if
11436                        needed. */
11437                     assign(t5, unop(Iop_32Sto64,
11438                                     binop(Iop_Shl32,
11439                                           binop(Iop_Mul32,
11440                                                 unop(Iop_16Sto32,
11441                                                      unop(Iop_32to16,
11442                                                           getIReg(rs))),
11443                                                 unop(Iop_16Sto32,
11444                                                      unop(Iop_32HIto16,
11445                                                           getIReg(rt)))),
11446                                           mkU8(0x1))));
11447
11448                     /* If both input arguments are equal 0x8000, saturate
11449                        intermediate product and write to DSPControl
11450                        register. */
11451                     assign(t6, binop(Iop_CmpEQ32,
11452                                      unop(Iop_16Uto32,
11453                                           unop(Iop_32to16, getIReg(rs))),
11454                                      mkU32(0x00008000)));
11455                     assign(t7, binop(Iop_CmpEQ32,
11456                                      unop(Iop_16Uto32,
11457                                           unop(Iop_32HIto16, getIReg(rt))),
11458                                      mkU32(0x00008000)));
11459
11460                     assign(t8, IRExpr_ITE(binop(Iop_CmpNE32,
11461                                                 binop(Iop_And32,
11462                                                       unop(Iop_1Sto32,
11463                                                            mkexpr(t6)),
11464                                                       unop(Iop_1Sto32,
11465                                                            mkexpr(t7))),
11466                                                 mkU32(0)),
11467                                           mkU64(0x000000007fffffffULL),
11468                                           mkexpr(t5)));
11469
11470                     putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32,
11471                                                    binop(Iop_And32,
11472                                                          unop(Iop_1Sto32,
11473                                                               mkexpr(t6)),
11474                                                          unop(Iop_1Sto32,
11475                                                               mkexpr(t7))),
11476                                                    mkU32(0)),
11477                                              binop(Iop_Or32,
11478                                                    getDSPControl(),
11479                                                    binop(Iop_Shl32,
11480                                                          mkU32(0x1),
11481                                                          mkU8(ac+16))),
11482                                              getDSPControl()));
11483                     /* Subtract intermediate products from value in the
11484                        accumulator. */
11485                     assign(t9,
11486                            binop(Iop_Sub64,
11487                                  mkexpr(t0),
11488                                  binop(Iop_Add64, mkexpr(t8), mkexpr(t4))));
11489
11490                     putAcc(ac,
11491                            IRExpr_ITE(binop(Iop_CmpEQ32,
11492                                             binop(Iop_And32,
11493                                                   unop(Iop_64HIto32,
11494                                                        mkexpr(t9)),
11495                                                   mkU32(0x80000000)),
11496                                             mkU32(0x0)),
11497                                       IRExpr_ITE(binop(Iop_CmpNE32,
11498                                                        unop(Iop_64HIto32,
11499                                                             binop(Iop_Shl64,
11500                                                                   mkexpr(t9),
11501                                                                   mkU8(1))),
11502                                                        mkU32(0x0)),
11503                                                  mkU64(0x000000007fffffffULL),
11504                                                  mkexpr(t9)),
11505                                       IRExpr_ITE(binop(Iop_CmpNE32,
11506                                                        unop(Iop_64HIto32,
11507                                                             binop(Iop_Shl64,
11508                                                                   mkexpr(t9),
11509                                                                   mkU8(1))),
11510                                                        mkU32(0xffffffff)),
11511                                                  mkU64(0xffffffff80000000ULL),
11512                                                  mkexpr(t9))));
11513                     assign(t10, IRExpr_ITE(binop(Iop_CmpEQ32,
11514                                                  unop(Iop_64to32,
11515                                                       mkexpr(t9)),
11516                                                  unop(Iop_64to32,
11517                                                       getAcc(ac))),
11518                                           getDSPControl(),
11519                                           binop(Iop_Or32,
11520                                                 getDSPControl(),
11521                                                 binop(Iop_Shl32,
11522                                                       mkU32(0x1),
11523                                                       mkU8(ac+16)))));
11524                     putDSPControl(IRExpr_ITE(binop(Iop_CmpEQ32,
11525                                                    unop(Iop_64HIto32,
11526                                                         mkexpr(t9)),
11527                                                    unop(Iop_64HIto32,
11528                                                         getAcc(ac))),
11529                                              mkexpr(t10),
11530                                              binop(Iop_Or32,
11531                                                    getDSPControl(),
11532                                                    binop(Iop_Shl32,
11533                                                          mkU32(0x1),
11534                                                          mkU8(ac+16)))));
11535                     break;
11536                  }
11537                  default:
11538                     return -1;
11539               }
11540               break;  /* end of DPAQ.W.PH */
11541            }
11542            case 0x31: {  /* APPEND */
11543               switch(sa) {
11544                  case 0x0: {  /* APPEND */
11545                     DIP("append r%d, r%d, %d", rt, rs, rd);
11546                     vassert(!mode64);
11547                     t1 = newTemp(Ity_I32);
11548                     t2 = newTemp(Ity_I32);
11549                     t3 = newTemp(Ity_I32);
11550
11551                     assign(t1, binop(Iop_Shl32, getIReg(rt), mkU8(rd)));
11552
11553                     if (31 == rd) {
11554                        putIReg(rt, binop(Iop_Or32,
11555                                          mkexpr(t1),
11556                                          binop(Iop_And32,
11557                                                getIReg(rs),
11558                                                mkU32(0x7fffffff))));
11559                     } else if (1 == rd) {
11560                        putIReg(rt,
11561                                binop(Iop_Or32,
11562                                      mkexpr(t1),
11563                                      binop(Iop_And32,
11564                                            getIReg(rs), mkU32(0x1))));
11565                     } else {
11566                        assign(t2,
11567                               unop(Iop_Not32,
11568                                    binop(Iop_Shl32,
11569                                          mkU32(0xffffffff), mkU8(rd))));
11570
11571                        putIReg(rt, binop(Iop_Or32,
11572                                          mkexpr(t1),
11573                                          binop(Iop_And32,
11574                                                getIReg(rs), mkexpr(t2))));
11575                     }
11576                     break;
11577                  }
11578                  case 0x1: {  /* PREPEND */
11579                     DIP("prepend r%d, r%d, %d", rt, rs, rd);
11580                     vassert(!mode64);
11581                     t1 = newTemp(Ity_I32);
11582                     t2 = newTemp(Ity_I32);
11583                     t3 = newTemp(Ity_I32);
11584
11585                     if (0 != rd) {
11586                        assign(t1, binop(Iop_Shr32, getIReg(rt), mkU8(rd)));
11587
11588                        if (31 == rd) {
11589                           putIReg(rt, binop(Iop_Or32,
11590                                             mkexpr(t1),
11591                                             binop(Iop_Shl32,
11592                                                   binop(Iop_And32,
11593                                                         getIReg(rs),
11594                                                         mkU32(0x7fffffff)),
11595                                                   mkU8(1))));
11596                        } else if (1 == rd) {
11597                           putIReg(rt, binop(Iop_Or32,
11598                                             mkexpr(t1),
11599                                             binop(Iop_Shl32,
11600                                                   binop(Iop_And32,
11601                                                         getIReg(rs),
11602                                                         mkU32(0x1)),
11603                                                   mkU8(31))));
11604                        } else {
11605                           assign(t2, binop(Iop_Add32, mkU32(rd), mkU32(0x1)));
11606
11607                           assign(t3, unop(Iop_Not32,
11608                                           binop(Iop_Shl32,
11609                                                 mkU32(0xffffffff),
11610                                                 unop(Iop_32to8, mkexpr(t2)))));
11611
11612                           putIReg(rt, binop(Iop_Or32,
11613                                             mkexpr(t1),
11614                                             binop(Iop_Shl32,
11615                                                   binop(Iop_And32,
11616                                                         getIReg(rs),
11617                                                         mkexpr(t3)),
11618                                                   mkU8(32-rd))));
11619                        }
11620                     }
11621                     break;
11622                  }
11623                  case 0x10: {  /* BALIGN */
11624                     DIP("balign r%d, r%d, %d", rt, rs, rd);
11625                     vassert(!mode64);
11626                     t1 = newTemp(Ity_I32);
11627                     t2 = newTemp(Ity_I32);
11628                     t3 = newTemp(Ity_I32);
11629
11630                     if ((2 != rd) && (0 != rd)) {
11631                        assign(t1, binop(Iop_Shl32,
11632                                         binop(Iop_And32,
11633                                               mkU32(rd), mkU32(0x3)),
11634                                         mkU8(0x3)));
11635                        assign(t2, binop(Iop_Shl32,
11636                                         getIReg(rt),
11637                                         unop(Iop_32to8, mkexpr(t1))));
11638                        assign(t3, binop(Iop_Shr32,
11639                                         getIReg(rs),
11640                                         unop(Iop_32to8,
11641                                              binop(Iop_Shl32,
11642                                                    binop(Iop_Sub32,
11643                                                          mkU32(0x4),
11644                                                          binop(Iop_And32,
11645                                                                mkU32(rd),
11646                                                                mkU32(0x3))),
11647                                                    mkU8(0x3)))));
11648                        putIReg(rt, binop(Iop_Or32, mkexpr(t2), mkexpr(t3)));
11649                     }
11650                     break;
11651                  }
11652                  default:
11653                     return -1;
11654               }
11655               break;  /* end of APPEND */
11656            }
11657            default:
11658               return -1;
11659         }
11660         break;
11661      }
11662      default:
11663            return -1;
11664   }
11665   return 0;
11666}
11667
11668/*------------------------------------------------------------*/
11669/*---          Disassemble a single instruction            ---*/
11670/*------------------------------------------------------------*/
11671
11672/* Disassemble a single instruction into IR. The instruction is
11673   located in host memory at guest_instr, and has guest IP of
11674   guest_PC_curr_instr, which will have been set before the call
11675   here. */
11676
11677static DisResult disInstr_MIPS_WRK ( Bool(*resteerOkFn) (/*opaque */void *,
11678                                                                    Addr64),
11679                                     Bool         resteerCisOk,
11680                                     void*        callback_opaque,
11681                                     Long         delta64,
11682                                     VexArchInfo* archinfo,
11683                                     VexAbiInfo*  abiinfo,
11684                                     Bool         sigill_diag )
11685{
11686   IRTemp t0, t1 = 0, t2, t3, t4, t5, t6, t7;
11687
11688   UInt opcode, cins, rs, rt, rd, sa, ft, fs, fd, fmt, tf, nd, function,
11689        trap_code, imm, instr_index, p, msb, lsb, size, rot, sel;
11690   /* Additional variables for instruction fields in DSP ASE insructions */
11691   UInt ac;
11692
11693   DisResult dres;
11694
11695   static IRExpr *lastn = NULL;  /* last jump addr */
11696   static IRStmt *bstmt = NULL;  /* branch (Exit) stmt */
11697
11698   /* The running delta */
11699   Int delta = (Int) delta64;
11700
11701   /* Holds eip at the start of the insn, so that we can print
11702      consistent error messages for unimplemented insns. */
11703   Int delta_start = delta;
11704
11705   /* Are we in a delay slot ? */
11706   Bool delay_slot_branch, likely_delay_slot, delay_slot_jump;
11707
11708   /* Set result defaults. */
11709   dres.whatNext = Dis_Continue;
11710   dres.len = 0;
11711   dres.continueAt = 0;
11712   dres.jk_StopHere = Ijk_INVALID;
11713
11714   delay_slot_branch = likely_delay_slot = delay_slot_jump = False;
11715
11716   UChar *code = (UChar *) (guest_code + delta);
11717   cins = getUInt(code);
11718   DIP("\t0x%lx:\t0x%08x\t", (long)guest_PC_curr_instr, cins);
11719
11720   if (delta != 0) {
11721      if (branch_or_jump(guest_code + delta - 4)) {
11722         if (lastn == NULL && bstmt == NULL) {
11723            vassert(0);
11724         } else {
11725            dres.whatNext = Dis_StopHere;
11726            if (lastn != NULL) {
11727               delay_slot_jump = True;
11728            } else if (bstmt != NULL) {
11729               delay_slot_branch = True;
11730            }
11731         }
11732      }
11733
11734      if (branch_or_link_likely(guest_code + delta - 4)) {
11735         likely_delay_slot = True;
11736      }
11737   }
11738
11739   /* Spot "Special" instructions (see comment at top of file). */
11740   {
11741      /* Spot the 16-byte preamble:
11742       ****mips32****
11743       "srl $0, $0, 13
11744       "srl $0, $0, 29
11745       "srl $0, $0, 3
11746       "srl $0, $0, 19
11747
11748       ****mips64****
11749       dsll $0, $0, 3
11750       dsll $0, $0, 13
11751       dsll $0, $0, 29
11752       dsll $0, $0, 19 */
11753
11754      UInt word1 = mode64 ? 0xF8  : 0x342;
11755      UInt word2 = mode64 ? 0x378 : 0x742;
11756      UInt word3 = mode64 ? 0x778 : 0xC2;
11757      UInt word4 = mode64 ? 0x4F8 : 0x4C2;
11758      if (getUInt(code + 0) == word1 && getUInt(code + 4) == word2 &&
11759          getUInt(code + 8) == word3 && getUInt(code + 12) == word4) {
11760         /* Got a "Special" instruction preamble. Which one is it? */
11761         if (getUInt(code + 16) == 0x01ad6825 /* or $13, $13, $13 */ ) {
11762            /* $11 = client_request ( $12 ) */
11763            DIP("$11 = client_request ( $12 )");
11764            if (mode64)
11765               putPC(mkU64(guest_PC_curr_instr + 20));
11766            else
11767               putPC(mkU32(guest_PC_curr_instr + 20));
11768            dres.jk_StopHere = Ijk_ClientReq;
11769            dres.whatNext    = Dis_StopHere;
11770
11771            goto decode_success;
11772         } else if (getUInt(code + 16) == 0x01ce7025 /* or $14, $14, $14 */ ) {
11773            /* $11 = guest_NRADDR */
11774            DIP("$11 = guest_NRADDR");
11775            dres.len = 20;
11776            delta += 20;
11777            if (mode64)
11778               putIReg(11, IRExpr_Get(offsetof(VexGuestMIPS64State,
11779                                               guest_NRADDR), Ity_I64));
11780            else
11781               putIReg(11, IRExpr_Get(offsetof(VexGuestMIPS32State,
11782                                               guest_NRADDR), Ity_I32));
11783            goto decode_success;
11784         } else if (getUInt(code + 16) == 0x01ef7825 /* or $15, $15, $15 */ ) {
11785            /*  branch-and-link-to-noredir $25 */
11786            DIP("branch-and-link-to-noredir $25");
11787            if (mode64)
11788               putIReg(31, mkU64(guest_PC_curr_instr + 20));
11789            else
11790               putIReg(31, mkU32(guest_PC_curr_instr + 20));
11791            putPC(getIReg(25));
11792            dres.jk_StopHere = Ijk_NoRedir;
11793            dres.whatNext    = Dis_StopHere;
11794            goto decode_success;
11795         } else if (getUInt(code + 16) == 0x016b5825 /* or $11,$11,$11 */ ) {
11796           /* IR injection */
11797            DIP("IR injection");
11798#if defined (_MIPSEL)
11799            vex_inject_ir(irsb, Iend_LE);
11800#elif defined (_MIPSEB)
11801            vex_inject_ir(irsb, Iend_BE);
11802#endif
11803            if (mode64) {
11804               stmt(IRStmt_Put(offsetof(VexGuestMIPS64State, guest_CMSTART),
11805                               mkU64(guest_PC_curr_instr)));
11806               stmt(IRStmt_Put(offsetof(VexGuestMIPS64State, guest_CMLEN),
11807                               mkU64(20)));
11808
11809               putPC(mkU64(guest_PC_curr_instr + 20));
11810            } else {
11811               stmt(IRStmt_Put(offsetof(VexGuestMIPS32State, guest_CMSTART),
11812                               mkU32(guest_PC_curr_instr)));
11813               stmt(IRStmt_Put(offsetof(VexGuestMIPS32State, guest_CMLEN),
11814                               mkU32(20)));
11815
11816               putPC(mkU32(guest_PC_curr_instr + 20));
11817            }
11818            dres.whatNext    = Dis_StopHere;
11819            dres.jk_StopHere = Ijk_InvalICache;
11820            dres.len = 20;
11821            delta += 20;
11822            goto decode_success;
11823         }
11824
11825         /* We don't know what it is.  Set opc1/opc2 so decode_failure
11826            can print the insn following the Special-insn preamble. */
11827         delta += 16;
11828         goto decode_failure;
11829       /*NOTREACHED*/}
11830   }
11831
11832   opcode = get_opcode(cins);
11833   imm = get_imm(cins);
11834   rs = get_rs(cins);
11835   rt = get_rt(cins);
11836   rd = get_rd(cins);
11837   sa = get_sa(cins);
11838   fs = get_fs(cins);
11839   fd = get_fd(cins);
11840   ft = get_ft(cins);
11841   tf = get_tf(cins);
11842   nd = get_nd(cins);
11843   sel = get_sel(cins);
11844   fmt = get_fmt(cins);
11845   instr_index = get_instr_index(cins);
11846   trap_code = get_code(cins);
11847   function = get_function(cins);
11848   IRType ty = mode64 ? Ity_I64 : Ity_I32;
11849   IRType tyF = fp_mode64 ? Ity_F64 : Ity_F32;
11850
11851   ac = get_acNo(cins);
11852
11853   switch (opcode) {
11854
11855   case 0x03:     /* JAL */
11856      DIP("jal 0x%x", instr_index);
11857      if (mode64) {
11858         putIReg(31, mkU64(guest_PC_curr_instr + 8));
11859         t0 = newTemp(ty);
11860         assign(t0, mkU64((guest_PC_curr_instr & 0xFFFFFFFFF0000000ULL) |
11861                          (instr_index << 2)));
11862      } else {
11863         putIReg(31, mkU32(guest_PC_curr_instr + 8));
11864         t0 = newTemp(ty);
11865         assign(t0, mkU32((guest_PC_curr_instr & 0xF0000000) |
11866                          (instr_index << 2)));
11867      }
11868      lastn = mkexpr(t0);
11869      break;
11870   case 0x02:     /* J */
11871      DIP("j 0x%x", instr_index);
11872      t0 = newTemp(ty);
11873      if (mode64)
11874         assign(t0, mkU64((guest_PC_curr_instr & 0xFFFFFFFFF0000000ULL) |
11875                          (instr_index << 2)));
11876      else
11877         assign(t0, mkU32((guest_PC_curr_instr & 0xF0000000) |
11878                          (instr_index << 2)));
11879      lastn = mkexpr(t0);
11880      break;
11881
11882   case 0x11: {  /* COP1 */
11883      if (fmt == 0x3 && fd == 0 && function == 0) {  /* MFHC1 */
11884         DIP("mfhc1 r%d, f%d", rt, fs);
11885         if (fp_mode64) {
11886            t0 = newTemp(Ity_I64);
11887            t1 = newTemp(Ity_I32);
11888            assign(t0, unop(Iop_ReinterpF64asI64, getDReg(fs)));
11889            assign(t1, unop(Iop_64HIto32, mkexpr(t0)));
11890            putIReg(rt, mkWidenFrom32(ty, mkexpr(t1), True));
11891         } else {
11892            ILLEGAL_INSTRUCTON;
11893         }
11894         break;
11895      } else if (fmt == 0x7 && fd == 0 && function == 0) {  /* MTHC1 */
11896         DIP("mthc1 r%d, f%d", rt, fs);
11897         if (fp_mode64) {
11898            t0 = newTemp(Ity_I64);
11899            assign(t0, binop(Iop_32HLto64, getIReg(rt),
11900                             unop(Iop_ReinterpF32asI32,
11901                                  getLoFromF64(Ity_F64 /* 32FPR mode. */,
11902                                               getDReg(fs)))));
11903            putDReg(fs, unop(Iop_ReinterpI64asF64, mkexpr(t0)));
11904         } else {
11905            ILLEGAL_INSTRUCTON;
11906         }
11907         break;
11908      } else if (fmt == 0x8) {  /* BC */
11909         /* FcConditionalCode(bc1_cc) */
11910         UInt bc1_cc = get_bc1_cc(cins);
11911         t1 = newTemp(Ity_I1);
11912         t2 = newTemp(Ity_I32);
11913         t3 = newTemp(Ity_I1);
11914
11915         assign(t1, binop(Iop_CmpEQ32, mkU32(0), mkU32(bc1_cc)));
11916         assign(t2, IRExpr_ITE(mkexpr(t1),
11917                               binop(Iop_And32,
11918                                     binop(Iop_Shr32, getFCSR(), mkU8(23)),
11919                                     mkU32(0x1)),
11920                               binop(Iop_And32,
11921                                     binop(Iop_Shr32, getFCSR(),
11922                                           mkU8(24 + bc1_cc)),
11923                                     mkU32(0x1))));
11924
11925         if (tf == 1 && nd == 0) {
11926            /* branch on true */
11927            DIP("bc1t %d, %d", bc1_cc, imm);
11928            assign(t3, binop(Iop_CmpEQ32, mkU32(1), mkexpr(t2)));
11929            dis_branch(False, mkexpr(t3), imm, &bstmt);
11930            break;
11931         } else if (tf == 0 && nd == 0) {
11932            /* branch on false */
11933            DIP("bc1f %d, %d", bc1_cc, imm);
11934            assign(t3, binop(Iop_CmpEQ32, mkU32(0), mkexpr(t2)));
11935            dis_branch(False, mkexpr(t3), imm, &bstmt);
11936            break;
11937         } else if (nd == 1 && tf == 0) {
11938            DIP("bc1fl %d, %d", bc1_cc, imm);
11939            lastn = dis_branch_likely(binop(Iop_CmpNE32, mkexpr(t2),
11940                                            mkU32(0x0)), imm);
11941            break;
11942         } else if (nd == 1 && tf == 1) {
11943            DIP("bc1tl %d, %d", bc1_cc, imm);
11944            lastn = dis_branch_likely(binop(Iop_CmpEQ32, mkexpr(t2),
11945                                            mkU32(0x0)), imm);
11946            break;
11947         } else
11948            goto decode_failure;
11949      } else {
11950         switch (function) {
11951            case 0x4: {  /* SQRT.fmt */
11952               switch (fmt) {
11953                  case 0x10: {  /* S */
11954                     IRExpr *rm = get_IR_roundingmode();
11955                     putFReg(fd, mkWidenFromF32(tyF, binop(Iop_SqrtF32, rm,
11956                                 getLoFromF64(tyF, getFReg(fs)))));
11957                     break;
11958                  }
11959                  case 0x11: {  /* D */
11960                     IRExpr *rm = get_IR_roundingmode();
11961                     putDReg(fd, binop(Iop_SqrtF64, rm, getDReg(fs)));
11962                     break;
11963                  }
11964                  default:
11965                     goto decode_failure;
11966                  }
11967               }
11968               break;
11969            case 0x5:  /* abs.fmt */
11970               switch (fmt) {
11971                  case 0x10:  /* S */
11972                     DIP("abs.s f%d, f%d", fd, fs);
11973                     putFReg(fd, mkWidenFromF32(tyF, unop(Iop_AbsF32,
11974                                 getLoFromF64(tyF, getFReg(fs)))));
11975                     break;
11976                  case 0x11:  /* D  */
11977                     DIP("abs.d f%d, f%d", fd, fs);
11978                     putDReg(fd, unop(Iop_AbsF64, getDReg(fs)));
11979                     break;
11980                  default:
11981                     goto decode_failure;
11982               }
11983               break;  /* case 0x5 */
11984
11985            case 0x02:  /* MUL.fmt */
11986               switch (fmt) {
11987                  case 0x11: {  /* D */
11988                     DIP("mul.d f%d, f%d, f%d", fd, fs, ft);
11989                     IRExpr *rm = get_IR_roundingmode();
11990                     putDReg(fd, triop(Iop_MulF64, rm, getDReg(fs),
11991                                       getDReg(ft)));
11992                     break;
11993                  }
11994                  case 0x10: {  /* S */
11995                     DIP("mul.s f%d, f%d, f%d", fd, fs, ft);
11996                     IRExpr *rm = get_IR_roundingmode();
11997                     putFReg(fd, mkWidenFromF32(tyF, triop(Iop_MulF32, rm,
11998                                 getLoFromF64(tyF, getFReg(fs)),
11999                                 getLoFromF64(tyF, getFReg(ft)))));
12000                     break;
12001                  }
12002                  default:
12003                     goto decode_failure;
12004               }
12005               break;  /* MUL.fmt */
12006
12007            case 0x03:  /* DIV.fmt */
12008               switch (fmt) {
12009                  case 0x11: {  /* D */
12010                     DIP("div.d f%d, f%d, f%d", fd, fs, ft);
12011                     IRExpr *rm = get_IR_roundingmode();
12012                     putDReg(fd, triop(Iop_DivF64, rm, getDReg(fs),
12013                                 getDReg(ft)));
12014                     break;
12015                  }
12016                  case 0x10: {  /* S */
12017                     DIP("div.s f%d, f%d, f%d", fd, fs, ft);
12018                     calculateFCSR(fs, ft, DIVS, False, 2);
12019                     IRExpr *rm = get_IR_roundingmode();
12020                     putFReg(fd, mkWidenFromF32(tyF, triop(Iop_DivF32, rm,
12021                                 getLoFromF64(tyF, getFReg(fs)),
12022                                 getLoFromF64(tyF, getFReg(ft)))));
12023                     break;
12024                  }
12025                  default:
12026                     goto decode_failure;
12027               }
12028               break;  /* DIV.fmt */
12029
12030            case 0x01:  /* SUB.fmt */
12031               switch (fmt) {
12032                  case 0x11: {  /* D */
12033                     DIP("sub.d f%d, f%d, f%d", fd, fs, ft);
12034                     calculateFCSR(fs, ft, SUBD, False, 2);
12035                     IRExpr *rm = get_IR_roundingmode();
12036                     putDReg(fd, triop(Iop_SubF64, rm, getDReg(fs),
12037                                       getDReg(ft)));
12038                     break;
12039                  }
12040                  case 0x10: {  /* S */
12041                     DIP("sub.s f%d, f%d, f%d", fd, fs, ft);
12042                     calculateFCSR(fs, ft, SUBS, True, 2);
12043                     IRExpr *rm = get_IR_roundingmode();
12044                     putFReg(fd, mkWidenFromF32(tyF, triop(Iop_SubF32, rm,
12045                                 getLoFromF64(tyF, getFReg(fs)),
12046                                 getLoFromF64(tyF, getFReg(ft)))));
12047                     break;
12048                  }
12049                  default:
12050                     goto decode_failure;
12051               }
12052               break;  /* SUB.fmt */
12053
12054            case 0x06:  /* MOV.fmt */
12055               switch (fmt) {
12056                  case 0x11:  /* D */
12057                     DIP("mov.d f%d, f%d", fd, fs);
12058                     if (fp_mode64) {
12059                        putDReg(fd, getDReg(fs));
12060                     } else {
12061                        putFReg(fd, getFReg(fs));
12062                        putFReg(fd + 1, getFReg(fs + 1));
12063                     }
12064                     break;
12065                  case 0x10:  /* S */
12066                     DIP("mov.s f%d, f%d", fd, fs);
12067                     putFReg(fd, getFReg(fs));
12068                     break;
12069                  default:
12070                     goto decode_failure;
12071               }
12072               break;  /* MOV.fmt */
12073
12074            case 0x7:  /* neg.fmt */
12075               switch (fmt) {
12076                  case 0x10:  /* S */
12077                     DIP("neg.s f%d, f%d", fd, fs);
12078                     putFReg(fd, mkWidenFromF32(tyF, unop(Iop_NegF32,
12079                                 getLoFromF64(tyF, getFReg(fs)))));
12080                     break;
12081                  case 0x11:  /* D */
12082                     DIP("neg.d f%d, f%d", fd, fs);
12083                     putDReg(fd, unop(Iop_NegF64, getDReg(fs)));
12084                     break;
12085                  default:
12086                     goto decode_failure;
12087               }
12088               break;  /* case 0x7 */
12089
12090            case 0x08:  /* ROUND.L.fmt */
12091               switch (fmt) {
12092                  case 0x10:  /* S */
12093                     DIP("round.l.s f%d, f%d", fd, fs);
12094                     if (fp_mode64) {
12095                        calculateFCSR(fs, 0, ROUNDLS, True, 1);
12096                        t0 = newTemp(Ity_I64);
12097
12098                        assign(t0, binop(Iop_F32toI64S, mkU32(0x0),
12099                                         getLoFromF64(Ity_F64, getFReg(fs))));
12100
12101                        putDReg(fd, unop(Iop_ReinterpI64asF64, mkexpr(t0)));
12102                     } else {
12103                        ILLEGAL_INSTRUCTON;
12104                     }
12105                     break;
12106                  case 0x11:  /* D */
12107                     DIP("round.l.d f%d, f%d", fd, fs);
12108                     if (fp_mode64) {
12109                        calculateFCSR(fs, 0, ROUNDLD, False, 1);
12110                        putDReg(fd, binop(Iop_RoundF64toInt, mkU32(0x0),
12111                                          getDReg(fs)));
12112                     } else {
12113                        ILLEGAL_INSTRUCTON;
12114                     }
12115                     break;
12116                  default:
12117                    goto decode_failure;
12118
12119               }
12120               break;  /* ROUND.L.fmt */
12121
12122            case 0x09:  /* TRUNC.L.fmt */
12123               switch (fmt) {
12124                  case 0x10:  /* S */
12125                     DIP("trunc.l.s f%d, f%d", fd, fs);
12126                     if (fp_mode64) {
12127                        calculateFCSR(fs, 0, TRUNCLS, True, 1);
12128                        t0 = newTemp(Ity_I64);
12129                        assign(t0, binop(Iop_F32toI64S, mkU32(0x3),
12130                                         getLoFromF64(Ity_F64, getFReg(fs))));
12131
12132                        putDReg(fd, unop(Iop_ReinterpI64asF64, mkexpr(t0)));
12133                     } else {
12134                        ILLEGAL_INSTRUCTON;
12135                     }
12136                     break;
12137                  case 0x11:  /* D */
12138                     DIP("trunc.l.d f%d, f%d", fd, fs);
12139                     if (fp_mode64) {
12140                        calculateFCSR(fs, 0, TRUNCLD, False, 1);
12141                        putDReg(fd, binop(Iop_RoundF64toInt, mkU32(0x3),
12142                                          getDReg(fs)));
12143                     } else {
12144                        ILLEGAL_INSTRUCTON;
12145                     }
12146                     break;
12147                  default:
12148                     goto decode_failure;
12149                 }
12150              break;  /* TRUNC.L.fmt */
12151
12152            case 0x15:  /* RECIP.fmt */
12153               switch (fmt) {
12154                  case 0x10: {  /* S */
12155                     DIP("recip.s f%d, f%d", fd, fs);
12156                     IRExpr *rm = get_IR_roundingmode();
12157                     putFReg(fd, mkWidenFromF32(tyF, triop(Iop_DivF32,
12158                                 rm, unop(Iop_ReinterpI32asF32,
12159                                 mkU32(ONE_SINGLE)), getLoFromF64(tyF,
12160                                 getFReg(fs)))));
12161                     break;
12162                  }
12163                  case 0x11: {  /* D */
12164                     DIP("recip.d f%d, f%d", fd, fs);
12165                     IRExpr *rm = get_IR_roundingmode();
12166                     /* putDReg(fd, 1.0/getDreg(fs)); */
12167                     putDReg(fd, triop(Iop_DivF64, rm,
12168                                 unop(Iop_ReinterpI64asF64,
12169                                 mkU64(ONE_DOUBLE)), getDReg(fs)));
12170                     break;
12171                  }
12172               default:
12173                  goto decode_failure;
12174
12175               }
12176               break;  /* case 0x15 */
12177
12178            case 0x13:  /* MOVN.fmt */
12179               switch (fmt) {
12180               case 0x10:  /* S */
12181                  DIP("movn.s f%d, f%d, r%d", fd, fs, rt);
12182                  t1 = newTemp(Ity_F64);
12183                  t2 = newTemp(Ity_F64);
12184                  t3 = newTemp(Ity_I1);
12185                  t4 = newTemp(Ity_F64);
12186                  if (mode64) {
12187                     assign(t1, getFReg(fs));
12188                     assign(t2, getFReg(fd));
12189                     assign(t3, binop(Iop_CmpNE64, mkU64(0), getIReg(rt)));
12190                  } else {
12191                     if (fp_mode64) {
12192                        assign(t1, getFReg(fs));
12193                        assign(t2, getFReg(fd));
12194                        assign(t3, binop(Iop_CmpNE32, mkU32(0), getIReg(rt)));
12195                     } else {
12196                        assign(t1, unop(Iop_F32toF64, getFReg(fs)));
12197                        assign(t2, unop(Iop_F32toF64, getFReg(fd)));
12198                        assign(t3, binop(Iop_CmpNE32, mkU32(0), getIReg(rt)));
12199                     }
12200                  }
12201
12202                  assign(t4, IRExpr_ITE(mkexpr(t3), mkexpr(t1), mkexpr(t2)));
12203                  if (fp_mode64) {
12204                     IRTemp f = newTemp(Ity_F64);
12205                     IRTemp fd_hi = newTemp(Ity_I32);
12206                     t5 = newTemp(Ity_I64);
12207                     assign(f, getFReg(fd));
12208                     assign(fd_hi, unop(Iop_64HIto32, unop(Iop_ReinterpF64asI64,
12209                                        mkexpr(f))));
12210
12211                     assign(t5, mkWidenFrom32(Ity_I64, unop(Iop_64to32,
12212                                unop(Iop_ReinterpF64asI64, mkexpr(t4))), True));
12213
12214                     putFReg(fd, unop (Iop_ReinterpI64asF64, mkexpr(t5)));
12215                  } else
12216                     putFReg(fd, binop(Iop_F64toF32, get_IR_roundingmode(),
12217                                       mkexpr(t4)));
12218                  break;
12219               case 0x11:  /* D */
12220                  DIP("movn.d f%d, f%d, r%d", fd, fs, rt);
12221
12222                  t3 = newTemp(Ity_I1);
12223                  t4 = newTemp(Ity_F64);
12224
12225                  if (mode64)
12226                     assign(t3, binop(Iop_CmpNE64, mkU64(0), getIReg(rt)));
12227                  else
12228                     assign(t3, binop(Iop_CmpNE32, mkU32(0), getIReg(rt)));
12229
12230                  putDReg(fd, IRExpr_ITE(mkexpr(t3), getDReg(fs), getDReg(fd)));
12231                  break;
12232               default:
12233                  goto decode_failure;
12234               }
12235               break;  /* MOVN.fmt */
12236
12237            case 0x12:  /* MOVZ.fmt */
12238               switch (fmt) {
12239               case 0x10:  /* S */
12240                  DIP("movz.s f%d, f%d, r%d", fd, fs, rt);
12241
12242                  t1 = newTemp(Ity_F64);
12243                  t2 = newTemp(Ity_F64);
12244                  t3 = newTemp(Ity_I1);
12245                  t4 = newTemp(Ity_F64);
12246                  if (fp_mode64) {
12247                     assign(t1, getFReg(fs));
12248                     assign(t2, getFReg(fd));
12249                     if (mode64)
12250                        assign(t3, binop(Iop_CmpEQ64, mkU64(0), getIReg(rt)));
12251                     else
12252                        assign(t3, binop(Iop_CmpEQ32, mkU32(0), getIReg(rt)));
12253                  } else {
12254                     assign(t1, unop(Iop_F32toF64, getFReg(fs)));
12255                     assign(t2, unop(Iop_F32toF64, getFReg(fd)));
12256                     assign(t3, binop(Iop_CmpEQ32, mkU32(0), getIReg(rt)));
12257                  }
12258                  assign(t4, IRExpr_ITE(mkexpr(t3), mkexpr(t1), mkexpr(t2)));
12259
12260                 if (fp_mode64) {
12261                     IRTemp f = newTemp(Ity_F64);
12262                     IRTemp fd_hi = newTemp(Ity_I32);
12263                     t7 = newTemp(Ity_I64);
12264                     assign(f, getFReg(fd));
12265                     assign(fd_hi, unop(Iop_64HIto32,
12266                                   unop(Iop_ReinterpF64asI64, mkexpr(f))));
12267                     assign(t7, mkWidenFrom32(Ity_I64, unop(Iop_64to32,
12268                                unop(Iop_ReinterpF64asI64, mkexpr(t4))), True));
12269
12270                     putFReg(fd, unop(Iop_ReinterpI64asF64, mkexpr(t7)));
12271                  } else
12272                     putFReg(fd, binop(Iop_F64toF32, get_IR_roundingmode(),
12273                                       mkexpr(t4)));
12274
12275                  break;
12276               case 0x11:  /* D */
12277                  DIP("movz.d f%d, f%d, r%d", fd, fs, rt);
12278                  t3 = newTemp(Ity_I1);
12279                  t4 = newTemp(Ity_F64);
12280                  if (mode64)
12281                     assign(t3, binop(Iop_CmpEQ64, mkU64(0), getIReg(rt)));
12282                  else
12283                     assign(t3, binop(Iop_CmpEQ32, mkU32(0), getIReg(rt)));
12284
12285                  putDReg(fd, IRExpr_ITE(mkexpr(t3), getDReg(fs), getDReg(fd)));
12286                  break;
12287               default:
12288                  goto decode_failure;
12289               }
12290               break;  /* MOVZ.fmt */
12291
12292            case 0x11:  /* MOVT.fmt */
12293               if (tf == 1) {
12294                  UInt mov_cc = get_mov_cc(cins);
12295                  switch (fmt) {  /* MOVCF = 010001 */
12296                  case 0x11:  /* D */
12297                     DIP("movt.d f%d, f%d, %d", fd, fs, mov_cc);
12298                     t1 = newTemp(Ity_I1);
12299                     t2 = newTemp(Ity_I32);
12300                     t3 = newTemp(Ity_I1);
12301                     t4 = newTemp(Ity_F64);
12302
12303                     assign(t1, binop(Iop_CmpEQ32, mkU32(0), mkU32(mov_cc)));
12304                     assign(t2, IRExpr_ITE(mkexpr(t1),
12305                                           binop(Iop_And32,
12306                                                 binop(Iop_Shr32, getFCSR(),
12307                                                       mkU8(23)),
12308                                                 mkU32(0x1)),
12309                                           binop(Iop_And32,
12310                                                 binop(Iop_Shr32, getFCSR(),
12311                                                       mkU8(24 + mov_cc)),
12312                                                 mkU32(0x1))
12313                                           ));
12314
12315                     assign(t3, binop(Iop_CmpEQ32, mkU32(1), mkexpr(t2)));
12316                     assign(t4, IRExpr_ITE(mkexpr(t3),
12317                                           getDReg(fs), getDReg(fd)));
12318                     putDReg(fd, mkexpr(t4));
12319                     break;
12320                  case 0x10:  /* S */
12321                     DIP("movt.s f%d, f%d, %d", fd, fs, mov_cc);
12322                     t1 = newTemp(Ity_I1);
12323                     t2 = newTemp(Ity_I32);
12324                     t3 = newTemp(Ity_I1);
12325                     t4 = newTemp(Ity_F64);
12326                     t5 = newTemp(Ity_F64);
12327                     t6 = newTemp(Ity_F64);
12328                     t7 = newTemp(Ity_I64);
12329
12330                     if (fp_mode64) {
12331                        assign(t5, getFReg(fs));
12332                        assign(t6, getFReg(fd));
12333                     } else {
12334                        assign(t5, unop(Iop_F32toF64, getFReg(fs)));
12335                        assign(t6, unop(Iop_F32toF64, getFReg(fd)));
12336                     }
12337
12338                     assign(t1, binop(Iop_CmpEQ32, mkU32(0), mkU32(mov_cc)));
12339                     assign(t2, IRExpr_ITE(mkexpr(t1),
12340                                           binop(Iop_And32,
12341                                                 binop(Iop_Shr32, getFCSR(),
12342                                                       mkU8(23)),
12343                                                 mkU32(0x1)),
12344                                           binop(Iop_And32,
12345                                                 binop(Iop_Shr32, getFCSR(),
12346                                                       mkU8(24 + mov_cc)),
12347                                                 mkU32(0x1))
12348                                           ));
12349
12350                     assign(t3, binop(Iop_CmpEQ32, mkU32(1), mkexpr(t2)));
12351                     assign(t4, IRExpr_ITE(mkexpr(t3),
12352                                           mkexpr(t5), mkexpr(t6)));
12353
12354                     if (fp_mode64) {
12355                        IRTemp f = newTemp(Ity_F64);
12356                        IRTemp fd_hi = newTemp(Ity_I32);
12357                        assign(f, getFReg(fd));
12358                        assign(fd_hi, unop(Iop_64HIto32,
12359                                      unop(Iop_ReinterpF64asI64, mkexpr(f))));
12360                        assign(t7, mkWidenFrom32(Ity_I64, unop(Iop_64to32,
12361                                      unop(Iop_ReinterpF64asI64, mkexpr(t4))),
12362                                      True));
12363
12364                        putFReg(fd, unop(Iop_ReinterpI64asF64, mkexpr(t7)));
12365                     } else
12366                        putFReg(fd, binop(Iop_F64toF32, get_IR_roundingmode(),
12367                                          mkexpr(t4)));
12368                     break;
12369                  default:
12370                     goto decode_failure;
12371                  }
12372               } else if (tf == 0)  /* movf.fmt */
12373               {
12374                  UInt mov_cc = get_mov_cc(cins);
12375                  switch (fmt)  /* MOVCF = 010001 */
12376                  {
12377                  case 0x11:  /* D */
12378                     DIP("movf.d f%d, f%d, %d", fd, fs, mov_cc);
12379                     t1 = newTemp(Ity_I1);
12380                     t2 = newTemp(Ity_I32);
12381                     t3 = newTemp(Ity_I1);
12382                     t4 = newTemp(Ity_F64);
12383
12384                     assign(t1, binop(Iop_CmpEQ32, mkU32(0), mkU32(mov_cc)));
12385                     assign(t2, IRExpr_ITE(mkexpr(t1),
12386                                           binop(Iop_And32,
12387                                                 binop(Iop_Shr32, getFCSR(),
12388                                                       mkU8(23)),
12389                                                 mkU32(0x1)),
12390                                           binop(Iop_And32,
12391                                                 binop(Iop_Shr32, getFCSR(),
12392                                                       mkU8(24 + mov_cc)),
12393                                                 mkU32(0x1))
12394                                           ));
12395
12396                     assign(t3, binop(Iop_CmpEQ32, mkU32(0), mkexpr(t2)));
12397                     assign(t4, IRExpr_ITE(mkexpr(t3),
12398                                           getDReg(fs), getDReg(fd)));
12399                     putDReg(fd, mkexpr(t4));
12400                     break;
12401                  case 0x10:  /* S */
12402                     DIP("movf.s f%d, f%d, %d", fd, fs, mov_cc);
12403                     t1 = newTemp(Ity_I1);
12404                     t2 = newTemp(Ity_I32);
12405                     t3 = newTemp(Ity_I1);
12406                     t4 = newTemp(Ity_F64);
12407                     t5 = newTemp(Ity_F64);
12408                     t6 = newTemp(Ity_F64);
12409
12410                     if (fp_mode64) {
12411                        assign(t5, getFReg(fs));
12412                        assign(t6, getFReg(fd));
12413                     } else {
12414                        assign(t5, unop(Iop_F32toF64, getFReg(fs)));
12415                        assign(t6, unop(Iop_F32toF64, getFReg(fd)));
12416                     }
12417
12418                     assign(t1, binop(Iop_CmpEQ32, mkU32(0), mkU32(mov_cc)));
12419                     assign(t2, IRExpr_ITE(mkexpr(t1),
12420                                           binop(Iop_And32,
12421                                                 binop(Iop_Shr32, getFCSR(),
12422                                                       mkU8(23)),
12423                                                 mkU32(0x1)),
12424                                           binop(Iop_And32,
12425                                                 binop(Iop_Shr32, getFCSR(),
12426                                                       mkU8(24 + mov_cc)),
12427                                                 mkU32(0x1))
12428                                           ));
12429
12430                     assign(t3, binop(Iop_CmpEQ32, mkU32(0), mkexpr(t2)));
12431                     assign(t4, IRExpr_ITE(mkexpr(t3),
12432                                           mkexpr(t5), mkexpr(t6)));
12433
12434                     if (fp_mode64) {
12435                        IRTemp f = newTemp(Ity_F64);
12436                        IRTemp fd_hi = newTemp(Ity_I32);
12437                        t7 = newTemp(Ity_I64);
12438                        assign(f, getFReg(fd));
12439                        assign(fd_hi, unop(Iop_64HIto32,
12440                                      unop(Iop_ReinterpF64asI64, mkexpr(f))));
12441                        assign(t7, mkWidenFrom32(Ity_I64, unop(Iop_64to32,
12442                                   unop(Iop_ReinterpF64asI64, mkexpr(t4))),
12443                                   True));
12444
12445                        putFReg(fd, unop(Iop_ReinterpI64asF64, mkexpr(t7)));
12446                     } else
12447                        putFReg(fd, binop(Iop_F64toF32, get_IR_roundingmode(),
12448                                          mkexpr(t4)));
12449                     break;
12450                  default:
12451                     goto decode_failure;
12452                  }
12453               }
12454
12455               break;  /* MOVT.fmt */
12456
12457            case 0x0:  /* add.fmt */
12458               switch (fmt) {
12459               case 0x10: {  /* S */
12460                  DIP("add.s f%d, f%d, f%d", fd, fs, ft);
12461                  calculateFCSR(fs, ft, ADDS, True, 2);
12462                  IRExpr *rm = get_IR_roundingmode();
12463                  putFReg(fd, mkWidenFromF32(tyF, triop(Iop_AddF32, rm,
12464                              getLoFromF64(tyF, getFReg(fs)),
12465                              getLoFromF64(tyF, getFReg(ft)))));
12466                  break;
12467               }
12468               case 0x11: {  /* D */
12469                  DIP("add.d f%d, f%d, f%d", fd, fs, ft);
12470                  calculateFCSR(fs, ft, ADDD, False, 2);
12471                  IRExpr *rm = get_IR_roundingmode();
12472                  putDReg(fd, triop(Iop_AddF64, rm, getDReg(fs), getDReg(ft)));
12473                  break;
12474               }
12475
12476               case 0x4:  /* MTC1 (Move Word to Floating Point) */
12477                  DIP("mtc1 r%d, f%d", rt, fs);
12478                  if (fp_mode64) {
12479                     t0 = newTemp(Ity_I32);
12480                     t1 = newTemp(Ity_F32);
12481                     assign(t0, mkNarrowTo32(ty, getIReg(rt)));
12482                     assign(t1, unop(Iop_ReinterpI32asF32, mkexpr(t0)));
12483
12484                     putFReg(fs, mkWidenFromF32(tyF, mkexpr(t1)));
12485                  } else
12486                     putFReg(fs, unop(Iop_ReinterpI32asF32, getIReg(rt)));
12487                  break;
12488
12489               case 0x5:  /* Doubleword Move to Floating Point DMTC1; MIPS64 */
12490                  DIP("dmtc1 r%d, f%d", rt, fs);
12491                  vassert(mode64);
12492                  putFReg(fs, unop(Iop_ReinterpI64asF64, getIReg(rt)));
12493                  break;
12494
12495               case 0x0:  /* MFC1 */
12496                  DIP("mfc1 r%d, f%d", rt, fs);
12497                  if (fp_mode64) {
12498                     t0 = newTemp(Ity_I64);
12499                     t1 = newTemp(Ity_I32);
12500                     assign(t0, unop(Iop_ReinterpF64asI64, getFReg(fs)));
12501                     assign(t1, unop(Iop_64to32, mkexpr(t0)));
12502                     putIReg(rt, mkWidenFrom32(ty, mkexpr(t1), True));
12503                  } else
12504                     putIReg(rt, unop(Iop_ReinterpF32asI32, getFReg(fs)));
12505                  break;
12506
12507               case 0x1:  /* Doubleword Move from Floating Point DMFC1;
12508                             MIPS64 */
12509                  DIP("dmfc1 r%d, f%d", rt, fs);
12510                  putIReg(rt, unop(Iop_ReinterpF64asI64, getFReg(fs)));
12511                  break;
12512
12513               case 0x6:  /* CTC1 */
12514                  DIP("ctc1 r%d, f%d", rt, fs);
12515                  t0 = newTemp(Ity_I32);
12516                  t1 = newTemp(Ity_I32);
12517                  t2 = newTemp(Ity_I32);
12518                  t3 = newTemp(Ity_I32);
12519                  t4 = newTemp(Ity_I32);
12520                  t5 = newTemp(Ity_I32);
12521                  t6 = newTemp(Ity_I32);
12522                  assign(t0, mkNarrowTo32(ty, getIReg(rt)));
12523                  if (fs == 25) {  /* FCCR */
12524                     assign(t1, binop(Iop_Shl32, binop(Iop_And32, mkexpr(t0),
12525                                      mkU32(0x000000FE)), mkU8(24)));
12526                     assign(t2, binop(Iop_And32, mkexpr(t0),
12527                                      mkU32(0x01000000)));
12528                     assign(t3, binop(Iop_Shl32, binop(Iop_And32, mkexpr(t0),
12529                                      mkU32(0x00000001)), mkU8(23)));
12530                     assign(t4, binop(Iop_And32, mkexpr(t0),
12531                                      mkU32(0x007FFFFF)));
12532                     putFCSR(binop(Iop_Or32, binop(Iop_Or32, mkexpr(t1),
12533                                   mkexpr(t2)), binop(Iop_Or32, mkexpr(t3),
12534                                   mkexpr(t4))));
12535                  } else if (fs == 26) {  /* FEXR */
12536                     assign(t1, binop(Iop_And32, getFCSR(), mkU32(0xFFFC0000)));
12537                     assign(t2, binop(Iop_And32, mkexpr(t0),
12538                                      mkU32(0x0003F000)));
12539                     assign(t3, binop(Iop_And32, getFCSR(), mkU32(0x00000F80)));
12540                     assign(t4, binop(Iop_And32, mkexpr(t0),
12541                                      mkU32(0x0000007C)));
12542                     assign(t5, binop(Iop_And32, getFCSR(), mkU32(0x00000003)));
12543                     putFCSR(binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Or32,
12544                                   mkexpr(t1), mkexpr(t2)), binop(Iop_Or32,
12545                                   mkexpr(t3), mkexpr(t4))), mkexpr(t5)));
12546                  } else if (fs == 28) {
12547                     assign(t1, binop(Iop_And32, getFCSR(), mkU32(0xFE000000)));
12548                     assign(t2, binop(Iop_Shl32, binop(Iop_And32, mkexpr(t0),
12549                                mkU32(0x00000002)), mkU8(22)));
12550                     assign(t3, binop(Iop_And32, getFCSR(), mkU32(0x00FFF000)));
12551                     assign(t4, binop(Iop_And32, mkexpr(t0),
12552                                mkU32(0x00000F80)));
12553                     assign(t5, binop(Iop_And32, getFCSR(), mkU32(0x0000007C)));
12554                     assign(t6, binop(Iop_And32, mkexpr(t0),
12555                                mkU32(0x00000003)));
12556                     putFCSR(binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Or32,
12557                                   mkexpr(t1), mkexpr(t2)), binop(Iop_Or32,
12558                                   mkexpr(t3), mkexpr(t4))), binop(Iop_Or32,
12559                                   mkexpr(t5), mkexpr(t6))));
12560                  } else if (fs == 31) {
12561                     putFCSR(mkexpr(t0));
12562                  }
12563                  break;
12564               case 0x2:  /* CFC1 */
12565                  DIP("cfc1 r%d, f%d", rt, fs);
12566                  t0 = newTemp(Ity_I32);
12567                  t1 = newTemp(Ity_I32);
12568                  t2 = newTemp(Ity_I32);
12569                  t3 = newTemp(Ity_I32);
12570                  t4 = newTemp(Ity_I32);
12571                  t5 = newTemp(Ity_I32);
12572                  t6 = newTemp(Ity_I32);
12573                  assign(t0, getFCSR());
12574                  if (fs == 0) {
12575                     putIReg(rt, mkWidenFrom32(ty,
12576                             IRExpr_Get(offsetof(VexGuestMIPS32State,
12577                                                 guest_FIR),
12578                                       Ity_I32),
12579                             False));
12580                  } else if (fs == 25) {
12581                     assign(t1, mkU32(0x000000FF));
12582                     assign(t2, binop(Iop_Shr32, binop(Iop_And32, mkexpr(t0),
12583                                      mkU32(0xFE000000)), mkU8(25)));
12584                     assign(t3, binop(Iop_Shr32, binop(Iop_And32, mkexpr(t0),
12585                                      mkU32(0x00800000)), mkU8(23)));
12586                     putIReg(rt, mkWidenFrom32(ty, binop(Iop_Or32,
12587                                 binop(Iop_Or32, mkexpr(t1), mkexpr(t2)),
12588                                 mkexpr(t3)), False));
12589                  } else if (fs == 26) {
12590                     assign(t1, mkU32(0xFFFFF07C));
12591                     assign(t2, binop(Iop_And32, mkexpr(t0),
12592                                mkU32(0x0003F000)));
12593                     assign(t3, binop(Iop_And32, mkexpr(t0),
12594                                      mkU32(0x0000007C)));
12595                     putIReg(rt, mkWidenFrom32(ty, binop(Iop_Or32,
12596                                 binop(Iop_Or32, mkexpr(t1), mkexpr(t2)),
12597                                 mkexpr(t3)), False));
12598                  } else if (fs == 28) {
12599                     assign(t1, mkU32(0x00000F87));
12600                     assign(t2, binop(Iop_And32, mkexpr(t0),
12601                                      mkU32(0x00000F83)));
12602                     assign(t3, binop(Iop_Shr32, binop(Iop_And32, mkexpr(t0),
12603                                      mkU32(0x01000000)), mkU8(22)));
12604                     putIReg(rt, mkWidenFrom32(ty, binop(Iop_Or32,
12605                                 binop(Iop_Or32, mkexpr(t1), mkexpr(t2)),
12606                                 mkexpr(t3)), False));
12607                  } else if (fs == 31) {
12608                     putIReg(rt, mkWidenFrom32(ty, getFCSR(), False));
12609                  }
12610                  break;
12611               default:
12612                  goto decode_failure;
12613               }
12614               break;
12615
12616            case 0x21:  /* CVT.D */
12617               switch (fmt) {
12618                  case 0x10:  /* S */
12619                     DIP("cvt.d.s f%d, f%d", fd, fs);
12620                     calculateFCSR(fs, 0, CVTDS, True, 1);
12621                     if (fp_mode64) {
12622                        t0 = newTemp(Ity_I64);
12623                        t1 = newTemp(Ity_I32);
12624                        t3 = newTemp(Ity_F32);
12625                        t4 = newTemp(Ity_F32);
12626                        /* get lo half of FPR */
12627                        assign(t0, unop(Iop_ReinterpF64asI64, getFReg(fs)));
12628
12629                        assign(t1, unop(Iop_64to32, mkexpr(t0)));
12630
12631                        assign(t3, unop(Iop_ReinterpI32asF32, mkexpr(t1)));
12632
12633                        putFReg(fd, unop(Iop_F32toF64, mkexpr(t3)));
12634                     } else
12635                        putDReg(fd, unop(Iop_F32toF64, getFReg(fs)));
12636                     break;
12637
12638                  case 0x14:
12639                     DIP("cvt.d.w %d, %d", fd, fs);
12640                     calculateFCSR(fs, 0, CVTDW, True, 1);
12641                     if (fp_mode64) {
12642                        t0 = newTemp(Ity_I64);
12643                        t1 = newTemp(Ity_I32);
12644                        t3 = newTemp(Ity_F32);
12645                        t4 = newTemp(Ity_F32);
12646                        /* get lo half of FPR */
12647                        assign(t0, unop(Iop_ReinterpF64asI64, getFReg(fs)));
12648
12649                        assign(t1, unop(Iop_64to32, mkexpr(t0)));
12650                        putDReg(fd,unop(Iop_I32StoF64, mkexpr(t1)));
12651                        break;
12652                     } else {
12653                        t0 = newTemp(Ity_I32);
12654                        assign(t0, unop(Iop_ReinterpF32asI32, getFReg(fs)));
12655                        putDReg(fd, unop(Iop_I32StoF64, mkexpr(t0)));
12656                        break;
12657                     }
12658
12659                  case 0x15: {  /* L */
12660                     if (fp_mode64) {
12661                        DIP("cvt.d.l %d, %d", fd, fs);
12662                        calculateFCSR(fs, 0, CVTDL, False, 1);
12663                        t0 = newTemp(Ity_I64);
12664                        assign(t0, unop(Iop_ReinterpF64asI64, getFReg(fs)));
12665
12666                        putFReg(fd, binop(Iop_I64StoF64,
12667                                          get_IR_roundingmode(), mkexpr(t0)));
12668                        break;
12669                     } else
12670                        goto decode_failure;
12671                  }
12672                  default:
12673                     goto decode_failure;
12674               }
12675               break;  /* CVT.D */
12676
12677            case 0x20:  /* cvt.s */
12678               switch (fmt) {
12679                  case 0x14:  /* W */
12680                     DIP("cvt.s.w %d, %d", fd, fs);
12681                     calculateFCSR(fs, 0, CVTSW, True, 1);
12682                     if (fp_mode64) {
12683                        t0 = newTemp(Ity_I64);
12684                        t1 = newTemp(Ity_I32);
12685                        t3 = newTemp(Ity_F32);
12686                        t4 = newTemp(Ity_F32);
12687                        /* get lo half of FPR */
12688                        assign(t0, unop(Iop_ReinterpF64asI64, getFReg(fs)));
12689
12690                        assign(t1, unop(Iop_64to32, mkexpr(t0)));
12691                        putFReg(fd, mkWidenFromF32(tyF, binop(Iop_I32StoF32,
12692                                    get_IR_roundingmode(), mkexpr(t1))));
12693                     } else {
12694                        t0 = newTemp(Ity_I32);
12695                        assign(t0, unop(Iop_ReinterpF32asI32, getFReg(fs)));
12696                        putFReg(fd, binop(Iop_I32StoF32, get_IR_roundingmode(),
12697                                    mkexpr(t0)));
12698                     }
12699                     break;
12700
12701                  case 0x11:  /* D */
12702                     DIP("cvt.s.d %d, %d", fd, fs);
12703                     calculateFCSR(fs, 0, CVTSD, False, 1);
12704                     t0 = newTemp(Ity_F32);
12705                     assign(t0, binop(Iop_F64toF32, get_IR_roundingmode(),
12706                                      getDReg(fs)));
12707                     putFReg(fd, mkWidenFromF32(tyF, mkexpr(t0)));
12708                     break;
12709
12710                  case 0x15:  /* L */
12711                     DIP("cvt.s.l %d, %d", fd, fs);
12712                     calculateFCSR(fs, 0, CVTSL, False, 1);
12713                     t0 = newTemp(Ity_I64);
12714                     assign(t0, unop(Iop_ReinterpF64asI64, getFReg(fs)));
12715
12716                     putFReg(fd, mkWidenFromF32(tyF, binop(Iop_I64StoF32,
12717                                 get_IR_roundingmode(), mkexpr(t0))));
12718                     break;
12719
12720                  default:
12721                     goto decode_failure;
12722               }
12723               break;  /* cvt.s */
12724
12725            case 0x24:  /* cvt.w */
12726               switch (fmt) {
12727               case 0x10:  /* S */
12728                  DIP("cvt.w.s %d, %d", fd, fs);
12729                  calculateFCSR(fs, 0, CVTWS, True, 1);
12730                  putFReg(fd,
12731                          mkWidenFromF32(tyF,
12732                                         binop(Iop_RoundF32toInt,
12733                                               get_IR_roundingmode(),
12734                                               getLoFromF64(tyF, getFReg(fs))))
12735                         );
12736                  break;
12737
12738               case 0x11:
12739                  DIP("cvt.w.d %d, %d", fd, fs);
12740                  calculateFCSR(fs, 0, CVTWD, False, 1);
12741                  t0 = newTemp(Ity_I32);
12742                  t1 = newTemp(Ity_F32);
12743                  assign(t0, binop(Iop_F64toI32S, get_IR_roundingmode(),
12744                                   getDReg(fs)));
12745                  assign(t1, unop(Iop_ReinterpI32asF32, mkexpr(t0)));
12746                  putFReg(fd, mkWidenFromF32(tyF, mkexpr(t1)));
12747                  break;
12748
12749               default:
12750                  goto decode_failure;
12751
12752               }
12753               break;
12754
12755            case 0x25:  /* cvt.l */
12756               switch (fmt) {
12757                  case 0x10:  /* S */
12758                     DIP("cvt.l.s %d, %d", fd, fs);
12759                     if (fp_mode64) {
12760                        calculateFCSR(fs, 0, CVTLS, True, 1);
12761                        t0 = newTemp(Ity_I64);
12762
12763                        assign(t0, binop(Iop_F32toI64S, get_IR_roundingmode(),
12764                                         getLoFromF64(tyF, getFReg(fs))));
12765
12766                        putDReg(fd, unop(Iop_ReinterpI64asF64, mkexpr(t0)));
12767                     } else {
12768                        ILLEGAL_INSTRUCTON;
12769                     }
12770                     break;
12771
12772                  case 0x11: {  /* D */
12773                     DIP("cvt.l.d %d, %d", fd, fs);
12774                     if (fp_mode64) {
12775                        calculateFCSR(fs, 0, CVTLD, False, 1);
12776                        putDReg(fd, binop(Iop_RoundF64toInt,
12777                                get_IR_roundingmode(), getDReg(fs)));
12778                     } else {
12779                        ILLEGAL_INSTRUCTON;
12780                     }
12781                     break;
12782                  }
12783
12784                  default:
12785                     goto decode_failure;
12786               }
12787               break;
12788
12789            case 0x0B:  /* FLOOR.L.fmt */
12790               switch (fmt) {
12791                  case 0x10:  /* S */
12792                     DIP("floor.l.s %d, %d", fd, fs);
12793                     if (fp_mode64) {
12794                        calculateFCSR(fs, 0, FLOORLS, True, 1);
12795                        t0 = newTemp(Ity_I64);
12796
12797                        assign(t0, binop(Iop_F32toI64S, mkU32(0x1),
12798                                         getLoFromF64(tyF, getFReg(fs))));
12799
12800                        putDReg(fd, unop(Iop_ReinterpI64asF64, mkexpr(t0)));
12801                     } else {
12802                        ILLEGAL_INSTRUCTON;
12803                     }
12804                     break;
12805
12806                  case 0x11:  /* D */
12807                     DIP("floor.l.d %d, %d", fd, fs);
12808                     if (fp_mode64) {
12809                        calculateFCSR(fs, 0, FLOORLD, False, 1);
12810                        putDReg(fd, binop(Iop_RoundF64toInt, mkU32(0x1),
12811                                          getDReg(fs)));
12812                     } else {
12813                        ILLEGAL_INSTRUCTON;
12814                     }
12815                     break;
12816                  default:
12817                     goto decode_failure;
12818               }
12819               break;
12820
12821            case 0x0C:  /* ROUND.W.fmt */
12822               switch (fmt) {
12823                  case 0x10:  /* S */
12824                     DIP("round.w.s f%d, f%d", fd, fs);
12825                     calculateFCSR(fs, 0, ROUNDWS, True, 1);
12826                     if (fp_mode64) {
12827                        t0 = newTemp(Ity_I64);
12828                        t1 = newTemp(Ity_I32);
12829                        t3 = newTemp(Ity_F32);
12830                        t4 = newTemp(Ity_F32);
12831                        /* get lo half of FPR */
12832                        assign(t0, unop(Iop_ReinterpF64asI64, getFReg(fs)));
12833
12834                        assign(t1, unop(Iop_64to32, mkexpr(t0)));
12835
12836                        assign(t3, unop(Iop_ReinterpI32asF32, mkexpr(t1)));
12837
12838                        assign(t4, binop(Iop_RoundF32toInt, mkU32(0x0),
12839                                         mkexpr(t3)));
12840
12841                        putFReg(fd, mkWidenFromF32(tyF, mkexpr(t4)));
12842                     } else
12843                        putFReg(fd, binop(Iop_RoundF32toInt, mkU32(0x0),
12844                                          getFReg(fs)));
12845                     break;
12846
12847                  case 0x11:  /* D */
12848                     DIP("round.w.d f%d, f%d", fd, fs);
12849                     calculateFCSR(fs, 0, ROUNDWD, False, 1);
12850                     if (fp_mode64) {
12851                        t0 = newTemp(Ity_I32);
12852                        assign(t0, binop(Iop_F64toI32S, mkU32(0x0),
12853                                         getDReg(fs)));
12854                        putFReg(fd, mkWidenFromF32(tyF,
12855                                    unop(Iop_ReinterpI32asF32, mkexpr(t0))));
12856                     } else {
12857                        t0 = newTemp(Ity_I32);
12858
12859                        assign(t0, binop(Iop_F64toI32S, mkU32(0x0),
12860                                         getDReg(fs)));
12861
12862                        putFReg(fd, unop(Iop_ReinterpI32asF32, mkexpr(t0)));
12863                     }
12864                     break;
12865                  default:
12866                     goto decode_failure;
12867
12868                  }
12869                  break;  /* ROUND.W.fmt */
12870
12871            case 0x0F:  /* FLOOR.W.fmt */
12872               switch (fmt) {
12873                  case 0x10:  /* S */
12874                     DIP("floor.w.s f%d, f%d", fd, fs);
12875                     calculateFCSR(fs, 0, FLOORWS, True, 1);
12876                     if (fp_mode64) {
12877                        t0 = newTemp(Ity_I64);
12878                        t1 = newTemp(Ity_I32);
12879                        t3 = newTemp(Ity_F32);
12880                        t4 = newTemp(Ity_F32);
12881                        /* get lo half of FPR */
12882                        assign(t0, unop(Iop_ReinterpF64asI64, getFReg(fs)));
12883
12884                        assign(t1, unop(Iop_64to32, mkexpr(t0)));
12885
12886                        assign(t3, unop(Iop_ReinterpI32asF32, mkexpr(t1)));
12887
12888                        assign(t4, binop(Iop_RoundF32toInt, mkU32(0x1),
12889                                         mkexpr(t3)));
12890
12891                        putFReg(fd, mkWidenFromF32(tyF, mkexpr(t4)));
12892                     } else
12893                        putFReg(fd, binop(Iop_RoundF32toInt, mkU32(0x1),
12894                                         getFReg(fs)));
12895                     break;
12896
12897                  case 0x11:  /* D */
12898                     DIP("floor.w.d f%d, f%d", fd, fs);
12899                     calculateFCSR(fs, 0, FLOORWD, False, 1);
12900                     if (fp_mode64) {
12901                        t0 = newTemp(Ity_I32);
12902                        assign(t0, binop(Iop_F64toI32S, mkU32(0x1),
12903                                         getDReg(fs)));
12904                        putFReg(fd, mkWidenFromF32(tyF,
12905                                    unop(Iop_ReinterpI32asF32, mkexpr(t0))));
12906                        break;
12907                     } else {
12908                        t0 = newTemp(Ity_I32);
12909
12910                        assign(t0, binop(Iop_F64toI32S, mkU32(0x1),
12911                                         getDReg(fs)));
12912
12913                        putFReg(fd, unop(Iop_ReinterpI32asF32, mkexpr(t0)));
12914                        break;
12915                     }
12916                  default:
12917                     goto decode_failure;
12918
12919               }
12920               break;  /* FLOOR.W.fmt */
12921
12922            case 0x0D:  /* TRUNC.W */
12923               switch (fmt) {
12924                  case 0x10:  /* S */
12925                     DIP("trunc.w.s %d, %d", fd, fs);
12926                     calculateFCSR(fs, 0, TRUNCWS, True, 1);
12927                     if (fp_mode64) {
12928                        t0 = newTemp(Ity_I64);
12929                        t1 = newTemp(Ity_I32);
12930                        t3 = newTemp(Ity_F32);
12931                        t4 = newTemp(Ity_F32);
12932                        /* get lo half of FPR */
12933                        assign(t0, unop(Iop_ReinterpF64asI64, getFReg(fs)));
12934
12935                        assign(t1, unop(Iop_64to32, mkexpr(t0)));
12936
12937                        assign(t3, unop(Iop_ReinterpI32asF32, mkexpr(t1)));
12938
12939                        assign(t4, binop(Iop_RoundF32toInt, mkU32(0x3),
12940                                         mkexpr(t3)));
12941
12942                        putFReg(fd, mkWidenFromF32(tyF, mkexpr(t4)));
12943                     } else
12944                        putFReg(fd, binop(Iop_RoundF32toInt, mkU32(0x3),
12945                                       getFReg(fs)));
12946                     break;
12947                  case 0x11:  /* D */
12948                     DIP("trunc.w.d %d, %d", fd, fs);
12949                     calculateFCSR(fs, 0, TRUNCWD, False, 1);
12950                     if (fp_mode64) {
12951                        t0 = newTemp(Ity_I32);
12952
12953                        assign(t0, binop(Iop_F64toI32S, mkU32(0x3),
12954                                         getFReg(fs)));
12955
12956                        putFReg(fd, mkWidenFromF32(tyF,
12957                                    unop(Iop_ReinterpI32asF32, mkexpr(t0))));
12958                     } else {
12959                        t0 = newTemp(Ity_I32);
12960
12961                        assign(t0, binop(Iop_F64toI32S, mkU32(0x3),
12962                                         getDReg(fs)));
12963
12964                        putFReg(fd, unop(Iop_ReinterpI32asF32, mkexpr(t0)));
12965                     }
12966                     break;
12967                  default:
12968                     goto decode_failure;
12969
12970               }
12971               break;
12972
12973            case 0x0E:  /* CEIL.W.fmt */
12974               switch (fmt) {
12975                  case 0x10:  /* S */
12976                     DIP("ceil.w.s %d, %d", fd, fs);
12977                     calculateFCSR(fs, 0, CEILWS, True, 1);
12978                     if (fp_mode64) {
12979                        t0 = newTemp(Ity_I64);
12980                        t1 = newTemp(Ity_I32);
12981                        t3 = newTemp(Ity_F32);
12982                        t4 = newTemp(Ity_F32);
12983                        /* get lo half of FPR */
12984                        assign(t0, unop(Iop_ReinterpF64asI64, getFReg(fs)));
12985
12986                        assign(t1, unop(Iop_64to32, mkexpr(t0)));
12987
12988                        assign(t3, unop(Iop_ReinterpI32asF32, mkexpr(t1)));
12989
12990                        assign(t4, binop(Iop_RoundF32toInt, mkU32(0x2),
12991                                         mkexpr(t3)));
12992
12993                        putFReg(fd, mkWidenFromF32(tyF, mkexpr(t4)));
12994                     } else
12995                        putFReg(fd, binop(Iop_RoundF32toInt, mkU32(0x2),
12996                                          getFReg(fs)));
12997                     break;
12998
12999                  case 0x11:  /* D */
13000                     DIP("ceil.w.d %d, %d", fd, fs);
13001                     calculateFCSR(fs, 0, CEILWD, False, 1);
13002                     if (!fp_mode64) {
13003                        t0 = newTemp(Ity_I32);
13004                        assign(t0, binop(Iop_F64toI32S, mkU32(0x2),
13005                                         getDReg(fs)));
13006                        putFReg(fd, unop(Iop_ReinterpI32asF32, mkexpr(t0)));
13007                     } else {
13008                        t0 = newTemp(Ity_I32);
13009                        assign(t0, binop(Iop_F64toI32S, mkU32(0x2),
13010                                         getDReg(fs)));
13011                        putFReg(fd, mkWidenFromF32(tyF,
13012                                    unop(Iop_ReinterpI32asF32, mkexpr(t0))));
13013                     }
13014                     break;
13015                  default:
13016                     goto decode_failure;
13017
13018               }
13019               break;
13020
13021            case 0x0A:  /* CEIL.L.fmt */
13022               switch (fmt) {
13023                  case 0x10:  /* S */
13024                     DIP("ceil.l.s %d, %d", fd, fs);
13025                     if (fp_mode64) {
13026                        calculateFCSR(fs, 0, CEILLS, True, 1);
13027                        t0 = newTemp(Ity_I64);
13028
13029                        assign(t0, binop(Iop_F32toI64S, mkU32(0x2),
13030                                   getLoFromF64(tyF, getFReg(fs))));
13031
13032                        putFReg(fd, unop(Iop_ReinterpI64asF64, mkexpr(t0)));
13033                     } else {
13034                        ILLEGAL_INSTRUCTON;
13035                     }
13036                     break;
13037
13038                  case 0x11:  /* D */
13039                     DIP("ceil.l.d %d, %d", fd, fs);
13040                     if (fp_mode64) {
13041                        calculateFCSR(fs, 0, CEILLD, False, 1);
13042                        putFReg(fd, binop(Iop_RoundF64toInt, mkU32(0x2),
13043                                          getFReg(fs)));
13044                     } else {
13045                        ILLEGAL_INSTRUCTON;
13046                     }
13047                     break;
13048
13049                  default:
13050                     goto decode_failure;
13051
13052               }
13053               break;
13054
13055            case 0x16:  /* RSQRT.fmt */
13056               switch (fmt) {
13057                  case 0x10: {  /* S */
13058                     DIP("rsqrt.s %d, %d", fd, fs);
13059                     IRExpr *rm = get_IR_roundingmode();
13060                     putFReg(fd, mkWidenFromF32(tyF, triop(Iop_DivF32, rm,
13061                                 unop(Iop_ReinterpI32asF32, mkU32(ONE_SINGLE)),
13062                                 binop(Iop_SqrtF32, rm, getLoFromF64(tyF,
13063                                 getFReg(fs))))));
13064                     break;
13065                  }
13066                  case 0x11: {  /* D */
13067                     DIP("rsqrt.d %d, %d", fd, fs);
13068                     IRExpr *rm = get_IR_roundingmode();
13069                     putDReg(fd, triop(Iop_DivF64, rm,
13070                                 unop(Iop_ReinterpI64asF64,
13071                                 mkU64(ONE_DOUBLE)),
13072                                 binop(Iop_SqrtF64, rm, getDReg(fs))));
13073                     break;
13074                  }
13075                  default:
13076                     goto decode_failure;
13077
13078               }
13079               break;
13080
13081            default:
13082               if (dis_instr_CCondFmt(cins))
13083                  break;
13084               goto decode_failure;
13085
13086            }
13087
13088         }
13089      }
13090      break;  /* COP1 */
13091   case 0x10:  /* COP0 */
13092      if (rs == 0) {  /* MFC0 */
13093         DIP("mfc0 r%d, r%d, %d", rt, rd, sel);
13094         IRTemp   val  = newTemp(Ity_I32);
13095         IRExpr** args = mkIRExprVec_3 (IRExpr_BBPTR(), mkU32(rd), mkU32(sel));
13096         IRDirty *d = unsafeIRDirty_1_N(val,
13097                                        0,
13098                                        "mips32_dirtyhelper_mfc0",
13099                                        &mips32_dirtyhelper_mfc0,
13100                                        args);
13101         stmt(IRStmt_Dirty(d));
13102         putIReg(rt, mkexpr(val));
13103      } else if (rs == 1) {
13104         /* Doubleword Move from Coprocessor 0 - DMFC0; MIPS64 */
13105         DIP("dmfc0 r%d, r%d, %d", rt, rd, sel);
13106         IRTemp   val  = newTemp(Ity_I64);
13107         IRExpr** args = mkIRExprVec_3 (IRExpr_BBPTR(), mkU64(rd), mkU64(sel));
13108         IRDirty *d = unsafeIRDirty_1_N(val,
13109                                        0,
13110                                        "mips64_dirtyhelper_dmfc0",
13111                                        &mips64_dirtyhelper_dmfc0,
13112                                        args);
13113         stmt(IRStmt_Dirty(d));
13114         putDReg(rt, mkexpr(val));
13115      } else
13116         goto decode_failure;
13117      break;
13118
13119   case 0x31:  /* LWC1 */
13120      /* Load Word to Floating Point - LWC1 (MIPS32) */
13121      DIP("lwc1 f%d, %d(r%d)", ft, imm, rs);
13122      if (fp_mode64) {
13123         t1 = newTemp(Ity_F32);
13124         t2 = newTemp(Ity_I64);
13125         if (mode64) {
13126            t0 = newTemp(Ity_I64);
13127            /* new LO */
13128            assign(t0, binop(Iop_Add64, getIReg(rs),
13129                             mkU64(extend_s_16to64(imm))));
13130         } else {
13131            t0 = newTemp(Ity_I32);
13132            /* new LO */
13133            assign(t0, binop(Iop_Add32, getIReg(rs),
13134                             mkU32(extend_s_16to32(imm))));
13135         }
13136         assign(t1, load(Ity_F32, mkexpr(t0)));
13137         assign(t2, mkWidenFrom32(Ity_I64, unop(Iop_ReinterpF32asI32,
13138                                                mkexpr(t1)), True));
13139         putDReg(ft, unop(Iop_ReinterpI64asF64, mkexpr(t2)));
13140      } else {
13141         t0 = newTemp(Ity_I32);
13142         assign(t0, binop(Iop_Add32, getIReg(rs),
13143                           mkU32(extend_s_16to32(imm))));
13144         putFReg(ft, load(Ity_F32, mkexpr(t0)));
13145      }
13146      break;
13147
13148   case 0x39:  /* SWC1 */
13149      DIP("swc1 f%d, %d(r%d)", ft, imm, rs);
13150      if (fp_mode64) {
13151         t0 = newTemp(Ity_I64);
13152         t2 = newTemp(Ity_I32);
13153         LOAD_STORE_PATTERN;
13154         assign(t0, unop(Iop_ReinterpF64asI64, getFReg(ft)));
13155         assign(t2, unop(Iop_64to32, mkexpr(t0)));
13156         store(mkexpr(t1), unop(Iop_ReinterpI32asF32, mkexpr(t2)));
13157      } else {
13158         LOAD_STORE_PATTERN;
13159         store(mkexpr(t1), getFReg(ft));
13160      }
13161      break;
13162
13163   case 0x33:  /* PREF */
13164      DIP("pref");
13165      break;
13166
13167   case 0x35:
13168      /* Load Doubleword to Floating Point - LDC1 (MIPS32) */
13169      DIP("ldc1 f%d, %d(%d)", rt, imm, rs);
13170      LOAD_STORE_PATTERN;
13171      putDReg(ft, load(Ity_F64, mkexpr(t1)));
13172      break;
13173
13174   case 0x3D:
13175      /* Store Doubleword from Floating Point - SDC1 */
13176      DIP("sdc1 f%d, %d(%d)", ft, imm, rs);
13177      LOAD_STORE_PATTERN;
13178      store(mkexpr(t1), getDReg(ft));
13179      break;
13180
13181   case 0x23:  /* LW */
13182      DIP("lw r%d, %d(r%d)", rt, imm, rs);
13183      LOAD_STORE_PATTERN;
13184      putIReg(rt, mkWidenFrom32(ty, load(Ity_I32, mkexpr(t1)), True));
13185      break;
13186
13187   case 0x20:  /* LB */
13188      DIP("lb r%d, %d(r%d)", rt, imm, rs);
13189      LOAD_STORE_PATTERN;
13190      if (mode64)
13191         putIReg(rt, unop(Iop_8Sto64, load(Ity_I8, mkexpr(t1))));
13192      else
13193         putIReg(rt, unop(Iop_8Sto32, load(Ity_I8, mkexpr(t1))));
13194      break;
13195
13196   case 0x24:  /* LBU */
13197      DIP("lbu r%d, %d(r%d)", rt, imm, rs);
13198      LOAD_STORE_PATTERN;
13199      if (mode64)
13200         putIReg(rt, unop(Iop_8Uto64, load(Ity_I8, mkexpr(t1))));
13201      else
13202         putIReg(rt, unop(Iop_8Uto32, load(Ity_I8, mkexpr(t1))));
13203      break;
13204
13205   case 0x21:  /* LH */
13206      DIP("lh r%d, %d(r%d)", rt, imm, rs);
13207      LOAD_STORE_PATTERN;
13208      if (mode64)
13209         putIReg(rt, unop(Iop_16Sto64, load(Ity_I16, mkexpr(t1))));
13210      else
13211         putIReg(rt, unop(Iop_16Sto32, load(Ity_I16, mkexpr(t1))));
13212      break;
13213
13214   case 0x25:  /* LHU */
13215      DIP("lhu r%d, %d(r%d)", rt, imm, rs);
13216      LOAD_STORE_PATTERN;
13217      if (mode64)
13218         putIReg(rt, unop(Iop_16Uto64, load(Ity_I16, mkexpr(t1))));
13219      else
13220         putIReg(rt, unop(Iop_16Uto32, load(Ity_I16, mkexpr(t1))));
13221      break;
13222
13223   case 0x0F:  /* LUI */
13224      p = (imm << 16);
13225      DIP("lui r%d, imm: 0x%x", rt, imm);
13226      if (mode64)
13227         putIReg(rt, mkU64(extend_s_32to64(p)));
13228      else
13229         putIReg(rt, mkU32(p));
13230      break;
13231
13232   case 0x13:  /* COP1X */
13233      switch (function) {
13234      case 0x0: {  /* LWXC1 */
13235         /* Load Word  Indexed to Floating Point - LWXC1 (MIPS32r2) */
13236         DIP("lwxc1 f%d, r%d(r%d)", fd, rt, rs);
13237         if (fp_mode64) {
13238            t0 = newTemp(Ity_I64);
13239            t1 = newTemp(Ity_I32);
13240            t3 = newTemp(Ity_F32);
13241            t4 = newTemp(Ity_I64);
13242
13243            t2 = newTemp(ty);
13244            /* new LO */
13245            assign(t2, binop(mode64 ? Iop_Add64 : Iop_Add32, getIReg(rs),
13246                             getIReg(rt)));
13247            assign(t3, load(Ity_F32, mkexpr(t2)));
13248
13249            assign(t4, mkWidenFrom32(Ity_I64, unop(Iop_ReinterpF32asI32,
13250                                                   mkexpr(t3)), True));
13251
13252            putFReg(fd, unop(Iop_ReinterpI64asF64, mkexpr(t4)));
13253         } else {
13254            t0 = newTemp(Ity_I32);
13255            assign(t0, binop(Iop_Add32, getIReg(rs), getIReg(rt)));
13256            putFReg(fd, load(Ity_F32, mkexpr(t0)));
13257         }
13258         break;
13259      }
13260
13261      case 0x1: {  /* LDXC1 */
13262         /* Load Doubleword  Indexed to Floating Point
13263            LDXC1 (MIPS32r2 and MIPS64) */
13264         if (fp_mode64) {
13265            DIP("ldxc1 f%d, r%d(r%d)", fd, rt, rs);
13266            t0 = newTemp(ty);
13267            assign(t0, binop(mode64 ? Iop_Add64 : Iop_Add32, getIReg(rs),
13268                             getIReg(rt)));
13269            putFReg(fd, load(Ity_F64, mkexpr(t0)));
13270            break;
13271         } else {
13272            t0 = newTemp(Ity_I32);
13273            assign(t0, binop(Iop_Add32, getIReg(rs), getIReg(rt)));
13274
13275            t1 = newTemp(Ity_I32);
13276            assign(t1, binop(Iop_Add32, mkexpr(t0), mkU32(4)));
13277
13278#if defined (_MIPSEL)
13279            putFReg(fd, load(Ity_F32, mkexpr(t0)));
13280            putFReg(fd + 1, load(Ity_F32, mkexpr(t1)));
13281#elif defined (_MIPSEB)
13282            putFReg(fd + 1, load(Ity_F32, mkexpr(t0)));
13283            putFReg(fd, load(Ity_F32, mkexpr(t1)));
13284#endif
13285            break;
13286         }
13287      }
13288
13289      case 0x5:  /* Load Doubleword Indexed Unaligned to Floating Point - LUXC1;
13290                    MIPS32r2 */
13291         DIP("luxc1 f%d, r%d(r%d)", fd, rt, rs);
13292         t0 = newTemp(Ity_I64);
13293         t1 = newTemp(Ity_I64);
13294         assign(t0, binop(Iop_Add64, getIReg(rs), getIReg(rt)));
13295         assign(t1, binop(Iop_And64, mkexpr(t0),
13296                                     mkU64(0xfffffffffffffff8ULL)));
13297         putFReg(fd, load(Ity_F64, mkexpr(t1)));
13298         break;
13299
13300      case 0x8: {  /* Store Word Indexed from Floating Point - SWXC1 */
13301         DIP("swxc1 f%d, r%d(r%d)", ft, rt, rs);
13302         if (fp_mode64) {
13303            t0 = newTemp(ty);
13304            assign(t0, binop(mode64 ? Iop_Add64 : Iop_Add32, getIReg(rs),
13305                             getIReg(rt)));
13306            store(mkexpr(t0), getLoFromF64(tyF, getFReg(fs)));
13307
13308         } else {
13309            t0 = newTemp(Ity_I32);
13310            assign(t0, binop(Iop_Add32, getIReg(rs), getIReg(rt)));
13311
13312            store(mkexpr(t0), getFReg(fs));
13313         }
13314         break;
13315      }
13316      case 0x9: {  /* Store Doubleword Indexed from Floating Point - SDXC1 */
13317         DIP("sdc1 f%d, %d(%d)", ft, imm, rs);
13318         if (fp_mode64) {
13319            t0 = newTemp(ty);
13320            assign(t0, binop(mode64 ? Iop_Add64 : Iop_Add32, getIReg(rs),
13321                             getIReg(rt)));
13322            store(mkexpr(t0), getFReg(fs));
13323         } else {
13324            t0 = newTemp(Ity_I32);
13325            assign(t0, binop(Iop_Add32, getIReg(rs), getIReg(rt)));
13326
13327            t1 = newTemp(Ity_I32);
13328            assign(t1, binop(Iop_Add32, mkexpr(t0), mkU32(4)));
13329
13330#if defined (_MIPSEL)
13331            store(mkexpr(t0), getFReg(fs));
13332            store(mkexpr(t1), getFReg(fs + 1));
13333#elif defined (_MIPSEB)
13334            store(mkexpr(t0), getFReg(fs + 1));
13335            store(mkexpr(t1), getFReg(fs));
13336#endif
13337         }
13338         break;
13339      }
13340      case 0xD:  /* Store Doubleword Indexed Unaligned from Floating Point -
13341                    SUXC1; MIPS64 MIPS32r2 */
13342         DIP("suxc1 f%d, r%d(r%d)", fd, rt, rs);
13343         t0 = newTemp(Ity_I64);
13344         t1 = newTemp(Ity_I64);
13345         assign(t0, binop(Iop_Add64, getIReg(rs), getIReg(rt)));
13346         assign(t1, binop(Iop_And64, mkexpr(t0), mkU64(0xfffffffffffffff8ULL)));
13347         store(mkexpr(t1), getFReg(fs));
13348         break;
13349
13350      case 0x0F: {
13351         DIP("prefx");
13352         break;
13353      }
13354      case 0x20:  {  /* MADD.S */
13355         DIP("madd.s f%d, f%d, f%d, f%d", fd, fmt, fs, ft);
13356         IRExpr *rm = get_IR_roundingmode();
13357         t1 = newTemp(Ity_F32);
13358         assign(t1, qop(Iop_MAddF32, rm,
13359                        getLoFromF64(tyF, getFReg(fmt)),
13360                        getLoFromF64(tyF, getFReg(fs)),
13361                        getLoFromF64(tyF, getFReg(ft))));
13362         putFReg(fd, mkWidenFromF32(tyF, mkexpr(t1)));
13363         break;  /* MADD.S */
13364      }
13365      case 0x21: {  /* MADD.D */
13366         DIP("madd.d f%d, f%d, f%d, f%d", fd, fmt, fs, ft);
13367         IRExpr *rm = get_IR_roundingmode();
13368         putDReg(fd, qop(Iop_MAddF64, rm, getDReg(fmt), getDReg(fs),
13369                         getDReg(ft)));
13370         break;  /* MADD.D */
13371      }
13372      case 0x28: {  /* MSUB.S */
13373         DIP("msub.s f%d, f%d, f%d, f%d", fd, fmt, fs, ft);
13374         IRExpr *rm = get_IR_roundingmode();
13375         t1 = newTemp(Ity_F32);
13376         assign(t1, qop(Iop_MSubF32, rm,
13377                        getLoFromF64(tyF, getFReg(fmt)),
13378                        getLoFromF64(tyF, getFReg(fs)),
13379                        getLoFromF64(tyF, getFReg(ft))));
13380         putFReg(fd, mkWidenFromF32(tyF, mkexpr(t1)));
13381         break;  /* MSUB.S */
13382      }
13383      case 0x29: {  /* MSUB.D */
13384         DIP("msub.d f%d, f%d, f%d, f%d", fd, fmt, fs, ft);
13385         IRExpr *rm = get_IR_roundingmode();
13386         putDReg(fd, qop(Iop_MSubF64, rm, getDReg(fmt), getDReg(fs),
13387                         getDReg(ft)));
13388         break;  /* MSUB.D */
13389      }
13390      case 0x30: {  /* NMADD.S */
13391         DIP("nmadd.s f%d, f%d, f%d, f%d", fd, fmt, fs, ft);
13392         IRExpr *rm = get_IR_roundingmode();
13393         t1 = newTemp(Ity_F32);
13394         assign(t1, qop(Iop_MAddF32, rm,
13395                        getLoFromF64(tyF, getFReg(fmt)),
13396                        getLoFromF64(tyF, getFReg(fs)),
13397                        getLoFromF64(tyF, getFReg(ft))));
13398
13399         putFReg(fd, mkWidenFromF32(tyF, unop(Iop_NegF32, mkexpr(t1))));
13400         break;  /* NMADD.S */
13401      }
13402      case 0x31: {  /* NMADD.D */
13403         DIP("nmadd.d f%d, f%d, f%d, f%d", fd, fmt, fs, ft);
13404         IRExpr *rm = get_IR_roundingmode();
13405         t1 = newTemp(Ity_F64);
13406         assign(t1, qop(Iop_MAddF64, rm, getDReg(fmt), getDReg(fs),
13407                        getDReg(ft)));
13408         putDReg(fd, unop(Iop_NegF64, mkexpr(t1)));
13409         break;  /* NMADD.D */
13410      }
13411      case 0x38: {  /* NMSUBB.S */
13412         DIP("nmsub.s f%d, f%d, f%d, f%d", fd, fmt, fs, ft);
13413         IRExpr *rm = get_IR_roundingmode();
13414         t1 = newTemp(Ity_F32);
13415         assign(t1, qop(Iop_MSubF32, rm,
13416                        getLoFromF64(tyF, getFReg(fmt)),
13417                        getLoFromF64(tyF, getFReg(fs)),
13418                        getLoFromF64(tyF, getFReg(ft))));
13419
13420         putFReg(fd, mkWidenFromF32(tyF, unop(Iop_NegF32, mkexpr(t1))));
13421         break;  /* NMSUBB.S */
13422      }
13423      case 0x39: {  /* NMSUBB.D */
13424         DIP("nmsub.d f%d, f%d, f%d, f%d", fd, fmt, fs, ft);
13425         IRExpr *rm = get_IR_roundingmode();
13426         t1 = newTemp(Ity_F64);
13427         assign(t1, qop(Iop_MSubF64, rm, getDReg(fmt), getDReg(fs),
13428                        getDReg(ft)));
13429         putDReg(fd, unop(Iop_NegF64, mkexpr(t1)));
13430         break;  /* NMSUBB.D */
13431      }
13432
13433      default:
13434         goto decode_failure;
13435      }
13436      break;
13437
13438   case 0x22:  /* LWL */
13439      DIP("lwl r%d, %d(r%d)", rt, imm, rs);
13440      if (mode64) {
13441         /* t1 = addr */
13442         t1 = newTemp(Ity_I64);
13443#if defined (_MIPSEL)
13444         assign(t1, binop(Iop_Add64, getIReg(rs), mkU64(extend_s_16to64(imm))));
13445         /* t2 = word addr */
13446         /* t4 = addr mod 4 */
13447         LWX_SWX_PATTERN64;
13448
13449         /* t3 = word content - shifted */
13450         t3 = newTemp(Ity_I32);
13451         assign(t3, binop(Iop_Shl32, mkNarrowTo32(ty, load(Ity_I64,
13452                          mkexpr(t2))), narrowTo(Ity_I8, binop(Iop_Shl32,
13453                    binop(Iop_Sub32, mkU32(0x03), mkexpr(t4)), mkU8(3)))));
13454
13455         /* rt content - adjusted */
13456         t5 = newTemp(Ity_I32);
13457         assign(t5, binop(Iop_And32,
13458                          mkNarrowTo32(ty, getIReg(rt)),
13459                          binop(Iop_Shr32,
13460                                mkU32(0x00FFFFFF),
13461                                      narrowTo(Ity_I8, binop(Iop_Mul32,
13462                                                             mkU32(0x08),
13463                                                             mkexpr(t4))))));
13464
13465         putIReg(rt, mkWidenFrom32(ty, binop(Iop_Or32, mkexpr(t5),
13466                                             mkexpr(t3)), True));
13467#elif defined (_MIPSEB)
13468         assign(t1, binop(Iop_Xor64, mkU64(0x3),
13469                binop(Iop_Add64, getIReg(rs), mkU64(extend_s_16to64(imm)))));
13470         /* t2 = word addr */
13471         /* t4 = addr mod 4 */
13472         LWX_SWX_PATTERN64;
13473
13474         /* t3 = word content - shifted */
13475         t3 = newTemp(Ity_I32);
13476         assign(t3, binop(Iop_Shl32, unop(Iop_64HIto32, load(Ity_I64,
13477                          mkexpr(t2))), narrowTo(Ity_I8, binop(Iop_Shl32,
13478                    binop(Iop_Sub32, mkU32(0x03), mkexpr(t4)), mkU8(3)))));
13479
13480         /* rt content - adjusted */
13481         t5 = newTemp(Ity_I32);
13482         assign(t5, binop(Iop_And32,
13483                          mkNarrowTo32(ty, getIReg(rt)),
13484                          binop(Iop_Shr32,
13485                                mkU32(0x00FFFFFF),
13486                                      narrowTo(Ity_I8, binop(Iop_Mul32,
13487                                                             mkU32(0x08),
13488                                                             mkexpr(t4))))));
13489
13490         putIReg(rt, mkWidenFrom32(ty, binop(Iop_Or32, mkexpr(t5),
13491                                             mkexpr(t3)), True));
13492#endif
13493      } else {
13494         /* t1 = addr */
13495         t1 = newTemp(Ity_I32);
13496#if defined (_MIPSEL)
13497         assign(t1, binop(Iop_Add32, getIReg(rs), mkU32(extend_s_16to32(imm))));
13498#elif defined (_MIPSEB)
13499         assign(t1, binop(Iop_Xor32, mkU32(0x3), binop(Iop_Add32, getIReg(rs),
13500                                     mkU32(extend_s_16to32(imm)))));
13501#endif
13502
13503         /* t2 = word addr */
13504         /* t4 = addr mod 4 */
13505         LWX_SWX_PATTERN;
13506
13507         /* t3 = word content - shifted */
13508         t3 = newTemp(Ity_I32);
13509         assign(t3, binop(Iop_Shl32, load(Ity_I32, mkexpr(t2)), narrowTo(Ity_I8,
13510                    binop(Iop_Shl32, binop(Iop_Sub32, mkU32(0x03), mkexpr(t4)),
13511                    mkU8(3)))));
13512
13513         /* rt content  - adjusted */
13514         t5 = newTemp(Ity_I32);
13515         assign(t5, binop(Iop_And32,
13516                          getIReg(rt),
13517                          binop(Iop_Shr32,
13518                                mkU32(0x00FFFFFF),
13519                                      narrowTo(Ity_I8, binop(Iop_Mul32,
13520                                                             mkU32(0x08),
13521                                                             mkexpr(t4))))));
13522
13523         putIReg(rt, binop(Iop_Or32, mkexpr(t5), mkexpr(t3)));
13524      }
13525      break;
13526
13527   case 0x26:  /* LWR */
13528      DIP("lwr r%d, %d(r%d)", rt, imm, rs);
13529      if (mode64) {
13530         /* t1 = addr */
13531         t1 = newTemp(Ity_I64);
13532#if defined (_MIPSEL)
13533         assign(t1, binop(Iop_Add64, getIReg(rs), mkU64(extend_s_16to64(imm))));
13534         /* t2 = word addr */
13535         /* t4 = addr mod 8 */
13536         LWX_SWX_PATTERN64;
13537
13538         /* t3 = word content - shifted */
13539         t3 = newTemp(Ity_I32);
13540         assign(t3, binop(Iop_Shr32, mkNarrowTo32(ty, load(Ity_I64,mkexpr(t2))),
13541                    narrowTo(Ity_I8, binop(Iop_Shl32, mkexpr(t4), mkU8(3)))));
13542
13543         /* rt content  - adjusted */
13544         t5 = newTemp(Ity_I32);
13545         assign(t5, binop(Iop_And32, mkNarrowTo32(ty, getIReg(rt)),
13546                unop(Iop_Not32, binop(Iop_Shr32, mkU32(0xFFFFFFFF),
13547                narrowTo(Ity_I8, binop(Iop_Shl32, mkexpr(t4), mkU8(0x3)))))));
13548
13549         putIReg(rt, mkWidenFrom32(ty, binop(Iop_Or32, mkexpr(t5),
13550                                       mkexpr(t3)), True));
13551#elif defined (_MIPSEB)
13552         assign(t1, binop(Iop_Xor64, mkU64(0x3), binop(Iop_Add64, getIReg(rs),
13553                          mkU64(extend_s_16to64(imm)))));
13554         /* t2 = word addr */
13555         /* t4 = addr mod 4 */
13556         LWX_SWX_PATTERN64;
13557
13558         /* t3 = word content - shifted */
13559         t3 = newTemp(Ity_I32);
13560         assign(t3, binop(Iop_Shr32, unop(Iop_64HIto32, load(Ity_I64,mkexpr(t2))),
13561                    narrowTo(Ity_I8, binop(Iop_Shl32, mkexpr(t4), mkU8(3)))));
13562
13563         /* rt content  - adjusted */
13564         t5 = newTemp(Ity_I32);
13565         assign(t5, binop(Iop_And32, mkNarrowTo32(ty, getIReg(rt)),
13566                unop(Iop_Not32, binop(Iop_Shr32, mkU32(0xFFFFFFFF),
13567                narrowTo(Ity_I8, binop(Iop_Shl32, mkexpr(t4), mkU8(0x3)))))));
13568
13569         putIReg(rt, mkWidenFrom32(ty, binop(Iop_Or32, mkexpr(t5),
13570                                       mkexpr(t3)), True));
13571#endif
13572
13573      } else {
13574         /* t1 = addr */
13575         t1 = newTemp(Ity_I32);
13576#if defined (_MIPSEL)
13577         assign(t1, binop(Iop_Add32, getIReg(rs), mkU32(extend_s_16to32(imm))));
13578#elif defined (_MIPSEB)
13579         assign(t1, binop(Iop_Xor32, mkU32(0x3), binop(Iop_Add32, getIReg(rs),
13580                                     mkU32(extend_s_16to32(imm)))));
13581#endif
13582
13583         /* t2 = word addr */
13584         /* t4 = addr mod 4 */
13585         LWX_SWX_PATTERN;
13586
13587         /* t3 = word content - shifted */
13588         t3 = newTemp(Ity_I32);
13589         assign(t3, binop(Iop_Shr32, load(Ity_I32, mkexpr(t2)),
13590                    narrowTo(Ity_I8, binop(Iop_Shl32, mkexpr(t4),
13591                    mkU8(3)))));
13592
13593         /* rt content  - adjusted */
13594         t5 = newTemp(Ity_I32);
13595         assign(t5, binop(Iop_And32, getIReg(rt), unop(Iop_Not32,
13596                    binop(Iop_Shr32, mkU32(0xFFFFFFFF), narrowTo(Ity_I8,
13597                          binop(Iop_Shl32, mkexpr(t4), mkU8(0x3)))))));
13598
13599         putIReg(rt, binop(Iop_Or32, mkexpr(t5), mkexpr(t3)));
13600      }
13601      break;
13602
13603   case 0x2B:  /* SW */
13604      DIP("sw r%d, %d(r%d)", rt, imm, rs);
13605      LOAD_STORE_PATTERN;
13606      store(mkexpr(t1), mkNarrowTo32(ty, getIReg(rt)));
13607      break;
13608
13609   case 0x2C: {  /* SDL rt, offset(base) MIPS64 */
13610      DIP("sdl r%u, %d(r%u)", rt, (Int) imm, rs);
13611      vassert(mode64);
13612      IRTemp A_byte = newTemp(Ity_I8);
13613      IRTemp B_byte = newTemp(Ity_I8);
13614      IRTemp C_byte = newTemp(Ity_I8);
13615      IRTemp D_byte = newTemp(Ity_I8);
13616      IRTemp E_byte = newTemp(Ity_I8);
13617      IRTemp F_byte = newTemp(Ity_I8);
13618      IRTemp G_byte = newTemp(Ity_I8);
13619      IRTemp H_byte = newTemp(Ity_I8);
13620      IRTemp B_pos  = newTemp(Ity_I64);
13621      IRTemp C_pos  = newTemp(Ity_I64);
13622      IRTemp D_pos  = newTemp(Ity_I64);
13623      IRTemp E_pos  = newTemp(Ity_I64);
13624      IRTemp F_pos  = newTemp(Ity_I64);
13625      IRTemp G_pos  = newTemp(Ity_I64);
13626
13627      /* H byte */
13628      assign(H_byte, getByteFromReg(rt, 0));
13629      /* G byte */
13630      assign(G_byte, getByteFromReg(rt, 1));
13631      /* F byte */
13632      assign(F_byte, getByteFromReg(rt, 2));
13633      /* E byte */
13634      assign(E_byte, getByteFromReg(rt, 3));
13635      /* D byte */
13636      assign(D_byte, getByteFromReg(rt, 4));
13637      /* C byte */
13638      assign(C_byte, getByteFromReg(rt, 5));
13639      /* B byte */
13640      assign(B_byte, getByteFromReg(rt, 6));
13641      /* A byte */
13642      assign(A_byte, getByteFromReg(rt, 7));
13643
13644      /* t1 = addr */
13645      t1 = newTemp(Ity_I64);
13646      assign(t1, binop(Iop_Add64, getIReg(rs), mkU64(extend_s_16to64(imm))));
13647
13648      /* t2 = word addr */
13649      t2 = newTemp(Ity_I64);
13650      assign(t2, binop(Iop_And64, mkexpr(t1), mkU64(0xFFFFFFFFFFFFFFF8ULL)));
13651
13652      /* t3 = addr mod 7 */
13653      t3 = newTemp(Ity_I64);
13654      assign(t3, binop(Iop_And64, mkexpr(t1), mkU64(0x7)));
13655
13656#if defined (_MIPSEL)
13657      /* Calculate X_byte position. */
13658      assign(B_pos, IRExpr_ITE(binop(Iop_CmpLT64U, mkexpr(t3), mkU64(0x1)),
13659                               mkU64(0x0),
13660                               mkU64(0x1)));
13661
13662      assign(C_pos, IRExpr_ITE(binop(Iop_CmpLT64U, mkexpr(t3), mkU64(0x2)),
13663                               mkU64(0x0),
13664                               mkU64(0x2)));
13665
13666      assign(D_pos, IRExpr_ITE(binop(Iop_CmpLT64U, mkexpr(t3), mkU64(0x3)),
13667                               mkU64(0x0),
13668                               mkU64(0x3)));
13669
13670      assign(E_pos, IRExpr_ITE(binop(Iop_CmpLT64U, mkexpr(t3), mkU64(0x4)),
13671                               mkU64(0x0),
13672                               mkU64(0x4)));
13673
13674      assign(F_pos, IRExpr_ITE(binop(Iop_CmpLT64U, mkexpr(t3), mkU64(0x5)),
13675                               mkU64(0x0),
13676                               mkU64(0x5)));
13677
13678      assign(G_pos, IRExpr_ITE(binop(Iop_CmpEQ64, mkexpr(t3), mkU64(0x7)),
13679                               mkU64(0x1),
13680                               mkU64(0x0)));
13681
13682      /* Store X_byte on the right place. */
13683      store(mkexpr(t2), mkexpr(H_byte));
13684      store(binop(Iop_Add64, mkexpr(t2), mkexpr(G_pos)), mkexpr(G_byte));
13685      store(binop(Iop_Sub64, mkexpr(t1), mkexpr(F_pos)), mkexpr(F_byte));
13686      store(binop(Iop_Sub64, mkexpr(t1), mkexpr(E_pos)), mkexpr(E_byte));
13687      store(binop(Iop_Sub64, mkexpr(t1), mkexpr(D_pos)), mkexpr(D_byte));
13688      store(binop(Iop_Sub64, mkexpr(t1), mkexpr(C_pos)), mkexpr(C_byte));
13689      store(binop(Iop_Sub64, mkexpr(t1), mkexpr(B_pos)), mkexpr(B_byte));
13690      store(mkexpr(t1), mkexpr(A_byte));
13691
13692#else /* _MIPSEB */
13693      /* Calculate X_byte position. */
13694      assign(B_pos, IRExpr_ITE(binop(Iop_CmpEQ64, mkexpr(t3), mkU64(0x7)),
13695                               mkU64(0x0),
13696                               mkU64(0x1)));
13697
13698      assign(C_pos, IRExpr_ITE(binop(Iop_CmpLT64U, mkexpr(t3), mkU64(0x6)),
13699                               mkU64(0x2),
13700                               mkU64(0x0)));
13701
13702      assign(D_pos, IRExpr_ITE(binop(Iop_CmpLT64U, mkexpr(t3), mkU64(0x5)),
13703                               mkU64(0x3),
13704                               mkU64(0x0)));
13705
13706      assign(E_pos, IRExpr_ITE(binop(Iop_CmpLT64U, mkexpr(t3), mkU64(0x4)),
13707                               mkU64(0x4),
13708                               mkU64(0x0)));
13709
13710      assign(F_pos, IRExpr_ITE(binop(Iop_CmpLT64U, mkexpr(t3), mkU64(0x3)),
13711                               mkU64(0x5),
13712                               mkU64(0x0)));
13713
13714      assign(G_pos, IRExpr_ITE(binop(Iop_CmpEQ64, mkexpr(t3), mkU64(0x0)),
13715                               mkU64(0x6),
13716                               mkU64(0x7)));
13717
13718      /* Store X_byte on the right place. */
13719      store(binop(Iop_Add64, mkexpr(t2), mkU64(0x7)), mkexpr(H_byte));
13720      store(binop(Iop_Add64, mkexpr(t2), mkexpr(G_pos)), mkexpr(G_byte));
13721      store(binop(Iop_Add64, mkexpr(t1), mkexpr(F_pos)), mkexpr(F_byte));
13722      store(binop(Iop_Add64, mkexpr(t1), mkexpr(E_pos)), mkexpr(E_byte));
13723      store(binop(Iop_Add64, mkexpr(t1), mkexpr(D_pos)), mkexpr(D_byte));
13724      store(binop(Iop_Add64, mkexpr(t1), mkexpr(C_pos)), mkexpr(C_byte));
13725      store(binop(Iop_Add64, mkexpr(t1), mkexpr(B_pos)), mkexpr(B_byte));
13726      store(mkexpr(t1), mkexpr(A_byte));
13727#endif
13728
13729      break;
13730   }
13731
13732   case 0x2D: {
13733      /* SDR rt, offset(base) - MIPS64 */
13734      vassert(mode64);
13735      DIP("sdr r%u, %d(r%u)", rt, imm, rs);
13736      IRTemp A_byte = newTemp(Ity_I8);
13737      IRTemp B_byte = newTemp(Ity_I8);
13738      IRTemp C_byte = newTemp(Ity_I8);
13739      IRTemp D_byte = newTemp(Ity_I8);
13740      IRTemp E_byte = newTemp(Ity_I8);
13741      IRTemp F_byte = newTemp(Ity_I8);
13742      IRTemp G_byte = newTemp(Ity_I8);
13743      IRTemp H_byte = newTemp(Ity_I8);
13744      IRTemp B_pos  = newTemp(Ity_I64);
13745      IRTemp C_pos  = newTemp(Ity_I64);
13746      IRTemp D_pos  = newTemp(Ity_I64);
13747      IRTemp E_pos  = newTemp(Ity_I64);
13748      IRTemp F_pos  = newTemp(Ity_I64);
13749      IRTemp G_pos  = newTemp(Ity_I64);
13750
13751      /* H byte */
13752      assign(H_byte, getByteFromReg(rt, 0));
13753      /* G byte */
13754      assign(G_byte, getByteFromReg(rt, 1));
13755      /* F byte */
13756      assign(F_byte, getByteFromReg(rt, 2));
13757      /* E byte */
13758      assign(E_byte, getByteFromReg(rt, 3));
13759      /* D byte */
13760      assign(D_byte, getByteFromReg(rt, 4));
13761      /* C byte */
13762      assign(C_byte, getByteFromReg(rt, 5));
13763      /* B byte */
13764      assign(B_byte, getByteFromReg(rt, 6));
13765      /* A byte */
13766      assign(A_byte, getByteFromReg(rt, 7));
13767
13768      /* t1 = addr */
13769      t1 = newTemp(Ity_I64);
13770      assign(t1, binop(Iop_Add64, getIReg(rs), mkU64(extend_s_16to64(imm))));
13771
13772      /* t2 = word addr */
13773      t2 = newTemp(Ity_I64);
13774      assign(t2, binop(Iop_And64, mkexpr(t1), mkU64(0xFFFFFFFFFFFFFFF8ULL)));
13775
13776      /* t3 = addr mod 7 */
13777      t3 = newTemp(Ity_I64);
13778      assign(t3, binop(Iop_And64, mkexpr(t1), mkU64(0x7)));
13779
13780#if defined (_MIPSEL)
13781      /* Calculate X_byte position. */
13782      assign(B_pos, IRExpr_ITE(binop(Iop_CmpLT64U, mkU64(0x1), mkexpr(t3)),
13783                               mkU64(0x0),
13784                               mkU64(0x6)));
13785
13786      assign(C_pos, IRExpr_ITE(binop(Iop_CmpLT64U, mkU64(0x2), mkexpr(t3)),
13787                               mkU64(0x0),
13788                               mkU64(0x5)));
13789
13790      assign(D_pos, IRExpr_ITE(binop(Iop_CmpLT64U, mkU64(0x3), mkexpr(t3)),
13791                               mkU64(0x0),
13792                               mkU64(0x4)));
13793
13794      assign(E_pos, IRExpr_ITE(binop(Iop_CmpLT64U, mkU64(0x4), mkexpr(t3)),
13795                               mkU64(0x0),
13796                               mkU64(0x3)));
13797
13798      assign(F_pos, IRExpr_ITE(binop(Iop_CmpLT64U, mkU64(0x5), mkexpr(t3)),
13799                               mkU64(0x0),
13800                               mkU64(0x2)));
13801
13802      assign(G_pos, IRExpr_ITE(binop(Iop_CmpEQ64, mkexpr(t3), mkU64(0x7)),
13803                               mkU64(0x0),
13804                               mkU64(0x1)));
13805
13806      /* Store X_byte on the right place. */
13807      store(binop(Iop_Add64, mkexpr(t2), mkU64(0x7)), mkexpr(A_byte));
13808      store(binop(Iop_Add64, mkexpr(t1), mkexpr(B_pos)), mkexpr(B_byte));
13809      store(binop(Iop_Add64, mkexpr(t1), mkexpr(C_pos)), mkexpr(C_byte));
13810      store(binop(Iop_Add64, mkexpr(t1), mkexpr(D_pos)), mkexpr(D_byte));
13811      store(binop(Iop_Add64, mkexpr(t1), mkexpr(E_pos)), mkexpr(E_byte));
13812      store(binop(Iop_Add64, mkexpr(t1), mkexpr(F_pos)), mkexpr(F_byte));
13813      store(binop(Iop_Add64, mkexpr(t1), mkexpr(G_pos)), mkexpr(G_byte));
13814      store(mkexpr(t1), mkexpr(H_byte));
13815
13816#else /* _MIPSEB */
13817      /* Calculate X_byte position. */
13818      assign(B_pos, IRExpr_ITE(binop(Iop_CmpLT64U, mkU64(0x5), mkexpr(t3)),
13819                               mkU64(0x6),
13820                               mkU64(0x0)));
13821
13822      assign(C_pos, IRExpr_ITE(binop(Iop_CmpLT64U, mkU64(0x4), mkexpr(t3)),
13823                               mkU64(0x5),
13824                               mkU64(0x0)));
13825
13826      assign(D_pos, IRExpr_ITE(binop(Iop_CmpLT64U, mkU64(0x3), mkexpr(t3)),
13827                               mkU64(0x4),
13828                               mkU64(0x0)));
13829
13830      assign(E_pos, IRExpr_ITE(binop(Iop_CmpLT64U, mkU64(0x2), mkexpr(t3)),
13831                               mkU64(0x3),
13832                               mkU64(0x0)));
13833
13834      assign(F_pos, IRExpr_ITE(binop(Iop_CmpLT64U, mkU64(0x1), mkexpr(t3)),
13835                               mkU64(0x2),
13836                               mkU64(0x0)));
13837
13838      assign(G_pos, IRExpr_ITE(binop(Iop_CmpEQ64, mkexpr(t3), mkU64(0x0)),
13839                               mkU64(0x0),
13840                               mkU64(0x1)));
13841
13842      /* Store X_byte on the right place. */
13843      store(mkexpr(t2), mkexpr(A_byte));
13844      store(binop(Iop_Sub64, mkexpr(t1), mkexpr(B_pos)), mkexpr(B_byte));
13845      store(binop(Iop_Sub64, mkexpr(t1), mkexpr(C_pos)), mkexpr(C_byte));
13846      store(binop(Iop_Sub64, mkexpr(t1), mkexpr(D_pos)), mkexpr(D_byte));
13847      store(binop(Iop_Sub64, mkexpr(t1), mkexpr(E_pos)), mkexpr(E_byte));
13848      store(binop(Iop_Sub64, mkexpr(t1), mkexpr(F_pos)), mkexpr(F_byte));
13849      store(binop(Iop_Sub64, mkexpr(t1), mkexpr(G_pos)), mkexpr(G_byte));
13850      store(mkexpr(t1), mkexpr(H_byte));
13851#endif
13852      break;
13853   }
13854
13855   case 0x28:  /* SB */
13856      DIP("sb r%d, %d(r%d)", rt, imm, rs);
13857      LOAD_STORE_PATTERN;
13858      store(mkexpr(t1), narrowTo(Ity_I8, getIReg(rt)));
13859      break;
13860
13861   case 0x29:  /* SH */
13862      DIP("sh r%d, %d(r%d)", rt, imm, rs);
13863      LOAD_STORE_PATTERN;
13864      store(mkexpr(t1), narrowTo(Ity_I16, getIReg(rt)));
13865      break;
13866
13867   case 0x2A:  /* SWL */
13868      DIP("swl r%d, %d(r%d)", rt, imm, rs);
13869      if (mode64) {
13870         IRTemp E_byte = newTemp(Ity_I8);
13871         IRTemp F_byte = newTemp(Ity_I8);
13872         IRTemp G_byte = newTemp(Ity_I8);
13873         IRTemp H_byte = newTemp(Ity_I8);
13874         IRTemp F_pos  = newTemp(Ity_I64);
13875         IRTemp G_pos  = newTemp(Ity_I64);
13876
13877         /* H byte */
13878         assign(H_byte, getByteFromReg(rt, 0));
13879         /* G byte */
13880         assign(G_byte, getByteFromReg(rt, 1));
13881         /* F byte */
13882         assign(F_byte, getByteFromReg(rt, 2));
13883         /* E byte */
13884         assign(E_byte, getByteFromReg(rt, 3));
13885
13886         /* t1 = addr */
13887         t1 = newTemp(Ity_I64);
13888         assign(t1, binop(Iop_Add64, getIReg(rs), mkU64(extend_s_16to64(imm))));
13889
13890         /* t2 = word addr */
13891         t2 = newTemp(Ity_I64);
13892         assign(t2, binop(Iop_And64, mkexpr(t1), mkU64(0xFFFFFFFFFFFFFFFCULL)));
13893
13894         /* t3 = addr mod 4 */
13895         t3 = newTemp(Ity_I64);
13896         assign(t3, binop(Iop_And64, mkexpr(t1), mkU64(0x3)));
13897
13898#if defined (_MIPSEL)
13899         /* Calculate X_byte position. */
13900         assign(F_pos, IRExpr_ITE(binop(Iop_CmpEQ64, mkexpr(t3), mkU64(0x0)),
13901                                  mkU64(0x0),
13902                                  mkU64(0x1)));
13903
13904         assign(G_pos, IRExpr_ITE(binop(Iop_CmpEQ64, mkexpr(t3), mkU64(0x3)),
13905                                  mkU64(0x1),
13906                                  mkU64(0x0)));
13907
13908         /* Store X_byte on the right place. */
13909         store(mkexpr(t2), mkexpr(H_byte));
13910         store(binop(Iop_Add64, mkexpr(t2), mkexpr(G_pos)), mkexpr(G_byte));
13911         store(binop(Iop_Sub64, mkexpr(t1), mkexpr(F_pos)), mkexpr(F_byte));
13912         store(mkexpr(t1), mkexpr(E_byte));
13913
13914#else    /* _MIPSEB */
13915         /* Calculate X_byte position. */
13916         assign(F_pos, IRExpr_ITE(binop(Iop_CmpEQ64, mkexpr(t3), mkU64(0x3)),
13917                                  mkU64(0x0),
13918                                  mkU64(0x1)));
13919
13920         assign(G_pos, IRExpr_ITE(binop(Iop_CmpEQ64, mkexpr(t3), mkU64(0x0)),
13921                                  mkU64(0x2),
13922                                  mkU64(0x3)));
13923
13924         store(binop(Iop_Add64, mkexpr(t2), mkU64(3)), mkexpr(H_byte));
13925         store(binop(Iop_Add64, mkexpr(t2), mkexpr(G_pos)), mkexpr(G_byte));
13926         store(binop(Iop_Add64, mkexpr(t1), mkexpr(F_pos)), mkexpr(F_byte));
13927         store(mkexpr(t1), mkexpr(E_byte));
13928
13929#endif
13930      } else {
13931         IRTemp E_byte = newTemp(Ity_I8);
13932         IRTemp F_byte = newTemp(Ity_I8);
13933         IRTemp G_byte = newTemp(Ity_I8);
13934         IRTemp H_byte = newTemp(Ity_I8);
13935         IRTemp F_pos  = newTemp(Ity_I32);
13936         IRTemp G_pos  = newTemp(Ity_I32);
13937
13938         /* H byte */
13939         assign(H_byte, getByteFromReg(rt, 0));
13940         /* G byte */
13941         assign(G_byte, getByteFromReg(rt, 1));
13942         /* F byte */
13943         assign(F_byte, getByteFromReg(rt, 2));
13944         /* E byte */
13945         assign(E_byte, getByteFromReg(rt, 3));
13946
13947         /* t1 = addr */
13948         t1 = newTemp(Ity_I32);
13949         assign(t1, binop(Iop_Add32, getIReg(rs), mkU32(extend_s_16to32(imm))));
13950
13951         /* t2 = word addr */
13952         t2 = newTemp(Ity_I32);
13953         assign(t2, binop(Iop_And32, mkexpr(t1), mkU32(0xFFFFFFFCULL)));
13954
13955         /* t3 = addr mod 4 */
13956         t3 = newTemp(Ity_I32);
13957         assign(t3, binop(Iop_And32, mkexpr(t1), mkU32(0x3)));
13958
13959#if defined (_MIPSEL)
13960         /* Calculate X_byte position. */
13961         assign(F_pos, IRExpr_ITE(binop(Iop_CmpEQ32, mkexpr(t3), mkU32(0x0)),
13962                                  mkU32(0x0),
13963                                  mkU32(0x1)));
13964
13965         assign(G_pos, IRExpr_ITE(binop(Iop_CmpEQ32, mkexpr(t3), mkU32(0x3)),
13966                                  mkU32(0x1),
13967                                  mkU32(0x0)));
13968
13969         /* Store X_byte on the right place. */
13970         store(mkexpr(t2), mkexpr(H_byte));
13971         store(binop(Iop_Add32, mkexpr(t2), mkexpr(G_pos)), mkexpr(G_byte));
13972         store(binop(Iop_Sub32, mkexpr(t1), mkexpr(F_pos)), mkexpr(F_byte));
13973         store(mkexpr(t1), mkexpr(E_byte));
13974
13975#else    /* _MIPSEB */
13976         /* Calculate X_byte position. */
13977         assign(F_pos, IRExpr_ITE(binop(Iop_CmpEQ32, mkexpr(t3), mkU32(0x3)),
13978                                  mkU32(0x0),
13979                                  mkU32(0x1)));
13980
13981         assign(G_pos, IRExpr_ITE(binop(Iop_CmpEQ32, mkexpr(t3), mkU32(0x0)),
13982                                  mkU32(0x2),
13983                                  mkU32(0x3)));
13984
13985         store(binop(Iop_Add32, mkexpr(t2), mkU32(3)), mkexpr(H_byte));
13986         store(binop(Iop_Add32, mkexpr(t2), mkexpr(G_pos)), mkexpr(G_byte));
13987         store(binop(Iop_Add32, mkexpr(t1), mkexpr(F_pos)), mkexpr(F_byte));
13988         store(mkexpr(t1), mkexpr(E_byte));
13989
13990#endif
13991      }
13992      break;
13993
13994   case 0x2E:  /* SWR */
13995      DIP("swr r%d, %d(r%d)", rt, imm, rs);
13996      if (mode64) {
13997         IRTemp E_byte = newTemp(Ity_I8);
13998         IRTemp F_byte = newTemp(Ity_I8);
13999         IRTemp G_byte = newTemp(Ity_I8);
14000         IRTemp H_byte = newTemp(Ity_I8);
14001         IRTemp F_pos  = newTemp(Ity_I64);
14002         IRTemp G_pos  = newTemp(Ity_I64);
14003
14004         /* H byte */
14005         assign(H_byte, getByteFromReg(rt, 0));
14006         /* G byte */
14007         assign(G_byte, getByteFromReg(rt, 1));
14008         /* F byte */
14009         assign(F_byte, getByteFromReg(rt, 2));
14010         /* E byte */
14011         assign(E_byte, getByteFromReg(rt, 3));
14012
14013         /* t1 = addr */
14014         t1 = newTemp(Ity_I64);
14015         assign(t1, binop(Iop_Add64, getIReg(rs), mkU64(extend_s_16to64(imm))));
14016
14017         /* t2 = word addr */
14018         t2 = newTemp(Ity_I64);
14019         assign(t2, binop(Iop_And64, mkexpr(t1), mkU64(0xFFFFFFFFFFFFFFFCULL)));
14020
14021         /* t3 = addr mod 4 */
14022         t3 = newTemp(Ity_I64);
14023         assign(t3, binop(Iop_And64, mkexpr(t1), mkU64(0x3)));
14024
14025#if defined (_MIPSEL)
14026         /* Calculate X_byte position. */
14027         assign(F_pos, IRExpr_ITE(binop(Iop_CmpEQ64, mkexpr(t3), mkU64(0x0)),
14028                                  mkU64(0x2),
14029                                  mkU64(0x3)));
14030
14031         assign(G_pos, IRExpr_ITE(binop(Iop_CmpEQ64, mkexpr(t3), mkU64(0x3)),
14032                                  mkU64(0x0),
14033                                  mkU64(0x1)));
14034
14035         /* Store X_byte on the right place. */
14036         store(binop(Iop_Add64, mkexpr(t2), mkU64(0x3)), mkexpr(E_byte));
14037         store(binop(Iop_Add64, mkexpr(t2), mkexpr(F_pos)), mkexpr(F_byte));
14038         store(binop(Iop_Add64, mkexpr(t1), mkexpr(G_pos)), mkexpr(G_byte));
14039         store(mkexpr(t1), mkexpr(H_byte));
14040
14041#else    /* _MIPSEB */
14042         /* Calculate X_byte position. */
14043         assign(F_pos, IRExpr_ITE(binop(Iop_CmpEQ64, mkexpr(t3), mkU64(0x3)),
14044                                  mkU64(0x1),
14045                                  mkU64(0x0)));
14046
14047         assign(G_pos, IRExpr_ITE(binop(Iop_CmpEQ64, mkexpr(t3), mkU64(0x0)),
14048                                  mkU64(0x0),
14049                                  mkU64(0x1)));
14050
14051         /* Store X_byte on the right place. */
14052         store(mkexpr(t2), mkexpr(E_byte));
14053         store(binop(Iop_Add64, mkexpr(t2), mkexpr(F_pos)), mkexpr(F_byte));
14054         store(binop(Iop_Sub64, mkexpr(t1), mkexpr(G_pos)), mkexpr(G_byte));
14055         store(mkexpr(t1), mkexpr(H_byte));
14056#endif
14057      } else {
14058         IRTemp E_byte = newTemp(Ity_I8);
14059         IRTemp F_byte = newTemp(Ity_I8);
14060         IRTemp G_byte = newTemp(Ity_I8);
14061         IRTemp H_byte = newTemp(Ity_I8);
14062         IRTemp F_pos  = newTemp(Ity_I32);
14063         IRTemp G_pos  = newTemp(Ity_I32);
14064
14065         /* H byte */
14066         assign(H_byte, getByteFromReg(rt, 0));
14067         /* G byte */
14068         assign(G_byte, getByteFromReg(rt, 1));
14069         /* F byte */
14070         assign(F_byte, getByteFromReg(rt, 2));
14071         /* E byte */
14072         assign(E_byte, getByteFromReg(rt, 3));
14073
14074         /* t1 = addr */
14075         t1 = newTemp(Ity_I32);
14076         assign(t1, binop(Iop_Add32, getIReg(rs), mkU32(extend_s_16to32(imm))));
14077
14078         /* t2 = word addr */
14079         t2 = newTemp(Ity_I32);
14080         assign(t2, binop(Iop_And32, mkexpr(t1), mkU32(0xFFFFFFFCULL)));
14081
14082         /* t3 = addr mod 4 */
14083         t3 = newTemp(Ity_I32);
14084         assign(t3, binop(Iop_And32, mkexpr(t1), mkU32(0x3)));
14085
14086#if defined (_MIPSEL)
14087         /* Calculate X_byte position. */
14088         assign(F_pos, IRExpr_ITE(binop(Iop_CmpEQ32, mkexpr(t3), mkU32(0x0)),
14089                                  mkU32(0x2),
14090                                  mkU32(0x3)));
14091
14092         assign(G_pos, IRExpr_ITE(binop(Iop_CmpEQ32, mkexpr(t3), mkU32(0x3)),
14093                                  mkU32(0x0),
14094                                  mkU32(0x1)));
14095
14096         /* Store X_byte on the right place. */
14097         store(binop(Iop_Add32, mkexpr(t2), mkU32(0x3)), mkexpr(E_byte));
14098         store(binop(Iop_Add32, mkexpr(t2), mkexpr(F_pos)), mkexpr(F_byte));
14099         store(binop(Iop_Add32, mkexpr(t1), mkexpr(G_pos)), mkexpr(G_byte));
14100         store(mkexpr(t1), mkexpr(H_byte));
14101
14102#else    /* _MIPSEB */
14103         /* Calculate X_byte position. */
14104         assign(F_pos, IRExpr_ITE(binop(Iop_CmpEQ32, mkexpr(t3), mkU32(0x3)),
14105                                  mkU32(0x1),
14106                                  mkU32(0x0)));
14107
14108         assign(G_pos, IRExpr_ITE(binop(Iop_CmpEQ32, mkexpr(t3), mkU32(0x0)),
14109                                  mkU32(0x0),
14110                                  mkU32(0x1)));
14111
14112         /* Store X_byte on the right place. */
14113         store(mkexpr(t2), mkexpr(E_byte));
14114         store(binop(Iop_Add32, mkexpr(t2), mkexpr(F_pos)), mkexpr(F_byte));
14115         store(binop(Iop_Sub32, mkexpr(t1), mkexpr(G_pos)), mkexpr(G_byte));
14116         store(mkexpr(t1), mkexpr(H_byte));
14117#endif
14118      }
14119      break;
14120
14121   case 0x1C:  /* Special2 */
14122      switch (function) {
14123      /* Cavium Specific instructions */
14124      case 0x03: case 0x32: case 0x33:  /* DMUL, CINS , CINS32 */
14125      case 0x3A: case 0x3B: case 0x2B:  /* EXT,  EXT32, SNE    */
14126      /* CVM Compare Instructions */
14127      case 0x2A: case 0x2E: case 0x2F:  /* SEQ,  SEQI,  SNEI   */
14128         if (VEX_MIPS_COMP_ID(archinfo->hwcaps) == VEX_PRID_COMP_CAVIUM) {
14129            if (dis_instr_CVM(cins))
14130               break;
14131            goto decode_failure;
14132         } else {
14133            goto decode_failure;
14134         }
14135         break;
14136      case 0x02: {  /* MUL */
14137         DIP("mul r%d, r%d, r%d", rd, rs, rt);
14138         if (mode64) {
14139            IRTemp tmpRs32 = newTemp(Ity_I32);
14140            IRTemp tmpRt32 = newTemp(Ity_I32);
14141            IRTemp tmpRes = newTemp(Ity_I32);
14142
14143            assign(tmpRs32, mkNarrowTo32(ty, getIReg(rs)));
14144            assign(tmpRt32, mkNarrowTo32(ty, getIReg(rt)));
14145            assign(tmpRes, binop(Iop_Mul32, mkexpr(tmpRs32), mkexpr(tmpRt32)));
14146            putIReg(rd, mkWidenFrom32(ty, mkexpr(tmpRes), True));
14147         } else
14148            putIReg(rd, binop(Iop_Mul32, getIReg(rs), getIReg(rt)));
14149         break;
14150      }
14151
14152         case 0x00: {  /* MADD */
14153            if (mode64) {
14154               DIP("madd r%d, r%d", rs, rt);
14155               t1 = newTemp(Ity_I32);
14156               t2 = newTemp(Ity_I32);
14157               t3 = newTemp(Ity_I64);
14158               t4 = newTemp(Ity_I64);
14159               t5 = newTemp(Ity_I64);
14160               t6 = newTemp(Ity_I32);
14161
14162               assign(t1, mkNarrowTo32(ty, getHI()));
14163               assign(t2, mkNarrowTo32(ty, getLO()));
14164
14165               assign(t3, binop(Iop_MullS32, mkNarrowTo32(ty, getIReg(rs)),
14166                                             mkNarrowTo32(ty, getIReg(rt))));
14167
14168               assign(t4, binop(Iop_32HLto64, mkexpr(t1), mkexpr(t2)));
14169               assign(t5, binop(Iop_Add64, mkexpr(t3), mkexpr(t4)));
14170
14171               putHI(mkWidenFrom32(ty, unop(Iop_64HIto32, mkexpr(t5)), True));
14172               putLO(mkWidenFrom32(ty, unop(Iop_64to32, mkexpr(t5)), True));
14173            } else {
14174               if ( (1 <= ac) && ( 3 >= ac) ) {
14175                  if (VEX_MIPS_PROC_DSP(archinfo->hwcaps)) {
14176                     /* If DSP is present -> DSP ASE MADD */
14177                     UInt retVal = disDSPInstr_MIPS_WRK ( cins );
14178                     if (0 != retVal ) {
14179                        goto decode_failure_dsp;
14180                     }
14181                     break;
14182                  } else {
14183                     goto decode_failure_dsp;
14184                  }
14185               } else {
14186                  DIP("madd r%d, r%d", rs, rt);
14187                  t1 = newTemp(Ity_I32);
14188                  t2 = newTemp(Ity_I32);
14189                  t3 = newTemp(Ity_I64);
14190                  t4 = newTemp(Ity_I32);
14191                  t5 = newTemp(Ity_I32);
14192                  t6 = newTemp(Ity_I32);
14193
14194                  assign(t1, getHI());
14195                  assign(t2, getLO());
14196
14197                  assign(t3, binop(Iop_MullS32, getIReg(rs), getIReg(rt)));
14198
14199                  assign(t4, binop(Iop_Add32, mkexpr(t2), unop(Iop_64to32,
14200                                                               mkexpr(t3))));
14201
14202                  assign(t5, unop(Iop_1Uto32, binop(Iop_CmpLT32U, mkexpr(t4),
14203                                              unop(Iop_64to32, mkexpr(t3)))));
14204                  assign(t6, binop(Iop_Add32, mkexpr(t5), mkexpr(t1)));
14205
14206                  putHI(binop(Iop_Add32, mkexpr(t6), unop(Iop_64HIto32,
14207                                                          mkexpr(t3))));
14208                  putLO(mkexpr(t4));
14209                  break;
14210               }
14211            }
14212            break;
14213         }
14214
14215      case 0x01: {  /* MADDU */
14216         if (mode64) {
14217            DIP("maddu r%d, r%d", rs, rt);
14218            t1 = newTemp(Ity_I32);
14219            t2 = newTemp(Ity_I32);
14220            t3 = newTemp(Ity_I64);
14221            t4 = newTemp(Ity_I64);
14222            t5 = newTemp(Ity_I64);
14223            t6 = newTemp(Ity_I32);
14224
14225            assign(t1, mkNarrowTo32(ty, getHI()));
14226            assign(t2, mkNarrowTo32(ty, getLO()));
14227
14228            assign(t3, binop(Iop_MullU32, mkNarrowTo32(ty, getIReg(rs)),
14229                                          mkNarrowTo32(ty, getIReg(rt))));
14230
14231            assign(t4, binop(Iop_32HLto64, mkexpr(t1), mkexpr(t2)));
14232            assign(t5, binop(Iop_Add64, mkexpr(t3), mkexpr(t4)));
14233
14234            putHI(mkWidenFrom32(ty, unop(Iop_64HIto32, mkexpr(t5)), True));
14235            putLO(mkWidenFrom32(ty, unop(Iop_64to32, mkexpr(t5)), True));
14236         } else {
14237            if ( (1 <= ac) && ( 3 >= ac) ) {
14238               if (VEX_MIPS_PROC_DSP(archinfo->hwcaps)) {
14239                  /* If DSP is present -> DSP ASE MADDU */
14240                  UInt retVal = disDSPInstr_MIPS_WRK ( cins );
14241                  if (0 != retVal ) {
14242                     goto decode_failure_dsp;
14243                  }
14244                  break;
14245               } else {
14246                  goto decode_failure_dsp;
14247               }
14248            } else {
14249               DIP("maddu r%d, r%d", rs, rt);
14250               t1 = newTemp(Ity_I32);
14251               t2 = newTemp(Ity_I32);
14252               t3 = newTemp(Ity_I64);
14253               t4 = newTemp(Ity_I32);
14254               t5 = newTemp(Ity_I32);
14255               t6 = newTemp(Ity_I32);
14256
14257               assign(t1, getHI());
14258               assign(t2, getLO());
14259
14260               assign(t3, binop(Iop_MullU32, getIReg(rs), getIReg(rt)));
14261
14262               assign(t4, binop(Iop_Add32, mkexpr(t2), unop(Iop_64to32,
14263                                                            mkexpr(t3))));
14264               assign(t5, unop(Iop_1Uto32, binop(Iop_CmpLT32U, mkexpr(t4),
14265                                           unop(Iop_64to32, mkexpr(t3)))));
14266               assign(t6, binop(Iop_Add32, mkexpr(t5), mkexpr(t1)));
14267
14268               putHI(binop(Iop_Add32, mkexpr(t6), unop(Iop_64HIto32,
14269                                                      mkexpr(t3))));
14270               putLO(mkexpr(t4));
14271               break;
14272            }
14273         }
14274         break;
14275      }
14276
14277      case 0x04: {  /* MSUB */
14278         if (mode64) {
14279            DIP("msub r%d, r%d", rs, rt);
14280            t1 = newTemp(Ity_I32);
14281            t2 = newTemp(Ity_I32);
14282            t3 = newTemp(Ity_I64);
14283            t4 = newTemp(Ity_I64);
14284            t5 = newTemp(Ity_I64);
14285            t6 = newTemp(Ity_I32);
14286
14287            assign(t1, mkNarrowTo32(ty, getHI()));
14288            assign(t2, mkNarrowTo32(ty, getLO()));
14289
14290            assign(t3, binop(Iop_MullS32, mkNarrowTo32(ty, getIReg(rs)),
14291                                          mkNarrowTo32(ty, getIReg(rt))));
14292
14293            assign(t4, binop(Iop_32HLto64, mkexpr(t1), mkexpr(t2)));
14294            assign(t5, binop(Iop_Sub64, mkexpr(t4), mkexpr(t3)));
14295
14296            putHI(mkWidenFrom32(ty, unop(Iop_64HIto32, mkexpr(t5)), True));
14297            putLO(mkWidenFrom32(ty, unop(Iop_64to32, mkexpr(t5)), True));
14298         } else {
14299            if ( (1 <= ac) && ( 3 >= ac) ) {
14300               if (VEX_MIPS_PROC_DSP(archinfo->hwcaps)) {
14301                  /* If DSP is present -> DSP ASE MSUB */
14302                  UInt retVal = disDSPInstr_MIPS_WRK ( cins );
14303                  if (0 != retVal ) {
14304                     goto decode_failure_dsp;
14305                  }
14306                  break;
14307               } else {
14308                  goto decode_failure_dsp;
14309               }
14310            } else {
14311               DIP("msub r%d, r%d", rs, rt);
14312               t1 = newTemp(Ity_I32);
14313               t2 = newTemp(Ity_I32);
14314               t3 = newTemp(Ity_I64);
14315               t4 = newTemp(Ity_I32);
14316               t5 = newTemp(Ity_I1);
14317               t6 = newTemp(Ity_I32);
14318
14319               assign(t1, getHI());
14320               assign(t2, getLO());
14321
14322               assign(t3, binop(Iop_MullS32, getIReg(rs), getIReg(rt)));
14323               assign(t4, unop(Iop_64to32, mkexpr(t3)));  /* new lo */
14324
14325               /* if lo<lo(mul) hi = hi - 1 */
14326               assign(t5, binop(Iop_CmpLT32U,
14327                                 mkexpr(t2),
14328                                 mkexpr(t4)));
14329
14330               assign(t6, IRExpr_ITE(mkexpr(t5),
14331                                       binop(Iop_Sub32, mkexpr(t1), mkU32(0x1)),
14332                                       mkexpr(t1)));
14333
14334               putHI(binop(Iop_Sub32, mkexpr(t6), unop(Iop_64HIto32,
14335                                                      mkexpr(t3))));
14336               putLO(binop(Iop_Sub32, mkexpr(t2), mkexpr(t4)));
14337               break;
14338            }
14339         }
14340         break;
14341      }
14342
14343      case 0x05: {  /* MSUBU */
14344         if (mode64) {
14345            DIP("msubu r%d, r%d", rs, rt);
14346            t1 = newTemp(Ity_I32);
14347            t2 = newTemp(Ity_I32);
14348            t3 = newTemp(Ity_I64);
14349            t4 = newTemp(Ity_I64);
14350            t5 = newTemp(Ity_I64);
14351            t6 = newTemp(Ity_I32);
14352
14353            assign(t1, mkNarrowTo32(ty, getHI()));
14354            assign(t2, mkNarrowTo32(ty, getLO()));
14355
14356            assign(t3, binop(Iop_MullU32, mkNarrowTo32(ty, getIReg(rs)),
14357                                          mkNarrowTo32(ty, getIReg(rt))));
14358
14359            assign(t4, binop(Iop_32HLto64, mkexpr(t1), mkexpr(t2)));
14360            assign(t5, binop(Iop_Sub64, mkexpr(t4), mkexpr(t3)));
14361
14362            putHI(mkWidenFrom32(ty, unop(Iop_64HIto32, mkexpr(t5)), True));
14363            putLO(mkWidenFrom32(ty, unop(Iop_64to32, mkexpr(t5)), True));
14364         } else {
14365            if ( (1 <= ac) && ( 3 >= ac) ) {
14366               if (VEX_MIPS_PROC_DSP(archinfo->hwcaps)) {
14367                  /* If DSP is present -> DSP ASE MSUBU */
14368                  UInt retVal = disDSPInstr_MIPS_WRK ( cins );
14369                  if (0 != retVal ) {
14370                     goto decode_failure_dsp;
14371                  }
14372                  break;
14373               } else {
14374                  goto decode_failure_dsp;
14375               }
14376            } else {
14377               DIP("msubu r%d, r%d", rs, rt);
14378               t1 = newTemp(Ity_I32);
14379               t2 = newTemp(Ity_I32);
14380               t3 = newTemp(Ity_I64);
14381               t4 = newTemp(Ity_I32);
14382               t5 = newTemp(Ity_I1);
14383               t6 = newTemp(Ity_I32);
14384
14385               assign(t1, getHI());
14386               assign(t2, getLO());
14387
14388               assign(t3, binop(Iop_MullU32, getIReg(rs), getIReg(rt)));
14389               assign(t4, unop(Iop_64to32, mkexpr(t3)));  /* new lo */
14390
14391               /* if lo<lo(mul) hi = hi - 1 */
14392               assign(t5, binop(Iop_CmpLT32U,
14393                                 mkexpr(t2),
14394                                 mkexpr(t4)));
14395
14396               assign(t6, IRExpr_ITE(mkexpr(t5),
14397                                    binop(Iop_Sub32,
14398                                          mkexpr(t1),
14399                                          mkU32(0x1)),
14400                                    mkexpr(t1)));
14401
14402               putHI(binop(Iop_Sub32, mkexpr(t6), unop(Iop_64HIto32,
14403                                                      mkexpr(t3))));
14404               putLO(binop(Iop_Sub32, mkexpr(t2), mkexpr(t4)));
14405               break;
14406            }
14407         }
14408         break;
14409      }
14410
14411      case 0x6:  /* dmul MIPS64 - Netlogic */
14412         DIP("dmul r%u, r%u, r%u", rd, rs, rt);
14413         t0 = newTemp(Ity_I128);
14414
14415         assign(t0, binop(Iop_MullU64, getIReg(rs), getIReg(rt)));
14416
14417         putIReg(rd, unop(Iop_128to64, mkexpr(t0)));
14418         break;
14419
14420      case 0x10:  /* LDADDW - Swap Word - Netlogic */
14421         DIP("ldaddw r%u, r%u", rt, rs);
14422         t0 = newTemp(Ity_I32);
14423         t1 = newTemp(Ity_I32);
14424         t2 = newTemp(Ity_I32);
14425         t3 = newTemp(Ity_I64);
14426         t4 = newTemp(Ity_I32);
14427         t5 = newTemp(Ity_I32);
14428         t6 = newTemp(Ity_I32);
14429
14430         /* v = GPR[rt] */
14431         assign(t0, mkNarrowTo32(ty, getIReg(rt)));
14432
14433         /* GPR[rt] = memory[base]; */
14434         assign(t1, load(Ity_I32, getIReg(rs)));
14435         putIReg(rt, mkWidenFrom32(ty, mkexpr(t1), True));
14436
14437         /* memory[base] = memory[base] + v; */
14438         store(getIReg(rs), binop(Iop_Add32, mkexpr(t0), mkexpr(t1)));
14439         break;
14440
14441      case 0x12:  /* LDADDD - Swap Word - Netlogic */
14442         DIP("ldaddw r%u, r%u", rt, rs);
14443         t0 = newTemp(Ity_I64);
14444         t1 = newTemp(Ity_I64);
14445
14446         /*  v = GPR[rt] */
14447         assign(t0, getIReg(rt));
14448
14449         /* GPR[rt] = memory[base]; */
14450         assign(t1, load(Ity_I64, getIReg(rs)));
14451         putIReg(rt, mkexpr(t1));
14452
14453         /* memory[base] = memory[base] + v; */
14454         store(getIReg(rs), binop(Iop_Add64, mkexpr(t0), mkexpr(t1)));
14455         break;
14456
14457      case 0x14:  /* SWAPW - Swap Word - Netlogic */
14458         DIP("swapw r%u, r%u", rt, rs);
14459         t0 = newTemp(Ity_I32);
14460         t1 = newTemp(Ity_I32);
14461         assign(t0, mkNarrowTo32(ty, getIReg(rt)));
14462         assign(t1, load(Ity_I32, getIReg(rs)));
14463         putIReg(rt, mkWidenFrom32(ty, mkexpr(t1), True));
14464         store(getIReg(rs), mkexpr(t0));
14465         break;
14466
14467      case 0x16:  /* SWAPD - Swap Double - Netlogic */
14468         DIP("swapw r%u, r%u", rt, rs);
14469         t0 = newTemp(Ity_I64);
14470         t1 = newTemp(Ity_I64);
14471         assign(t0, getIReg(rt));
14472         assign(t1, load(Ity_I64, getIReg(rs)));
14473         putIReg(rt, mkexpr(t1));
14474         store(getIReg(rs), mkexpr(t0));
14475         break;
14476
14477      case 0x20: {  /* CLZ */
14478         DIP("clz r%d, r%d", rd, rs);
14479         if (mode64) {
14480            IRTemp tmpClz32 = newTemp(Ity_I32);
14481            IRTemp tmpRs32 = newTemp(Ity_I32);
14482
14483            assign(tmpRs32, mkNarrowTo32(ty, getIReg(rs)));
14484            assign(tmpClz32, unop(Iop_Clz32, mkexpr(tmpRs32)));
14485            putIReg(rd, mkWidenFrom32(ty, mkexpr(tmpClz32), True));
14486         } else {
14487            t1 = newTemp(Ity_I1);
14488            assign(t1, binop(Iop_CmpEQ32, getIReg(rs), mkU32(0)));
14489            putIReg(rd, IRExpr_ITE(mkexpr(t1),
14490                                   mkU32(0x00000020),
14491                                   unop(Iop_Clz32, getIReg(rs))));
14492         }
14493         break;
14494      }
14495
14496      case 0x21: {  /* CLO */
14497         DIP("clo r%d, r%d", rd, rs);
14498         if (mode64) {
14499            IRTemp tmpClo32 = newTemp(Ity_I32);
14500            IRTemp tmpRs32 = newTemp(Ity_I32);
14501            assign(tmpRs32, mkNarrowTo32(ty, getIReg(rs)));
14502
14503            t1 = newTemp(Ity_I1);
14504            assign(t1, binop(Iop_CmpEQ32, mkexpr(tmpRs32), mkU32(0xffffffff)));
14505            assign(tmpClo32, IRExpr_ITE(mkexpr(t1),
14506                      mkU32(0x00000020),
14507                      unop(Iop_Clz32, unop(Iop_Not32, mkexpr(tmpRs32)))));
14508
14509            putIReg(rd, mkWidenFrom32(ty, mkexpr(tmpClo32), True));
14510            break;
14511         } else {
14512            t1 = newTemp(Ity_I1);
14513            assign(t1, binop(Iop_CmpEQ32, getIReg(rs), mkU32(0xffffffff)));
14514            putIReg(rd, IRExpr_ITE(mkexpr(t1),
14515                                   mkU32(0x00000020),
14516                                   unop(Iop_Clz32,
14517                                        unop(Iop_Not32, getIReg(rs)))));
14518            break;
14519         }
14520      }
14521
14522      case 0x24:  /* Count Leading Zeros in Doubleword - DCLZ; MIPS64 */
14523         DIP("dclz r%d, r%d", rd, rs);
14524         t1 = newTemp(Ity_I1);
14525         assign(t1, binop(Iop_CmpEQ64, getIReg(rs), mkU64(0)));
14526         putIReg(rd, IRExpr_ITE(mkexpr(t1),
14527                     mkU64(0x00000040),
14528                     unop(Iop_Clz64, getIReg(rs))));
14529         break;
14530
14531      case 0x25:  /* Count Leading Ones in Doubleword - DCLO; MIPS64 */
14532         DIP("dclo r%d, r%d", rd, rs);
14533         t1 = newTemp(Ity_I1);
14534         assign(t1, binop(Iop_CmpEQ64, getIReg(rs),
14535                                        mkU64(0xffffffffffffffffULL)));
14536         putIReg(rd, IRExpr_ITE(mkexpr(t1),
14537                                mkU64(0x40),
14538                                unop(Iop_Clz64, unop(Iop_Not64,
14539                                                     getIReg(rs)))));
14540         break;
14541
14542      default:
14543         goto decode_failure;
14544      }
14545      break;
14546
14547   case 0x1F:  /* Special3 */
14548      switch (function) {
14549         case 0x01: {
14550            /* Doubleword Extract Bit Field - DEXTM; MIPS64r2 */
14551            msb = get_msb(cins);
14552            lsb = get_lsb(cins);
14553            size = msb + 1;
14554            UInt srcPos = lsb;
14555            UInt dstSz = msb + 33;
14556            t1 = newTemp(Ity_I64);
14557            DIP("dextm r%u, r%u, %d, %d", rt, rs, lsb, msb + 1);
14558
14559            UChar lsAmt = 64 - (srcPos + dstSz);  /* left shift amount; */
14560            UChar rsAmt = 64 - dstSz;  /* right shift amount; */
14561
14562            assign(t1, binop(Iop_Shl64, getIReg(rs), mkU8(lsAmt)));
14563            putIReg(rt, binop(Iop_Shr64, mkexpr(t1), mkU8(rsAmt)));
14564
14565            break;
14566         }
14567         case 0x02: {
14568            /* Doubleword Extract Bit Field Upper - DEXTU; MIPS64r2 */
14569            msb = get_msb(cins);
14570            lsb = get_lsb(cins);
14571            size = msb + 1;
14572            UInt srcPos = lsb + 32;
14573            UInt dstSz = msb + 1;
14574            DIP("dextu r%u, r%u, %d, %d", rt, rs, srcPos, dstSz);
14575            t1 = newTemp(Ity_I64);
14576
14577            vassert(srcPos >= 32 && srcPos < 64);
14578            vassert(dstSz > 0 && dstSz <= 32);
14579            vassert((srcPos + dstSz) > 32 && (srcPos + dstSz) <= 64);
14580
14581            UChar lsAmt = 64 - (srcPos + dstSz);  /* left shift amount; */
14582            UChar rsAmt = 64 - dstSz;  /* right shift amount; */
14583
14584            assign(t1, binop(Iop_Shl64, getIReg(rs), mkU8(lsAmt)));
14585            putIReg(rt, binop(Iop_Shr64, mkexpr(t1), mkU8(rsAmt)));
14586            break;
14587         }
14588         case 0x05: {
14589            /* Doubleword Insert Bit Field Middle - DINSM; MIPS64r2 */
14590            msb = get_msb(cins);
14591            lsb = get_lsb(cins);
14592            size = msb + 1;
14593            UInt dstPos = lsb;
14594            UInt srcSz = msb - lsb + 33;
14595            t1 = newTemp(ty);
14596            t2 = newTemp(ty);
14597            t3 = newTemp(ty);
14598            t4 = newTemp(ty);
14599            IRTemp tmpT1 = newTemp(ty);
14600            IRTemp tmpT2 = newTemp(ty);
14601            IRTemp tmpT3 = newTemp(ty);
14602            IRTemp tmpT4 = newTemp(ty);
14603            IRTemp tmpT5 = newTemp(ty);
14604            IRTemp tmpT6 = newTemp(ty);
14605            IRTemp tmpT7 = newTemp(ty);
14606            IRTemp tmpRs = newTemp(ty);
14607            IRTemp tmpRt = newTemp(ty);
14608            IRTemp tmpRd = newTemp(ty);
14609
14610            assign(tmpRs, getIReg(rs));
14611            assign(tmpRt, getIReg(rt));
14612            DIP("dinsm r%u, r%u, %d, %d", rt, rs, lsb, msb);
14613
14614            UChar lsAmt = dstPos + srcSz - 1;   /* left shift amount; */
14615            UChar rsAmt = dstPos + srcSz - 1;   /* right shift amount; */
14616
14617            assign(t1, binop(Iop_Shr64, mkexpr(tmpRt), mkU8(rsAmt)));
14618            assign(tmpT1, binop(Iop_Shr64, mkexpr(t1), mkU8(1)));
14619            assign(t2, binop(Iop_Shl64, mkexpr(tmpT1), mkU8(lsAmt)));
14620            assign(tmpT2, binop(Iop_Shl64, mkexpr(t2), mkU8(1)));
14621
14622            lsAmt = 63 - dstPos; /* left shift amount; */
14623            rsAmt = 63 - dstPos; /* right shift amount; */
14624
14625            assign(t3, binop(Iop_Shl64, mkexpr(tmpRt), mkU8(lsAmt)));
14626            assign(tmpT3, binop(Iop_Shl64, mkexpr(t3), mkU8(1)));
14627            assign(t4, binop(Iop_Shr64, mkexpr(tmpT3), mkU8(rsAmt)));
14628            assign(tmpT4, binop(Iop_Shr64, mkexpr(t4), mkU8(1)));
14629
14630            /* extract size from src register */
14631            lsAmt = 64 - srcSz;  /* left shift amount; */
14632            rsAmt = 64 - (lsb + srcSz);   /* right shift amount; */
14633
14634            assign(tmpT5, binop(Iop_Shl64, mkexpr(tmpRs), mkU8(lsAmt)));
14635            assign(tmpT6, binop(Iop_Shr64, mkexpr(tmpT5), mkU8(rsAmt)));
14636
14637            assign(tmpT7, binop(Iop_Or64, mkexpr(tmpT2), mkexpr(tmpT4)));
14638            assign(tmpRd, binop(Iop_Or64, mkexpr(tmpT6), mkexpr(tmpT7)));
14639            putIReg(rt, mkexpr(tmpRd));
14640            break;
14641         }
14642         case 0x06: {
14643            /* Doubleword Insert Bit Field Upper - DINSU; MIPS64r2 */
14644            msb = get_msb(cins);
14645            lsb = get_lsb(cins);
14646            size = msb + 1;
14647            UInt dstPos = lsb + 32;
14648            UInt srcSz = msb - lsb + 1;
14649            IRTemp tmpT1 = newTemp(ty);
14650            IRTemp tmpT2 = newTemp(ty);
14651            IRTemp tmpT3 = newTemp(ty);
14652            IRTemp tmpT4 = newTemp(ty);
14653            IRTemp tmpT5 = newTemp(ty);
14654            IRTemp tmpT6 = newTemp(ty);
14655            IRTemp tmpT7 = newTemp(ty);
14656            IRTemp tmpT8 = newTemp(ty);
14657            IRTemp tmpT9 = newTemp(ty);
14658            IRTemp tmpRs = newTemp(ty);
14659            IRTemp tmpRt = newTemp(ty);
14660            IRTemp tmpRd = newTemp(ty);
14661
14662            assign(tmpRs, getIReg(rs));
14663            assign(tmpRt, getIReg(rt));
14664            DIP("dinsu r%u, r%u, %d, %d", rt, rs, lsb, msb);
14665
14666            UChar lsAmt = 64 - srcSz;  /* left shift amount; */
14667            UChar rsAmt = 64 - (dstPos + srcSz);  /* right shift amount; */
14668            assign(tmpT1, binop(Iop_Shl64, mkexpr(tmpRs), mkU8(lsAmt)));
14669            assign(tmpT2, binop(Iop_Shr64, mkexpr(tmpT1), mkU8(rsAmt)));
14670
14671            lsAmt = 64 - dstPos;  /* left shift amount; */
14672            rsAmt = 64 - dstPos;  /* right shift amount; */
14673            assign(tmpT3, binop(Iop_Shl64, mkexpr(tmpRt), mkU8(lsAmt)));
14674            assign(tmpT4, binop(Iop_Shr64, mkexpr(tmpT3), mkU8(rsAmt)));
14675
14676            lsAmt = dstPos;  /* left shift amount; */
14677            rsAmt = srcSz;  /* right shift amount; */
14678            assign(tmpT5, binop(Iop_Shr64, mkexpr(tmpRt), mkU8(rsAmt)));
14679            assign(tmpT6, binop(Iop_Shr64, mkexpr(tmpT5), mkU8(lsAmt)));
14680
14681            assign(tmpT7, binop(Iop_Shl64, mkexpr(tmpT6), mkU8(rsAmt)));
14682            assign(tmpT8, binop(Iop_Shl64, mkexpr(tmpT7), mkU8(lsAmt)));
14683
14684            assign(tmpT9, binop(Iop_Or64, mkexpr(tmpT8), mkexpr(tmpT4)));
14685            assign(tmpRd, binop(Iop_Or64, mkexpr(tmpT2), mkexpr(tmpT9)));
14686            putIReg(rt, mkexpr(tmpRd));
14687            break;
14688         }
14689         case 0x07: {
14690            /* Doubleword Insert Bit Field - DINS; MIPS64r2 */
14691            IRTemp tmp1 = newTemp(ty);
14692            IRTemp tmpT1 = newTemp(ty);
14693            IRTemp tmpT2 = newTemp(ty);
14694            IRTemp tmpT3 = newTemp(ty);
14695            IRTemp tmpT4 = newTemp(ty);
14696            IRTemp tmpT5 = newTemp(ty);
14697            IRTemp tmpT6 = newTemp(ty);
14698            IRTemp tmpT7 = newTemp(ty);
14699            IRTemp tmpT8 = newTemp(ty);
14700            IRTemp tmpT9 = newTemp(ty);
14701            IRTemp tmp = newTemp(ty);
14702            IRTemp tmpRs = newTemp(ty);
14703            IRTemp tmpRt = newTemp(ty);
14704            IRTemp tmpRd = newTemp(ty);
14705
14706            assign(tmpRs, getIReg(rs));
14707            assign(tmpRt, getIReg(rt));
14708
14709            msb = get_msb(cins);
14710            lsb = get_lsb(cins);
14711            size = msb + 1;
14712            DIP("dins r%u, r%u, %d, %d", rt, rs, lsb,
14713                msb - lsb + 1);
14714            UChar lsAmt = 63 - lsb;  /* left shift amount; */
14715            UChar rsAmt = 63 - lsb;  /* right shift amount; */
14716            assign(tmp, binop(Iop_Shl64, mkexpr(tmpRt), mkU8(lsAmt)));
14717            assign(tmpT1, binop(Iop_Shl64, mkexpr(tmp), mkU8(1)));
14718            assign(tmp1, binop(Iop_Shr64, mkexpr(tmpT1), mkU8(rsAmt)));
14719            assign(tmpT2, binop(Iop_Shr64, mkexpr(tmp1), mkU8(1)));
14720
14721            lsAmt = msb;  /* left shift amount; */
14722            rsAmt = 1;  /*right shift amount; */
14723            assign(tmpT3, binop(Iop_Shr64, mkexpr(tmpRt), mkU8(rsAmt)));
14724            assign(tmpT4, binop(Iop_Shr64, mkexpr(tmpT3), mkU8(lsAmt)));
14725            assign(tmpT5, binop(Iop_Shl64, mkexpr(tmpT4), mkU8(rsAmt)));
14726            assign(tmpT6, binop(Iop_Shl64, mkexpr(tmpT5), mkU8(lsAmt)));
14727
14728            lsAmt = 64 - (msb - lsb + 1);  /* left shift amount; */
14729            rsAmt = 64 - (msb + 1);  /* right shift amount; */
14730            assign(tmpT7, binop(Iop_Shl64, mkexpr(tmpRs), mkU8(lsAmt)));
14731            assign(tmpT8, binop(Iop_Shr64, mkexpr(tmpT7), mkU8(rsAmt)));
14732
14733            assign(tmpT9, binop(Iop_Or64, mkexpr(tmpT2), mkexpr(tmpT8)));
14734            assign(tmpRd, binop(Iop_Or64, mkexpr(tmpT6), mkexpr(tmpT9)));
14735            putIReg(rt, mkexpr(tmpRd));
14736            break;
14737         }
14738      case 0x24:  /* DBSHFL */
14739         lsb = get_lsb(cins);
14740         IRTemp tmpRs = newTemp(ty);
14741         IRTemp tmpRt = newTemp(ty);
14742         IRTemp tmpRd = newTemp(ty);
14743         assign(tmpRs, getIReg(rs));
14744         assign(tmpRt, getIReg(rt));
14745         switch (lsb) {
14746            case 0x02: {  /* DSBH */
14747               DIP("dsbh r%u, r%u", rd, rt);
14748               IRTemp tmpT1 = newTemp(ty);
14749               IRTemp tmpT2 = newTemp(ty);
14750               IRTemp tmpT3 = newTemp(ty);
14751               IRTemp tmpT4 = newTemp(ty);
14752               IRTemp tmpT5 = newTemp(Ity_I64);
14753               IRTemp tmpT6 = newTemp(ty);
14754               assign(tmpT5, mkU64(0xFF00FF00FF00FF00ULL));
14755               assign(tmpT6, mkU64(0x00FF00FF00FF00FFULL));
14756               assign(tmpT1, binop(Iop_And64, mkexpr(tmpRt), mkexpr(tmpT5)));
14757               assign(tmpT2, binop(Iop_Shr64, mkexpr(tmpT1), mkU8(8)));
14758               assign(tmpT3, binop(Iop_And64, mkexpr(tmpRt), mkexpr(tmpT6)));
14759               assign(tmpT4, binop(Iop_Shl64, mkexpr(tmpT3), mkU8(8)));
14760               assign(tmpRd, binop(Iop_Or64, mkexpr(tmpT4), mkexpr(tmpT2)));
14761               putIReg(rd, mkexpr(tmpRd));
14762               break;
14763            }
14764            case 0x05: {  /* DSHD */
14765               DIP("dshd r%u, r%u\n", rd, rt);
14766               IRTemp tmpT1 = newTemp(ty);
14767               IRTemp tmpT2 = newTemp(ty);
14768               IRTemp tmpT3 = newTemp(ty);
14769               IRTemp tmpT4 = newTemp(ty);
14770               IRTemp tmpT5 = newTemp(Ity_I64);
14771               IRTemp tmpT6 = newTemp(ty);
14772               IRTemp tmpT7 = newTemp(ty);
14773               IRTemp tmpT8 = newTemp(ty);
14774               IRTemp tmpT9 = newTemp(ty);
14775               assign(tmpT5, mkU64(0xFFFF0000FFFF0000ULL));
14776               assign(tmpT6, mkU64(0x0000FFFF0000FFFFULL));
14777               assign(tmpT1, binop(Iop_And64, mkexpr(tmpRt), mkexpr(tmpT5)));
14778               assign(tmpT2, binop(Iop_Shr64, mkexpr(tmpT1), mkU8(16)));
14779               assign(tmpT3, binop(Iop_And64, mkexpr(tmpRt), mkexpr(tmpT6)));
14780               assign(tmpT4, binop(Iop_Shl64, mkexpr(tmpT3), mkU8(16)));
14781               assign(tmpT7, binop(Iop_Or64, mkexpr(tmpT4), mkexpr(tmpT2)));
14782               assign(tmpT8, binop(Iop_Shl64, mkexpr(tmpT7), mkU8(32)));
14783               assign(tmpT9, binop(Iop_Shr64, mkexpr(tmpT7), mkU8(32)));
14784               assign(tmpRd, binop(Iop_Or64, mkexpr(tmpT8), mkexpr(tmpT9)));
14785               putIReg(rd, mkexpr(tmpRd));
14786               break;
14787            }
14788         default:
14789            vex_printf("\nop6o10 = %d", lsb);
14790            goto decode_failure;;
14791         }
14792         break;
14793      case 0x3B: {  /* RDHWR */
14794         DIP("rdhwr r%d, r%d", rt, rd);
14795            if (rd == 29) {
14796               putIReg(rt, getULR());
14797#if defined(__mips__) && ((defined(__mips_isa_rev) && __mips_isa_rev >= 2))
14798            } else if (rd == 1) {
14799               if (mode64) {
14800                  IRTemp   val  = newTemp(Ity_I64);
14801                  IRExpr** args = mkIRExprVec_2 (mkU64(rt), mkU64(rd));
14802                  IRDirty *d = unsafeIRDirty_1_N(val,
14803                                                 0,
14804                                                 "mips64_dirtyhelper_rdhwr",
14805                                                 &mips64_dirtyhelper_rdhwr,
14806                                                 args);
14807                  stmt(IRStmt_Dirty(d));
14808                  putIReg(rt, mkexpr(val));
14809               } else {
14810                  IRTemp   val  = newTemp(Ity_I32);
14811                  IRExpr** args = mkIRExprVec_2 (mkU32(rt), mkU32(rd));
14812                  IRDirty *d = unsafeIRDirty_1_N(val,
14813                                                 0,
14814                                                 "mips32_dirtyhelper_rdhwr",
14815                                                 &mips32_dirtyhelper_rdhwr,
14816                                                 args);
14817                  stmt(IRStmt_Dirty(d));
14818                  putIReg(rt, mkexpr(val));
14819               }
14820#endif
14821            } else
14822               goto decode_failure;
14823            break;
14824         }
14825      case 0x04:  /* INS */
14826         msb = get_msb(cins);
14827         lsb = get_lsb(cins);
14828         size = msb - lsb + 1;
14829         DIP("ins size:%d msb:%d lsb:%d", size, msb, lsb);
14830
14831         vassert(lsb + size <= 32);
14832         vassert(lsb + size > 0);
14833
14834         /* put size bits from rs at the pos in temporary */
14835         t0 = newTemp(Ity_I32);
14836         t3 = newTemp(Ity_I32);
14837         /* shift left for 32 - size to clear leading bits and get zeros
14838            at the end */
14839         assign(t0, binop(Iop_Shl32, mkNarrowTo32(ty, getIReg(rs)),
14840                          mkU8(32 - size)));
14841         /* now set it at pos */
14842         t1 = newTemp(Ity_I32);
14843         assign(t1, binop(Iop_Shr32, mkexpr(t0), mkU8(32 - size - lsb)));
14844
14845         if (lsb > 0) {
14846            t2 = newTemp(Ity_I32);
14847            /* clear everything but lower pos bits from rt */
14848            assign(t2, binop(Iop_Shl32, mkNarrowTo32(ty, getIReg(rt)),
14849                             mkU8(32 - lsb)));
14850            assign(t3, binop(Iop_Shr32, mkexpr(t2), mkU8(32 - lsb)));
14851         } else
14852            assign(t3, mkU32(0));
14853
14854         if (msb < 31) {
14855            t4 = newTemp(Ity_I32);
14856            /* clear everything but upper msb + 1 bits from rt */
14857            assign(t4, binop(Iop_Shr32, mkNarrowTo32(ty, getIReg(rt)),
14858                             mkU8(msb + 1)));
14859            t5 = newTemp(Ity_I32);
14860            assign(t5, binop(Iop_Shl32, mkexpr(t4), mkU8(msb + 1)));
14861
14862            /* now combine these registers */
14863            if (lsb > 0) {
14864               t6 = newTemp(Ity_I32);
14865               assign(t6, binop(Iop_Or32, mkexpr(t5), mkexpr(t1)));
14866               putIReg(rt, mkWidenFrom32(ty, binop(Iop_Or32, mkexpr(t6),
14867                                                   mkexpr(t3)), True));
14868            } else {
14869               putIReg(rt, mkWidenFrom32(ty, binop(Iop_Or32, mkexpr(t1),
14870                                                   mkexpr(t5)), True));
14871            }
14872         } else {
14873            putIReg(rt, mkWidenFrom32(ty, binop(Iop_Or32, mkexpr(t1),
14874                                                mkexpr(t3)), True));
14875         }
14876         break;
14877
14878      case 0x00:  /* EXT */
14879         msb = get_msb(cins);
14880         lsb = get_lsb(cins);
14881         size = msb + 1;
14882         DIP("ext size:%d msb:%d lsb:%d", size, msb, lsb);
14883         vassert(lsb + size <= 32);
14884         vassert(lsb + size > 0);
14885         /* put size bits from rs at the top of in temporary */
14886         if (lsb + size < 32) {
14887            t0 = newTemp(Ity_I32);
14888            assign(t0, binop(Iop_Shl32, mkNarrowTo32(ty, getIReg(rs)),
14889                             mkU8(32 - lsb - size)));
14890
14891            putIReg(rt, mkWidenFrom32(ty, binop(Iop_Shr32, mkexpr(t0),
14892                                                mkU8(32 - size)), True));
14893         } else {
14894            putIReg(rt, mkWidenFrom32(ty, binop(Iop_Shr32,
14895                                                mkNarrowTo32(ty, getIReg(rs)),
14896                                                mkU8(32 - size)), True));
14897         }
14898         break;
14899
14900      case 0x03:  /* Doubleword Extract Bit Field - DEXT; MIPS64r2 */
14901         msb = get_msb(cins);
14902         lsb = get_lsb(cins);
14903         size = msb + 1;
14904         DIP("dext r%u, r%u, %d, %d", rt, rs, lsb, msb + 1);
14905         t1 = newTemp(Ity_I64);
14906         vassert(lsb >= 0 && lsb < 32);
14907         vassert(size > 0 && size <= 32);
14908         vassert((lsb + size) > 0 && (lsb + size) <= 63);
14909
14910         UChar lsAmt = 63 - (lsb + msb);  /* left shift amount; */
14911         UChar rsAmt = 63 - msb;  /* right shift amount; */
14912
14913         assign(t1, binop(Iop_Shl64, getIReg(rs), mkU8(lsAmt)));
14914         putIReg(rt, binop(Iop_Shr64, mkexpr(t1), mkU8(rsAmt)));
14915
14916         break;
14917
14918      case 0x20:  /* BSHFL */
14919         switch (sa) {
14920            case 0x02:  /* WSBH */
14921               DIP("wsbh r%d, r%d", rd, rt);
14922               t0 = newTemp(Ity_I32);
14923               t1 = newTemp(Ity_I32);
14924               t2 = newTemp(Ity_I32);
14925               t3 = newTemp(Ity_I32);
14926               assign(t0, binop(Iop_Shl32, binop(Iop_And32, mkNarrowTo32(ty,
14927                                           getIReg(rt)), mkU32(0x00FF0000)),
14928                                           mkU8(0x8)));
14929               assign(t1, binop(Iop_Shr32, binop(Iop_And32, mkNarrowTo32(ty,
14930                                getIReg(rt)), mkU32(0xFF000000)), mkU8(0x8)));
14931               assign(t2, binop(Iop_Shl32, binop(Iop_And32, mkNarrowTo32(ty,
14932                                getIReg(rt)), mkU32(0x000000FF)), mkU8(0x8)));
14933               assign(t3, binop(Iop_Shr32, binop(Iop_And32, mkNarrowTo32(ty,
14934                                getIReg(rt)), mkU32(0x0000FF00)), mkU8(0x8)));
14935               putIReg(rd, mkWidenFrom32(ty, binop(Iop_Or32, binop(Iop_Or32,
14936                                         mkexpr(t0), mkexpr(t1)),
14937                                         binop(Iop_Or32, mkexpr(t2),
14938                                         mkexpr(t3))), True));
14939               break;
14940
14941            case 0x10:  /* SEB */
14942               DIP("seb r%d, r%d", rd, rt);
14943               if (mode64)
14944                  putIReg(rd, unop(Iop_8Sto64, unop(Iop_64to8, getIReg(rt))));
14945               else
14946                  putIReg(rd, unop(Iop_8Sto32, unop(Iop_32to8, getIReg(rt))));
14947               break;
14948
14949            case 0x18:  /* SEH */
14950               DIP("seh r%d, r%d", rd, rt);
14951               if (mode64)
14952                  putIReg(rd, unop(Iop_16Sto64, unop(Iop_64to16, getIReg(rt))));
14953               else
14954                  putIReg(rd, unop(Iop_16Sto32, unop(Iop_32to16, getIReg(rt))));
14955               break;
14956
14957            default:
14958               goto decode_failure;
14959
14960         }
14961         break;  /* BSHFL */
14962
14963      /* --- MIPS32(r2) DSP ASE(r2) / Cavium Specfic (LX) instructions --- */
14964      case 0xA:  /* LX */
14965         if (VEX_MIPS_COMP_ID(archinfo->hwcaps) == VEX_PRID_COMP_CAVIUM) {
14966            if (dis_instr_CVM(cins))
14967               break;
14968            goto decode_failure;
14969         }
14970      case 0xC:  /* INSV */
14971      case 0x38: {  /* EXTR.W */
14972         if (VEX_MIPS_PROC_DSP(archinfo->hwcaps)) {
14973            UInt retVal = disDSPInstr_MIPS_WRK ( cins );
14974            if (0 != retVal ) {
14975               goto decode_failure_dsp;
14976            }
14977            break;
14978         } else {
14979            goto decode_failure_dsp;
14980         }
14981         break;
14982      }
14983      case 0x10: {  /* ADDU.QB */
14984         switch(sa) {
14985            case  0xC:  /* SUBU_S.PH */
14986            case  0xD:  /* ADDU_S.PH */
14987            case 0x1E: {  /* MULQ_S.PH */
14988               if (VEX_MIPS_PROC_DSP2(archinfo->hwcaps)) {
14989                  UInt retVal = disDSPInstr_MIPS_WRK ( cins );
14990                  if (0 != retVal ) {
14991                     goto decode_failure_dsp;
14992                  }
14993                  break;
14994               } else {
14995                  goto decode_failure_dsp;
14996               }
14997               break;
14998            }
14999            default: {
15000               if (VEX_MIPS_PROC_DSP(archinfo->hwcaps)) {
15001                  UInt retVal = disDSPInstr_MIPS_WRK ( cins );
15002                  if (0 != retVal ) {
15003                     goto decode_failure_dsp;
15004                  }
15005                  break;
15006               } else {
15007                  goto decode_failure_dsp;
15008               }
15009               break;
15010            }
15011         }
15012         break;
15013      }
15014      case 0x11: {  /* CMPU.EQ.QB */
15015         switch(sa) {
15016            case 0x18:  /* CMPGDU.EQ.QB */
15017            case 0x19:  /* CMPGDU.LT.QB */
15018            case 0x1A:  /* CMPGDU.LE.QB */
15019            case 0x0D:  /* PRECR.QB.PH */
15020            case 0x1E:  /* PRECR_SRA.PH.W */
15021            case 0x1F: {  /* PRECR_SRA_R.PH.W */
15022               if (VEX_MIPS_PROC_DSP2(archinfo->hwcaps)) {
15023                  UInt retVal = disDSPInstr_MIPS_WRK ( cins );
15024                  if (0 != retVal ) {
15025                     goto decode_failure_dsp;
15026                  }
15027                  break;
15028               } else {
15029                  goto decode_failure_dsp;
15030               }
15031               break;
15032            }
15033            default: {
15034               if (VEX_MIPS_PROC_DSP(archinfo->hwcaps)) {
15035                  UInt retVal = disDSPInstr_MIPS_WRK ( cins );
15036                  if (0 != retVal ) {
15037                     goto decode_failure_dsp;
15038                  }
15039                  break;
15040               } else {
15041                  goto decode_failure_dsp;
15042               }
15043               break;
15044            }
15045         }
15046         break;
15047      }
15048      case 0x12: {  /* ABSQ_S.PH */
15049         switch(sa){
15050            case 0x1: {  /* ABSQ_S.QB */
15051               if (VEX_MIPS_PROC_DSP2(archinfo->hwcaps)) {
15052                  UInt retVal = disDSPInstr_MIPS_WRK ( cins );
15053                  if (0 != retVal ) {
15054                     goto decode_failure_dsp;
15055                  }
15056                  break;
15057               } else {
15058                  goto decode_failure_dsp;
15059               }
15060               break;
15061            }
15062            default: {
15063               if (VEX_MIPS_PROC_DSP(archinfo->hwcaps)) {
15064                  UInt retVal = disDSPInstr_MIPS_WRK ( cins );
15065                  if (0 != retVal ) {
15066                     goto decode_failure_dsp;
15067                  }
15068                  break;
15069               } else {
15070                  goto decode_failure_dsp;
15071               }
15072               break;
15073            }
15074         }
15075         break;
15076      }
15077      case 0x13: {  /* SHLL.QB */
15078         switch(sa) {
15079            case 0x04:  /* SHRA.QB */
15080            case 0x05:  /* SHRA_R.QB */
15081            case 0x06:  /* SHRAV.QB */
15082            case 0x07:  /* SHRAV_R.QB */
15083            case 0x19:  /* SHLR.PH */
15084            case 0x1B: {  /* SHLRV.PH */
15085               if (VEX_MIPS_PROC_DSP2(archinfo->hwcaps)) {
15086                  UInt retVal = disDSPInstr_MIPS_WRK ( cins );
15087                  if (0 != retVal ) {
15088                     goto decode_failure_dsp;
15089                  }
15090                  break;
15091               } else {
15092                  goto decode_failure_dsp;
15093               }
15094               break;
15095            }
15096            default: {
15097               if (VEX_MIPS_PROC_DSP(archinfo->hwcaps)) {
15098                  UInt retVal = disDSPInstr_MIPS_WRK ( cins );
15099                  if (0 != retVal ) {
15100                     goto decode_failure_dsp;
15101                  }
15102                  break;
15103               } else {
15104                  goto decode_failure_dsp;
15105               }
15106               break;
15107            }
15108         }
15109         break;
15110      }
15111      case 0x30: {  /* DPAQ.W.PH */
15112         switch(sa) {
15113            case  0x0:  /* DPA.W.PH */
15114            case 0x18:  /* DPAQX_S.W.PH */
15115            case 0x1A:  /* DPAQX_SA.W.PH */
15116            case  0x8:  /* DPAX.W.PH */
15117            case  0x1:  /* DPS.W.PH */
15118            case 0x19:  /* DPSQX_S.W.PH */
15119            case 0x1B:  /* DPSQX_SA.W.PH */
15120            case  0x9:  /* DPSX.W.PH */
15121            case  0x2: {  /* MULSA.W.PH */
15122               if (VEX_MIPS_PROC_DSP2(archinfo->hwcaps)) {
15123                  UInt retVal = disDSPInstr_MIPS_WRK ( cins );
15124                  if (0 != retVal ) {
15125                     goto decode_failure_dsp;
15126                  }
15127                  break;
15128               } else {
15129                  goto decode_failure_dsp;
15130               }
15131               break;
15132            }
15133            default: {
15134               if (VEX_MIPS_PROC_DSP(archinfo->hwcaps)) {
15135                  UInt retVal = disDSPInstr_MIPS_WRK ( cins );
15136                  if (0 != retVal ) {
15137                     goto decode_failure_dsp;
15138                  }
15139                  break;
15140               } else {
15141                  goto decode_failure_dsp;
15142               }
15143               break;
15144            }
15145         }
15146         break;
15147      }
15148      case 0x18:  /* ADDUH.QB/MUL.PH */
15149      case 0x31: {  /* APPEND */
15150         if (VEX_MIPS_PROC_DSP2(archinfo->hwcaps)) {
15151            UInt retVal = disDSPInstr_MIPS_WRK ( cins );
15152            if (0 != retVal ) {
15153               goto decode_failure_dsp;
15154            }
15155            break;
15156         } else {
15157            goto decode_failure_dsp;
15158         }
15159      }
15160      default:
15161         goto decode_failure;
15162
15163   }
15164      break;  /* Special3 */
15165
15166   case 0x3B:
15167      if (0x3B == function &&
15168          (VEX_MIPS_COMP_ID(archinfo->hwcaps) == VEX_PRID_COMP_BROADCOM)) {
15169         /*RDHWR*/
15170         DIP("rdhwr r%d, r%d", rt, rd);
15171         if (rd == 29) {
15172            putIReg(rt, getULR());
15173         } else
15174            goto decode_failure;
15175         break;
15176      } else {
15177         goto decode_failure;
15178      }
15179
15180   case 0x00:  /* Special */
15181
15182      switch (function) {
15183      case 0x1: {
15184         UInt mov_cc = get_mov_cc(cins);
15185         if (tf == 0) {  /* MOVF */
15186            DIP("movf r%d, r%d, %d", rd, rs, mov_cc);
15187            t1 = newTemp(Ity_I1);
15188            t2 = newTemp(Ity_I32);
15189            t3 = newTemp(Ity_I1);
15190
15191            assign(t1, binop(Iop_CmpEQ32, mkU32(0), mkU32(mov_cc)));
15192            assign(t2, IRExpr_ITE(mkexpr(t1),
15193                                  binop(Iop_And32,
15194                                        binop(Iop_Shr32, getFCSR(),
15195                                              mkU8(23)),
15196                                        mkU32(0x1)),
15197                                  binop(Iop_And32,
15198                                        binop(Iop_Shr32, getFCSR(),
15199                                              mkU8(24 + mov_cc)),
15200                                        mkU32(0x1))
15201                                  ));
15202            assign(t3, binop(Iop_CmpEQ32, mkU32(0), mkexpr(t2)));
15203            putIReg(rd, IRExpr_ITE(mkexpr(t3), getIReg(rs), getIReg(rd)));
15204         } else if (tf == 1) {  /* MOVT */
15205            DIP("movt r%d, r%d, %d", rd, rs, mov_cc);
15206            t1 = newTemp(Ity_I1);
15207            t2 = newTemp(Ity_I32);
15208            t3 = newTemp(Ity_I1);
15209
15210            assign(t1, binop(Iop_CmpEQ32, mkU32(0), mkU32(mov_cc)));
15211            assign(t2, IRExpr_ITE(mkexpr(t1),
15212                                  binop(Iop_And32,
15213                                        binop(Iop_Shr32, getFCSR(),
15214                                              mkU8(23)),
15215                                        mkU32(0x1)),
15216                                  binop(Iop_And32,
15217                                        binop(Iop_Shr32, getFCSR(),
15218                                              mkU8(24 + mov_cc)),
15219                                        mkU32(0x1))
15220                                  ));
15221            assign(t3, binop(Iop_CmpEQ32, mkU32(1), mkexpr(t2)));
15222            putIReg(rd, IRExpr_ITE(mkexpr(t3), getIReg(rs), getIReg(rd)));
15223         }
15224         break;
15225      }
15226      case 0x0A: {  /* MOVZ */
15227         DIP("movz r%d, r%d, r%d", rd, rs, rt);
15228         t1 = newTemp(ty);
15229         t2 = newTemp(ty);
15230         if (mode64) {
15231            assign(t1, unop(Iop_32Sto64, unop(Iop_1Sto32, binop(Iop_CmpEQ64,
15232                            getIReg(rt), mkU64(0x0)))));
15233            assign(t2, unop(Iop_32Sto64, unop(Iop_1Sto32, binop(Iop_CmpNE64,
15234                            getIReg(rt), mkU64(0x0)))));
15235            putIReg(rd, binop(Iop_Add64, binop(Iop_And64, getIReg(rs),
15236                        mkexpr(t1)), binop(Iop_And64, getIReg(rd),mkexpr(t2))));
15237         } else {
15238            assign(t1, unop(Iop_1Sto32, binop(Iop_CmpEQ32, getIReg(rt),
15239                                              mkU32(0x0))));
15240            assign(t2, unop(Iop_1Sto32, binop(Iop_CmpNE32, getIReg(rt),
15241                                              mkU32(0x0))));
15242            putIReg(rd, binop(Iop_Add32, binop(Iop_And32, getIReg(rs),
15243                        mkexpr(t1)), binop(Iop_And32, getIReg(rd),
15244                        mkexpr(t2))));
15245         }
15246         break;
15247      }
15248
15249      case 0x0B: {  /* MOVN */
15250         DIP("movn r%d, r%d, r%d", rd, rs, rt);
15251         t1 = newTemp(ty);
15252         t2 = newTemp(ty);
15253         if (mode64) {
15254            assign(t1, unop(Iop_32Sto64, unop(Iop_1Sto32, binop(Iop_CmpEQ64,
15255                            getIReg(rt), mkU64(0x0)))));
15256            assign(t2, unop(Iop_32Sto64, unop(Iop_1Sto32, binop(Iop_CmpNE64,
15257                            getIReg(rt), mkU64(0x0)))));
15258            putIReg(rd, binop(Iop_Add64, binop(Iop_And64, getIReg(rs),
15259                        mkexpr(t2)), binop(Iop_And64, getIReg(rd),
15260                                           mkexpr(t1))));
15261         } else {
15262            assign(t1, unop(Iop_1Sto32, binop(Iop_CmpEQ32, getIReg(rt),
15263                                              mkU32(0x0))));
15264            assign(t2, unop(Iop_1Sto32, binop(Iop_CmpNE32, getIReg(rt),
15265                                              mkU32(0x0))));
15266            putIReg(rd, binop(Iop_Add32, binop(Iop_And32, getIReg(rs),
15267                        mkexpr(t2)), binop(Iop_And32, getIReg(rd),
15268                        mkexpr(t1))));
15269         }
15270         break;
15271      }
15272
15273      case 0x18:  {  /* MULT */
15274         if ( (1 <= ac) && ( 3 >= ac) ) {
15275            if (VEX_MIPS_PROC_DSP(archinfo->hwcaps)) {
15276               /* If DSP is present -> DSP ASE MULT */
15277               UInt retVal = disDSPInstr_MIPS_WRK ( cins );
15278               if (0 != retVal ) {
15279                  goto decode_failure_dsp;
15280               }
15281               break;
15282            } else {
15283               goto decode_failure_dsp;
15284            }
15285         } else {
15286            DIP("mult r%d, r%d", rs, rt);
15287            t2 = newTemp(Ity_I64);
15288
15289            assign(t2, binop(Iop_MullS32, mkNarrowTo32(ty, getIReg(rs)),
15290                                          mkNarrowTo32(ty, getIReg(rt))));
15291
15292            putHI(mkWidenFrom32(ty, unop(Iop_64HIto32, mkexpr(t2)), True));
15293            putLO(mkWidenFrom32(ty, unop(Iop_64to32, mkexpr(t2)), True));
15294            break;
15295         }
15296      }
15297      case 0x19:  {  /* MULTU */
15298         if ( (1 <= ac) && ( 3 >= ac) ) {
15299            if (VEX_MIPS_PROC_DSP(archinfo->hwcaps)) {
15300               /* If DSP is present -> DSP ASE MULTU */
15301               UInt retVal = disDSPInstr_MIPS_WRK ( cins );
15302               if (0 != retVal ) {
15303                  goto decode_failure_dsp;
15304               }
15305               break;
15306            } else {
15307               goto decode_failure_dsp;
15308            }
15309         } else {
15310            DIP("multu r%d, r%d", rs, rt);
15311            t2 = newTemp(Ity_I64);
15312
15313            assign(t2, binop(Iop_MullU32, mkNarrowTo32(ty, getIReg(rs)),
15314                                          mkNarrowTo32(ty, getIReg(rt))));
15315
15316            putHI(mkWidenFrom32(ty, unop(Iop_64HIto32, mkexpr(t2)), True));
15317            putLO(mkWidenFrom32(ty, unop(Iop_64to32, mkexpr(t2)), True));
15318            break;
15319         }
15320      }
15321      case 0x20: {  /* ADD */
15322         DIP("add r%d, r%d, r%d", rd, rs, rt);
15323         IRTemp tmpRs32 = newTemp(Ity_I32);
15324         IRTemp tmpRt32 = newTemp(Ity_I32);
15325
15326         assign(tmpRs32, mkNarrowTo32(ty, getIReg(rs)));
15327         assign(tmpRt32, mkNarrowTo32(ty, getIReg(rt)));
15328
15329         t0 = newTemp(Ity_I32);
15330         t1 = newTemp(Ity_I32);
15331         t2 = newTemp(Ity_I32);
15332         t3 = newTemp(Ity_I32);
15333         t4 = newTemp(Ity_I32);
15334         /* dst = src0 + src1
15335            if (sign(src0 ) != sign(src1 ))
15336            goto no overflow;
15337            if (sign(dst) == sign(src0 ))
15338            goto no overflow;
15339            we have overflow! */
15340
15341         assign(t0, binop(Iop_Add32, mkexpr(tmpRs32), mkexpr(tmpRt32)));
15342         assign(t1, binop(Iop_Xor32, mkexpr(tmpRs32), mkexpr(tmpRt32)));
15343         assign(t2, unop(Iop_1Uto32,
15344                         binop(Iop_CmpEQ32,
15345                               binop(Iop_And32, mkexpr(t1), mkU32(0x80000000)),
15346                               mkU32(0x80000000))));
15347
15348         assign(t3, binop(Iop_Xor32, mkexpr(t0), mkexpr(tmpRs32)));
15349         assign(t4, unop(Iop_1Uto32,
15350                         binop(Iop_CmpNE32,
15351                               binop(Iop_And32, mkexpr(t3), mkU32(0x80000000)),
15352                               mkU32(0x80000000))));
15353
15354         stmt(IRStmt_Exit(binop(Iop_CmpEQ32,
15355                                binop(Iop_Or32, mkexpr(t2), mkexpr(t4)),
15356                                mkU32(0)),
15357                          Ijk_SigFPE_IntOvf,
15358                          mode64 ? IRConst_U64(guest_PC_curr_instr + 4) :
15359                                   IRConst_U32(guest_PC_curr_instr + 4),
15360                          OFFB_PC));
15361
15362         putIReg(rd,  mkWidenFrom32(ty, mkexpr(t0), True));
15363         break;
15364      }
15365      case 0x1A:  /* DIV */
15366         DIP("div r%d, r%d", rs, rt);
15367         if (mode64) {
15368            t2 = newTemp(Ity_I64);
15369
15370            assign(t2, binop(Iop_DivModS64to32,
15371                             getIReg(rs), mkNarrowTo32(ty, getIReg(rt))));
15372
15373            putHI(mkWidenFrom32(ty, unop(Iop_64HIto32, mkexpr(t2)), True));
15374            putLO(mkWidenFrom32(ty, unop(Iop_64to32, mkexpr(t2)), True));
15375         } else {
15376            t1 = newTemp(Ity_I64);
15377            t2 = newTemp(Ity_I64);
15378
15379            assign(t1, unop(Iop_32Sto64, getIReg(rs)));
15380            assign(t2, binop(Iop_DivModS64to32, mkexpr(t1), getIReg(rt)));
15381
15382            putHI(unop(Iop_64HIto32, mkexpr(t2)));
15383            putLO(unop(Iop_64to32, mkexpr(t2)));
15384         }
15385         break;
15386
15387      case 0x1B:  /* DIVU */
15388         DIP("divu r%d, r%d", rs, rt);
15389         if (mode64) {
15390            t2 = newTemp(Ity_I64);
15391
15392            assign(t2, binop(Iop_DivModU64to32,
15393                             getIReg(rs), mkNarrowTo32(ty, getIReg(rt))));
15394
15395            putHI(mkWidenFrom32(ty, unop(Iop_64HIto32, mkexpr(t2)), True));
15396            putLO(mkWidenFrom32(ty, unop(Iop_64to32, mkexpr(t2)), True));
15397         } else {
15398            t1 = newTemp(Ity_I64);
15399            t2 = newTemp(Ity_I64);
15400            assign(t1, unop(Iop_32Uto64, getIReg(rs)));
15401            assign(t2, binop(Iop_DivModU64to32, mkexpr(t1), getIReg(rt)));
15402            putHI(unop(Iop_64HIto32, mkexpr(t2)));
15403            putLO(unop(Iop_64to32, mkexpr(t2)));
15404         }
15405         break;
15406
15407      case 0x1C:  /* Doubleword Multiply - DMULT; MIPS64 */
15408         DIP("dmult r%u, r%u", rs, rt);
15409         t0 = newTemp(Ity_I128);
15410
15411         assign(t0, binop(Iop_MullS64, getIReg(rs), getIReg(rt)));
15412
15413         putHI(unop(Iop_128HIto64, mkexpr(t0)));
15414         putLO(unop(Iop_128to64, mkexpr(t0)));
15415         break;
15416
15417      case 0x1D:  /* Doubleword Multiply Unsigned - DMULTU; MIPS64 */
15418         DIP("dmultu r%u, r%u", rs, rt);
15419         t0 = newTemp(Ity_I128);
15420
15421         assign(t0, binop(Iop_MullU64, getIReg(rs), getIReg(rt)));
15422
15423         putHI(unop(Iop_128HIto64, mkexpr(t0)));
15424         putLO(unop(Iop_128to64, mkexpr(t0)));
15425         break;
15426
15427      case 0x1E:  /* Doubleword Divide DDIV; MIPS64 */
15428         DIP("ddiv r%u, r%u", rs, rt);
15429         t1 = newTemp(Ity_I128);
15430
15431         assign(t1, binop(Iop_DivModS64to64, getIReg(rs), getIReg(rt)));
15432
15433         putHI(unop(Iop_128HIto64, mkexpr(t1)));
15434         putLO(unop(Iop_128to64, mkexpr(t1)));
15435         break;
15436
15437      case 0x1F:  /* Doubleword Divide Unsigned DDIVU; MIPS64 check this */
15438         DIP("ddivu r%u, r%u", rs, rt);
15439         t1 = newTemp(Ity_I128);
15440         t2 = newTemp(Ity_I128);
15441
15442         assign(t1, binop(Iop_64HLto128, mkU64(0), getIReg(rs)));
15443
15444         assign(t2, binop(Iop_DivModU128to64, mkexpr(t1), getIReg(rt)));
15445
15446         putHI(unop(Iop_128HIto64, mkexpr(t2)));
15447         putLO(unop(Iop_128to64, mkexpr(t2)));
15448         break;
15449
15450      case 0x10: {  /* MFHI */
15451         if (VEX_MIPS_PROC_DSP(archinfo->hwcaps)) {
15452            /* If DSP is present -> DSP ASE MFHI */
15453            UInt retVal = disDSPInstr_MIPS_WRK ( cins );
15454            if (0 != retVal ) {
15455               goto decode_failure;
15456            }
15457            break;
15458         } else {
15459            DIP("mfhi r%d", rd);
15460            putIReg(rd, getHI());
15461            break;
15462         }
15463      }
15464
15465      case 0x11:  {  /* MTHI */
15466         if (VEX_MIPS_PROC_DSP(archinfo->hwcaps)) {
15467            /* If DSP is present -> DSP ASE MTHI */
15468            UInt retVal = disDSPInstr_MIPS_WRK ( cins );
15469            if (0 != retVal ) {
15470               goto decode_failure;
15471            }
15472            break;
15473         } else {
15474            DIP("mthi r%d", rs);
15475            putHI(getIReg(rs));
15476            break;
15477         }
15478      }
15479
15480      case 0x12:  {  /* MFLO */
15481         if (VEX_MIPS_PROC_DSP(archinfo->hwcaps)) {
15482            /* If DSP is present -> DSP ASE MFLO */
15483            UInt retVal = disDSPInstr_MIPS_WRK ( cins );
15484            if (0 != retVal ) {
15485               goto decode_failure;
15486            }
15487            break;
15488         } else {
15489            DIP("mflo r%d", rd);
15490            putIReg(rd, getLO());
15491            break;
15492         }
15493      }
15494
15495      case 0x13:  {  /* MTLO */
15496         if (VEX_MIPS_PROC_DSP(archinfo->hwcaps)) {
15497            /* If DSP is present -> DSP ASE MTLO */
15498            UInt retVal = disDSPInstr_MIPS_WRK ( cins );
15499            if (0 != retVal ) {
15500               goto decode_failure;
15501            }
15502            break;
15503         } else {
15504            DIP("mtlo r%d", rs);
15505            putLO(getIReg(rs));
15506            break;
15507         }
15508      }
15509
15510      case 0x21:  /* ADDU */
15511         DIP("addu r%d, r%d, r%d", rd, rs, rt);
15512         if (mode64) {
15513            ALU_PATTERN64(Iop_Add32);
15514         } else {
15515            ALU_PATTERN(Iop_Add32);
15516         }
15517         break;
15518
15519      case 0x22: {  /* SUB */
15520         DIP("sub r%d, r%d, r%d", rd, rs, rt);
15521         IRTemp tmpRs32 = newTemp(Ity_I32);
15522         IRTemp tmpRt32 = newTemp(Ity_I32);
15523
15524         assign(tmpRs32, mkNarrowTo32(ty, getIReg(rs)));
15525         assign(tmpRt32, mkNarrowTo32(ty, getIReg(rt)));
15526         t0 = newTemp(Ity_I32);
15527         t1 = newTemp(Ity_I32);
15528         t2 = newTemp(Ity_I32);
15529         t3 = newTemp(Ity_I32);
15530         t4 = newTemp(Ity_I32);
15531         t5 = newTemp(Ity_I32);
15532         /* dst = src0 + (-1 * src1)
15533            if(sign(src0 ) != sign((-1 * src1) ))
15534            goto no overflow;
15535            if(sign(dst) == sign(src0 ))
15536            goto no overflow;
15537            we have overflow! */
15538
15539         assign(t5, binop(Iop_Mul32, mkexpr(tmpRt32), mkU32(-1)));
15540         assign(t0, binop(Iop_Add32, mkexpr(tmpRs32), mkexpr(t5)));
15541         assign(t1, binop(Iop_Xor32, mkexpr(tmpRs32), mkexpr(t5)));
15542         assign(t2, unop(Iop_1Sto32, binop(Iop_CmpEQ32, binop(Iop_And32,
15543                         mkexpr(t1), mkU32(0x80000000)), mkU32(0x80000000))));
15544
15545         assign(t3, binop(Iop_Xor32, mkexpr(t0), mkexpr(tmpRs32)));
15546         assign(t4, unop(Iop_1Sto32, binop(Iop_CmpNE32, binop(Iop_And32,
15547                         mkexpr(t3), mkU32(0x80000000)), mkU32(0x80000000))));
15548
15549         stmt(IRStmt_Exit(binop(Iop_CmpEQ32, binop(Iop_Or32, mkexpr(t2),
15550                                mkexpr(t4)), mkU32(0)), Ijk_SigFPE_IntOvf,
15551                          mode64 ? IRConst_U64(guest_PC_curr_instr + 4) :
15552                                   IRConst_U32(guest_PC_curr_instr + 4),
15553                          OFFB_PC));
15554
15555         putIReg(rd, mkWidenFrom32(ty, mkexpr(t0), True));
15556         break;
15557      }
15558      case 0x23:  /* SUBU */
15559         DIP("subu r%d, r%d, r%d", rd, rs, rt);
15560         if (mode64) {
15561            ALU_PATTERN64(Iop_Sub32);
15562         } else {
15563            ALU_PATTERN(Iop_Sub32);
15564         }
15565         break;
15566
15567      case 0x24:  /* AND */
15568         DIP("and r%d, r%d, r%d", rd, rs, rt);
15569         if (mode64) {
15570            ALU_PATTERN(Iop_And64);
15571         } else {
15572            ALU_PATTERN(Iop_And32);
15573         }
15574         break;
15575
15576      case 0x25:  /* OR */
15577         DIP("or r%d, r%d, r%d", rd, rs, rt);
15578         if (mode64) {
15579            ALU_PATTERN(Iop_Or64);
15580         } else {
15581            ALU_PATTERN(Iop_Or32);
15582         }
15583         break;
15584
15585      case 0x26:  /* XOR */
15586         DIP("xor r%d, r%d, r%d", rd, rs, rt);
15587         if (mode64) {
15588            ALU_PATTERN(Iop_Xor64);
15589         } else {
15590            ALU_PATTERN(Iop_Xor32);
15591         }
15592         break;
15593
15594      case 0x27:  /* NOR */
15595         DIP("nor r%d, r%d, r%d", rd, rs, rt);
15596         if (mode64)
15597            putIReg(rd, unop(Iop_Not64, binop(Iop_Or64, getIReg(rs),
15598                                              getIReg(rt))));
15599         else
15600            putIReg(rd, unop(Iop_Not32, binop(Iop_Or32, getIReg(rs),
15601                                              getIReg(rt))));
15602         break;
15603
15604      case 0x08:  /* JR */
15605         DIP("jr r%d", rs);
15606         t0 = newTemp(ty);
15607         assign(t0, getIReg(rs));
15608         lastn = mkexpr(t0);
15609         break;
15610
15611      case 0x09:  /* JALR */
15612         DIP("jalr r%d r%d", rd, rs);
15613         if (mode64) {
15614            putIReg(rd, mkU64(guest_PC_curr_instr + 8));
15615            t0 = newTemp(Ity_I64);
15616            assign(t0, getIReg(rs));
15617            lastn = mkexpr(t0);
15618         } else {
15619            putIReg(rd, mkU32(guest_PC_curr_instr + 8));
15620            t0 = newTemp(Ity_I32);
15621            assign(t0, getIReg(rs));
15622            lastn = mkexpr(t0);
15623         }
15624         break;
15625
15626      case 0x0C:  /* SYSCALL */
15627         DIP("syscall");
15628         if (mode64)
15629            putPC(mkU64(guest_PC_curr_instr + 4));
15630         else
15631            putPC(mkU32(guest_PC_curr_instr + 4));
15632         dres.jk_StopHere = Ijk_Sys_syscall;
15633         dres.whatNext    = Dis_StopHere;
15634         break;
15635
15636      case 0x2A:  /* SLT */
15637         DIP("slt r%d, r%d, r%d", rd, rs, rt);
15638         if (mode64)
15639            putIReg(rd, unop(Iop_1Uto64, binop(Iop_CmpLT64S, getIReg(rs),
15640                                               getIReg(rt))));
15641         else
15642            putIReg(rd, unop(Iop_1Uto32, binop(Iop_CmpLT32S, getIReg(rs),
15643                                               getIReg(rt))));
15644         break;
15645
15646      case 0x2B:  /* SLTU */
15647         DIP("sltu r%d, r%d, r%d", rd, rs, rt);
15648         if (mode64)
15649            putIReg(rd, unop(Iop_1Uto64, binop(Iop_CmpLT64U, getIReg(rs),
15650                                         getIReg(rt))));
15651         else
15652            putIReg(rd, unop(Iop_1Uto32, binop(Iop_CmpLT32U, getIReg(rs),
15653                                         getIReg(rt))));
15654         break;
15655
15656      case 0x00: {  /* SLL */
15657         DIP("sll r%d, r%d, %d", rd, rt, sa);
15658         IRTemp tmpRt32 = newTemp(Ity_I32);
15659         IRTemp tmpSh32 = newTemp(Ity_I32);
15660         IRTemp tmpRd = newTemp(Ity_I64);
15661         if (mode64) {
15662            assign(tmpRt32, mkNarrowTo32(ty, getIReg(rt)));
15663            assign(tmpSh32, binop(Iop_Shl32, mkexpr(tmpRt32), mkU8(sa)));
15664            assign(tmpRd, mkWidenFrom32(ty, mkexpr(tmpSh32), True));
15665            putIReg(rd, mkexpr(tmpRd));
15666         } else
15667            SXX_PATTERN(Iop_Shl32);
15668         break;
15669      }
15670
15671      case 0x04: {  /* SLLV */
15672         DIP("sllv r%d, r%d, r%d", rd, rt, rs);
15673         if (mode64) {
15674            IRTemp tmpRs8 = newTemp(Ity_I8);
15675            IRTemp tmpRt32 = newTemp(Ity_I32);
15676            IRTemp tmpSh32 = newTemp(Ity_I32);
15677            IRTemp tmp = newTemp(ty);
15678            assign(tmp, binop(mkSzOp(ty, Iop_And8), getIReg(rs),
15679                              mkSzImm(ty, 31)));
15680            assign(tmpRs8, mkNarrowTo8(ty, mkexpr(tmp)));
15681            assign(tmpRt32, mkNarrowTo32(ty, getIReg(rt)));
15682            assign(tmpSh32, binop(Iop_Shl32, mkexpr(tmpRt32), mkexpr(tmpRs8)));
15683            putIReg(rd, mkWidenFrom32(ty, mkexpr(tmpSh32), True));
15684         } else {
15685            SXXV_PATTERN(Iop_Shl32);
15686         }
15687         break;
15688      }
15689
15690      case 0x03:  /* SRA */
15691         DIP("sra r%d, r%d, %d", rd, rt, sa);
15692         if (mode64) {
15693            IRTemp tmpRt32 = newTemp(Ity_I32);
15694            IRTemp tmpSh32 = newTemp(Ity_I32);
15695
15696            t1 = newTemp(Ity_I64);
15697            t2 = newTemp(Ity_I64);
15698            t3 = newTemp(Ity_I64);
15699
15700            assign(t1, binop(Iop_And64, getIReg(rt),  /* hi */
15701                             mkU64(0xFFFFFFFF00000000ULL)));
15702
15703            assign(t2, binop(Iop_Sar64, mkexpr(t1), mkU8(sa)));
15704
15705            assign(tmpRt32, mkNarrowTo32(ty, getIReg(rt)));
15706            assign(tmpSh32, binop(Iop_Sar32, mkexpr(tmpRt32), mkU8(sa)));
15707
15708            putIReg(rd, mkWidenFrom32(ty, mkexpr(tmpSh32), True));
15709         } else {
15710            SXX_PATTERN(Iop_Sar32);
15711         }
15712         break;
15713
15714      case 0x07:  /* SRAV */
15715         DIP("srav r%d, r%d, r%d", rd, rt, rs);
15716         if (mode64) {
15717            IRTemp tmpRt32 = newTemp(Ity_I32);
15718            IRTemp tmpSh32 = newTemp(Ity_I32);
15719
15720            t1 = newTemp(Ity_I64);
15721            t2 = newTemp(Ity_I64);
15722            t3 = newTemp(Ity_I64);
15723            t4 = newTemp(Ity_I8);
15724
15725            assign(t4, unop(Iop_32to8, binop(Iop_And32,
15726                       mkNarrowTo32(ty, getIReg(rs)), mkU32(0x0000001F))));
15727
15728            assign(t1, binop(Iop_And64, getIReg(rt),  /* hi */
15729                   mkU64(0xFFFFFFFF00000000ULL)));
15730
15731            assign(t2, binop(Iop_Sar64, mkexpr(t1), mkexpr(t4)));
15732
15733            assign(tmpRt32, mkNarrowTo32(ty, getIReg(rt)));
15734            assign(tmpSh32, binop(Iop_Sar32, mkexpr(tmpRt32), mkexpr(t4)));
15735
15736            putIReg(rd, mkWidenFrom32(ty, mkexpr(tmpSh32), True));
15737         } else {
15738            SXXV_PATTERN(Iop_Sar32);
15739         }
15740         break;
15741
15742      case 0x02: {  /* SRL */
15743         rot = get_rot(cins);
15744         if (rot) {
15745            DIP("rotr r%d, r%d, %d", rd, rt, sa);
15746            putIReg(rd, mkWidenFrom32(ty, genROR32(mkNarrowTo32(ty,
15747                        getIReg(rt)), sa), True));
15748         } else {
15749            DIP("srl r%d, r%d, %d", rd, rt, sa);
15750            if (mode64) {
15751               IRTemp tmpSh32 = newTemp(Ity_I32);
15752               IRTemp tmpRt32 = newTemp(Ity_I32);
15753
15754               assign(tmpRt32, mkNarrowTo32(ty, getIReg(rt)));
15755               assign(tmpSh32, binop(Iop_Shr32, mkexpr(tmpRt32), mkU8(sa)));
15756               putIReg(rd, mkWidenFrom32(ty, mkexpr(tmpSh32), True));
15757            } else {
15758               SXX_PATTERN(Iop_Shr32);
15759            }
15760         }
15761      break;
15762      }
15763
15764      case 0x06: {
15765         rot = get_rotv(cins);
15766         if (rot) {
15767            DIP("rotrv r%d, r%d, r%d", rd, rt, rs);
15768            putIReg(rd, mkWidenFrom32(ty, genRORV32(mkNarrowTo32(ty,
15769                        getIReg(rt)), mkNarrowTo32(ty, getIReg(rs))), True));
15770            break;
15771         } else {  /* SRLV */
15772            DIP("srlv r%d, r%d, r%d", rd, rt, rs);
15773            if (mode64) {
15774               SXXV_PATTERN64(Iop_Shr32);
15775            } else {
15776               SXXV_PATTERN(Iop_Shr32);
15777            }
15778            break;
15779         }
15780      }
15781
15782      case 0x0D:  /* BREAK */
15783         DIP("break 0x%x", trap_code);
15784         if (mode64)
15785            jmp_lit64(&dres, Ijk_SigTRAP, (guest_PC_curr_instr + 4));
15786         else
15787            jmp_lit32(&dres, Ijk_SigTRAP, (guest_PC_curr_instr + 4));
15788         vassert(dres.whatNext == Dis_StopHere);
15789         break;
15790
15791      case 0x30: {  /* TGE */
15792         DIP("tge r%d, r%d %d", rs, rt, trap_code);
15793         if (mode64) {
15794            if (trap_code == 7)
15795               stmt (IRStmt_Exit (unop (Iop_Not1,
15796                                        binop (Iop_CmpLT64S,
15797                                               getIReg (rs),
15798                                               getIReg (rt))),
15799                                Ijk_SigFPE_IntDiv,
15800                                IRConst_U64(guest_PC_curr_instr + 4),
15801                                OFFB_PC));
15802            else if (trap_code == 6)
15803               stmt (IRStmt_Exit (unop (Iop_Not1,
15804                                        binop (Iop_CmpLT64S,
15805                                               getIReg (rs),
15806                                               getIReg (rt))),
15807                                Ijk_SigFPE_IntOvf,
15808                                IRConst_U64(guest_PC_curr_instr + 4),
15809                                OFFB_PC));
15810            else
15811               stmt (IRStmt_Exit (unop (Iop_Not1,
15812                                        binop (Iop_CmpLT64S,
15813                                               getIReg (rs),
15814                                               getIReg (rt))),
15815                                Ijk_SigTRAP,
15816                                IRConst_U64(guest_PC_curr_instr + 4),
15817                                OFFB_PC));
15818         } else {
15819            if (trap_code == 7)
15820               stmt (IRStmt_Exit (unop (Iop_Not1,
15821                                        binop (Iop_CmpLT32S,
15822                                               getIReg (rs),
15823                                               getIReg (rt))),
15824                                  Ijk_SigFPE_IntDiv,
15825                                  IRConst_U32(guest_PC_curr_instr + 4),
15826                                  OFFB_PC));
15827            else if (trap_code == 6)
15828               stmt (IRStmt_Exit (unop (Iop_Not1,
15829                                        binop (Iop_CmpLT32S,
15830                                               getIReg (rs),
15831                                               getIReg (rt))),
15832                                  Ijk_SigFPE_IntOvf,
15833                                  IRConst_U32(guest_PC_curr_instr + 4),
15834                                  OFFB_PC));
15835            else
15836               stmt (IRStmt_Exit (unop (Iop_Not1,
15837                                        binop (Iop_CmpLT32S,
15838                                               getIReg (rs),
15839                                               getIReg (rt))),
15840                                  Ijk_SigTRAP,
15841                                  IRConst_U32(guest_PC_curr_instr + 4),
15842                                  OFFB_PC));
15843         }
15844         break;
15845      }
15846      case 0x31: {  /* TGEU */
15847         DIP("tgeu r%d, r%d %d", rs, rt, trap_code);
15848         if (mode64) {
15849            if (trap_code == 7)
15850               stmt (IRStmt_Exit (unop (Iop_Not1,
15851                                        binop (Iop_CmpLT64U,
15852                                               getIReg (rs),
15853                                               getIReg (rt))),
15854                                  Ijk_SigFPE_IntDiv,
15855                                  IRConst_U64(guest_PC_curr_instr + 4),
15856                                  OFFB_PC));
15857            else if (trap_code == 6)
15858               stmt (IRStmt_Exit (unop (Iop_Not1,
15859                                        binop (Iop_CmpLT64U,
15860                                               getIReg (rs),
15861                                               getIReg (rt))),
15862                                  Ijk_SigFPE_IntOvf,
15863                                  IRConst_U64(guest_PC_curr_instr + 4),
15864                                  OFFB_PC));
15865            else
15866               stmt (IRStmt_Exit (unop (Iop_Not1,
15867                                        binop (Iop_CmpLT64U,
15868                                               getIReg (rs),
15869                                               getIReg (rt))),
15870                                  Ijk_SigTRAP,
15871                                  IRConst_U64(guest_PC_curr_instr + 4),
15872                                  OFFB_PC));
15873         } else {
15874            if (trap_code == 7)
15875               stmt (IRStmt_Exit (unop (Iop_Not1,
15876                                        binop (Iop_CmpLT32U,
15877                                               getIReg (rs),
15878                                               getIReg (rt))),
15879                                  Ijk_SigFPE_IntDiv,
15880                                  IRConst_U32(guest_PC_curr_instr + 4),
15881                                  OFFB_PC));
15882            else if (trap_code == 6)
15883               stmt (IRStmt_Exit (unop (Iop_Not1,
15884                                        binop (Iop_CmpLT32U,
15885                                               getIReg (rs),
15886                                               getIReg (rt))),
15887                                  Ijk_SigFPE_IntOvf,
15888                                  IRConst_U32(guest_PC_curr_instr + 4),
15889                                  OFFB_PC));
15890            else
15891               stmt (IRStmt_Exit (unop (Iop_Not1,
15892                                        binop (Iop_CmpLT32U,
15893                                               getIReg (rs),
15894                                               getIReg (rt))),
15895                                  Ijk_SigTRAP,
15896                                  IRConst_U32(guest_PC_curr_instr + 4),
15897                                  OFFB_PC));
15898         }
15899         break;
15900      }
15901      case 0x32: {  /* TLT */
15902         DIP("tlt r%d, r%d %d", rs, rt, trap_code);
15903         if (mode64) {
15904            if (trap_code == 7)
15905               stmt(IRStmt_Exit(binop(Iop_CmpLT64S, getIReg(rs),
15906                                      getIReg(rt)), Ijk_SigFPE_IntDiv,
15907                                IRConst_U64(guest_PC_curr_instr + 4),
15908                                OFFB_PC));
15909            else if (trap_code == 6)
15910               stmt(IRStmt_Exit(binop(Iop_CmpLT64S, getIReg(rs),
15911                                      getIReg(rt)), Ijk_SigFPE_IntOvf,
15912                                IRConst_U64(guest_PC_curr_instr + 4),
15913                                OFFB_PC));
15914            else
15915               stmt(IRStmt_Exit(binop(Iop_CmpLT64S, getIReg(rs),
15916                                      getIReg(rt)), Ijk_SigTRAP,
15917                                IRConst_U64(guest_PC_curr_instr + 4),
15918                                OFFB_PC));
15919         } else {
15920            if (trap_code == 7)
15921               stmt(IRStmt_Exit(binop(Iop_CmpLT32S, getIReg(rs),
15922                                      getIReg(rt)), Ijk_SigFPE_IntDiv,
15923                                IRConst_U32(guest_PC_curr_instr + 4),
15924                                OFFB_PC));
15925            else if (trap_code == 6)
15926               stmt(IRStmt_Exit(binop(Iop_CmpLT32S, getIReg(rs),
15927                                      getIReg(rt)), Ijk_SigFPE_IntOvf,
15928                                IRConst_U32(guest_PC_curr_instr + 4),
15929                                OFFB_PC));
15930            else
15931               stmt(IRStmt_Exit(binop(Iop_CmpLT32S, getIReg(rs),
15932                                      getIReg(rt)), Ijk_SigTRAP,
15933                                IRConst_U32(guest_PC_curr_instr + 4),
15934                                OFFB_PC));
15935         }
15936         break;
15937      }
15938      case 0x33: {  /* TLTU */
15939         DIP("tltu r%d, r%d %d", rs, rt, trap_code);
15940         if (mode64) {
15941            if (trap_code == 7)
15942               stmt(IRStmt_Exit(binop(Iop_CmpLT64U, getIReg(rs),
15943                                      getIReg(rt)), Ijk_SigFPE_IntDiv,
15944                                IRConst_U64(guest_PC_curr_instr + 4),
15945                                OFFB_PC));
15946            else if (trap_code == 6)
15947               stmt(IRStmt_Exit(binop(Iop_CmpLT64U, getIReg(rs),
15948                                      getIReg(rt)), Ijk_SigFPE_IntOvf,
15949                                IRConst_U64(guest_PC_curr_instr + 4),
15950                                OFFB_PC));
15951            else
15952               stmt(IRStmt_Exit(binop(Iop_CmpLT64U, getIReg(rs),
15953                                      getIReg(rt)), Ijk_SigTRAP,
15954                                IRConst_U64(guest_PC_curr_instr + 4),
15955                                OFFB_PC));
15956         } else {
15957            if (trap_code == 7)
15958               stmt(IRStmt_Exit(binop(Iop_CmpLT32U, getIReg(rs),
15959                                      getIReg(rt)), Ijk_SigFPE_IntDiv,
15960                                IRConst_U32(guest_PC_curr_instr + 4),
15961                                OFFB_PC));
15962            else if (trap_code == 6)
15963               stmt(IRStmt_Exit(binop(Iop_CmpLT32U, getIReg(rs),
15964                                      getIReg(rt)), Ijk_SigFPE_IntOvf,
15965                                IRConst_U32(guest_PC_curr_instr + 4),
15966                                OFFB_PC));
15967            else
15968               stmt(IRStmt_Exit(binop(Iop_CmpLT32U, getIReg(rs),
15969                                      getIReg (rt)), Ijk_SigTRAP,
15970                                IRConst_U32(guest_PC_curr_instr + 4),
15971                                OFFB_PC));
15972         }
15973         break;
15974      }
15975      case 0x34: {  /* TEQ */
15976         DIP("teq r%d, r%d, %d", rs, rt, trap_code);
15977         if (mode64) {
15978            if (trap_code == 7)
15979               stmt(IRStmt_Exit(binop(Iop_CmpEQ64, getIReg(rs),
15980                                      getIReg(rt)), Ijk_SigFPE_IntDiv,
15981                                IRConst_U64(guest_PC_curr_instr + 4),
15982                                OFFB_PC));
15983            else if (trap_code == 6)
15984               stmt(IRStmt_Exit(binop(Iop_CmpEQ64, getIReg(rs),
15985                                      getIReg(rt)), Ijk_SigFPE_IntOvf,
15986                                IRConst_U64(guest_PC_curr_instr + 4),
15987                                OFFB_PC));
15988            else
15989               stmt(IRStmt_Exit(binop(Iop_CmpEQ64, getIReg(rs),
15990                                      getIReg(rt)), Ijk_SigTRAP,
15991                                IRConst_U64(guest_PC_curr_instr + 4),
15992                                OFFB_PC));
15993         } else {
15994            if (trap_code == 7)
15995               stmt(IRStmt_Exit(binop(Iop_CmpEQ32, getIReg(rs),
15996                                      getIReg(rt)), Ijk_SigFPE_IntDiv,
15997                                IRConst_U32(guest_PC_curr_instr + 4),
15998                                OFFB_PC));
15999            else if (trap_code == 6)
16000               stmt(IRStmt_Exit(binop(Iop_CmpEQ32, getIReg(rs),
16001                                      getIReg(rt)), Ijk_SigFPE_IntOvf,
16002                                IRConst_U32(guest_PC_curr_instr + 4),
16003                                OFFB_PC));
16004            else
16005               stmt(IRStmt_Exit(binop(Iop_CmpEQ32, getIReg(rs),
16006                                      getIReg(rt)), Ijk_SigTRAP,
16007                                IRConst_U32(guest_PC_curr_instr + 4),
16008                                OFFB_PC));
16009         }
16010         break;
16011      }
16012      case 0x36: {  /* TNE */
16013         DIP("tne r%d, r%d %d", rs, rt, trap_code);
16014         if (mode64) {
16015            if (trap_code == 7)
16016               stmt(IRStmt_Exit(binop(Iop_CmpNE64, getIReg(rs),
16017                                      getIReg(rt)), Ijk_SigFPE_IntDiv,
16018                                IRConst_U64(guest_PC_curr_instr + 4),
16019                                OFFB_PC));
16020            else if (trap_code == 6)
16021               stmt(IRStmt_Exit(binop(Iop_CmpNE64, getIReg(rs),
16022                                      getIReg(rt)), Ijk_SigFPE_IntOvf,
16023                                IRConst_U64(guest_PC_curr_instr + 4),
16024                                OFFB_PC));
16025            else
16026               stmt(IRStmt_Exit(binop(Iop_CmpNE64, getIReg(rs),
16027                                      getIReg(rt)), Ijk_SigTRAP,
16028                                IRConst_U64(guest_PC_curr_instr + 4),
16029                                OFFB_PC));
16030         } else {
16031            if (trap_code == 7)
16032               stmt(IRStmt_Exit(binop(Iop_CmpNE32, getIReg(rs),
16033                                      getIReg(rt)), Ijk_SigFPE_IntDiv,
16034                                IRConst_U32(guest_PC_curr_instr + 4),
16035                                OFFB_PC));
16036            else if (trap_code == 6)
16037               stmt(IRStmt_Exit(binop(Iop_CmpNE32, getIReg(rs),
16038                                      getIReg(rt)), Ijk_SigFPE_IntOvf,
16039                                IRConst_U32(guest_PC_curr_instr + 4),
16040                                OFFB_PC));
16041            else
16042               stmt(IRStmt_Exit(binop(Iop_CmpNE32, getIReg(rs),
16043                                      getIReg(rt)), Ijk_SigTRAP,
16044                                IRConst_U32(guest_PC_curr_instr + 4),
16045                                OFFB_PC));
16046         }
16047         break;
16048      }
16049      case 0x14:
16050      case 0x16:
16051      case 0x17:  /* DSLLV, DROTRV:DSRLV, DSRAV */
16052      case 0x38:
16053      case 0x3A:
16054      case 0x3B:  /* DSLL, DROTL:DSRL, DSRA  */
16055      case 0x3C:
16056      case 0x3E:
16057      case 0x3F:  /* DSLL32, DROTR32:DSRL32, DSRA32 */
16058         if (dis_instr_shrt(cins))
16059            break;
16060         goto decode_failure;
16061
16062      case 0x0F:  /* SYNC */
16063         DIP("sync 0x%x", sel);
16064         /* Just ignore it. */
16065         break;
16066
16067      case 0x2C: {  /* Doubleword Add - DADD; MIPS64 */
16068         DIP("dadd r%d, r%d, r%d", rd, rs, rt);
16069         IRTemp tmpRs64 = newTemp(Ity_I64);
16070         IRTemp tmpRt64 = newTemp(Ity_I64);
16071
16072         assign(tmpRs64, getIReg(rs));
16073         assign(tmpRt64, getIReg(rt));
16074
16075         t0 = newTemp(Ity_I64);
16076         t1 = newTemp(Ity_I64);
16077         t2 = newTemp(Ity_I64);
16078         t3 = newTemp(Ity_I64);
16079         t4 = newTemp(Ity_I64);
16080         /* dst = src0 + src1
16081            if(sign(src0 ) != sign(src1 ))
16082            goto no overflow;
16083            if(sign(dst) == sign(src0 ))
16084            goto no overflow;
16085            we have overflow! */
16086
16087         assign(t0, binop(Iop_Add64, mkexpr(tmpRs64), mkexpr(tmpRt64)));
16088         assign(t1, binop(Iop_Xor64, mkexpr(tmpRs64), mkexpr(tmpRt64)));
16089         assign(t2, unop(Iop_1Uto64,
16090                         binop(Iop_CmpEQ64,
16091                               binop(Iop_And64, mkexpr(t1),
16092                                     mkU64(0x8000000000000000ULL)),
16093                               mkU64(0x8000000000000000ULL))));
16094
16095         assign(t3, binop(Iop_Xor64, mkexpr(t0), mkexpr(tmpRs64)));
16096         assign(t4, unop(Iop_1Uto64,
16097                         binop(Iop_CmpNE64,
16098                               binop(Iop_And64, mkexpr(t3),
16099                                     mkU64(0x8000000000000000ULL)),
16100                               mkU64(0x8000000000000000ULL))));
16101
16102         stmt(IRStmt_Exit(binop(Iop_CmpEQ64,
16103                                binop(Iop_Or64, mkexpr(t2), mkexpr(t4)),
16104                                mkU64(0)),
16105                          Ijk_SigFPE_IntOvf,
16106                          IRConst_U64(guest_PC_curr_instr + 4),
16107                          OFFB_PC));
16108
16109         putIReg(rd,  mkexpr(t0));
16110         break;
16111      }
16112
16113      case 0x2D:  /* Doubleword Add Unsigned - DADDU; MIPS64 */
16114         DIP("daddu r%d, r%d, r%d", rd, rs, rt);
16115         ALU_PATTERN(Iop_Add64);
16116         break;
16117
16118      case 0x2E: {  /* Doubleword Subtract - DSUB; MIPS64 */
16119         DIP("dsub r%u, r%u, r%u", rd, rs, rt);
16120         IRTemp tmpRs64 = newTemp(Ity_I64);
16121         IRTemp tmpRt64 = newTemp(Ity_I64);
16122
16123         assign(tmpRs64, getIReg(rs));
16124         assign(tmpRt64, getIReg(rt));
16125         t0 = newTemp(Ity_I64);
16126         t1 = newTemp(Ity_I64);
16127         t2 = newTemp(Ity_I64);
16128         t3 = newTemp(Ity_I64);
16129         t4 = newTemp(Ity_I64);
16130         t5 = newTemp(Ity_I64);
16131         /* dst = src0 + (-1 * src1)
16132            if(sign(src0 ) != sign((-1 * src1) ))
16133            goto no overflow;
16134            if(sign(dst) == sign(src0 ))
16135            goto no overflow;
16136            we have overflow! */
16137
16138         assign(t5, binop(Iop_Mul64,
16139                          mkexpr(tmpRt64),
16140                          mkU64(0xffffffffffffffffULL)));
16141         assign(t0, binop(Iop_Add64, mkexpr(tmpRs64), mkexpr(t5)));
16142         assign(t1, binop(Iop_Xor64, mkexpr(tmpRs64), mkexpr(t5)));
16143         assign(t2, unop(Iop_1Sto64,
16144                         binop(Iop_CmpEQ64,
16145                               binop(Iop_And64,
16146                                     mkexpr(t1),
16147                                     mkU64(0x8000000000000000ULL)),
16148                               mkU64(0x8000000000000000ULL))));
16149
16150         assign(t3, binop(Iop_Xor64, mkexpr(t0), mkexpr(tmpRs64)));
16151         assign(t4, unop(Iop_1Sto64,
16152                         binop(Iop_CmpNE64,
16153                               binop(Iop_And64,
16154                                     mkexpr(t3),
16155                                     mkU64(0x8000000000000000ULL)),
16156                               mkU64(0x8000000000000000ULL))));
16157
16158         stmt(IRStmt_Exit(binop(Iop_CmpEQ64, binop(Iop_Or64, mkexpr(t2),
16159                                mkexpr(t4)), mkU64(0)), Ijk_SigFPE_IntOvf,
16160                          IRConst_U64(guest_PC_curr_instr + 4),
16161                          OFFB_PC));
16162
16163         putIReg(rd, binop(Iop_Sub64, getIReg(rs), getIReg(rt)));
16164         break;
16165      }
16166
16167      case 0x2F:  /* Doubleword Subtract Unsigned - DSUBU; MIPS64 */
16168         DIP("dsub r%u, r%u,r%u", rd, rt, rt);
16169         ALU_PATTERN(Iop_Sub64);
16170         break;
16171
16172      default:
16173         goto decode_failure;
16174      }
16175      break;
16176
16177   case 0x01:  /* Regimm */
16178
16179      switch (rt) {
16180      case 0x00:  /* BLTZ */
16181         DIP("bltz r%d, %d", rs, imm);
16182         if (mode64) {
16183            if (!dis_instr_branch(cins, &dres, resteerOkFn,
16184                        callback_opaque, &bstmt))
16185               goto decode_failure;
16186         } else
16187            dis_branch(False, binop(Iop_CmpEQ32, binop(Iop_And32, getIReg(rs),
16188                       mkU32(0x80000000)), mkU32(0x80000000)), imm, &bstmt);
16189         break;
16190
16191      case 0x01:  /* BGEZ */
16192         DIP("bgez r%d, %d", rs, imm);
16193         if (mode64) {
16194            if (!dis_instr_branch(cins, &dres, resteerOkFn,
16195                                  callback_opaque, &bstmt))
16196               goto decode_failure;
16197         } else
16198            dis_branch(False, binop(Iop_CmpEQ32, binop(Iop_And32, getIReg(rs),
16199                              mkU32(0x80000000)), mkU32(0x0)), imm, &bstmt);
16200         break;
16201
16202      case 0x02:  /* BLTZL */
16203         DIP("bltzl r%d, %d", rs, imm);
16204         lastn = dis_branch_likely(binop(mode64 ? Iop_CmpNE64 : Iop_CmpNE32,
16205                     binop(mode64 ? Iop_And64 : Iop_And32, getIReg(rs),
16206                     mode64 ? mkU64(0x8000000000000000ULL) : mkU32(0x80000000)),
16207                     mode64 ? mkU64(0x8000000000000000ULL) : mkU32(0x80000000)),
16208                     imm);
16209         break;
16210
16211      case 0x03:  /* BGEZL */
16212         DIP("bgezl r%d, %d", rs, imm);
16213         lastn = dis_branch_likely(binop(mode64 ? Iop_CmpNE64 : Iop_CmpNE32,
16214                     binop(mode64 ? Iop_And64 : Iop_And32, getIReg(rs),
16215                     mode64 ? mkU64(0x8000000000000000ULL) : mkU32(0x80000000)),
16216                     mode64 ? mkU64(0x0) : mkU32(0x0)), imm);
16217         break;
16218
16219      case 0x10:  /* BLTZAL */
16220         DIP("bltzal r%d, %d", rs, imm);
16221         if (mode64) {
16222            if (!dis_instr_branch(cins, &dres, resteerOkFn,
16223                        callback_opaque, &bstmt))
16224               goto decode_failure;
16225         } else
16226            dis_branch(True, binop(Iop_CmpEQ32, binop(Iop_And32, getIReg(rs),
16227                       mkU32(0x80000000)), mkU32(0x80000000)), imm, &bstmt);
16228         break;
16229
16230      case 0x12:  /* BLTZALL */
16231         DIP("bltzall r%d, %d", rs, imm);
16232         putIReg(31, mode64 ? mkU64(guest_PC_curr_instr + 8) :
16233                              mkU32(guest_PC_curr_instr + 8));
16234         lastn = dis_branch_likely(binop(mode64 ? Iop_CmpNE64 : Iop_CmpNE32,
16235                     binop(mode64 ? Iop_And64 : Iop_And32, getIReg(rs),
16236                     mode64 ? mkU64(0x8000000000000000ULL) : mkU32(0x80000000)),
16237                     mode64 ? mkU64(0x8000000000000000ULL) : mkU32(0x80000000)),
16238                     imm);
16239         break;
16240
16241      case 0x11:  /* BGEZAL */
16242         DIP("bgezal r%d, %d", rs, imm);
16243         if (mode64) {
16244            if (!dis_instr_branch(cins, &dres, resteerOkFn,
16245                        callback_opaque, &bstmt))
16246               goto decode_failure;
16247         } else
16248            dis_branch(True, binop(Iop_CmpEQ32, binop(Iop_And32, getIReg(rs),
16249                       mkU32(0x80000000)), mkU32(0x0)), imm, &bstmt);
16250         break;
16251
16252      case 0x13:  /* BGEZALL */
16253         DIP("bgezall r%d, %d", rs, imm);
16254         if (mode64) {
16255            putIReg(31, mkU64(guest_PC_curr_instr + 8));
16256            lastn = dis_branch_likely(binop(Iop_CmpNE64,
16257                                            binop(Iop_And64,
16258                                                  getIReg(rs),
16259                                                  mkU64(0x8000000000000000ULL)),
16260                                            mkU64(0x0)),
16261                                      imm);
16262         } else {
16263            putIReg(31, mkU32(guest_PC_curr_instr + 8));
16264            lastn = dis_branch_likely(binop(Iop_CmpNE32, binop(Iop_And32,
16265                                      getIReg(rs), mkU32(0x80000000)),
16266                                      mkU32(0x0)), imm);
16267         }
16268         break;
16269
16270      case 0x08:  /* TGEI */
16271         DIP("tgei r%d, %d %d", rs, imm, trap_code);
16272         if (mode64) {
16273            stmt (IRStmt_Exit (unop (Iop_Not1,
16274                                     binop (Iop_CmpLT64S,
16275                                            getIReg (rs),
16276                                            mkU64 (extend_s_16to64 (imm)))),
16277                             Ijk_SigTRAP,
16278                             IRConst_U64(guest_PC_curr_instr + 4),
16279                             OFFB_PC));
16280         } else {
16281            stmt (IRStmt_Exit (unop (Iop_Not1,
16282                                     binop (Iop_CmpLT32S,
16283                                     getIReg (rs),
16284                                     mkU32 (extend_s_16to32 (imm)))),
16285                             Ijk_SigTRAP,
16286                             IRConst_U32(guest_PC_curr_instr + 4),
16287                             OFFB_PC));
16288         }
16289         break;
16290
16291      case 0x09: {  /* TGEIU */
16292         DIP("tgeiu r%d, %d %d", rs, imm, trap_code);
16293         if (mode64) {
16294            stmt (IRStmt_Exit (unop (Iop_Not1,
16295                                     binop (Iop_CmpLT64U,
16296                                            getIReg (rs),
16297                                            mkU64 (extend_s_16to64 (imm)))),
16298                             Ijk_SigTRAP,
16299                             IRConst_U64(guest_PC_curr_instr + 4),
16300                             OFFB_PC));
16301         } else {
16302            stmt (IRStmt_Exit (unop (Iop_Not1,
16303                                     binop (Iop_CmpLT32U,
16304                                            getIReg (rs),
16305                                            mkU32 (extend_s_16to32 (imm)))),
16306                               Ijk_SigTRAP,
16307                               IRConst_U32(guest_PC_curr_instr + 4),
16308                               OFFB_PC));
16309         }
16310         break;
16311      }
16312      case 0x0A: {  /* TLTI */
16313         DIP("tlti r%d, %d %d", rs, imm, trap_code);
16314         if (mode64) {
16315            stmt (IRStmt_Exit (binop (Iop_CmpLT64S, getIReg (rs),
16316                                      mkU64 (extend_s_16to64 (imm))),
16317                             Ijk_SigTRAP,
16318                             IRConst_U64(guest_PC_curr_instr + 4),
16319                             OFFB_PC));
16320         } else {
16321            stmt (IRStmt_Exit (binop (Iop_CmpLT32S, getIReg (rs),
16322                                      mkU32 (extend_s_16to32 (imm))),
16323                               Ijk_SigTRAP,
16324                               IRConst_U32(guest_PC_curr_instr + 4),
16325                               OFFB_PC));
16326         }
16327         break;
16328      }
16329      case 0x0B: {  /* TLTIU */
16330         DIP("tltiu r%d, %d %d", rs, imm, trap_code);
16331         if (mode64) {
16332            stmt (IRStmt_Exit (binop (Iop_CmpLT64U, getIReg (rs),
16333                                      mkU64 (extend_s_16to64 (imm))),
16334                             Ijk_SigTRAP,
16335                             IRConst_U64(guest_PC_curr_instr + 4),
16336                             OFFB_PC));
16337         } else {
16338            stmt (IRStmt_Exit (binop (Iop_CmpLT32U, getIReg (rs),
16339                                      mkU32 (extend_s_16to32 (imm))),
16340                               Ijk_SigTRAP,
16341                               IRConst_U32(guest_PC_curr_instr + 4),
16342                               OFFB_PC));
16343         }
16344         break;
16345      }
16346      case 0x0C: {  /* TEQI */
16347          DIP("teqi r%d, %d %d", rs, imm, trap_code);
16348         if (mode64) {
16349            stmt (IRStmt_Exit (binop (Iop_CmpEQ64, getIReg (rs),
16350                                      mkU64 (extend_s_16to64 (imm))),
16351                               Ijk_SigTRAP,
16352                               IRConst_U64(guest_PC_curr_instr + 4),
16353                               OFFB_PC));
16354         } else {
16355            stmt (IRStmt_Exit (binop (Iop_CmpEQ32, getIReg (rs),
16356                                      mkU32 (extend_s_16to32 (imm))),
16357                               Ijk_SigTRAP,
16358                               IRConst_U32(guest_PC_curr_instr + 4),
16359                               OFFB_PC));
16360         }
16361         break;
16362      }
16363      case 0x0E: {  /* TNEI */
16364         DIP("tnei r%d, %d %d", rs, imm, trap_code);
16365         if (mode64) {
16366            stmt (IRStmt_Exit (binop (Iop_CmpNE64, getIReg (rs),
16367                                      mkU64 (extend_s_16to64 (imm))),
16368                               Ijk_SigTRAP,
16369                               IRConst_U64(guest_PC_curr_instr + 4),
16370                               OFFB_PC));
16371         } else {
16372            stmt (IRStmt_Exit (binop (Iop_CmpNE32, getIReg (rs),
16373                                      mkU32 (extend_s_16to32 (imm))),
16374                               Ijk_SigTRAP,
16375                               IRConst_U32(guest_PC_curr_instr + 4),
16376                               OFFB_PC));
16377         }
16378         break;
16379      }
16380      case 0x1C: {  /* BPOSGE32 */
16381         DIP("bposge32 %d", imm);
16382         vassert(!mode64);
16383         t0 = newTemp(Ity_I32);
16384         /* Get pos field from DSPControl register. */
16385         assign(t0, binop(Iop_And32, getDSPControl(), mkU32(0x3f)));
16386         dis_branch(False, unop(Iop_Not1, binop(Iop_CmpLT32U, mkexpr(t0),
16387                                mkU32(32))), imm, &bstmt);
16388      }
16389      case 0x1F:
16390         /* SYNCI */
16391         /* Just ignore it */
16392         break;
16393
16394      default:
16395         goto decode_failure;
16396      }
16397      break;
16398
16399   case 0x04:
16400      DIP("beq r%d, r%d, %d", rs, rt, imm);
16401      if (mode64)
16402         dis_branch(False, binop(Iop_CmpEQ64, getIReg(rs), getIReg(rt)),
16403                                 imm, &bstmt);
16404      else
16405         dis_branch(False, binop(Iop_CmpEQ32, getIReg(rs), getIReg(rt)),
16406                                 imm, &bstmt);
16407      break;
16408
16409   case 0x14:
16410      DIP("beql r%d, r%d, %d", rs, rt, imm);
16411      lastn = dis_branch_likely(binop(mode64 ? Iop_CmpNE64 : Iop_CmpNE32,
16412                                getIReg(rs), getIReg(rt)), imm);
16413      break;
16414
16415   case 0x05:
16416      DIP("bne r%d, r%d, %d", rs, rt, imm);
16417      if (mode64)
16418         dis_branch(False, binop(Iop_CmpNE64, getIReg(rs), getIReg(rt)),
16419                                 imm, &bstmt);
16420      else
16421         dis_branch(False, binop(Iop_CmpNE32, getIReg(rs), getIReg(rt)),
16422                                 imm, &bstmt);
16423      break;
16424
16425   case 0x15:
16426      DIP("bnel r%d, r%d, %d", rs, rt, imm);
16427      lastn = dis_branch_likely(binop(mode64 ? Iop_CmpEQ64 : Iop_CmpEQ32,
16428                                      getIReg(rs), getIReg(rt)), imm);
16429      break;
16430
16431   case 0x07:  /* BGTZ */
16432      DIP("bgtz r%d, %d", rs, imm);
16433      if (mode64)
16434         dis_branch(False, unop(Iop_Not1, binop(Iop_CmpLE64S, getIReg(rs),
16435                                mkU64(0x00))), imm, &bstmt);
16436      else
16437         dis_branch(False, unop(Iop_Not1, binop(Iop_CmpLE32S, getIReg(rs),
16438                                mkU32(0x00))), imm, &bstmt);
16439      break;
16440
16441   case 0x17:  /* BGTZL */
16442      DIP("bgtzl r%d, %d", rs, imm);
16443      if (mode64)
16444         lastn = dis_branch_likely(binop(Iop_CmpLE64S, getIReg(rs),
16445                                         mkU64(0x00)), imm);
16446      else
16447         lastn = dis_branch_likely(binop(Iop_CmpLE32S, getIReg(rs),
16448                                         mkU32(0x00)), imm);
16449      break;
16450
16451   case 0x06:  /* BLEZ */
16452      DIP("blez r%d, %d", rs, imm);
16453      if (mode64)
16454         dis_branch(False, binop(Iop_CmpLE64S, getIReg(rs), mkU64(0x0)),
16455                                imm, &bstmt);
16456      else
16457         dis_branch(False,binop(Iop_CmpLE32S, getIReg(rs), mkU32(0x0)), imm,
16458                                &bstmt);
16459      break;
16460
16461   case 0x16:  /* BLEZL */
16462      DIP("blezl r%d, %d", rs, imm);
16463      lastn = dis_branch_likely(unop(Iop_Not1, (binop(mode64 ? Iop_CmpLE64S :
16464                                     Iop_CmpLE32S, getIReg(rs), mode64 ?
16465                                     mkU64(0x0) : mkU32(0x0)))), imm);
16466      break;
16467
16468   case 0x08: {  /* ADDI */
16469      DIP("addi r%d, r%d, %d", rt, rs, imm);
16470      IRTemp tmpRs32 = newTemp(Ity_I32);
16471      assign(tmpRs32, mkNarrowTo32(ty, getIReg(rs)));
16472
16473      t0 = newTemp(Ity_I32);
16474      t1 = newTemp(Ity_I32);
16475      t2 = newTemp(Ity_I32);
16476      t3 = newTemp(Ity_I32);
16477      t4 = newTemp(Ity_I32);
16478      /* dst = src0 + sign(imm)
16479         if(sign(src0 ) != sign(imm ))
16480         goto no overflow;
16481         if(sign(dst) == sign(src0 ))
16482         goto no overflow;
16483         we have overflow! */
16484
16485      assign(t0, binop(Iop_Add32, mkexpr(tmpRs32),
16486                       mkU32(extend_s_16to32(imm))));
16487      assign(t1, binop(Iop_Xor32, mkexpr(tmpRs32),
16488                       mkU32(extend_s_16to32(imm))));
16489      assign(t2, unop(Iop_1Sto32, binop(Iop_CmpEQ32, binop(Iop_And32,
16490                      mkexpr(t1), mkU32(0x80000000)), mkU32(0x80000000))));
16491
16492      assign(t3, binop(Iop_Xor32, mkexpr(t0), mkexpr(tmpRs32)));
16493      assign(t4, unop(Iop_1Sto32, binop(Iop_CmpNE32, binop(Iop_And32,
16494                      mkexpr(t3), mkU32(0x80000000)), mkU32(0x80000000))));
16495
16496      stmt(IRStmt_Exit(binop(Iop_CmpEQ32, binop(Iop_Or32, mkexpr(t2),
16497                             mkexpr(t4)), mkU32(0)), Ijk_SigFPE_IntOvf,
16498                       mode64 ? IRConst_U64(guest_PC_curr_instr + 4) :
16499                                IRConst_U32(guest_PC_curr_instr + 4),
16500                       OFFB_PC));
16501
16502      putIReg(rt,  mkWidenFrom32(ty, mkexpr(t0), True));
16503      break;
16504   }
16505   case 0x09:  /* ADDIU */
16506      DIP("addiu r%d, r%d, %d", rt, rs, imm);
16507      if (mode64) {
16508         putIReg(rt, mkWidenFrom32(ty, binop(Iop_Add32,
16509                     mkNarrowTo32(ty, getIReg(rs)),mkU32(extend_s_16to32(imm))),
16510                     True));
16511      } else
16512         putIReg(rt, binop(Iop_Add32, getIReg(rs),mkU32(extend_s_16to32(imm))));
16513      break;
16514
16515   case 0x0C:  /* ANDI */
16516      DIP("andi r%d, r%d, %d", rt, rs, imm);
16517      if (mode64) {
16518         ALUI_PATTERN64(Iop_And64);
16519      } else {
16520         ALUI_PATTERN(Iop_And32);
16521      }
16522      break;
16523
16524   case 0x0E:  /* XORI */
16525      DIP("xori r%d, r%d, %d", rt, rs, imm);
16526      if (mode64) {
16527         ALUI_PATTERN64(Iop_Xor64);
16528      } else {
16529         ALUI_PATTERN(Iop_Xor32);
16530      }
16531      break;
16532
16533   case 0x0D:  /* ORI */
16534      DIP("ori r%d, r%d, %d", rt, rs, imm);
16535      if (mode64) {
16536         ALUI_PATTERN64(Iop_Or64);
16537      } else {
16538         ALUI_PATTERN(Iop_Or32);
16539      }
16540      break;
16541
16542   case 0x0A:  /* SLTI */
16543      DIP("slti r%d, r%d, %d", rt, rs, imm);
16544      if (mode64)
16545         putIReg(rt, unop(Iop_1Uto64, binop(Iop_CmpLT64S, getIReg(rs),
16546                                            mkU64(extend_s_16to64(imm)))));
16547      else
16548         putIReg(rt, unop(Iop_1Uto32, binop(Iop_CmpLT32S, getIReg(rs),
16549                                            mkU32(extend_s_16to32(imm)))));
16550      break;
16551
16552   case 0x0B:  /* SLTIU */
16553      DIP("sltiu r%d, r%d, %d", rt, rs, imm);
16554      if (mode64)
16555         putIReg(rt, unop(Iop_1Uto64, binop(Iop_CmpLT64U, getIReg(rs),
16556                                            mkU64(extend_s_16to64(imm)))));
16557      else
16558         putIReg(rt, unop(Iop_1Uto32, binop(Iop_CmpLT32U, getIReg(rs),
16559                                            mkU32(extend_s_16to32(imm)))));
16560      break;
16561
16562   case 0x18: {  /* Doubleword Add Immidiate - DADD; MIPS64 */
16563      DIP("daddi r%d, r%d, %d", rt, rs, imm);
16564      IRTemp tmpRs64 = newTemp(Ity_I64);
16565      assign(tmpRs64, getIReg(rs));
16566
16567      t0 = newTemp(Ity_I64);
16568      t1 = newTemp(Ity_I64);
16569      t2 = newTemp(Ity_I64);
16570      t3 = newTemp(Ity_I64);
16571      t4 = newTemp(Ity_I64);
16572      /* dst = src0 + sign(imm)
16573         if(sign(src0 ) != sign(imm ))
16574         goto no overflow;
16575         if(sign(dst) == sign(src0 ))
16576         goto no overflow;
16577         we have overflow! */
16578
16579      assign(t0, binop(Iop_Add64, mkexpr(tmpRs64),
16580                       mkU64(extend_s_16to64(imm))));
16581      assign(t1, binop(Iop_Xor64, mkexpr(tmpRs64),
16582                       mkU64(extend_s_16to64(imm))));
16583      assign(t2, unop(Iop_1Sto64, binop(Iop_CmpEQ64, binop(Iop_And64,
16584                      mkexpr(t1), mkU64(0x8000000000000000ULL)),
16585                                        mkU64(0x8000000000000000ULL))));
16586
16587      assign(t3, binop(Iop_Xor64, mkexpr(t0), mkexpr(tmpRs64)));
16588      assign(t4, unop(Iop_1Sto64, binop(Iop_CmpNE64, binop(Iop_And64,
16589                      mkexpr(t3), mkU64(0x8000000000000000ULL)),
16590                                        mkU64(0x8000000000000000ULL))));
16591
16592      stmt(IRStmt_Exit(binop(Iop_CmpEQ64, binop(Iop_Or64, mkexpr(t2),
16593                             mkexpr(t4)), mkU64(0)), Ijk_SigFPE_IntOvf,
16594                       IRConst_U64(guest_PC_curr_instr + 4),
16595                       OFFB_PC));
16596
16597      putIReg(rt,  mkexpr(t0));
16598      break;
16599   }
16600
16601   case 0x19:  /* Doubleword Add Immidiate Unsigned - DADDIU; MIPS64 */
16602      DIP("daddiu r%d, r%d, %d", rt, rs, imm);
16603      putIReg(rt, binop(Iop_Add64, getIReg(rs), mkU64(extend_s_16to64(imm))));
16604      break;
16605
16606   case 0x1A: {
16607      /* Load Doubleword Left - LDL; MIPS64 */
16608      vassert(mode64);
16609      DIP("ldl r%u, %d(r%u)", rt, imm, rs);
16610      /* t1 = addr */
16611#if defined (_MIPSEL)
16612      t1 = newTemp(Ity_I64);
16613      assign(t1, binop(Iop_Add64, getIReg(rs), mkU64(extend_s_16to64(imm))));
16614#elif defined (_MIPSEB)
16615      t1 = newTemp(Ity_I64);
16616      assign(t1, binop(Iop_Xor64, mkU64(0x7), binop(Iop_Add64, getIReg(rs),
16617                                  mkU64(extend_s_16to64(imm)))));
16618#endif
16619      /* t2 = word addr */
16620      /* t4 = addr mod 8 */
16621      LWX_SWX_PATTERN64_1;
16622
16623      /* t3 = word content - shifted */
16624      t3 = newTemp(Ity_I64);
16625      assign(t3, binop(Iop_Shl64, load(Ity_I64, mkexpr(t2)),
16626                 narrowTo(Ity_I8, binop(Iop_Shl64, binop(Iop_Sub64, mkU64(0x07),
16627                 mkexpr(t4)), mkU8(3)))));
16628
16629      /* rt content  - adjusted */
16630      t5 = newTemp(Ity_I64);
16631      t6 = newTemp(Ity_I64);
16632      t7 = newTemp(Ity_I64);
16633
16634      assign(t5, binop(Iop_Mul64, mkexpr(t4), mkU64(0x8)));
16635
16636      assign(t6, binop(Iop_Shr64, mkU64(0x00FFFFFFFFFFFFFFULL),
16637                       narrowTo(Ity_I8, mkexpr(t5))));
16638
16639      assign(t7, binop(Iop_And64, getIReg(rt), mkexpr(t6)));
16640
16641      putIReg(rt, binop(Iop_Or64, mkexpr(t7), mkexpr(t3)));
16642      break;
16643   }
16644
16645   case 0x1B: {
16646      /* Load Doubleword Right - LDR; MIPS64 */
16647      vassert(mode64);
16648      DIP("ldr r%u,%d(r%u)", rt, imm, rs);
16649      /* t1 = addr */
16650#if defined (_MIPSEL)
16651      t1 = newTemp(Ity_I64);
16652      assign(t1, binop(Iop_Add64, getIReg(rs), mkU64(extend_s_16to64(imm))));
16653#elif defined (_MIPSEB)
16654      t1 = newTemp(Ity_I64);
16655      assign(t1, binop(Iop_Xor64, mkU64(0x7), binop(Iop_Add64, getIReg(rs),
16656                                  mkU64(extend_s_16to64(imm)))));
16657#endif
16658      /* t2 = word addr */
16659      /* t4 = addr mod 8 */
16660      LWX_SWX_PATTERN64_1;
16661
16662      /* t3 = word content - shifted */
16663      t3 = newTemp(Ity_I64);
16664      assign(t3, binop(Iop_Shr64, load(Ity_I64, mkexpr(t2)),
16665                 narrowTo(Ity_I8, binop(Iop_Shl64, mkexpr(t4), mkU8(3)))));
16666
16667      /* rt content  - adjusted */
16668      t5 = newTemp(Ity_I64);
16669      assign(t5, binop(Iop_And64, getIReg(rt), unop(Iop_Not64,
16670                 binop(Iop_Shr64, mkU64(0xFFFFFFFFFFFFFFFFULL),
16671                 narrowTo(Ity_I8, binop(Iop_Shl64, mkexpr(t4), mkU8(0x3)))))));
16672
16673      putIReg(rt, binop(Iop_Or64, mkexpr(t5), mkexpr(t3)));
16674      break;
16675   }
16676
16677   case 0x27:  /* Load Word unsigned - LWU; MIPS64 */
16678      DIP("lwu r%u,%d(r%u)", rt, imm, rs);
16679      LOAD_STORE_PATTERN;
16680
16681      putIReg(rt, mkWidenFrom32(ty, load(Ity_I32, mkexpr(t1)), False));
16682      break;
16683
16684   case 0x30:  /* LL / LWC0 */
16685      DIP("ll r%d, %d(r%d)", rt, imm, rs);
16686      LOAD_STORE_PATTERN;
16687
16688      t2 = newTemp(Ity_I32);
16689#if defined (_MIPSEL)
16690      stmt(IRStmt_LLSC(Iend_LE, t2, mkexpr(t1), NULL /* this is a load */ ));
16691#elif defined (_MIPSEB)
16692      stmt(IRStmt_LLSC(Iend_BE, t2, mkexpr(t1), NULL /* this is a load */ ));
16693#endif
16694      if (mode64)
16695         putIReg(rt, unop(Iop_32Sto64, mkexpr(t2)));
16696      else
16697         putIReg(rt, mkexpr(t2));
16698      break;
16699
16700   case 0x34:  /* Load Linked Doubleword - LLD; MIPS64 */
16701      DIP("lld r%d, %d(r%d)", rt, imm, rs);
16702      LOAD_STORE_PATTERN;
16703
16704      t2 = newTemp(Ity_I64);
16705#if defined (_MIPSEL)
16706      stmt(IRStmt_LLSC
16707           (Iend_LE, t2, mkexpr(t1), NULL /* this is a load */ ));
16708#elif defined (_MIPSEB)
16709      stmt(IRStmt_LLSC
16710           (Iend_BE, t2, mkexpr(t1), NULL /* this is a load */ ));
16711#endif
16712
16713      putIReg(rt, mkexpr(t2));
16714      break;
16715
16716   case 0x38:  /* SC / SWC0 */
16717      DIP("sc r%d, %d(r%d)", rt, imm, rs);
16718      LOAD_STORE_PATTERN;
16719
16720      t2 = newTemp(Ity_I1);
16721#if defined (_MIPSEL)
16722      stmt(IRStmt_LLSC(Iend_LE, t2, mkexpr(t1), mkNarrowTo32(ty, getIReg(rt))));
16723#elif defined (_MIPSEB)
16724      stmt(IRStmt_LLSC(Iend_BE, t2, mkexpr(t1), mkNarrowTo32(ty, getIReg(rt))));
16725#endif
16726
16727      putIReg(rt, unop(mode64 ? Iop_1Uto64 : Iop_1Uto32, mkexpr(t2)));
16728      break;
16729
16730   case 0x3C:  /* Store Conditional Doubleword - SCD; MIPS64 */
16731      DIP("sdc r%d, %d(r%d)", rt, imm, rs);
16732      LOAD_STORE_PATTERN;
16733
16734      t2 = newTemp(Ity_I1);
16735#if defined (_MIPSEL)
16736      stmt(IRStmt_LLSC(Iend_LE, t2, mkexpr(t1), getIReg(rt)));
16737#elif defined (_MIPSEB)
16738      stmt(IRStmt_LLSC(Iend_BE, t2, mkexpr(t1), getIReg(rt)));
16739#endif
16740
16741      putIReg(rt, unop(Iop_1Uto64, mkexpr(t2)));
16742      break;
16743
16744   case 0x37:  /* Load Doubleword - LD; MIPS64 */
16745      DIP("ld r%u, %d(r%u)", rt, imm, rs);
16746      LOAD_STORE_PATTERN;
16747      putIReg(rt, load(Ity_I64, mkexpr(t1)));
16748      break;
16749
16750   case 0x3F:  /* Store Doubleword - SD; MIPS64 */
16751      DIP("sd r%u, %d(r%u)", rt, imm, rs);
16752      LOAD_STORE_PATTERN;
16753      store(mkexpr(t1), getIReg(rt));
16754      break;
16755
16756   decode_failure_dsp:
16757      vex_printf("Error occured while trying to decode MIPS32 DSP "
16758                 "instruction.\nYour platform probably doesn't support "
16759                 "MIPS32 DSP ASE.\n");
16760   decode_failure:
16761      /* All decode failures end up here. */
16762      if (sigill_diag)
16763         vex_printf("vex mips->IR: unhandled instruction bytes: "
16764                    "0x%x 0x%x 0x%x 0x%x\n",
16765                    (Int) getIByte(delta_start + 0),
16766                    (Int) getIByte(delta_start + 1),
16767                    (Int) getIByte(delta_start + 2),
16768                    (Int) getIByte(delta_start + 3));
16769
16770      /* Tell the dispatcher that this insn cannot be decoded, and so has
16771         not been executed, and (is currently) the next to be executed.
16772         EIP should be up-to-date since it made so at the start bnezof each
16773         insn, but nevertheless be paranoid and update it again right
16774         now. */
16775      if (mode64) {
16776         stmt(IRStmt_Put(offsetof(VexGuestMIPS64State, guest_PC),
16777              mkU64(guest_PC_curr_instr)));
16778         jmp_lit64(&dres, Ijk_NoDecode, guest_PC_curr_instr);
16779      } else {
16780         stmt(IRStmt_Put(offsetof(VexGuestMIPS32State, guest_PC),
16781              mkU32(guest_PC_curr_instr)));
16782         jmp_lit32(&dres, Ijk_NoDecode, guest_PC_curr_instr);
16783      }
16784      dres.whatNext = Dis_StopHere;
16785      dres.len = 0;
16786      return dres;
16787   }  /* switch (opc) for the main (primary) opcode switch. */
16788
16789   /* All MIPS insn have 4 bytes */
16790
16791   if (delay_slot_branch) {
16792      delay_slot_branch = False;
16793      stmt(bstmt);
16794      bstmt = NULL;
16795      if (mode64)
16796         putPC(mkU64(guest_PC_curr_instr + 4));
16797      else
16798         putPC(mkU32(guest_PC_curr_instr + 4));
16799      dres.jk_StopHere = is_Branch_or_Jump_and_Link(guest_code + delta - 4) ?
16800                         Ijk_Call : Ijk_Boring;
16801   }
16802
16803   if (likely_delay_slot) {
16804      dres.jk_StopHere = Ijk_Boring;
16805      dres.whatNext = Dis_StopHere;
16806      putPC(lastn);
16807      lastn = NULL;
16808   }
16809   if (delay_slot_jump) {
16810      putPC(lastn);
16811      lastn = NULL;
16812      dres.jk_StopHere = is_Branch_or_Jump_and_Link(guest_code + delta - 4) ?
16813                         Ijk_Call : Ijk_Boring;
16814   }
16815
16816 decode_success:
16817   /* All decode successes end up here. */
16818   switch (dres.whatNext) {
16819      case Dis_Continue:
16820         if (mode64)
16821            putPC(mkU64(guest_PC_curr_instr + 4));
16822         else
16823            putPC(mkU32(guest_PC_curr_instr + 4));
16824         break;
16825      case Dis_ResteerU:
16826      case Dis_ResteerC:
16827         putPC(mkU32(dres.continueAt));
16828         break;
16829      case Dis_StopHere:
16830         break;
16831      default:
16832         vassert(0);
16833         break;
16834   }
16835
16836   /* On MIPS we need to check if the last instruction in block is branch or
16837      jump. */
16838   if (((vex_control.guest_max_insns - 1) == (delta + 4) / 4)
16839       &&  (dres.whatNext != Dis_StopHere))
16840      if (branch_or_jump(guest_code + delta + 4)) {
16841         dres.whatNext = Dis_StopHere;
16842         dres.jk_StopHere = Ijk_Boring;
16843         if (mode64)
16844            putPC(mkU64(guest_PC_curr_instr + 4));
16845         else
16846            putPC(mkU32(guest_PC_curr_instr + 4));
16847      }
16848   dres.len = 4;
16849
16850   DIP("\n");
16851
16852   return dres;
16853
16854}
16855
16856/*------------------------------------------------------------*/
16857/*--- Top-level fn                                         ---*/
16858/*------------------------------------------------------------*/
16859
16860/* Disassemble a single instruction into IR.  The instruction
16861   is located in host memory at &guest_code[delta]. */
16862DisResult disInstr_MIPS( IRSB*        irsb_IN,
16863                         Bool         (*resteerOkFn) ( void *, Addr64 ),
16864                         Bool         resteerCisOk,
16865                         void*        callback_opaque,
16866                         UChar*       guest_code_IN,
16867                         Long         delta,
16868                         Addr64       guest_IP,
16869                         VexArch      guest_arch,
16870                         VexArchInfo* archinfo,
16871                         VexAbiInfo*  abiinfo,
16872                         Bool         host_bigendian_IN,
16873                         Bool         sigill_diag_IN )
16874{
16875   DisResult dres;
16876   /* Set globals (see top of this file) */
16877   vassert(guest_arch == VexArchMIPS32 || guest_arch == VexArchMIPS64);
16878
16879   mode64 = guest_arch != VexArchMIPS32;
16880#if (__mips_fpr==64)
16881   fp_mode64 = ((VEX_MIPS_REV(archinfo->hwcaps) == VEX_PRID_CPU_32FPR)
16882                || guest_arch == VexArchMIPS64);
16883#endif
16884
16885   guest_code = guest_code_IN;
16886   irsb = irsb_IN;
16887   host_is_bigendian = host_bigendian_IN;
16888#if defined(VGP_mips32_linux)
16889   guest_PC_curr_instr = (Addr32)guest_IP;
16890#elif defined(VGP_mips64_linux)
16891   guest_PC_curr_instr = (Addr64)guest_IP;
16892#endif
16893
16894   dres = disInstr_MIPS_WRK(resteerOkFn, resteerCisOk, callback_opaque,
16895                            delta, archinfo, abiinfo, sigill_diag_IN);
16896
16897   return dres;
16898}
16899
16900/*--------------------------------------------------------------------*/
16901/*--- end                                        guest_mips_toIR.c ---*/
16902/*--------------------------------------------------------------------*/
16903