1 
2 /*--------------------------------------------------------------------*/
3 /*--- begin                                      guest_mips_toIR.c ---*/
4 /*--------------------------------------------------------------------*/
5 
6 /*
7    This file is part of Valgrind, a dynamic binary instrumentation
8    framework.
9 
10    Copyright (C) 2010-2017 RT-RK
11       mips-valgrind@rt-rk.com
12 
13    This program is free software; you can redistribute it and/or
14    modify it under the terms of the GNU General Public License as
15    published by the Free Software Foundation; either version 2 of the
16    License, or (at your option) any later version.
17 
18    This program is distributed in the hope that it will be useful, but
19    WITHOUT ANY WARRANTY; without even the implied warranty of
20    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
21    General Public License for more details.
22 
23    You should have received a copy of the GNU General Public License
24    along with this program; if not, write to the Free Software
25    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
26    02111-1307, USA.
27 
28    The GNU General Public License is contained in the file COPYING.
29 */
30 
31 /* Translates MIPS code to IR. */
32 
33 #include "libvex_basictypes.h"
34 #include "libvex_ir.h"
35 #include "libvex.h"
36 #include "libvex_guest_mips32.h"
37 #include "libvex_guest_mips64.h"
38 
39 #include "main_util.h"
40 #include "main_globals.h"
41 #include "guest_generic_bb_to_IR.h"
42 #include "guest_mips_defs.h"
43 
44 /*------------------------------------------------------------*/
45 /*---                      Globals                         ---*/
46 /*------------------------------------------------------------*/
47 
48 /* These are set at the start of the translation of a instruction, so
49    that we don't have to pass them around endlessly. CONST means does
50    not change during translation of the instruction. */
51 
52 /* CONST: what is the host's endianness?  This has to do with float vs
53    double register accesses on VFP, but it's complex and not properly
54    thought out. */
55 static VexEndness host_endness;
56 
57 /* Pointer to the guest code area. */
58 static const UChar *guest_code;
59 
60 /* CONST: The guest address for the instruction currently being
61    translated. */
62 #if defined(VGP_mips32_linux)
63 static Addr32 guest_PC_curr_instr;
64 #else
65 static Addr64 guest_PC_curr_instr;
66 #endif
67 
68 /* MOD: The IRSB* into which we're generating code. */
69 static IRSB *irsb;
70 
71 /* Is our guest binary 32 or 64bit? Set at each call to
72    disInstr_MIPS below. */
73 static Bool mode64 = False;
74 
75 /* CPU has FPU and 32 dbl. prec. FP registers. */
76 static Bool fp_mode64 = False;
77 
78 /* FPU works in FRE mode */
79 static Bool fp_mode64_fre = False;
80 
81 /* CPU has MSA unit */
82 static Bool has_msa = False;
83 
84 /* Define 1.0 in single and double precision. */
85 #define ONE_SINGLE 0x3F800000
86 #define ONE_DOUBLE 0x3FF0000000000000ULL
87 
88 /*------------------------------------------------------------*/
89 /*---                  Debugging output                    ---*/
90 /*------------------------------------------------------------*/
91 
92 #define DIP(format, args...)           \
93    if (vex_traceflags & VEX_TRACE_FE)  \
94       vex_printf(format, ## args)
95 
96 /*------------------------------------------------------------*/
97 /*--- Helper bits and pieces for deconstructing the        ---*/
98 /*--- mips insn stream.                                    ---*/
99 /*------------------------------------------------------------*/
100 
101 /* ---------------- Integer registers ---------------- */
102 
integerGuestRegOffset(UInt iregNo)103 static UInt integerGuestRegOffset(UInt iregNo)
104 {
105    /* Do we care about endianness here?  We do if sub-parts of integer
106       registers are accessed, but I don't think that ever happens on
107       MIPS. */
108    UInt ret;
109    if (!mode64)
110       switch (iregNo) {
111          case 0:
112             ret = offsetof(VexGuestMIPS32State, guest_r0); break;
113          case 1:
114             ret = offsetof(VexGuestMIPS32State, guest_r1); break;
115          case 2:
116             ret = offsetof(VexGuestMIPS32State, guest_r2); break;
117          case 3:
118             ret = offsetof(VexGuestMIPS32State, guest_r3); break;
119          case 4:
120             ret = offsetof(VexGuestMIPS32State, guest_r4); break;
121          case 5:
122             ret = offsetof(VexGuestMIPS32State, guest_r5); break;
123          case 6:
124             ret = offsetof(VexGuestMIPS32State, guest_r6); break;
125          case 7:
126             ret = offsetof(VexGuestMIPS32State, guest_r7); break;
127          case 8:
128             ret = offsetof(VexGuestMIPS32State, guest_r8); break;
129          case 9:
130             ret = offsetof(VexGuestMIPS32State, guest_r9); break;
131          case 10:
132             ret = offsetof(VexGuestMIPS32State, guest_r10); break;
133          case 11:
134             ret = offsetof(VexGuestMIPS32State, guest_r11); break;
135          case 12:
136             ret = offsetof(VexGuestMIPS32State, guest_r12); break;
137          case 13:
138             ret = offsetof(VexGuestMIPS32State, guest_r13); break;
139          case 14:
140             ret = offsetof(VexGuestMIPS32State, guest_r14); break;
141          case 15:
142             ret = offsetof(VexGuestMIPS32State, guest_r15); break;
143          case 16:
144             ret = offsetof(VexGuestMIPS32State, guest_r16); break;
145          case 17:
146             ret = offsetof(VexGuestMIPS32State, guest_r17); break;
147          case 18:
148             ret = offsetof(VexGuestMIPS32State, guest_r18); break;
149          case 19:
150             ret = offsetof(VexGuestMIPS32State, guest_r19); break;
151          case 20:
152             ret = offsetof(VexGuestMIPS32State, guest_r20); break;
153          case 21:
154             ret = offsetof(VexGuestMIPS32State, guest_r21); break;
155          case 22:
156             ret = offsetof(VexGuestMIPS32State, guest_r22); break;
157          case 23:
158             ret = offsetof(VexGuestMIPS32State, guest_r23); break;
159          case 24:
160             ret = offsetof(VexGuestMIPS32State, guest_r24); break;
161          case 25:
162             ret = offsetof(VexGuestMIPS32State, guest_r25); break;
163          case 26:
164             ret = offsetof(VexGuestMIPS32State, guest_r26); break;
165          case 27:
166             ret = offsetof(VexGuestMIPS32State, guest_r27); break;
167          case 28:
168             ret = offsetof(VexGuestMIPS32State, guest_r28); break;
169          case 29:
170             ret = offsetof(VexGuestMIPS32State, guest_r29); break;
171          case 30:
172             ret = offsetof(VexGuestMIPS32State, guest_r30); break;
173          case 31:
174             ret = offsetof(VexGuestMIPS32State, guest_r31); break;
175          default:
176             vassert(0);
177             break;
178       }
179    else
180       switch (iregNo) {
181          case 0:
182             ret = offsetof(VexGuestMIPS64State, guest_r0); break;
183          case 1:
184             ret = offsetof(VexGuestMIPS64State, guest_r1); break;
185          case 2:
186             ret = offsetof(VexGuestMIPS64State, guest_r2); break;
187          case 3:
188             ret = offsetof(VexGuestMIPS64State, guest_r3); break;
189          case 4:
190             ret = offsetof(VexGuestMIPS64State, guest_r4); break;
191          case 5:
192             ret = offsetof(VexGuestMIPS64State, guest_r5); break;
193          case 6:
194             ret = offsetof(VexGuestMIPS64State, guest_r6); break;
195          case 7:
196             ret = offsetof(VexGuestMIPS64State, guest_r7); break;
197          case 8:
198             ret = offsetof(VexGuestMIPS64State, guest_r8); break;
199          case 9:
200             ret = offsetof(VexGuestMIPS64State, guest_r9); break;
201          case 10:
202             ret = offsetof(VexGuestMIPS64State, guest_r10); break;
203          case 11:
204             ret = offsetof(VexGuestMIPS64State, guest_r11); break;
205          case 12:
206             ret = offsetof(VexGuestMIPS64State, guest_r12); break;
207          case 13:
208             ret = offsetof(VexGuestMIPS64State, guest_r13); break;
209          case 14:
210             ret = offsetof(VexGuestMIPS64State, guest_r14); break;
211          case 15:
212             ret = offsetof(VexGuestMIPS64State, guest_r15); break;
213          case 16:
214             ret = offsetof(VexGuestMIPS64State, guest_r16); break;
215          case 17:
216             ret = offsetof(VexGuestMIPS64State, guest_r17); break;
217          case 18:
218             ret = offsetof(VexGuestMIPS64State, guest_r18); break;
219          case 19:
220             ret = offsetof(VexGuestMIPS64State, guest_r19); break;
221          case 20:
222             ret = offsetof(VexGuestMIPS64State, guest_r20); break;
223          case 21:
224             ret = offsetof(VexGuestMIPS64State, guest_r21); break;
225          case 22:
226             ret = offsetof(VexGuestMIPS64State, guest_r22); break;
227          case 23:
228             ret = offsetof(VexGuestMIPS64State, guest_r23); break;
229          case 24:
230             ret = offsetof(VexGuestMIPS64State, guest_r24); break;
231          case 25:
232             ret = offsetof(VexGuestMIPS64State, guest_r25); break;
233          case 26:
234             ret = offsetof(VexGuestMIPS64State, guest_r26); break;
235          case 27:
236             ret = offsetof(VexGuestMIPS64State, guest_r27); break;
237          case 28:
238             ret = offsetof(VexGuestMIPS64State, guest_r28); break;
239          case 29:
240             ret = offsetof(VexGuestMIPS64State, guest_r29); break;
241          case 30:
242             ret = offsetof(VexGuestMIPS64State, guest_r30); break;
243          case 31:
244             ret = offsetof(VexGuestMIPS64State, guest_r31); break;
245          default:
246             vassert(0);
247             break;
248       }
249    return ret;
250 }
251 
252 #if defined(VGP_mips32_linux)
253 #define OFFB_PC     offsetof(VexGuestMIPS32State, guest_PC)
254 #else
255 #define OFFB_PC     offsetof(VexGuestMIPS64State, guest_PC)
256 #endif
257 
258 /* ---------------- Floating point registers ---------------- */
259 
floatGuestRegOffset(UInt fregNo)260 static UInt floatGuestRegOffset(UInt fregNo)
261 {
262    vassert(fregNo < 32);
263    UInt ret;
264    if (!mode64)
265       switch (fregNo) {
266          case 0:
267             ret = offsetof(VexGuestMIPS32State, guest_f0); break;
268          case 1:
269             ret = offsetof(VexGuestMIPS32State, guest_f1); break;
270          case 2:
271             ret = offsetof(VexGuestMIPS32State, guest_f2); break;
272          case 3:
273             ret = offsetof(VexGuestMIPS32State, guest_f3); break;
274          case 4:
275             ret = offsetof(VexGuestMIPS32State, guest_f4); break;
276          case 5:
277             ret = offsetof(VexGuestMIPS32State, guest_f5); break;
278          case 6:
279             ret = offsetof(VexGuestMIPS32State, guest_f6); break;
280          case 7:
281             ret = offsetof(VexGuestMIPS32State, guest_f7); break;
282          case 8:
283             ret = offsetof(VexGuestMIPS32State, guest_f8); break;
284          case 9:
285             ret = offsetof(VexGuestMIPS32State, guest_f9); break;
286          case 10:
287             ret = offsetof(VexGuestMIPS32State, guest_f10); break;
288          case 11:
289             ret = offsetof(VexGuestMIPS32State, guest_f11); break;
290          case 12:
291             ret = offsetof(VexGuestMIPS32State, guest_f12); break;
292          case 13:
293             ret = offsetof(VexGuestMIPS32State, guest_f13); break;
294          case 14:
295             ret = offsetof(VexGuestMIPS32State, guest_f14); break;
296          case 15:
297             ret = offsetof(VexGuestMIPS32State, guest_f15); break;
298          case 16:
299             ret = offsetof(VexGuestMIPS32State, guest_f16); break;
300          case 17:
301             ret = offsetof(VexGuestMIPS32State, guest_f17); break;
302          case 18:
303             ret = offsetof(VexGuestMIPS32State, guest_f18); break;
304          case 19:
305             ret = offsetof(VexGuestMIPS32State, guest_f19); break;
306          case 20:
307             ret = offsetof(VexGuestMIPS32State, guest_f20); break;
308          case 21:
309             ret = offsetof(VexGuestMIPS32State, guest_f21); break;
310          case 22:
311             ret = offsetof(VexGuestMIPS32State, guest_f22); break;
312          case 23:
313             ret = offsetof(VexGuestMIPS32State, guest_f23); break;
314          case 24:
315             ret = offsetof(VexGuestMIPS32State, guest_f24); break;
316          case 25:
317             ret = offsetof(VexGuestMIPS32State, guest_f25); break;
318          case 26:
319             ret = offsetof(VexGuestMIPS32State, guest_f26); break;
320          case 27:
321             ret = offsetof(VexGuestMIPS32State, guest_f27); break;
322          case 28:
323             ret = offsetof(VexGuestMIPS32State, guest_f28); break;
324          case 29:
325             ret = offsetof(VexGuestMIPS32State, guest_f29); break;
326          case 30:
327             ret = offsetof(VexGuestMIPS32State, guest_f30); break;
328          case 31:
329             ret = offsetof(VexGuestMIPS32State, guest_f31); break;
330          default:
331             vassert(0);
332             break;
333       }
334    else
335       switch (fregNo) {
336          case 0:
337             ret = offsetof(VexGuestMIPS64State, guest_f0); break;
338          case 1:
339             ret = offsetof(VexGuestMIPS64State, guest_f1); break;
340          case 2:
341             ret = offsetof(VexGuestMIPS64State, guest_f2); break;
342          case 3:
343             ret = offsetof(VexGuestMIPS64State, guest_f3); break;
344          case 4:
345             ret = offsetof(VexGuestMIPS64State, guest_f4); break;
346          case 5:
347             ret = offsetof(VexGuestMIPS64State, guest_f5); break;
348          case 6:
349             ret = offsetof(VexGuestMIPS64State, guest_f6); break;
350          case 7:
351             ret = offsetof(VexGuestMIPS64State, guest_f7); break;
352          case 8:
353             ret = offsetof(VexGuestMIPS64State, guest_f8); break;
354          case 9:
355             ret = offsetof(VexGuestMIPS64State, guest_f9); break;
356          case 10:
357             ret = offsetof(VexGuestMIPS64State, guest_f10); break;
358          case 11:
359             ret = offsetof(VexGuestMIPS64State, guest_f11); break;
360          case 12:
361             ret = offsetof(VexGuestMIPS64State, guest_f12); break;
362          case 13:
363             ret = offsetof(VexGuestMIPS64State, guest_f13); break;
364          case 14:
365             ret = offsetof(VexGuestMIPS64State, guest_f14); break;
366          case 15:
367             ret = offsetof(VexGuestMIPS64State, guest_f15); break;
368          case 16:
369             ret = offsetof(VexGuestMIPS64State, guest_f16); break;
370          case 17:
371             ret = offsetof(VexGuestMIPS64State, guest_f17); break;
372          case 18:
373             ret = offsetof(VexGuestMIPS64State, guest_f18); break;
374          case 19:
375             ret = offsetof(VexGuestMIPS64State, guest_f19); break;
376          case 20:
377             ret = offsetof(VexGuestMIPS64State, guest_f20); break;
378          case 21:
379             ret = offsetof(VexGuestMIPS64State, guest_f21); break;
380          case 22:
381             ret = offsetof(VexGuestMIPS64State, guest_f22); break;
382          case 23:
383             ret = offsetof(VexGuestMIPS64State, guest_f23); break;
384          case 24:
385             ret = offsetof(VexGuestMIPS64State, guest_f24); break;
386          case 25:
387             ret = offsetof(VexGuestMIPS64State, guest_f25); break;
388          case 26:
389             ret = offsetof(VexGuestMIPS64State, guest_f26); break;
390          case 27:
391             ret = offsetof(VexGuestMIPS64State, guest_f27); break;
392          case 28:
393             ret = offsetof(VexGuestMIPS64State, guest_f28); break;
394          case 29:
395             ret = offsetof(VexGuestMIPS64State, guest_f29); break;
396          case 30:
397             ret = offsetof(VexGuestMIPS64State, guest_f30); break;
398          case 31:
399             ret = offsetof(VexGuestMIPS64State, guest_f31); break;
400          default:
401             vassert(0);
402             break;
403       }
404    return ret;
405 }
406 
407 /* ---------------- MIPS32 DSP ASE(r2) accumulators ---------------- */
408 
accumulatorGuestRegOffset(UInt acNo)409 static UInt accumulatorGuestRegOffset(UInt acNo)
410 {
411    vassert(!mode64);
412    vassert(acNo <= 3);
413    UInt ret;
414    switch (acNo) {
415       case 0:
416          ret = offsetof(VexGuestMIPS32State, guest_ac0); break;
417       case 1:
418          ret = offsetof(VexGuestMIPS32State, guest_ac1); break;
419       case 2:
420          ret = offsetof(VexGuestMIPS32State, guest_ac2); break;
421       case 3:
422          ret = offsetof(VexGuestMIPS32State, guest_ac3); break;
423       default:
424          vassert(0);
425     break;
426    }
427    return ret;
428 }
429 
430 /* ---------------- MIPS32 MSA registers ---------------- */
431 
msaGuestRegOffset(UInt msaRegNo)432 static UInt msaGuestRegOffset(UInt msaRegNo) {
433    vassert(msaRegNo <= 31);
434    UInt ret;
435 
436    if (mode64) {
437       switch (msaRegNo) {
438          case 0:
439             ret = offsetof(VexGuestMIPS64State, guest_w0);
440             break;
441 
442          case 1:
443             ret = offsetof(VexGuestMIPS64State, guest_w1);
444             break;
445 
446          case 2:
447             ret = offsetof(VexGuestMIPS64State, guest_w2);
448             break;
449 
450          case 3:
451             ret = offsetof(VexGuestMIPS64State, guest_w3);
452             break;
453 
454          case 4:
455             ret = offsetof(VexGuestMIPS64State, guest_w4);
456             break;
457 
458          case 5:
459             ret = offsetof(VexGuestMIPS64State, guest_w5);
460             break;
461 
462          case 6:
463             ret = offsetof(VexGuestMIPS64State, guest_w6);
464             break;
465 
466          case 7:
467             ret = offsetof(VexGuestMIPS64State, guest_w7);
468             break;
469 
470          case 8:
471             ret = offsetof(VexGuestMIPS64State, guest_w8);
472             break;
473 
474          case 9:
475             ret = offsetof(VexGuestMIPS64State, guest_w9);
476             break;
477 
478          case 10:
479             ret = offsetof(VexGuestMIPS64State, guest_w10);
480             break;
481 
482          case 11:
483             ret = offsetof(VexGuestMIPS64State, guest_w11);
484             break;
485 
486          case 12:
487             ret = offsetof(VexGuestMIPS64State, guest_w12);
488             break;
489 
490          case 13:
491             ret = offsetof(VexGuestMIPS64State, guest_w13);
492             break;
493 
494          case 14:
495             ret = offsetof(VexGuestMIPS64State, guest_w14);
496             break;
497 
498          case 15:
499             ret = offsetof(VexGuestMIPS64State, guest_w15);
500             break;
501 
502          case 16:
503             ret = offsetof(VexGuestMIPS64State, guest_w16);
504             break;
505 
506          case 17:
507             ret = offsetof(VexGuestMIPS64State, guest_w17);
508             break;
509 
510          case 18:
511             ret = offsetof(VexGuestMIPS64State, guest_w18);
512             break;
513 
514          case 19:
515             ret = offsetof(VexGuestMIPS64State, guest_w19);
516             break;
517 
518          case 20:
519             ret = offsetof(VexGuestMIPS64State, guest_w20);
520             break;
521 
522          case 21:
523             ret = offsetof(VexGuestMIPS64State, guest_w21);
524             break;
525 
526          case 22:
527             ret = offsetof(VexGuestMIPS64State, guest_w22);
528             break;
529 
530          case 23:
531             ret = offsetof(VexGuestMIPS64State, guest_w23);
532             break;
533 
534          case 24:
535             ret = offsetof(VexGuestMIPS64State, guest_w24);
536             break;
537 
538          case 25:
539             ret = offsetof(VexGuestMIPS64State, guest_w25);
540             break;
541 
542          case 26:
543             ret = offsetof(VexGuestMIPS64State, guest_w26);
544             break;
545 
546          case 27:
547             ret = offsetof(VexGuestMIPS64State, guest_w27);
548             break;
549 
550          case 28:
551             ret = offsetof(VexGuestMIPS64State, guest_w28);
552             break;
553 
554          case 29:
555             ret = offsetof(VexGuestMIPS64State, guest_w29);
556             break;
557 
558          case 30:
559             ret = offsetof(VexGuestMIPS64State, guest_w30);
560             break;
561 
562          case 31:
563             ret = offsetof(VexGuestMIPS64State, guest_w31);
564             break;
565 
566          default:
567             vassert(0);
568             break;
569       }
570    } else {
571       switch (msaRegNo) {
572          case 0:
573             ret = offsetof(VexGuestMIPS32State, guest_w0);
574             break;
575 
576          case 1:
577             ret = offsetof(VexGuestMIPS32State, guest_w1);
578             break;
579 
580          case 2:
581             ret = offsetof(VexGuestMIPS32State, guest_w2);
582             break;
583 
584          case 3:
585             ret = offsetof(VexGuestMIPS32State, guest_w3);
586             break;
587 
588          case 4:
589             ret = offsetof(VexGuestMIPS32State, guest_w4);
590             break;
591 
592          case 5:
593             ret = offsetof(VexGuestMIPS32State, guest_w5);
594             break;
595 
596          case 6:
597             ret = offsetof(VexGuestMIPS32State, guest_w6);
598             break;
599 
600          case 7:
601             ret = offsetof(VexGuestMIPS32State, guest_w7);
602             break;
603 
604          case 8:
605             ret = offsetof(VexGuestMIPS32State, guest_w8);
606             break;
607 
608          case 9:
609             ret = offsetof(VexGuestMIPS32State, guest_w9);
610             break;
611 
612          case 10:
613             ret = offsetof(VexGuestMIPS32State, guest_w10);
614             break;
615 
616          case 11:
617             ret = offsetof(VexGuestMIPS32State, guest_w11);
618             break;
619 
620          case 12:
621             ret = offsetof(VexGuestMIPS32State, guest_w12);
622             break;
623 
624          case 13:
625             ret = offsetof(VexGuestMIPS32State, guest_w13);
626             break;
627 
628          case 14:
629             ret = offsetof(VexGuestMIPS32State, guest_w14);
630             break;
631 
632          case 15:
633             ret = offsetof(VexGuestMIPS32State, guest_w15);
634             break;
635 
636          case 16:
637             ret = offsetof(VexGuestMIPS32State, guest_w16);
638             break;
639 
640          case 17:
641             ret = offsetof(VexGuestMIPS32State, guest_w17);
642             break;
643 
644          case 18:
645             ret = offsetof(VexGuestMIPS32State, guest_w18);
646             break;
647 
648          case 19:
649             ret = offsetof(VexGuestMIPS32State, guest_w19);
650             break;
651 
652          case 20:
653             ret = offsetof(VexGuestMIPS32State, guest_w20);
654             break;
655 
656          case 21:
657             ret = offsetof(VexGuestMIPS32State, guest_w21);
658             break;
659 
660          case 22:
661             ret = offsetof(VexGuestMIPS32State, guest_w22);
662             break;
663 
664          case 23:
665             ret = offsetof(VexGuestMIPS32State, guest_w23);
666             break;
667 
668          case 24:
669             ret = offsetof(VexGuestMIPS32State, guest_w24);
670             break;
671 
672          case 25:
673             ret = offsetof(VexGuestMIPS32State, guest_w25);
674             break;
675 
676          case 26:
677             ret = offsetof(VexGuestMIPS32State, guest_w26);
678             break;
679 
680          case 27:
681             ret = offsetof(VexGuestMIPS32State, guest_w27);
682             break;
683 
684          case 28:
685             ret = offsetof(VexGuestMIPS32State, guest_w28);
686             break;
687 
688          case 29:
689             ret = offsetof(VexGuestMIPS32State, guest_w29);
690             break;
691 
692          case 30:
693             ret = offsetof(VexGuestMIPS32State, guest_w30);
694             break;
695 
696          case 31:
697             ret = offsetof(VexGuestMIPS32State, guest_w31);
698             break;
699 
700          default:
701             vassert(0);
702             break;
703       }
704    }
705 
706    return ret;
707 }
708 
709 
710 /* Do a endian load of a 32-bit word, regardless of the endianness of the
711    underlying host. */
getUInt(const UChar * p)712 static inline UInt getUInt(const UChar * p)
713 {
714    UInt w = 0;
715 #if defined (_MIPSEL)
716    w = (w << 8) | p[3];
717    w = (w << 8) | p[2];
718    w = (w << 8) | p[1];
719    w = (w << 8) | p[0];
720 #elif defined (_MIPSEB)
721    w = (w << 8) | p[0];
722    w = (w << 8) | p[1];
723    w = (w << 8) | p[2];
724    w = (w << 8) | p[3];
725 #endif
726    return w;
727 }
728 
729 #define BITS2(_b1,_b0) \
730    (((_b1) << 1) | (_b0))
731 
732 #define BITS3(_b2,_b1,_b0)                      \
733   (((_b2) << 2) | ((_b1) << 1) | (_b0))
734 
735 #define BITS4(_b3,_b2,_b1,_b0) \
736    (((_b3) << 3) | ((_b2) << 2) | ((_b1) << 1) | (_b0))
737 
738 #define BITS5(_b4,_b3,_b2,_b1,_b0)  \
739    (((_b4) << 4) | BITS4((_b3),(_b2),(_b1),(_b0)))
740 
741 #define BITS6(_b5,_b4,_b3,_b2,_b1,_b0)  \
742    ((BITS2((_b5),(_b4)) << 4) \
743     | BITS4((_b3),(_b2),(_b1),(_b0)))
744 
745 #define BITS8(_b7,_b6,_b5,_b4,_b3,_b2,_b1,_b0)  \
746    ((BITS4((_b7),(_b6),(_b5),(_b4)) << 4) \
747     | BITS4((_b3),(_b2),(_b1),(_b0)))
748 
749 #define LOAD_STORE_PATTERN \
750    t1 = newTemp(mode64 ? Ity_I64 : Ity_I32); \
751       if(!mode64) \
752          assign(t1, binop(Iop_Add32, getIReg(rs), \
753                                      mkU32(extend_s_16to32(imm)))); \
754       else \
755          assign(t1, binop(Iop_Add64, getIReg(rs), \
756                                      mkU64(extend_s_16to64(imm)))); \
757 
758 #define LOAD_STORE_PATTERN_MSA(imm) \
759    t1 = newTemp(mode64 ? Ity_I64 : Ity_I32); \
760       if (!mode64) \
761          assign(t1, binop(Iop_Add32, getIReg(ws),  \
762                                      mkU32(extend_s_10to32(imm)))); \
763       else \
764          assign(t1, binop(Iop_Add64, getIReg(ws), \
765                                      mkU64(extend_s_10to64(imm)))); \
766 
767 #define LOADX_STORE_PATTERN \
768    t1 = newTemp(mode64 ? Ity_I64 : Ity_I32); \
769       if(!mode64) \
770          assign(t1, binop(Iop_Add32, getIReg(regRs), getIReg(regRt))); \
771       else \
772          assign(t1, binop(Iop_Add64, getIReg(regRs), getIReg(regRt)));
773 
774 #define LWX_SWX_PATTERN64 \
775    t2 = newTemp(Ity_I64); \
776    assign(t2, binop(Iop_And64, mkexpr(t1), mkU64(0xFFFFFFFFFFFFFFFCULL))); \
777    t4 = newTemp(Ity_I32); \
778    assign(t4, mkNarrowTo32( ty, binop(Iop_And64, \
779                                       mkexpr(t1), mkU64(0x3))));
780 
781 #define LWX_SWX_PATTERN64_1 \
782    t2 = newTemp(Ity_I64); \
783    assign(t2, binop(Iop_And64, mkexpr(t1), mkU64(0xFFFFFFFFFFFFFFF8ULL))); \
784    t4 = newTemp(Ity_I64); \
785    assign(t4, binop(Iop_And64, mkexpr(t1), mkU64(0x7)));
786 
787 #define LWX_SWX_PATTERN \
788    t2 = newTemp(Ity_I32); \
789    assign(t2, binop(Iop_And32, mkexpr(t1), mkU32(0xFFFFFFFC))); \
790    t4 = newTemp(Ity_I32); \
791    assign(t4, binop(Iop_And32, mkexpr(t1), mkU32(0x00000003)))
792 
793 #define SXXV_PATTERN(op) \
794    putIReg(rd, binop(op, \
795          getIReg(rt), \
796             unop(Iop_32to8, \
797                binop(Iop_And32, \
798                   getIReg(rs), \
799                   mkU32(0x0000001F) \
800                ) \
801             ) \
802          ) \
803       )
804 
805 #define SXXV_PATTERN64(op) \
806    putIReg(rd, mkWidenFrom32(ty, binop(op, \
807            mkNarrowTo32(ty, getIReg(rt)), \
808              unop(Iop_32to8, \
809                 binop(Iop_And32, \
810                    mkNarrowTo32(ty, getIReg(rs)), \
811                    mkU32(0x0000001F) \
812                 ) \
813              ) \
814           ), True \
815        ))
816 
817 #define SXX_PATTERN(op) \
818    putIReg(rd, binop(op, getIReg(rt), mkU8(sa)));
819 
820 #define ALU_PATTERN(op) \
821    putIReg(rd, binop(op, getIReg(rs), getIReg(rt)));
822 
823 #define ALUI_PATTERN(op) \
824    putIReg(rt, binop(op, getIReg(rs), mkU32(imm)));
825 
826 #define ALUI_PATTERN64(op) \
827    putIReg(rt, binop(op, getIReg(rs), mkU64(imm)));
828 
829 #define ALU_PATTERN64(op) \
830    putIReg(rd, mkWidenFrom32(ty, binop(op, \
831                              mkNarrowTo32(ty, getIReg(rs)), \
832                              mkNarrowTo32(ty, getIReg(rt))), True));
833 
834 #define FP_CONDITIONAL_CODE \
835    t3 = newTemp(Ity_I32);   \
836    assign(t3, binop(Iop_And32, \
837                  IRExpr_ITE( binop(Iop_CmpEQ32, mkU32(cc), mkU32(0)), \
838                              binop(Iop_Shr32, getFCSR(), mkU8(23)), \
839                              binop(Iop_Shr32, getFCSR(), mkU8(24+cc))), \
840                  mkU32(0x1)));
841 
842 #define ILLEGAL_INSTRUCTON \
843    putPC(mkU32(guest_PC_curr_instr + 4)); \
844    dres.jk_StopHere = Ijk_SigILL; \
845    dres.whatNext    = Dis_StopHere;
846 
847 #define LLADDR_INVALID \
848    (mode64 ? mkU64(0xFFFFFFFFFFFFFFFFULL) : mkU32(0xFFFFFFFF))
849 
850 /*------------------------------------------------------------*/
851 /*---                  Field helpers                       ---*/
852 /*------------------------------------------------------------*/
853 
get_opcode(UInt mipsins)854 static UInt get_opcode(UInt mipsins)
855 {
856    return (0xFC000000 & mipsins) >> 26;
857 }
858 
get_rs(UInt mipsins)859 static UInt get_rs(UInt mipsins)
860 {
861    return (0x03E00000 & mipsins) >> 21;
862 }
863 
get_rt(UInt mipsins)864 static UInt get_rt(UInt mipsins)
865 {
866    return (0x001F0000 & mipsins) >> 16;
867 }
868 
get_imm(UInt mipsins)869 static UInt get_imm(UInt mipsins)
870 {
871    return (0x0000FFFF & mipsins);
872 }
873 
get_instr_index(UInt mipsins)874 static UInt get_instr_index(UInt mipsins)
875 {
876    return (0x03FFFFFF & mipsins);
877 }
878 
get_rd(UInt mipsins)879 static UInt get_rd(UInt mipsins)
880 {
881    return (0x0000F800 & mipsins) >> 11;
882 }
883 
get_sa(UInt mipsins)884 static UInt get_sa(UInt mipsins)
885 {
886    return (0x000007C0 & mipsins) >> 6;
887 }
888 
get_function(UInt mipsins)889 static UInt get_function(UInt mipsins)
890 {
891    return (0x0000003F & mipsins);
892 }
893 
get_ft(UInt mipsins)894 static UInt get_ft(UInt mipsins)
895 {
896    return (0x001F0000 & mipsins) >> 16;
897 }
898 
get_fs(UInt mipsins)899 static UInt get_fs(UInt mipsins)
900 {
901    return (0x0000F800 & mipsins) >> 11;
902 }
903 
get_fd(UInt mipsins)904 static UInt get_fd(UInt mipsins)
905 {
906    return (0x000007C0 & mipsins) >> 6;
907 }
908 
get_mov_cc(UInt mipsins)909 static UInt get_mov_cc(UInt mipsins)
910 {
911    return (0x001C0000 & mipsins) >> 18;
912 }
913 
get_bc1_cc(UInt mipsins)914 static UInt get_bc1_cc(UInt mipsins)
915 {
916    return (0x001C0000 & mipsins) >> 18;
917 }
918 
get_fpc_cc(UInt mipsins)919 static UInt get_fpc_cc(UInt mipsins)
920 {
921    return (0x00000700 & mipsins) >> 8;
922 }
923 
get_tf(UInt mipsins)924 static UInt get_tf(UInt mipsins)
925 {
926    return (0x00010000 & mipsins) >> 16;
927 }
928 
get_nd(UInt mipsins)929 static UInt get_nd(UInt mipsins)
930 {
931    return (0x00020000 & mipsins) >> 17;
932 }
933 
get_fmt(UInt mipsins)934 static UInt get_fmt(UInt mipsins)
935 {
936    return (0x03E00000 & mipsins) >> 21;
937 }
938 
get_FC(UInt mipsins)939 static UInt get_FC(UInt mipsins)
940 {
941    return (0x000000F0 & mipsins) >> 4;
942 }
943 
get_cond(UInt mipsins)944 static UInt get_cond(UInt mipsins)
945 {
946    return (0x0000000F & mipsins);
947 }
948 
949 /* for break & syscall */
get_code(UInt mipsins)950 static UInt get_code(UInt mipsins)
951 {
952    return (0xFFC0 & mipsins) >> 6;
953 }
954 
get_lsb(UInt mipsins)955 static UInt get_lsb(UInt mipsins)
956 {
957    return (0x7C0 & mipsins) >> 6;
958 }
959 
get_msb(UInt mipsins)960 static UInt get_msb(UInt mipsins)
961 {
962    return (0x0000F800 & mipsins) >> 11;
963 }
964 
get_rot(UInt mipsins)965 static UInt get_rot(UInt mipsins)
966 {
967    return (0x00200000 & mipsins) >> 21;
968 }
969 
get_rotv(UInt mipsins)970 static UInt get_rotv(UInt mipsins)
971 {
972    return (0x00000040 & mipsins) >> 6;
973 }
974 
get_sel(UInt mipsins)975 static UInt get_sel(UInt mipsins)
976 {
977    return (0x00000007 & mipsins);
978 }
979 
980 /* Get acc number for all MIPS32 DSP ASE(r2) instructions that use them,
981    except for MFHI and MFLO. */
get_acNo(UInt mipsins)982 static UInt get_acNo(UInt mipsins)
983 {
984    return (0x00001800 & mipsins) >> 11;
985 }
986 
987 /* Get accumulator number for MIPS32 DSP ASEr2 MFHI and MFLO instructions. */
get_acNo_mfhilo(UInt mipsins)988 static UInt get_acNo_mfhilo(UInt mipsins)
989 {
990    return (0x00600000 & mipsins) >> 21;
991 }
992 
993 /* Get mask field (helper function for wrdsp instruction). */
get_wrdspMask(UInt mipsins)994 static UInt get_wrdspMask(UInt mipsins)
995 {
996    return (0x001ff800 & mipsins) >> 11;
997 }
998 
999 /* Get mask field (helper function for rddsp instruction). */
get_rddspMask(UInt mipsins)1000 static UInt get_rddspMask(UInt mipsins)
1001 {
1002    return (0x03ff0000 & mipsins) >> 16;
1003 }
1004 
1005 /* Get shift field (helper function for DSP ASE instructions). */
get_shift(UInt mipsins)1006 static UInt get_shift(UInt mipsins)
1007 {
1008    return (0x03f00000 & mipsins) >> 20;
1009 }
1010 
1011 /* Get immediate field for DSP ASE instructions. */
get_dspImm(UInt mipsins)1012 static UInt get_dspImm(UInt mipsins)
1013 {
1014    return (0x03ff0000 & mipsins) >> 16;
1015 }
1016 
branch_or_jump(const UChar * addr)1017 static Bool branch_or_jump(const UChar * addr)
1018 {
1019    UInt fmt;
1020    UInt cins = getUInt(addr);
1021 
1022    UInt opcode = get_opcode(cins);
1023    UInt rt = get_rt(cins);
1024    UInt function = get_function(cins);
1025 
1026    /* bgtz, blez, bne, beq, jal */
1027    if (opcode == 0x07 || opcode == 0x06 || opcode == 0x05 || opcode == 0x04
1028        || opcode == 0x03 || opcode == 0x02) {
1029       return True;
1030    }
1031 
1032    /* bgez */
1033    if (opcode == 0x01 && rt == 0x01) {
1034       return True;
1035    }
1036 
1037    /* bgezal */
1038    if (opcode == 0x01 && rt == 0x11) {
1039       return True;
1040    }
1041 
1042    /* bltzal */
1043    if (opcode == 0x01 && rt == 0x10) {
1044       return True;
1045    }
1046 
1047    /* bltz */
1048    if (opcode == 0x01 && rt == 0x00) {
1049       return True;
1050    }
1051 
1052    /* jalr */
1053    if (opcode == 0x00 && function == 0x09) {
1054       return True;
1055    }
1056 
1057    /* jr */
1058    if (opcode == 0x00 && function == 0x08) {
1059       return True;
1060    }
1061 
1062    if (opcode == 0x11) {
1063       /* bc1f & bc1t */
1064       fmt = get_fmt(cins);
1065       if (fmt == 0x08) {
1066          return True;
1067       }
1068 
1069       /* MSA branches */
1070       /* bnz.df, bz.df */
1071       if (fmt >= 0x18) {
1072          return True;
1073       }
1074       /* bnz.v */
1075       if (fmt == 0x0f) {
1076          return True;
1077       }
1078       /* bz.v */
1079       if (fmt == 0x0b) {
1080          return True;
1081       }
1082 
1083       /* R6 branches */
1084       /* bc1eqz */
1085       if (fmt == 0x09) {
1086          return True;
1087       }
1088 
1089       /* bc1nez */
1090       if (fmt == 0x0D) {
1091          return True;
1092       }
1093    }
1094 
1095    /* bposge32 */
1096    if (opcode == 0x01 && rt == 0x1c) {
1097       return True;
1098    }
1099 
1100    /* Cavium Specific instructions. */
1101    if (opcode == 0x32 || opcode == 0x3A || opcode == 0x36 || opcode == 0x3E) {
1102        /* BBIT0, BBIT1, BBIT032, BBIT132 */
1103       return True;
1104    }
1105 
1106    return False;
1107 }
1108 
is_Branch_or_Jump_and_Link(const UChar * addr)1109 static Bool is_Branch_or_Jump_and_Link(const UChar * addr)
1110 {
1111    UInt cins = getUInt(addr);
1112 
1113    UInt opcode = get_opcode(cins);
1114    UInt rt = get_rt(cins);
1115    UInt function = get_function(cins);
1116 
1117    /* jal */
1118    if (opcode == 0x02) {
1119       return True;
1120    }
1121 
1122    /* bgezal or bal(r6) */
1123    if (opcode == 0x01 && rt == 0x11) {
1124       return True;
1125    }
1126 
1127    /* bltzal */
1128    if (opcode == 0x01 && rt == 0x10) {
1129       return True;
1130    }
1131 
1132    /* jalr */
1133    if (opcode == 0x00 && function == 0x09) {
1134       return True;
1135    }
1136 
1137    return False;
1138 }
1139 
branch_or_link_likely(const UChar * addr)1140 static Bool branch_or_link_likely(const UChar * addr)
1141 {
1142    UInt cins = getUInt(addr);
1143    UInt opcode = get_opcode(cins);
1144    UInt rt = get_rt(cins);
1145 
1146    /* bgtzl, blezl, bnel, beql */
1147    if (opcode == 0x17 || opcode == 0x16 || opcode == 0x15 || opcode == 0x14)
1148       return True;
1149 
1150    /* bgezl */
1151    if (opcode == 0x01 && rt == 0x03)
1152       return True;
1153 
1154    /* bgezall */
1155    if (opcode == 0x01 && rt == 0x13)
1156       return True;
1157 
1158    /* bltzall */
1159    if (opcode == 0x01 && rt == 0x12)
1160       return True;
1161 
1162    /* bltzl */
1163    if (opcode == 0x01 && rt == 0x02)
1164       return True;
1165 
1166    return False;
1167 }
1168 
1169 /*------------------------------------------------------------*/
1170 /*--- Helper bits and pieces for creating IR fragments.    ---*/
1171 /*------------------------------------------------------------*/
1172 
mkU8(UInt i)1173 static IRExpr *mkU8(UInt i)
1174 {
1175    vassert(i < 256);
1176    return IRExpr_Const(IRConst_U8((UChar) i));
1177 }
1178 
1179 /* Create an expression node for a 16-bit integer constant. */
mkU16(UInt i)1180 static IRExpr *mkU16(UInt i)
1181 {
1182    return IRExpr_Const(IRConst_U16(i));
1183 }
1184 
1185 /* Create an expression node for a 32-bit integer constant. */
mkU32(UInt i)1186 static IRExpr *mkU32(UInt i)
1187 {
1188    return IRExpr_Const(IRConst_U32(i));
1189 }
1190 
1191 /* Create an expression node for a 64-bit integer constant. */
mkU64(ULong i)1192 static IRExpr *mkU64(ULong i)
1193 {
1194    return IRExpr_Const(IRConst_U64(i));
1195 }
1196 
mkexpr(IRTemp tmp)1197 static IRExpr *mkexpr(IRTemp tmp)
1198 {
1199    return IRExpr_RdTmp(tmp);
1200 }
1201 
unop(IROp op,IRExpr * a)1202 static IRExpr *unop(IROp op, IRExpr * a)
1203 {
1204    return IRExpr_Unop(op, a);
1205 }
1206 
binop(IROp op,IRExpr * a1,IRExpr * a2)1207 static IRExpr *binop(IROp op, IRExpr * a1, IRExpr * a2)
1208 {
1209    return IRExpr_Binop(op, a1, a2);
1210 }
1211 
triop(IROp op,IRExpr * a1,IRExpr * a2,IRExpr * a3)1212 static IRExpr *triop(IROp op, IRExpr * a1, IRExpr * a2, IRExpr * a3)
1213 {
1214    return IRExpr_Triop(op, a1, a2, a3);
1215 }
1216 
qop(IROp op,IRExpr * a1,IRExpr * a2,IRExpr * a3,IRExpr * a4)1217 static IRExpr *qop ( IROp op, IRExpr * a1, IRExpr * a2, IRExpr * a3,
1218                      IRExpr * a4 )
1219 {
1220    return IRExpr_Qop(op, a1, a2, a3, a4);
1221 }
1222 
load(IRType ty,IRExpr * addr)1223 static IRExpr *load(IRType ty, IRExpr * addr)
1224 {
1225    IRExpr *load1 = NULL;
1226 #if defined (_MIPSEL)
1227    load1 = IRExpr_Load(Iend_LE, ty, addr);
1228 #elif defined (_MIPSEB)
1229    load1 = IRExpr_Load(Iend_BE, ty, addr);
1230 #endif
1231    return load1;
1232 }
1233 
1234 /* Add a statement to the list held by "irsb". */
stmt(IRStmt * st)1235 static void stmt(IRStmt * st)
1236 {
1237    addStmtToIRSB(irsb, st);
1238 }
1239 
assign(IRTemp dst,IRExpr * e)1240 static void assign(IRTemp dst, IRExpr * e)
1241 {
1242    stmt(IRStmt_WrTmp(dst, e));
1243 }
1244 
store(IRExpr * addr,IRExpr * data)1245 static void store(IRExpr * addr, IRExpr * data)
1246 {
1247 #if defined (_MIPSEL)
1248    stmt(IRStmt_Store(Iend_LE, addr, data));
1249 #elif defined (_MIPSEB)
1250    stmt(IRStmt_Store(Iend_BE, addr, data));
1251 #endif
1252 }
1253 
1254 /* Generate a new temporary of the given type. */
newTemp(IRType ty)1255 static IRTemp newTemp(IRType ty)
1256 {
1257    vassert(isPlausibleIRType(ty));
1258    return newIRTemp(irsb->tyenv, ty);
1259 }
1260 
1261 /* Generate an expression for SRC rotated right by ROT. */
genROR32(IRExpr * src,Int rot)1262 static IRExpr *genROR32(IRExpr * src, Int rot)
1263 {
1264    vassert(rot >= 0 && rot < 32);
1265    if (rot == 0)
1266       return src;
1267    return binop(Iop_Or32, binop(Iop_Shl32, src, mkU8(32 - rot)),
1268                           binop(Iop_Shr32, src, mkU8(rot)));
1269 }
1270 
genRORV32(IRExpr * src,IRExpr * rs)1271 static IRExpr *genRORV32(IRExpr * src, IRExpr * rs)
1272 {
1273    IRTemp t0 = newTemp(Ity_I8);
1274    IRTemp t1 = newTemp(Ity_I8);
1275 
1276    assign(t0, unop(Iop_32to8, binop(Iop_And32, rs, mkU32(0x0000001F))));
1277    assign(t1, binop(Iop_Sub8, mkU8(32), mkexpr(t0)));
1278    return binop(Iop_Or32, binop(Iop_Shl32, src, mkexpr(t1)),
1279                           binop(Iop_Shr32, src, mkexpr(t0)));
1280 }
1281 
1282 
extend_s_9to16(UInt x)1283 static UShort extend_s_9to16(UInt x)
1284 {
1285    return (UShort) ((((Int) x) << 23) >> 23);
1286 }
1287 
extend_s_10to16(UInt x)1288 static UShort extend_s_10to16(UInt x)
1289 {
1290    return (UShort) ((((Int) x) << 22) >> 22);
1291 }
1292 
extend_s_10to32(UInt x)1293 static UInt extend_s_10to32(UInt x)
1294 {
1295    return (UInt)((((Int) x) << 22) >> 22);
1296 }
1297 
extend_s_10to64(UInt x)1298 static ULong extend_s_10to64(UInt x)
1299 {
1300    return (ULong)((((Long) x) << 54) >> 54);
1301 }
1302 
extend_s_16to32(UInt x)1303 static UInt extend_s_16to32(UInt x)
1304 {
1305    return (UInt) ((((Int) x) << 16) >> 16);
1306 }
1307 
extend_s_18to32(UInt x)1308 static UInt extend_s_18to32(UInt x)
1309 {
1310    return (UInt) ((((Int) x) << 14) >> 14);
1311 }
1312 
extend_s_19to32(UInt x)1313 static UInt extend_s_19to32(UInt x)
1314 {
1315    return (UInt) ((((Int) x) << 13) >> 13);
1316 }
1317 
extend_s_23to32(UInt x)1318 static UInt extend_s_23to32(UInt x)
1319 {
1320    return (UInt) ((((Int) x) << 9) >> 9);
1321 }
1322 
extend_s_26to32(UInt x)1323 static UInt extend_s_26to32(UInt x)
1324 {
1325    return (UInt) ((((Int) x) << 6) >> 6);
1326 }
1327 
extend_s_16to64(UInt x)1328 static ULong extend_s_16to64 ( UInt x )
1329 {
1330    return (ULong) ((((Long) x) << 48) >> 48);
1331 }
1332 
extend_s_18to64(UInt x)1333 static ULong extend_s_18to64 ( UInt x )
1334 {
1335    return (ULong) ((((Long) x) << 46) >> 46);
1336 }
1337 
extend_s_19to64(UInt x)1338 static ULong extend_s_19to64(UInt x)
1339 {
1340    return (ULong) ((((Long) x) << 45) >> 45);
1341 }
1342 
extend_s_23to64(UInt x)1343 static ULong extend_s_23to64(UInt x)
1344 {
1345    return (ULong) ((((Long) x) << 41) >> 41);
1346 }
1347 
extend_s_26to64(UInt x)1348 static ULong extend_s_26to64(UInt x)
1349 {
1350    return (ULong) ((((Long) x) << 38) >> 38);
1351 }
1352 
extend_s_32to64(UInt x)1353 static ULong extend_s_32to64 ( UInt x )
1354 {
1355    return (ULong) ((((Long) x) << 32) >> 32);
1356 }
1357 
jmp_lit32(DisResult * dres,IRJumpKind kind,Addr32 d32)1358 static void jmp_lit32 ( /*MOD*/ DisResult* dres, IRJumpKind kind, Addr32 d32 )
1359 {
1360    vassert(dres->whatNext    == Dis_Continue);
1361    vassert(dres->len         == 0);
1362    vassert(dres->continueAt  == 0);
1363    vassert(dres->jk_StopHere == Ijk_INVALID);
1364    dres->whatNext    = Dis_StopHere;
1365    dres->jk_StopHere = kind;
1366    stmt( IRStmt_Put( OFFB_PC, mkU32(d32) ) );
1367 }
1368 
jmp_lit64(DisResult * dres,IRJumpKind kind,Addr64 d64)1369 static void jmp_lit64 ( /*MOD*/ DisResult* dres, IRJumpKind kind, Addr64 d64 )
1370 {
1371    vassert(dres->whatNext    == Dis_Continue);
1372    vassert(dres->len         == 0);
1373    vassert(dres->continueAt  == 0);
1374    vassert(dres->jk_StopHere == Ijk_INVALID);
1375    dres->whatNext    = Dis_StopHere;
1376    dres->jk_StopHere = kind;
1377    stmt(IRStmt_Put(OFFB_PC, mkU64(d64)));
1378 }
1379 
1380 /* Get value from accumulator (helper function for MIPS32 DSP ASE instructions).
1381    This function should be called before any other operation if widening
1382    multiplications are used. */
getAcc(UInt acNo)1383 static IRExpr *getAcc(UInt acNo)
1384 {
1385    vassert(!mode64);
1386    vassert(acNo <= 3);
1387    return IRExpr_Get(accumulatorGuestRegOffset(acNo), Ity_I64);
1388 }
1389 
1390 /* Get value from DSPControl register (helper function for MIPS32 DSP ASE
1391    instructions). */
getDSPControl(void)1392 static IRExpr *getDSPControl(void)
1393 {
1394    vassert(!mode64);
1395    return IRExpr_Get(offsetof(VexGuestMIPS32State, guest_DSPControl), Ity_I32);
1396 }
1397 
1398 /* Put value to DSPControl register. Expression e is written to DSPControl as
1399    is. If only certain bits of DSPControl need to be changed, it should be done
1400    before calling putDSPControl(). It could be done by reading DSPControl and
1401    ORing it with appropriate mask. */
putDSPControl(IRExpr * e)1402 static void putDSPControl(IRExpr * e)
1403 {
1404    vassert(!mode64);
1405    stmt(IRStmt_Put(offsetof(VexGuestMIPS32State, guest_DSPControl), e));
1406 }
1407 
1408 /* Fetch a byte from the guest insn stream. */
getIByte(Int delta)1409 static UChar getIByte(Int delta)
1410 {
1411    return guest_code[delta];
1412 }
1413 
getIReg(UInt iregNo)1414 static IRExpr *getIReg(UInt iregNo)
1415 {
1416    if (0 == iregNo) {
1417       return mode64 ? mkU64(0x0) : mkU32(0x0);
1418    } else {
1419       IRType ty = mode64 ? Ity_I64 : Ity_I32;
1420       vassert(iregNo < 32);
1421       return IRExpr_Get(integerGuestRegOffset(iregNo), ty);
1422    }
1423 }
1424 
1425 
getWReg(UInt wregNo)1426 static IRExpr *getWReg(UInt wregNo) {
1427    vassert(wregNo <= 31);
1428    return IRExpr_Get(msaGuestRegOffset(wregNo), Ity_V128);
1429 }
1430 
getHI(void)1431 static IRExpr *getHI(void)
1432 {
1433    if (mode64)
1434       return IRExpr_Get(offsetof(VexGuestMIPS64State, guest_HI), Ity_I64);
1435    else
1436       return IRExpr_Get(offsetof(VexGuestMIPS32State, guest_HI), Ity_I32);
1437 }
1438 
getLO(void)1439 static IRExpr *getLO(void)
1440 {
1441    if (mode64)
1442       return IRExpr_Get(offsetof(VexGuestMIPS64State, guest_LO), Ity_I64);
1443    else
1444       return IRExpr_Get(offsetof(VexGuestMIPS32State, guest_LO), Ity_I32);
1445 }
1446 
getFCSR(void)1447 static IRExpr *getFCSR(void)
1448 {
1449    if (mode64)
1450       return IRExpr_Get(offsetof(VexGuestMIPS64State, guest_FCSR), Ity_I32);
1451    else
1452       return IRExpr_Get(offsetof(VexGuestMIPS32State, guest_FCSR), Ity_I32);
1453 }
1454 
getLLaddr(void)1455 static IRExpr *getLLaddr(void)
1456 {
1457    if (mode64)
1458       return IRExpr_Get(offsetof(VexGuestMIPS64State, guest_LLaddr), Ity_I64);
1459    else
1460       return IRExpr_Get(offsetof(VexGuestMIPS32State, guest_LLaddr), Ity_I32);
1461 }
1462 
getLLdata(void)1463 static IRExpr *getLLdata(void)
1464 {
1465    if (mode64)
1466       return IRExpr_Get(offsetof(VexGuestMIPS64State, guest_LLdata), Ity_I64);
1467    else
1468       return IRExpr_Get(offsetof(VexGuestMIPS32State, guest_LLdata), Ity_I32);
1469 }
1470 
getMSACSR(void)1471 static IRExpr *getMSACSR(void) {
1472    if (mode64)
1473       return IRExpr_Get(offsetof(VexGuestMIPS64State, guest_MSACSR), Ity_I32);
1474    else
1475       return IRExpr_Get(offsetof(VexGuestMIPS32State, guest_MSACSR), Ity_I32);
1476 }
1477 
1478 /* Get byte from register reg, byte pos from 0 to 3 (or 7 for MIPS64) . */
getByteFromReg(UInt reg,UInt byte_pos)1479 static IRExpr *getByteFromReg(UInt reg, UInt byte_pos)
1480 {
1481   UInt pos = byte_pos * 8;
1482   if (mode64)
1483       return unop(Iop_64to8, binop(Iop_And64,
1484                                    binop(Iop_Shr64, getIReg(reg), mkU8(pos)),
1485                                    mkU64(0xFF)));
1486    else
1487       return unop(Iop_32to8, binop(Iop_And32,
1488                                    binop(Iop_Shr32, getIReg(reg), mkU8(pos)),
1489                                    mkU32(0xFF)));
1490 }
1491 
putFCSR(IRExpr * e)1492 static void putFCSR(IRExpr * e)
1493 {
1494    if (mode64)
1495       stmt(IRStmt_Put(offsetof(VexGuestMIPS64State, guest_FCSR), e));
1496    else
1497       stmt(IRStmt_Put(offsetof(VexGuestMIPS32State, guest_FCSR), e));
1498 }
1499 
putLLaddr(IRExpr * e)1500 static void putLLaddr(IRExpr * e)
1501 {
1502    if (mode64)
1503       stmt(IRStmt_Put(offsetof(VexGuestMIPS64State, guest_LLaddr), e));
1504    else
1505       stmt(IRStmt_Put(offsetof(VexGuestMIPS32State, guest_LLaddr), e));
1506 }
1507 
putLLdata(IRExpr * e)1508 static void putLLdata(IRExpr * e)
1509 {
1510    if (mode64)
1511       stmt(IRStmt_Put(offsetof(VexGuestMIPS64State, guest_LLdata), e));
1512    else
1513       stmt(IRStmt_Put(offsetof(VexGuestMIPS32State, guest_LLdata), e));
1514 }
1515 
putMSACSR(IRExpr * e)1516 static void putMSACSR(IRExpr * e) {
1517    if (mode64)
1518       stmt(IRStmt_Put(offsetof(VexGuestMIPS64State, guest_MSACSR), e));
1519    else
1520       stmt(IRStmt_Put(offsetof(VexGuestMIPS32State, guest_MSACSR), e));
1521 }
1522 
1523 /* fs   - fpu source register number.
1524    inst - fpu instruction that needs to be executed.
1525    sz32 - size of source register.
1526    opN  - number of operads:
1527           1 - unary operation.
1528           2 - binary operation. */
calculateFCSR(UInt fs,UInt ft,UInt inst,Bool sz32,UInt opN)1529 static void calculateFCSR(UInt fs, UInt ft, UInt inst, Bool sz32, UInt opN)
1530 {
1531    IRDirty *d;
1532    IRTemp fcsr = newTemp(Ity_I32);
1533    /* IRExpr_GSPTR() => Need to pass pointer to guest state to helper. */
1534    if (fp_mode64)
1535       d = unsafeIRDirty_1_N(fcsr, 0,
1536                             "mips_dirtyhelper_calculate_FCSR_fp64",
1537                             &mips_dirtyhelper_calculate_FCSR_fp64,
1538                             mkIRExprVec_4(IRExpr_GSPTR(),
1539                                           mkU32(fs),
1540                                           mkU32(ft),
1541                                           mkU32(inst)));
1542    else
1543       d = unsafeIRDirty_1_N(fcsr, 0,
1544                             "mips_dirtyhelper_calculate_FCSR_fp32",
1545                             &mips_dirtyhelper_calculate_FCSR_fp32,
1546                             mkIRExprVec_4(IRExpr_GSPTR(),
1547                                           mkU32(fs),
1548                                           mkU32(ft),
1549                                           mkU32(inst)));
1550 
1551    if (opN == 1) {  /* Unary operation. */
1552       /* Declare we're reading guest state. */
1553       if (sz32 || fp_mode64)
1554          d->nFxState = 2;
1555       else
1556          d->nFxState = 3;
1557       vex_bzero(&d->fxState, sizeof(d->fxState));
1558 
1559       d->fxState[0].fx     = Ifx_Read;  /* read */
1560       if (mode64)
1561          d->fxState[0].offset = offsetof(VexGuestMIPS64State, guest_FCSR);
1562       else
1563          d->fxState[0].offset = offsetof(VexGuestMIPS32State, guest_FCSR);
1564       d->fxState[0].size   = sizeof(UInt);
1565       d->fxState[1].fx     = Ifx_Read;  /* read */
1566       d->fxState[1].offset = floatGuestRegOffset(fs);
1567       d->fxState[1].size   = sizeof(ULong);
1568 
1569       if (!(sz32 || fp_mode64)) {
1570          d->fxState[2].fx     = Ifx_Read;  /* read */
1571          d->fxState[2].offset = floatGuestRegOffset(fs+1);
1572          d->fxState[2].size   = sizeof(ULong);
1573       }
1574    } else if (opN == 2) {  /* Binary operation. */
1575       /* Declare we're reading guest state. */
1576       if (sz32 || fp_mode64)
1577          d->nFxState = 3;
1578       else
1579          d->nFxState = 5;
1580       vex_bzero(&d->fxState, sizeof(d->fxState));
1581 
1582       d->fxState[0].fx     = Ifx_Read;  /* read */
1583       if (mode64)
1584          d->fxState[0].offset = offsetof(VexGuestMIPS64State, guest_FCSR);
1585       else
1586          d->fxState[0].offset = offsetof(VexGuestMIPS32State, guest_FCSR);
1587       d->fxState[0].size   = sizeof(UInt);
1588       d->fxState[1].fx     = Ifx_Read;  /* read */
1589       d->fxState[1].offset = floatGuestRegOffset(fs);
1590       d->fxState[1].size   = sizeof(ULong);
1591       d->fxState[2].fx     = Ifx_Read;  /* read */
1592       d->fxState[2].offset = floatGuestRegOffset(ft);
1593       d->fxState[2].size   = sizeof(ULong);
1594 
1595       if (!(sz32 || fp_mode64)) {
1596          d->fxState[3].fx     = Ifx_Read;  /* read */
1597          d->fxState[3].offset = floatGuestRegOffset(fs+1);
1598          d->fxState[3].size   = sizeof(ULong);
1599          d->fxState[4].fx     = Ifx_Read;  /* read */
1600          d->fxState[4].offset = floatGuestRegOffset(ft+1);
1601          d->fxState[4].size   = sizeof(ULong);
1602       }
1603    }
1604 
1605    stmt(IRStmt_Dirty(d));
1606 
1607    putFCSR(mkexpr(fcsr));
1608 }
1609 
1610 /* ws, wt - source MSA register numbers.
1611    inst   - MSA fp instruction that needs to be executed.
1612    opN    - number of operads:
1613              1 - unary operation.
1614              2 - binary operation. */
calculateMSACSR(UInt ws,UInt wt,UInt inst,UInt opN)1615 static void calculateMSACSR(UInt ws, UInt wt, UInt inst, UInt opN) {
1616    IRDirty *d;
1617    IRTemp msacsr = newTemp(Ity_I32);
1618    /* IRExpr_BBPTR() => Need to pass pointer to guest state to helper. */
1619    d = unsafeIRDirty_1_N(msacsr, 0,
1620                          "mips_dirtyhelper_calculate_MSACSR",
1621                          &mips_dirtyhelper_calculate_MSACSR,
1622                          mkIRExprVec_4(IRExpr_GSPTR(),
1623                                        mkU32(ws),
1624                                        mkU32(wt),
1625                                        mkU32(inst)));
1626 
1627    if (opN == 1) {  /* Unary operation. */
1628       /* Declare we're reading guest state. */
1629       d->nFxState = 2;
1630       vex_bzero(&d->fxState, sizeof(d->fxState));
1631       d->fxState[0].fx     = Ifx_Read;  /* read */
1632 
1633       if (mode64)
1634          d->fxState[0].offset = offsetof(VexGuestMIPS64State, guest_MSACSR);
1635       else
1636          d->fxState[0].offset = offsetof(VexGuestMIPS32State, guest_MSACSR);
1637 
1638       d->fxState[0].size   = sizeof(UInt);
1639       d->fxState[1].fx     = Ifx_Read;  /* read */
1640       d->fxState[1].offset = msaGuestRegOffset(ws);
1641       d->fxState[1].size   = sizeof(ULong);
1642    } else if (opN == 2) {  /* Binary operation. */
1643       /* Declare we're reading guest state. */
1644       d->nFxState = 3;
1645       vex_bzero(&d->fxState, sizeof(d->fxState));
1646       d->fxState[0].fx     = Ifx_Read;  /* read */
1647 
1648       if (mode64)
1649          d->fxState[0].offset = offsetof(VexGuestMIPS64State, guest_MSACSR);
1650       else
1651          d->fxState[0].offset = offsetof(VexGuestMIPS32State, guest_MSACSR);
1652 
1653       d->fxState[0].size   = sizeof(UInt);
1654       d->fxState[1].fx     = Ifx_Read;  /* read */
1655       d->fxState[1].offset = msaGuestRegOffset(ws);
1656       d->fxState[1].size   = sizeof(ULong);
1657       d->fxState[2].fx     = Ifx_Read;  /* read */
1658       d->fxState[2].offset = msaGuestRegOffset(wt);
1659       d->fxState[2].size   = sizeof(ULong);
1660    }
1661 
1662    stmt(IRStmt_Dirty(d));
1663    putMSACSR(mkexpr(msacsr));
1664 }
1665 
getULR(void)1666 static IRExpr *getULR(void)
1667 {
1668    if (mode64)
1669       return IRExpr_Get(offsetof(VexGuestMIPS64State, guest_ULR), Ity_I64);
1670    else
1671       return IRExpr_Get(offsetof(VexGuestMIPS32State, guest_ULR), Ity_I32);
1672 }
1673 
putIReg(UInt archreg,IRExpr * e)1674 static void putIReg(UInt archreg, IRExpr * e)
1675 {
1676    IRType ty = mode64 ? Ity_I64 : Ity_I32;
1677    vassert(archreg < 32);
1678    vassert(typeOfIRExpr(irsb->tyenv, e) == ty);
1679    if (archreg != 0)
1680       stmt(IRStmt_Put(integerGuestRegOffset(archreg), e));
1681 }
1682 
putWReg(UInt wregNo,IRExpr * e)1683 static void putWReg(UInt wregNo, IRExpr * e) {
1684    vassert(wregNo <= 31);
1685    vassert(typeOfIRExpr(irsb->tyenv, e) == Ity_V128);
1686    stmt(IRStmt_Put(msaGuestRegOffset(wregNo), e));
1687    stmt(IRStmt_Put(floatGuestRegOffset(wregNo),
1688                    unop(Iop_ReinterpI64asF64, unop(Iop_V128to64, e))));
1689 }
1690 
mkNarrowTo32(IRType ty,IRExpr * src)1691 static IRExpr *mkNarrowTo32(IRType ty, IRExpr * src)
1692 {
1693    vassert(ty == Ity_I32 || ty == Ity_I64);
1694    return ty == Ity_I64 ? unop(Iop_64to32, src) : src;
1695 }
1696 
putLO(IRExpr * e)1697 static void putLO(IRExpr * e)
1698 {
1699    if (mode64) {
1700       stmt(IRStmt_Put(offsetof(VexGuestMIPS64State, guest_LO), e));
1701    } else {
1702       stmt(IRStmt_Put(offsetof(VexGuestMIPS32State, guest_LO), e));
1703    /* Add value to lower 32 bits of ac0 to maintain compatibility between
1704       regular MIPS32 instruction set and MIPS DSP ASE. Keep higher 32bits
1705       unchanged. */
1706       IRTemp t_lo = newTemp(Ity_I32);
1707       IRTemp t_hi = newTemp(Ity_I32);
1708       assign(t_lo, e);
1709       assign(t_hi, unop(Iop_64HIto32, getAcc(0)));
1710       stmt(IRStmt_Put(accumulatorGuestRegOffset(0),
1711            binop(Iop_32HLto64, mkexpr(t_hi), mkexpr(t_lo))));
1712    }
1713 }
1714 
putHI(IRExpr * e)1715 static void putHI(IRExpr * e)
1716 {
1717    if (mode64) {
1718       stmt(IRStmt_Put(offsetof(VexGuestMIPS64State, guest_HI), e));
1719    } else {
1720       stmt(IRStmt_Put(offsetof(VexGuestMIPS32State, guest_HI), e));
1721    /* Add value to higher 32 bits of ac0 to maintain compatibility between
1722       regular MIPS32 instruction set and MIPS DSP ASE. Keep lower 32bits
1723       unchanged. */
1724       IRTemp t_lo = newTemp(Ity_I32);
1725       IRTemp t_hi = newTemp(Ity_I32);
1726       assign(t_hi, e);
1727       assign(t_lo, unop(Iop_64to32, getAcc(0)));
1728       stmt(IRStmt_Put(accumulatorGuestRegOffset(0),
1729            binop(Iop_32HLto64, mkexpr(t_hi), mkexpr(t_lo))));
1730    }
1731 }
1732 
1733 /* Put value to accumulator(helper function for MIPS32 DSP ASE instructions). */
putAcc(UInt acNo,IRExpr * e)1734 static void putAcc(UInt acNo, IRExpr * e)
1735 {
1736    vassert(!mode64);
1737    vassert(acNo <= 3);
1738    vassert(typeOfIRExpr(irsb->tyenv, e) == Ity_I64);
1739    stmt(IRStmt_Put(accumulatorGuestRegOffset(acNo), e));
1740 /* If acNo = 0, split value to HI and LO regs in order to maintain compatibility
1741    between MIPS32 and MIPS DSP ASE insn sets. */
1742    if (0 == acNo) {
1743      putLO(unop(Iop_64to32, e));
1744      putHI(unop(Iop_64HIto32, e));
1745    }
1746 }
1747 
mkNarrowTo8(IRType ty,IRExpr * src)1748 static IRExpr *mkNarrowTo8 ( IRType ty, IRExpr * src )
1749 {
1750    vassert(ty == Ity_I32 || ty == Ity_I64);
1751    return ty == Ity_I64 ? unop(Iop_64to8, src) : unop(Iop_32to8, src);
1752 }
1753 
mkNarrowTo16(IRType ty,IRExpr * src)1754 static IRExpr *mkNarrowTo16 ( IRType ty, IRExpr * src )
1755 {
1756    vassert(ty == Ity_I32 || ty == Ity_I64);
1757    return ty == Ity_I64 ? unop(Iop_64to16, src) : unop(Iop_32to16, src);
1758 }
1759 
putPC(IRExpr * e)1760 static void putPC(IRExpr * e)
1761 {
1762    stmt(IRStmt_Put(OFFB_PC, e));
1763 }
1764 
mkWidenFrom32(IRType ty,IRExpr * src,Bool sined)1765 static IRExpr *mkWidenFrom32(IRType ty, IRExpr * src, Bool sined)
1766 {
1767    vassert(ty == Ity_I32 || ty == Ity_I64);
1768    if (ty == Ity_I32)
1769       return src;
1770    return (sined) ? unop(Iop_32Sto64, src) : unop(Iop_32Uto64, src);
1771 }
1772 
1773 /* Narrow 8/16/32 bit int expr to 8/16/32.  Clearly only some
1774    of these combinations make sense. */
narrowTo(IRType dst_ty,IRExpr * e)1775 static IRExpr *narrowTo(IRType dst_ty, IRExpr * e)
1776 {
1777    IRType src_ty = typeOfIRExpr(irsb->tyenv, e);
1778    if (src_ty == dst_ty)
1779       return e;
1780    if (src_ty == Ity_I32 && dst_ty == Ity_I16)
1781       return unop(Iop_32to16, e);
1782    if (src_ty == Ity_I32 && dst_ty == Ity_I8)
1783       return unop(Iop_32to8, e);
1784    if (src_ty == Ity_I64 && dst_ty == Ity_I8) {
1785       vassert(mode64);
1786       return unop(Iop_64to8, e);
1787    }
1788    if (src_ty == Ity_I64 && dst_ty == Ity_I16) {
1789       vassert(mode64);
1790       return unop(Iop_64to16, e);
1791    }
1792    vpanic("narrowTo(mips)");
1793    return 0;
1794 }
1795 
getLoFromF64(IRType ty,IRExpr * src)1796 static IRExpr *getLoFromF64(IRType ty, IRExpr * src)
1797 {
1798    vassert(ty == Ity_F32 || ty == Ity_F64);
1799    if (ty == Ity_F64) {
1800       IRTemp t0, t1;
1801       t0 = newTemp(Ity_I64);
1802       t1 = newTemp(Ity_I32);
1803       assign(t0, unop(Iop_ReinterpF64asI64, src));
1804       assign(t1, unop(Iop_64to32, mkexpr(t0)));
1805       return unop(Iop_ReinterpI32asF32, mkexpr(t1));
1806    } else
1807       return src;
1808 }
1809 
getHiFromF64(IRExpr * src)1810 static inline IRExpr *getHiFromF64(IRExpr * src)
1811 {
1812    vassert(typeOfIRExpr(irsb->tyenv, src) == Ity_F64);
1813    return unop(Iop_ReinterpI32asF32, unop(Iop_64HIto32,
1814                                           unop(Iop_ReinterpF64asI64, src)));
1815 }
1816 
mkWidenFromF32(IRType ty,IRExpr * src)1817 static IRExpr *mkWidenFromF32(IRType ty, IRExpr * src)
1818 {
1819    vassert(ty == Ity_F32 || ty == Ity_F64);
1820    if (ty == Ity_F64) {
1821       IRTemp t0 = newTemp(Ity_I32);
1822       IRTemp t1 = newTemp(Ity_I64);
1823       assign(t0, unop(Iop_ReinterpF32asI32, src));
1824       assign(t1, binop(Iop_32HLto64, mkU32(0x0), mkexpr(t0)));
1825       return unop(Iop_ReinterpI64asF64, mkexpr(t1));
1826    } else
1827       return src;
1828 }
1829 
1830 /* Convenience function to move to next instruction on condition. */
mips_next_insn_if(IRExpr * condition)1831 static void mips_next_insn_if(IRExpr *condition) {
1832    vassert(typeOfIRExpr(irsb->tyenv, condition) == Ity_I1);
1833 
1834    stmt(IRStmt_Exit(condition, Ijk_Boring,
1835         mode64 ? IRConst_U64(guest_PC_curr_instr + 4) :
1836                  IRConst_U32(guest_PC_curr_instr + 4),
1837         OFFB_PC));
1838 }
1839 
dis_branch_likely(IRExpr * guard,UInt imm)1840 static IRExpr *dis_branch_likely(IRExpr * guard, UInt imm)
1841 {
1842    ULong branch_offset;
1843    IRTemp t0;
1844 
1845    /* PC = PC + (SignExtend(signed_immed_24) << 2)
1846       An 18-bit signed offset (the 16-bit offset field shifted left 2 bits)
1847       is added to the address of the instruction following
1848       the branch (not the branch itself), in the branch delay slot, to form
1849       a PC-relative effective target address. */
1850    if (mode64)
1851       branch_offset = extend_s_18to64(imm << 2);
1852    else
1853       branch_offset = extend_s_18to32(imm << 2);
1854 
1855    t0 = newTemp(Ity_I1);
1856    assign(t0, guard);
1857 
1858    if (mode64)
1859       stmt(IRStmt_Exit(mkexpr(t0), Ijk_Boring,
1860                        IRConst_U64(guest_PC_curr_instr + 8), OFFB_PC));
1861    else
1862       stmt(IRStmt_Exit(mkexpr(t0), Ijk_Boring,
1863                        IRConst_U32(guest_PC_curr_instr + 8), OFFB_PC));
1864 
1865    irsb->jumpkind = Ijk_Boring;
1866 
1867    if (mode64)
1868       return mkU64(guest_PC_curr_instr + 4 + branch_offset);
1869    else
1870       return mkU32(guest_PC_curr_instr + 4 + branch_offset);
1871 }
1872 
dis_branch(Bool link,IRExpr * guard,UInt imm,IRStmt ** set)1873 static void dis_branch(Bool link, IRExpr * guard, UInt imm, IRStmt ** set)
1874 {
1875    ULong branch_offset;
1876    IRTemp t0;
1877 
1878    if (link) {  /* LR (GPR31) = addr of the 2nd instr after branch instr */
1879       if (mode64)
1880          putIReg(31, mkU64(guest_PC_curr_instr + 8));
1881       else
1882          putIReg(31, mkU32(guest_PC_curr_instr + 8));
1883    }
1884 
1885    /* PC = PC + (SignExtend(signed_immed_24) << 2)
1886       An 18-bit signed offset (the 16-bit offset field shifted left 2 bits)
1887       is added to the address of the instruction following
1888       the branch (not the branch itself), in the branch delay slot, to form
1889       a PC-relative effective target address. */
1890 
1891    if (mode64)
1892       branch_offset = extend_s_18to64(imm << 2);
1893    else
1894       branch_offset = extend_s_18to32(imm << 2);
1895 
1896    t0 = newTemp(Ity_I1);
1897    assign(t0, guard);
1898    if (mode64)
1899       *set = IRStmt_Exit(mkexpr(t0), link ? Ijk_Call : Ijk_Boring,
1900                          IRConst_U64(guest_PC_curr_instr + 4 + branch_offset),
1901                          OFFB_PC);
1902    else
1903       *set = IRStmt_Exit(mkexpr(t0), link ? Ijk_Call : Ijk_Boring,
1904                          IRConst_U32(guest_PC_curr_instr + 4 +
1905                                      (UInt) branch_offset), OFFB_PC);
1906 }
1907 
dis_branch_compact(Bool link,IRExpr * guard,UInt imm,DisResult * dres)1908 static void dis_branch_compact(Bool link, IRExpr * guard, UInt imm,
1909                                DisResult *dres)
1910 {
1911    ULong branch_offset;
1912    IRTemp t0;
1913 
1914    if (link) {  /* LR (GPR31) = addr of the instr after branch instr */
1915       if (mode64)
1916          putIReg(31, mkU64(guest_PC_curr_instr + 4));
1917       else
1918          putIReg(31, mkU32(guest_PC_curr_instr + 4));
1919       dres->jk_StopHere = Ijk_Call;
1920    } else {
1921       dres->jk_StopHere = Ijk_Boring;
1922    }
1923 
1924    dres->whatNext = Dis_StopHere;
1925 
1926    /* PC = PC + (SignExtend(signed_immed_24) << 2)
1927       An 18-bit signed offset (the 16-bit offset field shifted left 2 bits)
1928       is added to the address of the instruction following
1929       the branch (not the branch itself), in the branch delay slot, to form
1930       a PC-relative effective target address. */
1931 
1932    if (mode64)
1933       branch_offset = extend_s_18to64(imm << 2);
1934    else
1935       branch_offset = extend_s_18to32(imm << 2);
1936 
1937    t0 = newTemp(Ity_I1);
1938    assign(t0, guard);
1939 
1940    if (mode64) {
1941       stmt(IRStmt_Exit(mkexpr(t0), link ? Ijk_Call : Ijk_Boring,
1942                          IRConst_U64(guest_PC_curr_instr + 4 + branch_offset),
1943                          OFFB_PC));
1944       putPC(mkU64(guest_PC_curr_instr + 4));
1945    } else {
1946       stmt(IRStmt_Exit(mkexpr(t0), link ? Ijk_Call : Ijk_Boring,
1947                          IRConst_U32(guest_PC_curr_instr + 4 +
1948                                      (UInt) branch_offset), OFFB_PC));
1949       putPC(mkU32(guest_PC_curr_instr + 4));
1950    }
1951 }
1952 
getFReg(UInt fregNo)1953 static IRExpr *getFReg(UInt fregNo)
1954 {
1955    vassert(fregNo < 32);
1956    IRType ty = fp_mode64 ? Ity_F64 : Ity_F32;
1957    return IRExpr_Get(floatGuestRegOffset(fregNo), ty);
1958 }
1959 
getDReg(UInt dregNo)1960 static IRExpr *getDReg(UInt dregNo)
1961 {
1962    vassert(dregNo < 32);
1963    if (fp_mode64) {
1964       return IRExpr_Get(floatGuestRegOffset(dregNo), Ity_F64);
1965    } else {
1966       /* Read a floating point register pair and combine their contents into a
1967          64-bit value */
1968       IRTemp t0 = newTemp(Ity_F32);
1969       IRTemp t1 = newTemp(Ity_F32);
1970       IRTemp t2 = newTemp(Ity_F64);
1971       IRTemp t3 = newTemp(Ity_I32);
1972       IRTemp t4 = newTemp(Ity_I32);
1973       IRTemp t5 = newTemp(Ity_I64);
1974 
1975       assign(t0, getFReg(dregNo & (~1)));
1976       assign(t1, getFReg(dregNo | 1));
1977 
1978       assign(t3, unop(Iop_ReinterpF32asI32, mkexpr(t0)));
1979       assign(t4, unop(Iop_ReinterpF32asI32, mkexpr(t1)));
1980       assign(t5, binop(Iop_32HLto64, mkexpr(t4), mkexpr(t3)));
1981       assign(t2, unop(Iop_ReinterpI64asF64, mkexpr(t5)));
1982 
1983       return mkexpr(t2);
1984    }
1985 }
1986 
putFReg(UInt dregNo,IRExpr * e)1987 static void putFReg(UInt dregNo, IRExpr * e)
1988 {
1989    vassert(dregNo < 32);
1990    IRType ty = fp_mode64 ? Ity_F64 : Ity_F32;
1991    vassert(typeOfIRExpr(irsb->tyenv, e) == ty);
1992 
1993    if (fp_mode64_fre) {
1994       IRTemp t0 = newTemp(Ity_F32);
1995       assign(t0, getLoFromF64(ty, e));
1996 #if defined (_MIPSEL)
1997       stmt(IRStmt_Put(floatGuestRegOffset(dregNo), mkexpr(t0)));
1998       if (dregNo & 1)
1999          stmt(IRStmt_Put(floatGuestRegOffset(dregNo) - 4, mkexpr(t0)));
2000 #else
2001       stmt(IRStmt_Put(floatGuestRegOffset(dregNo) + 4, mkexpr(t0)));
2002       if (dregNo & 1)
2003          stmt(IRStmt_Put(floatGuestRegOffset(dregNo & (~1)), mkexpr(t0)));
2004 #endif
2005    } else {
2006       stmt(IRStmt_Put(floatGuestRegOffset(dregNo), e));
2007    }
2008 
2009    if (has_msa && fp_mode64) {
2010       stmt(IRStmt_Put(msaGuestRegOffset(dregNo),
2011            binop(Iop_64HLtoV128,
2012                     unop(Iop_ReinterpF64asI64, e),
2013                     unop(Iop_ReinterpF64asI64, e))));
2014    }
2015 }
2016 
putDReg(UInt dregNo,IRExpr * e)2017 static void putDReg(UInt dregNo, IRExpr * e)
2018 {
2019    if (fp_mode64) {
2020       vassert(dregNo < 32);
2021       IRType ty = Ity_F64;
2022       vassert(typeOfIRExpr(irsb->tyenv, e) == ty);
2023       stmt(IRStmt_Put(floatGuestRegOffset(dregNo), e));
2024       if (fp_mode64_fre) {
2025          IRTemp t0 = newTemp(Ity_F32);
2026          if (dregNo & 1) {
2027             assign(t0, getLoFromF64(ty, e));
2028 #if defined (_MIPSEL)
2029             stmt(IRStmt_Put(floatGuestRegOffset(dregNo) - 4, mkexpr(t0)));
2030 #else
2031             stmt(IRStmt_Put(floatGuestRegOffset(dregNo & (~1)), mkexpr(t0)));
2032 #endif
2033          } else {
2034             assign(t0, getHiFromF64(e));
2035 #if defined (_MIPSEL)
2036             stmt(IRStmt_Put(floatGuestRegOffset(dregNo | 1), mkexpr(t0)));
2037 #else
2038             stmt(IRStmt_Put(floatGuestRegOffset(dregNo | 1) + 4, mkexpr(t0)));
2039 #endif
2040          }
2041       }
2042       if (has_msa)
2043          stmt(IRStmt_Put(msaGuestRegOffset(dregNo),
2044               binop(Iop_64HLtoV128,
2045                     unop(Iop_ReinterpF64asI64, e),
2046                     unop(Iop_ReinterpF64asI64, e))));
2047    } else {
2048       vassert(dregNo < 32);
2049       vassert(typeOfIRExpr(irsb->tyenv, e) == Ity_F64);
2050       IRTemp t1 = newTemp(Ity_F64);
2051       IRTemp t4 = newTemp(Ity_I32);
2052       IRTemp t5 = newTemp(Ity_I32);
2053       IRTemp t6 = newTemp(Ity_I64);
2054       assign(t1, e);
2055       assign(t6, unop(Iop_ReinterpF64asI64, mkexpr(t1)));
2056       assign(t4, unop(Iop_64HIto32, mkexpr(t6)));  /* hi */
2057       assign(t5, unop(Iop_64to32, mkexpr(t6)));    /* lo */
2058       putFReg(dregNo & (~1), unop(Iop_ReinterpI32asF32, mkexpr(t5)));
2059       putFReg(dregNo | 1, unop(Iop_ReinterpI32asF32, mkexpr(t4)));
2060    }
2061 }
2062 
setFPUCondCode(IRExpr * e,UInt cc)2063 static void setFPUCondCode(IRExpr * e, UInt cc)
2064 {
2065    if (cc == 0) {
2066       putFCSR(binop(Iop_And32, getFCSR(), mkU32(0xFF7FFFFF)));
2067       putFCSR(binop(Iop_Or32, getFCSR(), binop(Iop_Shl32, e, mkU8(23))));
2068    } else {
2069       putFCSR(binop(Iop_And32, getFCSR(), unop(Iop_Not32,
2070                                binop(Iop_Shl32, mkU32(0x01000000), mkU8(cc)))));
2071       putFCSR(binop(Iop_Or32, getFCSR(), binop(Iop_Shl32, e, mkU8(24 + cc))));
2072    }
2073 }
2074 
get_IR_roundingmode(void)2075 static IRExpr* get_IR_roundingmode ( void )
2076 {
2077 /*
2078    rounding mode | MIPS | IR
2079    ------------------------
2080    to nearest    | 00  | 00
2081    to zero       | 01  | 11
2082    to +infinity  | 10  | 10
2083    to -infinity  | 11  | 01
2084 */
2085    IRTemp rm_MIPS = newTemp(Ity_I32);
2086    /* Last two bits in FCSR are rounding mode. */
2087 
2088    if (mode64)
2089       assign(rm_MIPS, binop(Iop_And32, IRExpr_Get(offsetof(VexGuestMIPS64State,
2090                                        guest_FCSR), Ity_I32), mkU32(3)));
2091    else
2092       assign(rm_MIPS, binop(Iop_And32, IRExpr_Get(offsetof(VexGuestMIPS32State,
2093                                        guest_FCSR), Ity_I32), mkU32(3)));
2094 
2095    /* rm_IR = XOR( rm_MIPS32, (rm_MIPS32 << 1) & 2) */
2096 
2097    return binop(Iop_Xor32, mkexpr(rm_MIPS), binop(Iop_And32,
2098                 binop(Iop_Shl32, mkexpr(rm_MIPS), mkU8(1)), mkU32(2)));
2099 }
2100 
get_IR_roundingmode_MSA(void)2101 static IRExpr* get_IR_roundingmode_MSA ( void ) {
2102    /*
2103       rounding mode | MIPS | IR
2104       ------------------------
2105       to nearest    | 00  | 00
2106       to zero       | 01  | 11
2107       to +infinity  | 10  | 10
2108       to -infinity  | 11  | 01
2109    */
2110    IRTemp rm_MIPS = newTemp(Ity_I32);
2111    /* Last two bits in MSACSR are rounding mode. */
2112 
2113    if (mode64)
2114       assign(rm_MIPS, binop(Iop_And32, IRExpr_Get(offsetof(VexGuestMIPS64State,
2115                             guest_MSACSR), Ity_I32), mkU32(3)));
2116    else
2117       assign(rm_MIPS, binop(Iop_And32, IRExpr_Get(offsetof(VexGuestMIPS32State,
2118                             guest_MSACSR), Ity_I32), mkU32(3)));
2119 
2120    /* rm_IR = XOR( rm_MIPS32, (rm_MIPS32 << 1) & 2) */
2121    return binop(Iop_Xor32, mkexpr(rm_MIPS), binop(Iop_And32,
2122                 binop(Iop_Shl32, mkexpr(rm_MIPS), mkU8(1)), mkU32(2)));
2123 }
2124 
2125 /* sz, ULong -> IRExpr */
mkSzImm(IRType ty,ULong imm64)2126 static IRExpr *mkSzImm ( IRType ty, ULong imm64 )
2127 {
2128    vassert(ty == Ity_I32 || ty == Ity_I64);
2129    return ty == Ity_I64 ? mkU64(imm64) : mkU32((UInt) imm64);
2130 }
2131 
mkSzConst(IRType ty,ULong imm64)2132 static IRConst *mkSzConst ( IRType ty, ULong imm64 )
2133 {
2134    vassert(ty == Ity_I32 || ty == Ity_I64);
2135    return (ty == Ity_I64 ? IRConst_U64(imm64) : IRConst_U32((UInt) imm64));
2136 }
2137 
2138 /* Make sure we get valid 32 and 64bit addresses */
mkSzAddr(IRType ty,Addr64 addr)2139 static Addr64 mkSzAddr ( IRType ty, Addr64 addr )
2140 {
2141    vassert(ty == Ity_I32 || ty == Ity_I64);
2142    return (ty == Ity_I64 ? (Addr64) addr :
2143                            (Addr64) extend_s_32to64(toUInt(addr)));
2144 }
2145 
2146 /* Shift and Rotate instructions for MIPS64 */
dis_instr_shrt(UInt theInstr)2147 static Bool dis_instr_shrt ( UInt theInstr )
2148 {
2149    UInt opc2 = get_function(theInstr);
2150    UChar regRs = get_rs(theInstr);
2151    UChar regRt = get_rt(theInstr);
2152    UChar regRd = get_rd(theInstr);
2153    UChar uImmsa = get_sa(theInstr);
2154    Long sImmsa = extend_s_16to64(uImmsa);
2155    IRType ty = mode64 ? Ity_I64 : Ity_I32;
2156    IRTemp tmp = newTemp(ty);
2157    IRTemp tmpOr = newTemp(ty);
2158    IRTemp tmpRt = newTemp(ty);
2159    IRTemp tmpRs = newTemp(ty);
2160    IRTemp tmpRd = newTemp(ty);
2161 
2162    assign(tmpRs, getIReg(regRs));
2163    assign(tmpRt, getIReg(regRt));
2164 
2165    switch (opc2) {
2166       case 0x3A:
2167          if ((regRs & 0x01) == 0) {
2168             /* Doubleword Shift Right Logical - DSRL; MIPS64 */
2169             DIP("dsrl r%u, r%u, %lld", regRd, regRt, sImmsa);
2170             assign(tmpRd, binop(Iop_Shr64, mkexpr(tmpRt), mkU8(uImmsa)));
2171             putIReg(regRd, mkexpr(tmpRd));
2172          } else if ((regRs & 0x01) == 1) {
2173             /* Doubleword Rotate Right - DROTR; MIPS64r2 */
2174             vassert(mode64);
2175             DIP("drotr r%u, r%u, %lld", regRd, regRt, sImmsa);
2176             IRTemp tmpL = newTemp(ty);
2177             IRTemp tmpR = newTemp(ty);
2178             assign(tmpR, binop(Iop_Shr64, mkexpr(tmpRt), mkU8(uImmsa)));
2179             assign(tmp, binop(Iop_Shl64, mkexpr(tmpRt), mkU8(63 - uImmsa)));
2180             assign(tmpL, binop(Iop_Shl64, mkexpr(tmp), mkU8(1)));
2181             assign(tmpRd, binop(Iop_Or64, mkexpr(tmpL), mkexpr(tmpR)));
2182             putIReg(regRd, mkexpr(tmpRd));
2183          } else
2184             return False;
2185          break;
2186 
2187       case 0x3E:
2188          if ((regRs & 0x01) == 0) {
2189             /* Doubleword Shift Right Logical Plus 32 - DSRL32; MIPS64 */
2190             DIP("dsrl32 r%u, r%u, %lld", regRd, regRt, sImmsa + 32);
2191             assign(tmpRd, binop(Iop_Shr64, mkexpr(tmpRt), mkU8(uImmsa + 32)));
2192             putIReg(regRd, mkexpr(tmpRd));
2193          } else if ((regRs & 0x01) == 1) {
2194             /* Doubleword Rotate Right Plus 32 - DROTR32; MIPS64r2 */
2195             DIP("drotr32 r%u, r%u, %lld", regRd, regRt, sImmsa);
2196             vassert(mode64);
2197             IRTemp tmpL = newTemp(ty);
2198             IRTemp tmpR = newTemp(ty);
2199             /* (tmpRt >> sa) | (tmpRt << (64 - sa)) */
2200             assign(tmpR, binop(Iop_Shr64, mkexpr(tmpRt), mkU8(uImmsa + 32)));
2201             assign(tmp, binop(Iop_Shl64, mkexpr(tmpRt),
2202                               mkU8(63 - (uImmsa + 32))));
2203             assign(tmpL, binop(Iop_Shl64, mkexpr(tmp), mkU8(1)));
2204             assign(tmpRd, binop(Iop_Or64, mkexpr(tmpL), mkexpr(tmpR)));
2205             putIReg(regRd, mkexpr(tmpRd));
2206          } else
2207             return False;
2208          break;
2209 
2210       case 0x16:
2211          if ((uImmsa & 0x01) == 0) {
2212             /* Doubleword Shift Right Logical Variable - DSRLV; MIPS64 */
2213             DIP("dsrlv r%u, r%u, r%u", regRd, regRt, regRs);
2214             IRTemp tmpRs8 = newTemp(Ity_I8);
2215             /* s = tmpRs[5..0] */
2216             assign(tmp, binop(Iop_And64, mkexpr(tmpRs), mkU64(63)));
2217             assign(tmpRs8, mkNarrowTo8(ty, mkexpr(tmp)));
2218             assign(tmpRd, binop(Iop_Shr64, mkexpr(tmpRt), mkexpr(tmpRs8)));
2219             putIReg(regRd, mkexpr(tmpRd));
2220          } else if ((uImmsa & 0x01) == 1) {
2221             /* Doubleword Rotate Right Variable - DROTRV; MIPS64r2 */
2222             DIP("drotrv r%u, r%u, r%u", regRd, regRt, regRs);
2223             IRTemp tmpL = newTemp(ty);
2224             IRTemp tmpR = newTemp(ty);
2225             IRTemp tmpRs8 = newTemp(Ity_I8);
2226             IRTemp tmpLs8 = newTemp(Ity_I8);
2227             IRTemp tmp64 = newTemp(ty);
2228             /* s = tmpRs[5...0]
2229                m = 64 - s
2230                (tmpRt << s) | (tmpRt >> m) */
2231 
2232             assign(tmp64, binop(Iop_And64, mkexpr(tmpRs), mkSzImm(ty, 63)));
2233             assign(tmp, binop(Iop_Sub64, mkU64(63), mkexpr(tmp64)));
2234 
2235             assign(tmpLs8, mkNarrowTo8(ty, mkexpr(tmp)));
2236             assign(tmpRs8, mkNarrowTo8(ty, mkexpr(tmp64)));
2237 
2238             assign(tmpR, binop(Iop_Shr64, mkexpr(tmpRt), mkexpr(tmpRs8)));
2239             assign(tmpL, binop(Iop_Shl64, mkexpr(tmpRt), mkexpr(tmpLs8)));
2240             assign(tmpRd, binop(Iop_Shl64, mkexpr(tmpL), mkU8(1)));
2241             assign(tmpOr, binop(Iop_Or64, mkexpr(tmpRd), mkexpr(tmpR)));
2242 
2243             putIReg(regRd, mkexpr(tmpOr));
2244          } else
2245             return False;
2246          break;
2247 
2248       case 0x38:  /* Doubleword Shift Left Logical - DSLL; MIPS64 */
2249          DIP("dsll r%u, r%u, %lld", regRd, regRt, sImmsa);
2250          vassert(mode64);
2251          assign(tmpRd, binop(Iop_Shl64, mkexpr(tmpRt), mkU8(uImmsa)));
2252          putIReg(regRd, mkexpr(tmpRd));
2253          break;
2254 
2255       case 0x3C:  /* Doubleword Shift Left Logical Plus 32 - DSLL32; MIPS64 */
2256          DIP("dsll32 r%u, r%u, %lld", regRd, regRt, sImmsa);
2257          assign(tmpRd, binop(Iop_Shl64, mkexpr(tmpRt), mkU8(uImmsa + 32)));
2258          putIReg(regRd, mkexpr(tmpRd));
2259          break;
2260 
2261       case 0x14: {  /* Doubleword Shift Left Logical Variable - DSLLV; MIPS64 */
2262          DIP("dsllv r%u, r%u, r%u", regRd, regRt, regRs);
2263          IRTemp tmpRs8 = newTemp(Ity_I8);
2264 
2265          assign(tmp, binop(Iop_And64, mkexpr(tmpRs), mkSzImm(ty, 63)));
2266          assign(tmpRs8, mkNarrowTo8(ty, mkexpr(tmp)));
2267          assign(tmpRd, binop(Iop_Shl64, mkexpr(tmpRt), mkexpr(tmpRs8)));
2268          putIReg(regRd, mkexpr(tmpRd));
2269          break;
2270       }
2271 
2272       case 0x3B:  /* Doubleword Shift Right Arithmetic - DSRA; MIPS64 */
2273          DIP("dsra r%u, r%u, %lld", regRd, regRt, sImmsa);
2274          assign(tmpRd, binop(Iop_Sar64, mkexpr(tmpRt), mkU8(uImmsa)));
2275          putIReg(regRd, mkexpr(tmpRd));
2276          break;
2277 
2278       case 0x3F:  /* Doubleword Shift Right Arithmetic Plus 32 - DSRA32;
2279                      MIPS64 */
2280          DIP("dsra32 r%u, r%u, %lld", regRd, regRt, sImmsa);
2281          assign(tmpRd, binop(Iop_Sar64, mkexpr(tmpRt), mkU8(uImmsa + 32)));
2282          putIReg(regRd, mkexpr(tmpRd));
2283          break;
2284 
2285       case 0x17: {  /* Doubleword Shift Right Arithmetic Variable - DSRAV;
2286                        MIPS64 */
2287          DIP("dsrav r%u, r%u, r%u", regRd, regRt, regRs);
2288          IRTemp tmpRs8 = newTemp(Ity_I8);
2289          assign(tmp, binop(Iop_And64, mkexpr(tmpRs), mkSzImm(ty, 63)));
2290          assign(tmpRs8, mkNarrowTo8(ty, mkexpr(tmp)));
2291          assign(tmpRd, binop(Iop_Sar64, mkexpr(tmpRt), mkexpr(tmpRs8)));
2292          putIReg(regRd, mkexpr(tmpRd));
2293          break;
2294 
2295       }
2296 
2297       default:
2298          return False;
2299 
2300    }
2301    return True;
2302 }
2303 
mkSzOp(IRType ty,IROp op8)2304 static IROp mkSzOp ( IRType ty, IROp op8 )
2305 {
2306    Int adj;
2307    vassert(ty == Ity_I8 || ty == Ity_I16 || ty == Ity_I32 || ty == Ity_I64);
2308    vassert(op8 == Iop_Add8 || op8 == Iop_Sub8 || op8 == Iop_Mul8
2309            || op8 == Iop_Or8 || op8 == Iop_And8 || op8 == Iop_Xor8
2310            || op8 == Iop_Shl8 || op8 == Iop_Shr8 || op8 == Iop_Sar8
2311            || op8 == Iop_CmpEQ8 || op8 == Iop_CmpNE8 || op8 == Iop_Not8);
2312    adj = ty == Ity_I8 ? 0 : (ty == Ity_I16 ? 1 : (ty == Ity_I32 ? 2 : 3));
2313    return adj + op8;
2314 }
2315 
2316 /*********************************************************/
2317 /*---             Floating Point Compare              ---*/
2318 /*********************************************************/
2319 /* Function that returns a string that represent mips cond
2320    mnemonic for the input code. */
showCondCode(UInt code)2321 static const HChar* showCondCode(UInt code) {
2322    const HChar* ret;
2323    switch (code) {
2324       case 0: ret = "f"; break;
2325       case 1: ret = "un"; break;
2326       case 2: ret = "eq"; break;
2327       case 3: ret = "ueq"; break;
2328       case 4: ret = "olt"; break;
2329       case 5: ret = "ult"; break;
2330       case 6: ret = "ole"; break;
2331       case 7: ret = "ule"; break;
2332       case 8: ret = "sf"; break;
2333       case 9: ret = "ngle"; break;
2334       case 10: ret = "seq"; break;
2335       case 11: ret = "ngl"; break;
2336       case 12: ret = "lt"; break;
2337       case 13: ret = "nge"; break;
2338       case 14: ret = "le"; break;
2339       case 15: ret = "ngt"; break;
2340       default: vpanic("showCondCode"); break;
2341    }
2342    return ret;
2343 }
2344 
dis_instr_CCondFmt(UInt cins)2345 static Bool dis_instr_CCondFmt ( UInt cins )
2346 {
2347    IRTemp t0, t1, t2, t3, tmp5, tmp6;
2348    IRTemp ccIR = newTemp(Ity_I32);
2349    IRTemp ccMIPS = newTemp(Ity_I32);
2350    UInt FC = get_FC(cins);
2351    UInt fmt = get_fmt(cins);
2352    UInt fs = get_fs(cins);
2353    UInt ft = get_ft(cins);
2354    UInt cond = get_cond(cins);
2355 
2356    if (FC == 0x3) {  /* C.cond.fmt */
2357       UInt fpc_cc = get_fpc_cc(cins);
2358       switch (fmt) {
2359          case 0x10: {  /* C.cond.S */
2360             DIP("c.%s.s %u, f%u, f%u", showCondCode(cond), fpc_cc, fs, ft);
2361             if (fp_mode64) {
2362                t0 = newTemp(Ity_I32);
2363                t1 = newTemp(Ity_I32);
2364                t2 = newTemp(Ity_I32);
2365                t3 = newTemp(Ity_I32);
2366 
2367                tmp5 = newTemp(Ity_F64);
2368                tmp6 = newTemp(Ity_F64);
2369 
2370                assign(tmp5, unop(Iop_F32toF64, getLoFromF64(Ity_F64,
2371                                  getFReg(fs))));
2372                assign(tmp6, unop(Iop_F32toF64, getLoFromF64(Ity_F64,
2373                                  getFReg(ft))));
2374 
2375                assign(ccIR, binop(Iop_CmpF64, mkexpr(tmp5), mkexpr(tmp6)));
2376                putHI(mkWidenFrom32(mode64 ? Ity_I64: Ity_I32,
2377                                    mkexpr(ccIR), True));
2378                /* Map compare result from IR to MIPS
2379                   FP cmp result | MIPS | IR
2380                   --------------------------
2381                   UN            | 0x1 | 0x45
2382                   EQ            | 0x2 | 0x40
2383                   GT            | 0x4 | 0x00
2384                   LT            | 0x8 | 0x01
2385                 */
2386 
2387                /* ccMIPS = Shl(1, (~(ccIR>>5) & 2) | ((ccIR ^ (ccIR>>6)) & 1) */
2388                assign(ccMIPS, binop(Iop_Shl32, mkU32(1), unop(Iop_32to8,
2389                               binop(Iop_Or32, binop(Iop_And32, unop(Iop_Not32,
2390                               binop(Iop_Shr32, mkexpr(ccIR),mkU8(5))),mkU32(2)),
2391                               binop(Iop_And32, binop(Iop_Xor32, mkexpr(ccIR),
2392                               binop(Iop_Shr32, mkexpr(ccIR), mkU8(6))),
2393                               mkU32(1))))));
2394                putLO(mkWidenFrom32(mode64 ? Ity_I64: Ity_I32,
2395                                    mkexpr(ccMIPS), True));
2396 
2397                /* UN */
2398                assign(t0, binop(Iop_And32, mkexpr(ccMIPS), mkU32(0x1)));
2399                /* EQ */
2400                assign(t1, binop(Iop_And32, binop(Iop_Shr32, mkexpr(ccMIPS),
2401                                                  mkU8(0x1)), mkU32(0x1)));
2402                /* NGT */
2403                assign(t2, binop(Iop_And32, unop(Iop_Not32, binop(Iop_Shr32,
2404                                  mkexpr(ccMIPS), mkU8(0x2))),mkU32(0x1)));
2405                /* LT */
2406                assign(t3, binop(Iop_And32, binop(Iop_Shr32, mkexpr(ccMIPS),
2407                                                  mkU8(0x3)), mkU32(0x1)));
2408                switch (cond) {
2409                   case 0x0:
2410                      setFPUCondCode(mkU32(0), fpc_cc);
2411                      break;
2412                   case 0x1:
2413                      setFPUCondCode(mkexpr(t0), fpc_cc);
2414                      break;
2415                   case 0x2:
2416                      setFPUCondCode(mkexpr(t1), fpc_cc);
2417                      break;
2418                   case 0x3:
2419                      setFPUCondCode(binop(Iop_Or32, mkexpr(t0), mkexpr(t1)),
2420                                           fpc_cc);
2421                      break;
2422                   case 0x4:
2423                      setFPUCondCode(mkexpr(t3), fpc_cc);
2424                      break;
2425                   case 0x5:
2426                      setFPUCondCode(binop(Iop_Or32, mkexpr(t0), mkexpr(t3)),
2427                                           fpc_cc);
2428                      break;
2429                   case 0x6:
2430                      setFPUCondCode(binop(Iop_Or32, mkexpr(t3), mkexpr(t1)),
2431                                           fpc_cc);
2432                      break;
2433                   case 0x7:
2434                      setFPUCondCode(mkexpr(t2), fpc_cc);
2435                      break;
2436                   case 0x8:
2437                      setFPUCondCode(mkU32(0), fpc_cc);
2438                      break;
2439                   case 0x9:
2440                      setFPUCondCode(mkexpr(t0), fpc_cc);
2441                      break;
2442                   case 0xA:
2443                      setFPUCondCode(mkexpr(t1), fpc_cc);
2444                      break;
2445                   case 0xB:
2446                      setFPUCondCode(binop(Iop_Or32, mkexpr(t0), mkexpr(t1)),
2447                                           fpc_cc);
2448                      break;
2449                   case 0xC:
2450                      setFPUCondCode(mkexpr(t3), fpc_cc);
2451                      break;
2452                   case 0xD:
2453                      setFPUCondCode(binop(Iop_Or32, mkexpr(t0), mkexpr(t3)),
2454                                           fpc_cc);
2455                      break;
2456                   case 0xE:
2457                      setFPUCondCode(binop(Iop_Or32, mkexpr(t3), mkexpr(t1)),
2458                                           fpc_cc);
2459                      break;
2460                   case 0xF:
2461                      setFPUCondCode(mkexpr(t2), fpc_cc);
2462                      break;
2463 
2464                   default:
2465                      return False;
2466                }
2467 
2468             } else {
2469                t0 = newTemp(Ity_I32);
2470                t1 = newTemp(Ity_I32);
2471                t2 = newTemp(Ity_I32);
2472                t3 = newTemp(Ity_I32);
2473 
2474                assign(ccIR, binop(Iop_CmpF64, unop(Iop_F32toF64, getFReg(fs)),
2475                                   unop(Iop_F32toF64, getFReg(ft))));
2476                /* Map compare result from IR to MIPS
2477                   FP cmp result | MIPS | IR
2478                   --------------------------
2479                   UN            | 0x1 | 0x45
2480                   EQ            | 0x2 | 0x40
2481                   GT            | 0x4 | 0x00
2482                   LT            | 0x8 | 0x01
2483                 */
2484 
2485                /* ccMIPS = Shl(1, (~(ccIR>>5) & 2) | ((ccIR ^ (ccIR>>6)) & 1) */
2486                assign(ccMIPS, binop(Iop_Shl32, mkU32(1), unop(Iop_32to8,
2487                               binop(Iop_Or32, binop(Iop_And32, unop(Iop_Not32,
2488                               binop(Iop_Shr32, mkexpr(ccIR), mkU8(5))),
2489                                     mkU32(2)), binop(Iop_And32,
2490                               binop(Iop_Xor32, mkexpr(ccIR),
2491                               binop(Iop_Shr32, mkexpr(ccIR), mkU8(6))),
2492                               mkU32(1))))));
2493                /* UN */
2494                assign(t0, binop(Iop_And32, mkexpr(ccMIPS), mkU32(0x1)));
2495                /* EQ */
2496                assign(t1, binop(Iop_And32, binop(Iop_Shr32, mkexpr(ccMIPS),
2497                       mkU8(0x1)), mkU32(0x1)));
2498                /* NGT */
2499                assign(t2, binop(Iop_And32, unop(Iop_Not32, binop(Iop_Shr32,
2500                       mkexpr(ccMIPS), mkU8(0x2))), mkU32(0x1)));
2501                /* LT */
2502                assign(t3, binop(Iop_And32, binop(Iop_Shr32, mkexpr(ccMIPS),
2503                       mkU8(0x3)), mkU32(0x1)));
2504 
2505                switch (cond) {
2506                   case 0x0:
2507                      setFPUCondCode(mkU32(0), fpc_cc);
2508                      break;
2509                   case 0x1:
2510                      setFPUCondCode(mkexpr(t0), fpc_cc);
2511                      break;
2512                   case 0x2:
2513                      setFPUCondCode(mkexpr(t1), fpc_cc);
2514                      break;
2515                   case 0x3:
2516                      setFPUCondCode(binop(Iop_Or32, mkexpr(t0), mkexpr(t1)),
2517                                           fpc_cc);
2518                      break;
2519                   case 0x4:
2520                      setFPUCondCode(mkexpr(t3), fpc_cc);
2521                      break;
2522                   case 0x5:
2523                      setFPUCondCode(binop(Iop_Or32, mkexpr(t0), mkexpr(t3)),
2524                                           fpc_cc);
2525                      break;
2526                   case 0x6:
2527                      setFPUCondCode(binop(Iop_Or32, mkexpr(t3), mkexpr(t1)),
2528                                           fpc_cc);
2529                      break;
2530                   case 0x7:
2531                      setFPUCondCode(mkexpr(t2), fpc_cc);
2532                      break;
2533                   case 0x8:
2534                      setFPUCondCode(mkU32(0), fpc_cc);
2535                      break;
2536                   case 0x9:
2537                      setFPUCondCode(mkexpr(t0), fpc_cc);
2538                      break;
2539                   case 0xA:
2540                      setFPUCondCode(mkexpr(t1), fpc_cc);
2541                      break;
2542                   case 0xB:
2543                      setFPUCondCode(binop(Iop_Or32, mkexpr(t0), mkexpr(t1)),
2544                                           fpc_cc);
2545                      break;
2546                   case 0xC:
2547                      setFPUCondCode(mkexpr(t3), fpc_cc);
2548                      break;
2549                   case 0xD:
2550                      setFPUCondCode(binop(Iop_Or32, mkexpr(t0), mkexpr(t3)),
2551                                           fpc_cc);
2552                      break;
2553                   case 0xE:
2554                      setFPUCondCode(binop(Iop_Or32, mkexpr(t3), mkexpr(t1)),
2555                                           fpc_cc);
2556                      break;
2557                   case 0xF:
2558                      setFPUCondCode(mkexpr(t2), fpc_cc);
2559                      break;
2560 
2561                   default:
2562                      return False;
2563                }
2564             }
2565          }
2566             break;
2567 
2568          case 0x11: {  /* C.cond.D */
2569             DIP("c.%s.d %u, f%u, f%u", showCondCode(cond), fpc_cc, fs, ft);
2570             t0 = newTemp(Ity_I32);
2571             t1 = newTemp(Ity_I32);
2572             t2 = newTemp(Ity_I32);
2573             t3 = newTemp(Ity_I32);
2574             assign(ccIR, binop(Iop_CmpF64, getDReg(fs), getDReg(ft)));
2575             /* Map compare result from IR to MIPS
2576                FP cmp result | MIPS | IR
2577                --------------------------
2578                UN            | 0x1 | 0x45
2579                EQ            | 0x2 | 0x40
2580                GT            | 0x4 | 0x00
2581                LT            | 0x8 | 0x01
2582              */
2583 
2584             /* ccMIPS = Shl(1, (~(ccIR>>5) & 2) | ((ccIR ^ (ccIR>>6)) & 1) */
2585             assign(ccMIPS, binop(Iop_Shl32, mkU32(1), unop(Iop_32to8,
2586                            binop(Iop_Or32, binop(Iop_And32, unop(Iop_Not32,
2587                            binop(Iop_Shr32, mkexpr(ccIR), mkU8(5))), mkU32(2)),
2588                            binop(Iop_And32, binop(Iop_Xor32, mkexpr(ccIR),
2589                            binop(Iop_Shr32, mkexpr(ccIR), mkU8(6))),
2590                            mkU32(1))))));
2591 
2592             /* UN */
2593             assign(t0, binop(Iop_And32, mkexpr(ccMIPS), mkU32(0x1)));
2594             /* EQ */
2595             assign(t1, binop(Iop_And32, binop(Iop_Shr32, mkexpr(ccMIPS),
2596                    mkU8(0x1)), mkU32(0x1)));
2597             /* NGT */
2598             assign(t2, binop(Iop_And32, unop(Iop_Not32, binop(Iop_Shr32,
2599                    mkexpr(ccMIPS), mkU8(0x2))), mkU32(0x1)));
2600             /* LT */
2601             assign(t3, binop(Iop_And32, binop(Iop_Shr32, mkexpr(ccMIPS),
2602                    mkU8(0x3)), mkU32(0x1)));
2603 
2604             switch (cond) {
2605                case 0x0:
2606                   setFPUCondCode(mkU32(0), fpc_cc);
2607                   break;
2608                case 0x1:
2609                   setFPUCondCode(mkexpr(t0), fpc_cc);
2610                   break;
2611                case 0x2:
2612                   setFPUCondCode(mkexpr(t1), fpc_cc);
2613                   break;
2614                case 0x3:
2615                   setFPUCondCode(binop(Iop_Or32, mkexpr(t0), mkexpr(t1)),
2616                                        fpc_cc);
2617                   break;
2618                case 0x4:
2619                   setFPUCondCode(mkexpr(t3), fpc_cc);
2620                   break;
2621                case 0x5:
2622                   setFPUCondCode(binop(Iop_Or32, mkexpr(t0), mkexpr(t3)),
2623                                        fpc_cc);
2624                   break;
2625                case 0x6:
2626                   setFPUCondCode(binop(Iop_Or32, mkexpr(t3), mkexpr(t1)),
2627                                        fpc_cc);
2628                   break;
2629                case 0x7:
2630                   setFPUCondCode(mkexpr(t2), fpc_cc);
2631                   break;
2632                case 0x8:
2633                   setFPUCondCode(mkU32(0), fpc_cc);
2634                   break;
2635                case 0x9:
2636                   setFPUCondCode(mkexpr(t0), fpc_cc);
2637                   break;
2638                case 0xA:
2639                   setFPUCondCode(mkexpr(t1), fpc_cc);
2640                   break;
2641                case 0xB:
2642                   setFPUCondCode(binop(Iop_Or32, mkexpr(t0), mkexpr(t1)),
2643                                        fpc_cc);
2644                   break;
2645                case 0xC:
2646                   setFPUCondCode(mkexpr(t3), fpc_cc);
2647                   break;
2648                case 0xD:
2649                   setFPUCondCode(binop(Iop_Or32, mkexpr(t0), mkexpr(t3)),
2650                                        fpc_cc);
2651                   break;
2652                case 0xE:
2653                   setFPUCondCode(binop(Iop_Or32, mkexpr(t3), mkexpr(t1)),
2654                                        fpc_cc);
2655                   break;
2656                case 0xF:
2657                   setFPUCondCode(mkexpr(t2), fpc_cc);
2658                   break;
2659                default:
2660                   return False;
2661             }
2662          }
2663          break;
2664 
2665          default:
2666             return False;
2667       }
2668    } else {
2669       return False;
2670    }
2671 
2672    return True;
2673 }
2674 
2675 /*********************************************************/
2676 /*---        Branch Instructions for mips64           ---*/
2677 /*********************************************************/
dis_instr_branch(UInt theInstr,DisResult * dres,Bool (* resteerOkFn)(void *,Addr),void * callback_opaque,IRStmt ** set)2678 static Bool dis_instr_branch ( UInt theInstr, DisResult * dres,
2679                                Bool(*resteerOkFn) (void *, Addr),
2680                                void *callback_opaque, IRStmt ** set )
2681 {
2682    UInt jmpKind = 0;
2683    UChar opc1 = get_opcode(theInstr);
2684    UChar regRs = get_rs(theInstr);
2685    UChar regRt = get_rt(theInstr);
2686    UInt offset = get_imm(theInstr);
2687    Long sOffset = extend_s_16to64(offset);
2688    IRType ty = mode64 ? Ity_I64 : Ity_I32;
2689    IROp opSlt = mode64 ? Iop_CmpLT64S : Iop_CmpLT32S;
2690 
2691    IRTemp tmp = newTemp(ty);
2692    IRTemp tmpRs = newTemp(ty);
2693    IRTemp tmpRt = newTemp(ty);
2694    IRTemp tmpLt = newTemp(ty);
2695    IRTemp tmpReg0 = newTemp(ty);
2696 
2697    UChar regLnk = 31;   /* reg 31 is link reg in MIPS */
2698    Addr64 addrTgt = 0;
2699    Addr64 cia = guest_PC_curr_instr;
2700 
2701    IRExpr *eConst0 = mkSzImm(ty, (UInt) 0);
2702    IRExpr *eNia = mkSzImm(ty, cia + 8);
2703    IRExpr *eCond = NULL;
2704 
2705    assign(tmpRs, getIReg(regRs));
2706    assign(tmpRt, getIReg(regRt));
2707    assign(tmpReg0, getIReg(0));
2708 
2709    eCond = binop(mkSzOp(ty, Iop_CmpNE8), mkexpr(tmpReg0), mkexpr(tmpReg0));
2710 
2711    switch (opc1) {
2712       case 0x01:
2713          switch (regRt) {
2714             case 0x00: {  /* BLTZ rs, offset */
2715                addrTgt = mkSzAddr(ty, cia + 4 + (sOffset << 2));
2716                IRTemp tmpLtRes = newTemp(Ity_I1);
2717 
2718                assign(tmp, eConst0);
2719                assign(tmpLtRes, binop(opSlt, mkexpr(tmpRs), mkexpr(tmp)));
2720                assign(tmpLt, mode64 ? unop(Iop_1Uto64, mkexpr(tmpLtRes)) :
2721                       unop(Iop_1Uto32, mkexpr(tmpLtRes)));
2722 
2723                eCond = binop(mkSzOp(ty, Iop_CmpNE8), mkexpr(tmpLt),
2724                              mkexpr(tmpReg0));
2725 
2726                jmpKind = Ijk_Boring;
2727                break;
2728             }
2729 
2730             case 0x01: {  /* BGEZ rs, offset */
2731                IRTemp tmpLtRes = newTemp(Ity_I1);
2732                addrTgt = mkSzAddr(ty, cia + 4 + (sOffset << 2));
2733 
2734                assign(tmp, eConst0);
2735                assign(tmpLtRes, binop(opSlt, mkexpr(tmpRs), mkexpr(tmp)));
2736                assign(tmpLt, mode64 ? unop(Iop_1Uto64, mkexpr(tmpLtRes)) :
2737                                       unop(Iop_1Uto32, mkexpr(tmpLtRes)));
2738                eCond = binop(mkSzOp(ty, Iop_CmpEQ8), mkexpr(tmpLt),
2739                                     mkexpr(tmpReg0));
2740 
2741                jmpKind = Ijk_Boring;
2742                break;
2743             }
2744 
2745             case 0x11: {  /* BGEZAL rs, offset */
2746                addrTgt = mkSzAddr(ty, cia + 4 + (sOffset << 2));
2747                putIReg(regLnk, eNia);
2748                IRTemp tmpLtRes = newTemp(Ity_I1);
2749 
2750                assign(tmpLtRes, binop(opSlt, mkexpr(tmpRs), eConst0));
2751                assign(tmpLt, mode64 ? unop(Iop_1Uto64, mkexpr(tmpLtRes)) :
2752                                       unop(Iop_1Uto32, mkexpr(tmpLtRes)));
2753 
2754                eCond = binop(mkSzOp(ty, Iop_CmpEQ8), mkexpr(tmpLt),
2755                                     mkexpr(tmpReg0));
2756 
2757                jmpKind = Ijk_Call;
2758                break;
2759             }
2760 
2761             case 0x10: {  /* BLTZAL rs, offset */
2762                IRTemp tmpLtRes = newTemp(Ity_I1);
2763                IRTemp tmpRes = newTemp(ty);
2764 
2765                addrTgt = mkSzAddr(ty, cia + 4 + (sOffset << 2));
2766                putIReg(regLnk, eNia);
2767 
2768                assign(tmp, eConst0);
2769                assign(tmpLtRes, binop(opSlt, mkexpr(tmpRs), mkexpr(tmp)));
2770                assign(tmpRes, mode64 ? unop(Iop_1Uto64,
2771                       mkexpr(tmpLtRes)) : unop(Iop_1Uto32, mkexpr(tmpLtRes)));
2772                eCond = binop(mkSzOp(ty, Iop_CmpNE8), mkexpr(tmpRes),
2773                                                      mkexpr(tmpReg0));
2774 
2775                jmpKind = Ijk_Call;
2776                break;
2777             }
2778 
2779          }
2780          break;
2781       default:
2782          return False;
2783       }
2784    *set = IRStmt_Exit(eCond, jmpKind, mkSzConst(ty, addrTgt), OFFB_PC);
2785    return True;
2786 }
2787 
2788 /*********************************************************/
2789 /*---         Cavium Specific Instructions            ---*/
2790 /*********************************************************/
2791 
2792 /* Convenience function to yield to thread scheduler */
jump_back(IRExpr * condition)2793 static void jump_back(IRExpr *condition)
2794 {
2795    stmt( IRStmt_Exit(condition,
2796                      Ijk_Yield,
2797                      IRConst_U64( guest_PC_curr_instr ),
2798                      OFFB_PC) );
2799 }
2800 
2801 /* Based on s390_irgen_load_and_add32. */
mips_load_store32(IRTemp op1addr,IRTemp new_val,IRTemp expd,UChar rd,Bool putIntoRd)2802 static void mips_load_store32(IRTemp op1addr, IRTemp new_val,
2803                               IRTemp expd, UChar rd, Bool putIntoRd)
2804 {
2805    IRCAS *cas;
2806    IRTemp old_mem = newTemp(Ity_I32);
2807    IRType ty      = mode64 ? Ity_I64 : Ity_I32;
2808 
2809    cas = mkIRCAS(IRTemp_INVALID, old_mem,
2810 #if defined (_MIPSEL)
2811                  Iend_LE, mkexpr(op1addr),
2812 #else /* _MIPSEB */
2813                  Iend_BE, mkexpr(op1addr),
2814 #endif
2815                  NULL, mkexpr(expd), /* expected value */
2816                  NULL, mkexpr(new_val)  /* new value */);
2817    stmt(IRStmt_CAS(cas));
2818 
2819    /* If old_mem contains the expected value, then the CAS succeeded.
2820       Otherwise, it did not */
2821    jump_back(binop(Iop_CmpNE32, mkexpr(old_mem), mkexpr(expd)));
2822    if (putIntoRd)
2823       putIReg(rd, mkWidenFrom32(ty, mkexpr(old_mem), True));
2824 }
2825 
2826 /* Based on s390_irgen_load_and_add64. */
mips_load_store64(IRTemp op1addr,IRTemp new_val,IRTemp expd,UChar rd,Bool putIntoRd)2827 static void mips_load_store64(IRTemp op1addr, IRTemp new_val,
2828                               IRTemp expd, UChar rd, Bool putIntoRd)
2829 {
2830    IRCAS *cas;
2831    IRTemp old_mem = newTemp(Ity_I64);
2832    vassert(mode64);
2833    cas = mkIRCAS(IRTemp_INVALID, old_mem,
2834 #if defined (_MIPSEL)
2835                  Iend_LE, mkexpr(op1addr),
2836 #else /* _MIPSEB */
2837                  Iend_BE, mkexpr(op1addr),
2838 #endif
2839                  NULL, mkexpr(expd), /* expected value */
2840                  NULL, mkexpr(new_val)  /* new value */);
2841    stmt(IRStmt_CAS(cas));
2842 
2843    /* If old_mem contains the expected value, then the CAS succeeded.
2844       Otherwise, it did not */
2845    jump_back(binop(Iop_CmpNE64, mkexpr(old_mem), mkexpr(expd)));
2846    if (putIntoRd)
2847       putIReg(rd, mkexpr(old_mem));
2848 }
2849 
dis_instr_CVM(UInt theInstr)2850 static Bool dis_instr_CVM ( UInt theInstr )
2851 {
2852    UChar  opc2     = get_function(theInstr);
2853    UChar  opc1     = get_opcode(theInstr);
2854    UChar  regRs    = get_rs(theInstr);
2855    UChar  regRt    = get_rt(theInstr);
2856    UChar  regRd    = get_rd(theInstr);
2857    /* MIPS trap instructions extract code from theInstr[15:6].
2858       Cavium OCTEON instructions SNEI, SEQI extract immediate operands
2859       from the same bit field [15:6]. */
2860    UInt   imm      = get_code(theInstr);
2861    UChar  lenM1    = get_msb(theInstr);
2862    UChar  p        = get_lsb(theInstr);
2863    IRType ty       = mode64? Ity_I64 : Ity_I32;
2864    IRTemp tmp      = newTemp(ty);
2865    IRTemp tmpRs    = newTemp(ty);
2866    IRTemp tmpRt    = newTemp(ty);
2867    IRTemp t1       = newTemp(ty);
2868    UInt size;
2869    assign(tmpRs, getIReg(regRs));
2870 
2871    switch(opc1) {
2872       case 0x1C: {
2873          switch(opc2) {
2874             case 0x03: {  /* DMUL rd, rs, rt */
2875                DIP("dmul r%u, r%u, r%u", regRd, regRs, regRt);
2876                IRTemp t0 = newTemp(Ity_I128);
2877                assign(t0, binop(Iop_MullU64, getIReg(regRs), getIReg(regRt)));
2878                putIReg(regRd, unop(Iop_128to64, mkexpr(t0)));
2879                break;
2880             }
2881 
2882             case 0x18: {  /* Store Atomic Add Word - SAA; Cavium OCTEON */
2883                DIP("saa r%u, (r%u)", regRt, regRs);
2884                IRTemp addr = newTemp(Ity_I64);
2885                IRTemp new_val = newTemp(Ity_I32);
2886                IRTemp old = newTemp(Ity_I32);
2887                assign(addr, getIReg(regRs));
2888                assign(old, load(Ity_I32, mkexpr(addr)));
2889                assign(new_val, binop(Iop_Add32,
2890                                      mkexpr(old),
2891                                      mkNarrowTo32(ty, getIReg(regRt))));
2892                mips_load_store32(addr, new_val, old, 0, False);
2893                break;
2894             }
2895 
2896             /* Store Atomic Add Doubleword - SAAD; Cavium OCTEON */
2897             case 0x19: {
2898                DIP( "saad r%u, (r%u)", regRt, regRs);
2899                IRTemp addr = newTemp(Ity_I64);
2900                IRTemp new_val = newTemp(Ity_I64);
2901                IRTemp old = newTemp(Ity_I64);
2902                assign(addr, getIReg(regRs));
2903                assign(old, load(Ity_I64, mkexpr(addr)));
2904                assign(new_val, binop(Iop_Add64,
2905                                      mkexpr(old),
2906                                      getIReg(regRt)));
2907                mips_load_store64(addr, new_val, old, 0, False);
2908                break;
2909             }
2910 
2911             /* LAI, LAID, LAD, LADD, LAS, LASD,
2912                LAC, LACD, LAA, LAAD, LAW, LAWD */
2913             case 0x1f: {
2914                UInt opc3 = get_sa(theInstr);
2915                IRTemp addr = newTemp(Ity_I64);
2916                switch (opc3) {
2917                   /* Load Atomic Increment Word - LAI; Cavium OCTEON2 */
2918                   case 0x02: {
2919                      DIP("lai r%u,(r%u)\n", regRd, regRs);
2920                      IRTemp new_val = newTemp(Ity_I32);
2921                      IRTemp old = newTemp(Ity_I32);
2922                      assign(addr, getIReg(regRs));
2923                      assign(old, load(Ity_I32, mkexpr(addr)));
2924                      assign(new_val, binop(Iop_Add32,
2925                                            mkexpr(old),
2926                                            mkU32(1)));
2927                      mips_load_store32(addr, new_val, old, regRd, True);
2928                      break;
2929                   }
2930                   /* Load Atomic Increment Doubleword - LAID; Cavium OCTEON2 */
2931                   case 0x03: {
2932                      DIP("laid r%u,(r%u)\n", regRd, regRs);
2933                      IRTemp new_val = newTemp(Ity_I64);
2934                      IRTemp old = newTemp(Ity_I64);
2935                      assign(addr, getIReg(regRs));
2936                      assign(old, load(Ity_I64, mkexpr(addr)));
2937                      assign(new_val, binop(Iop_Add64,
2938                                            mkexpr(old),
2939                                            mkU64(1)));
2940                      mips_load_store64(addr, new_val, old, regRd, True);
2941                      break;
2942                   }
2943                   /* Load Atomic Decrement Word - LAD; Cavium OCTEON2 */
2944                   case 0x06: {
2945                      DIP("lad r%u,(r%u)\n", regRd, regRs);
2946                      IRTemp new_val = newTemp(Ity_I32);
2947                      IRTemp old = newTemp(Ity_I32);
2948                      assign(addr, getIReg(regRs));
2949                      assign(old, load(Ity_I32, mkexpr(addr)));
2950                      assign(new_val, binop(Iop_Sub32,
2951                                            mkexpr(old),
2952                                            mkU32(1)));
2953                      mips_load_store32(addr, new_val, old, regRd, True);
2954                      break;
2955                   }
2956                   /* Load Atomic Decrement Doubleword - LADD; Cavium OCTEON2 */
2957                   case 0x07: {
2958                      DIP("ladd r%u,(r%u)\n", regRd, regRs);
2959                      IRTemp new_val = newTemp(Ity_I64);
2960                      IRTemp old = newTemp(Ity_I64);
2961                      assign(addr, getIReg(regRs));
2962                      assign(old, load(Ity_I64, mkexpr(addr)));
2963                      assign(new_val, binop(Iop_Sub64,
2964                                            mkexpr(old),
2965                                            mkU64(1)));
2966                      mips_load_store64(addr, new_val, old, regRd, True);
2967                      break;
2968                   }
2969                   /* Load Atomic Set Word - LAS; Cavium OCTEON2 */
2970                   case 0x0a: {
2971                      DIP("las r%u,(r%u)\n", regRd, regRs);
2972                      IRTemp new_val = newTemp(Ity_I32);
2973                      IRTemp old = newTemp(Ity_I32);
2974                      assign(addr, getIReg(regRs));
2975                      assign(new_val, mkU32(0xffffffff));
2976                      assign(old, load(Ity_I32, mkexpr(addr)));
2977                      mips_load_store32(addr, new_val, old, regRd, True);
2978                      break;
2979                   }
2980                   /* Load Atomic Set Doubleword - LASD; Cavium OCTEON2 */
2981                   case 0x0b: {
2982                      DIP("lasd r%u,(r%u)\n", regRd, regRs);
2983                      IRTemp new_val = newTemp(Ity_I64);
2984                      IRTemp old = newTemp(Ity_I64);
2985                      assign(addr, getIReg(regRs));
2986                      assign(new_val, mkU64(0xffffffffffffffffULL));
2987                      assign(old, load(Ity_I64, mkexpr(addr)));
2988                      mips_load_store64(addr, new_val, old, regRd, True);
2989                      break;
2990                   }
2991                   /* Load Atomic Clear Word - LAC; Cavium OCTEON2 */
2992                   case 0x0e: {
2993                      DIP("lac r%u,(r%u)\n", regRd, regRs);
2994                      IRTemp new_val = newTemp(Ity_I32);
2995                      IRTemp old = newTemp(Ity_I32);
2996                      assign(addr, getIReg(regRs));
2997                      assign(new_val, mkU32(0));
2998                      assign(old, load(Ity_I32, mkexpr(addr)));
2999                      mips_load_store32(addr, new_val, old, regRd, True);
3000                      break;
3001                   }
3002                   /* Load Atomic Clear Doubleword - LACD; Cavium OCTEON2 */
3003                   case 0x0f: {
3004                      DIP("lacd r%u,(r%u)\n", regRd, regRs);
3005                      IRTemp new_val = newTemp(Ity_I64);
3006                      IRTemp old = newTemp(Ity_I64);
3007                      assign(addr, getIReg(regRs));
3008                      assign(new_val, mkU64(0));
3009                      assign(old, load(Ity_I64, mkexpr(addr)));
3010                      mips_load_store64(addr, new_val, old, regRd, True);
3011                      break;
3012                   }
3013                   /* Load Atomic Add Word - LAA; Cavium OCTEON2 */
3014                   case 0x12: {
3015                      DIP("laa r%u,(r%u),r%u\n", regRd, regRs, regRt);
3016                      IRTemp new_val = newTemp(Ity_I32);
3017                      IRTemp old = newTemp(Ity_I32);
3018                      assign(addr, getIReg(regRs));
3019                      assign(old, load(Ity_I32, mkexpr(addr)));
3020                      assign(new_val, binop(Iop_Add32,
3021                                            mkexpr(old),
3022                                            mkNarrowTo32(ty, getIReg(regRt))));
3023                      mips_load_store32(addr, new_val, old, regRd, True);
3024                      break;
3025                   }
3026                   /* Load Atomic Add Doubleword - LAAD; Cavium OCTEON2 */
3027                   case 0x13: {
3028                      DIP("laad r%u,(r%u),r%u\n", regRd, regRs, regRt);
3029                      IRTemp new_val = newTemp(Ity_I64);
3030                      IRTemp old = newTemp(Ity_I64);
3031                      assign(addr, getIReg(regRs));
3032                      assign(old, load(Ity_I64, mkexpr(addr)));
3033                      assign(new_val, binop(Iop_Add64,
3034                                            load(Ity_I64, mkexpr(addr)),
3035                                            getIReg(regRt)));
3036                      mips_load_store64(addr, new_val, old, regRd, True);
3037                      break;
3038                   }
3039                   /* Load Atomic Swap Word - LAW; Cavium OCTEON2 */
3040                   case 0x16: {
3041                      DIP("law r%u,(r%u)\n", regRd, regRs);
3042                      IRTemp new_val = newTemp(Ity_I32);
3043                      IRTemp old = newTemp(Ity_I32);
3044                      assign(addr, getIReg(regRs));
3045                      assign(new_val, mkNarrowTo32(ty, getIReg(regRt)));
3046                      assign(old, load(Ity_I32, mkexpr(addr)));
3047                      mips_load_store32(addr, new_val, old, regRd, True);
3048                      break;
3049                   }
3050                   /* Load Atomic Swap Doubleword - LAWD; Cavium OCTEON2 */
3051                   case 0x17: {
3052                      DIP("lawd r%u,(r%u)\n", regRd, regRs);
3053                      IRTemp new_val = newTemp(Ity_I64);
3054                      IRTemp old = newTemp(Ity_I64);
3055                      assign(addr, getIReg(regRs));
3056                      assign(new_val, getIReg(regRt));
3057                      assign(old, load(Ity_I64, mkexpr(addr)));
3058                      mips_load_store64(addr, new_val, old, regRd, True);
3059                      break;
3060                   }
3061                   default:
3062                      vex_printf("Unknown laxx instruction, opc3=0x%x\n", opc3);
3063                      vex_printf("Instruction=0x%08x\n", theInstr);
3064                      return False;
3065                }
3066                break;
3067             }
3068 
3069             /* Unsigned Byte Add - BADDU rd, rs, rt; Cavium OCTEON */
3070             case 0x28: {
3071                DIP("BADDU r%u, r%u, r%u", regRs, regRt, regRd);
3072                IRTemp t0 = newTemp(Ity_I8);
3073 
3074                assign(t0, binop(Iop_Add8,
3075                                 mkNarrowTo8(ty, getIReg(regRs)),
3076                                 mkNarrowTo8(ty, getIReg(regRt))));
3077 
3078                if (mode64)
3079                   putIReg(regRd, binop(mkSzOp(ty, Iop_And8),
3080                                        unop(Iop_8Uto64, mkexpr(t0)),
3081                                        mkSzImm(ty, 0xFF)));
3082                else
3083                   putIReg(regRd, binop(mkSzOp(ty, Iop_And8),
3084                                        unop(Iop_8Uto32, mkexpr(t0)),
3085                                        mkSzImm(ty, 0xFF)));
3086                break;
3087             }
3088 
3089             case 0x2c: {  /* Count Ones in a Word - POP; Cavium OCTEON */
3090                int i, shift[5];
3091                IRTemp mask[5];
3092                IRTemp old = newTemp(ty);
3093                IRTemp nyu = IRTemp_INVALID;
3094                assign(old, getIReg(regRs));
3095                DIP("pop r%u, r%u", regRd, regRs);
3096 
3097                for (i = 0; i < 5; i++) {
3098                   mask[i] = newTemp(ty);
3099                   shift[i] = 1 << i;
3100                }
3101                if(mode64) {
3102                   assign(mask[0], mkU64(0x0000000055555555));
3103                   assign(mask[1], mkU64(0x0000000033333333));
3104                   assign(mask[2], mkU64(0x000000000F0F0F0F));
3105                   assign(mask[3], mkU64(0x0000000000FF00FF));
3106                   assign(mask[4], mkU64(0x000000000000FFFF));
3107 
3108                   for (i = 0; i < 5; i++) {
3109                      nyu = newTemp(ty);
3110                      assign(nyu,
3111                             binop(Iop_Add64,
3112                                   binop(Iop_And64,
3113                                         mkexpr(old), mkexpr(mask[i])),
3114                                   binop(Iop_And64,
3115                                         binop(Iop_Shr64,
3116                                               mkexpr(old), mkU8(shift[i])),
3117                                         mkexpr(mask[i]))));
3118                      old = nyu;
3119                   }
3120                } else {
3121                   assign(mask[0], mkU32(0x55555555));
3122                   assign(mask[1], mkU32(0x33333333));
3123                   assign(mask[2], mkU32(0x0F0F0F0F));
3124                   assign(mask[3], mkU32(0x00FF00FF));
3125                   assign(mask[4], mkU32(0x0000FFFF));
3126                   assign(old, getIReg(regRs));
3127 
3128                   for (i = 0; i < 5; i++) {
3129                      nyu = newTemp(ty);
3130                      assign(nyu,
3131                             binop(Iop_Add32,
3132                                   binop(Iop_And32,
3133                                         mkexpr(old), mkexpr(mask[i])),
3134                                   binop(Iop_And32,
3135                                         binop(Iop_Shr32,
3136                                               mkexpr(old), mkU8(shift[i])),
3137                                         mkexpr(mask[i]))));
3138                      old = nyu;
3139                   }
3140                }
3141                putIReg(regRd, mkexpr(nyu));
3142                break;
3143             }
3144 
3145             /* Count Ones in a Doubleword - DPOP; Cavium OCTEON */
3146             case 0x2d: {
3147                int i, shift[6];
3148                IRTemp mask[6];
3149                IRTemp old = newTemp(ty);
3150                IRTemp nyu = IRTemp_INVALID;
3151                DIP("dpop r%u, r%u", regRd, regRs);
3152 
3153                for (i = 0; i < 6; i++) {
3154                   mask[i] = newTemp(ty);
3155                   shift[i] = 1 << i;
3156                }
3157                vassert(mode64); /*Caution! Only for Mode 64*/
3158                assign(mask[0], mkU64(0x5555555555555555ULL));
3159                assign(mask[1], mkU64(0x3333333333333333ULL));
3160                assign(mask[2], mkU64(0x0F0F0F0F0F0F0F0FULL));
3161                assign(mask[3], mkU64(0x00FF00FF00FF00FFULL));
3162                assign(mask[4], mkU64(0x0000FFFF0000FFFFULL));
3163                assign(mask[5], mkU64(0x00000000FFFFFFFFULL));
3164                assign(old, getIReg(regRs));
3165                for (i = 0; i < 6; i++) {
3166                   nyu = newTemp(Ity_I64);
3167                   assign(nyu,
3168                          binop(Iop_Add64,
3169                                binop(Iop_And64,
3170                                      mkexpr(old), mkexpr(mask[i])),
3171                                binop(Iop_And64,
3172                                      binop(Iop_Shr64,
3173                                            mkexpr(old), mkU8(shift[i])),
3174                                      mkexpr(mask[i]))));
3175                   old = nyu;
3176                }
3177                putIReg(regRd, mkexpr(nyu));
3178                break;
3179             }
3180 
3181             case 0x32:  /* 5. CINS rd, rs, p, lenm1 */
3182                DIP("cins r%u, r%u, %u, %u\n", regRt, regRs, p, lenM1);
3183                assign ( tmp  , binop(Iop_Shl64, mkexpr(tmpRs),
3184                                      mkU8(64-( lenM1+1 ))));
3185                assign ( tmpRt, binop(Iop_Shr64, mkexpr( tmp ),
3186                                      mkU8(64-(p+lenM1+1))));
3187                putIReg( regRt, mkexpr(tmpRt));
3188                break;
3189 
3190             case 0x33:  /* 6. CINS32 rd, rs, p+32, lenm1 */
3191                DIP("cins32 r%u, r%u, %d, %d\n", regRt, regRs, p+32, lenM1);
3192                assign ( tmp  , binop(Iop_Shl64, mkexpr(tmpRs),
3193                                      mkU8(64-( lenM1+1 ))));
3194                assign ( tmpRt, binop(Iop_Shr64, mkexpr( tmp ),
3195                                      mkU8(32-(p+lenM1+1))));
3196                putIReg( regRt, mkexpr(tmpRt));
3197                break;
3198 
3199             case 0x3A:  /* 3. EXTS rt, rs, p len */
3200                DIP("exts r%u, r%u, %d, %d\n", regRt, regRs, p, lenM1);
3201                size = lenM1 + 1;  /* lenm1+1 */
3202                UChar lsAmt = 64 - (p + size);  /* p+lenm1+1 */
3203                UChar rsAmt = 64 - size;  /* lenm1+1 */
3204                tmp = newTemp(Ity_I64);
3205                assign(tmp, binop(Iop_Shl64, mkexpr(tmpRs), mkU8(lsAmt)));
3206                putIReg(regRt, binop(Iop_Sar64, mkexpr(tmp), mkU8(rsAmt)));
3207                break;
3208 
3209             case 0x3B:  /* 4. EXTS32 rt, rs, p len */
3210                DIP("exts32 r%u, r%u, %d, %d\n", regRt, regRs, p, lenM1);
3211                assign ( tmp  , binop(Iop_Shl64, mkexpr(tmpRs),
3212                                      mkU8(32-(p+lenM1+1))));
3213                assign ( tmpRt, binop(Iop_Sar64, mkexpr(tmp),
3214                                      mkU8(64-(lenM1+1))) );
3215                putIReg( regRt, mkexpr(tmpRt));
3216                break;
3217 
3218             case 0x2B:  /* 20. SNE rd, rs, rt */
3219                DIP("sne r%u, r%u, r%u", regRd,regRs, regRt);
3220                if (mode64)
3221                   putIReg(regRd, unop(Iop_1Uto64, binop(Iop_CmpNE64,
3222                                                         getIReg(regRs),
3223                                                         getIReg(regRt))));
3224                else
3225                   putIReg(regRd,unop(Iop_1Uto32, binop(Iop_CmpNE32,
3226                                                        getIReg(regRs),
3227                                                        getIReg(regRt))));
3228                break;
3229 
3230             case 0x2A:  /* Set Equals - SEQ; Cavium OCTEON */
3231                DIP("seq r%u, r%u, %d", regRd, regRs, regRt);
3232                if (mode64)
3233                   putIReg(regRd, unop(Iop_1Uto64,
3234                                       binop(Iop_CmpEQ64, getIReg(regRs),
3235                                             getIReg(regRt))));
3236                else
3237                   putIReg(regRd, unop(Iop_1Uto32,
3238                                       binop(Iop_CmpEQ32, getIReg(regRs),
3239                                             getIReg(regRt))));
3240                break;
3241 
3242             case 0x2E:  /* Set Equals Immediate - SEQI; Cavium OCTEON */
3243                DIP("seqi r%u, r%u, %u", regRt, regRs, imm);
3244                if (mode64)
3245                   putIReg(regRt, unop(Iop_1Uto64,
3246                                       binop(Iop_CmpEQ64, getIReg(regRs),
3247                                             mkU64(extend_s_10to64(imm)))));
3248                else
3249                   putIReg(regRt, unop(Iop_1Uto32,
3250                                       binop(Iop_CmpEQ32, getIReg(regRs),
3251                                             mkU32(extend_s_10to32(imm)))));
3252                break;
3253 
3254             case 0x2F:  /* Set Not Equals Immediate - SNEI; Cavium OCTEON */
3255                DIP("snei r%u, r%u, %u", regRt, regRs, imm);
3256                if (mode64)
3257                   putIReg(regRt, unop(Iop_1Uto64,
3258                                    binop(Iop_CmpNE64,
3259                                          getIReg(regRs),
3260                                          mkU64(extend_s_10to64(imm)))));
3261                else
3262                   putIReg(regRt, unop(Iop_1Uto32,
3263                                    binop(Iop_CmpNE32,
3264                                          getIReg(regRs),
3265                                          mkU32(extend_s_10to32(imm)))));
3266                break;
3267 
3268             default:
3269                return False;
3270          }
3271          break;
3272       } /* opc1 0x1C ends here*/
3273       case 0x1F: {
3274          switch(opc2) {
3275             case 0x0A: {  // lx - Load indexed instructions
3276                switch (get_sa(theInstr)) {
3277                   case 0x00: {  // LWX rd, index(base)
3278                      DIP("lwx r%u, r%u(r%u)", regRd, regRt, regRs);
3279                      LOADX_STORE_PATTERN;
3280                      putIReg(regRd, mkWidenFrom32(ty, load(Ity_I32, mkexpr(t1)),
3281                                                   True));
3282                      break;
3283                   }
3284                   case 0x04:  // LHX rd, index(base)
3285                      DIP("lhx r%u, r%u(r%u)", regRd, regRt, regRs);
3286                      LOADX_STORE_PATTERN;
3287                      if (mode64)
3288                         putIReg(regRd, unop(Iop_16Sto64, load(Ity_I16,
3289                                                               mkexpr(t1))));
3290                      else
3291                         putIReg(regRd, unop(Iop_16Sto32, load(Ity_I16,
3292                                                               mkexpr(t1))));
3293                      break;
3294                   case 0x08: {  // LDX rd, index(base)
3295                      DIP("ldx r%u, r%u(r%u)", regRd, regRt, regRs);
3296                      vassert(mode64); /* Currently Implemented only for n64 */
3297                      LOADX_STORE_PATTERN;
3298                      putIReg(regRd, load(Ity_I64, mkexpr(t1)));
3299                      break;
3300                   }
3301                   case 0x06: {  // LBUX rd, index(base)
3302                      DIP("lbux r%u, r%u(r%u)", regRd, regRt, regRs);
3303                      LOADX_STORE_PATTERN;
3304                      if (mode64)
3305                         putIReg(regRd, unop(Iop_8Uto64, load(Ity_I8,
3306                                                              mkexpr(t1))));
3307                      else
3308                         putIReg(regRd, unop(Iop_8Uto32, load(Ity_I8,
3309                                                              mkexpr(t1))));
3310                      break;
3311                   }
3312                   case 0x10: {  // LWUX rd, index(base) (Cavium OCTEON)
3313                      DIP("lwux r%u, r%u(r%u)", regRd, regRt, regRs);
3314                      LOADX_STORE_PATTERN; /* same for both 32 and 64 modes*/
3315                      putIReg(regRd, mkWidenFrom32(ty, load(Ity_I32, mkexpr(t1)),
3316                                                   False));
3317                      break;
3318                   }
3319                   case 0x14: {  // LHUX rd, index(base) (Cavium OCTEON)
3320                      DIP("lhux r%u, r%u(r%u)", regRd, regRt, regRs);
3321                      LOADX_STORE_PATTERN;
3322                      if (mode64)
3323                         putIReg(regRd,
3324                                 unop(Iop_16Uto64, load(Ity_I16, mkexpr(t1))));
3325                      else
3326                         putIReg(regRd,
3327                                 unop(Iop_16Uto32, load(Ity_I16, mkexpr(t1))));
3328                      break;
3329                   }
3330                   case 0x16: {  // LBX rd, index(base) (Cavium OCTEON)
3331                      DIP("lbx r%u, r%u(r%u)", regRd, regRs, regRt);
3332                      LOADX_STORE_PATTERN;
3333                      if (mode64)
3334                         putIReg(regRd,
3335                                 unop(Iop_8Sto64, load(Ity_I8, mkexpr(t1))));
3336                      else
3337                         putIReg(regRd,
3338                                 unop(Iop_8Sto32, load(Ity_I8, mkexpr(t1))));
3339                      break;
3340                   }
3341                   default:
3342                      vex_printf("\nUnhandled LX instruction opc3 = %x\n",
3343                                 get_sa(theInstr));
3344                      return False;
3345                }
3346                break;
3347             }
3348          } /* opc1 = 0x1F & opc2 = 0xA (LX) ends here*/
3349          break;
3350       } /* opc1 = 0x1F ends here*/
3351       default:
3352          return False;
3353    } /* main opc1 switch ends here */
3354    return True;
3355 }
3356 
3357 /*------------------------------------------------------------*/
3358 /*---       Disassemble a single DSP ASE instruction       ---*/
3359 /*------------------------------------------------------------*/
3360 
disDSPInstr_MIPS_WRK(UInt cins)3361 static UInt disDSPInstr_MIPS_WRK ( UInt cins )
3362 {
3363    IRTemp t0, t1 = 0, t2, t3, t4, t5, t6, t7, t8, t9, t10, t11, t12, t13, t14,
3364           t15, t16, t17;
3365    UInt opcode, rs, rt, rd, sa, function, ac, ac_mfhilo, rddsp_mask,
3366         wrdsp_mask, dsp_imm, shift;
3367 
3368    opcode = get_opcode(cins);
3369    rs = get_rs(cins);
3370    rt = get_rt(cins);
3371    rd = get_rd(cins);
3372    sa = get_sa(cins);
3373    function = get_function(cins);
3374    ac = get_acNo(cins);
3375    ac_mfhilo = get_acNo_mfhilo(cins);
3376    rddsp_mask = get_rddspMask(cins);
3377    wrdsp_mask = get_wrdspMask(cins);
3378    dsp_imm = get_dspImm(cins);
3379    shift = get_shift(cins);
3380 
3381    switch (opcode) {
3382       case 0x00: {  /* Special */
3383          switch (function) {
3384             case 0x10: {  /* MFHI */
3385                DIP("mfhi ac%u r%u", ac_mfhilo, rd);
3386                putIReg(rd, unop(Iop_64HIto32, getAcc(ac_mfhilo)));
3387                break;
3388             }
3389 
3390             case 0x11: {  /* MTHI */
3391                DIP("mthi ac%u r%u", ac, rs);
3392                t1 = newTemp(Ity_I32);
3393                assign(t1, unop(Iop_64to32, getAcc(ac)));
3394                putAcc(ac, binop(Iop_32HLto64, getIReg(rs), mkexpr(t1)));
3395                break;
3396             }
3397 
3398             case 0x12: {  /* MFLO */
3399                DIP("mflo ac%u r%u", ac_mfhilo, rd);
3400                putIReg(rd, unop(Iop_64to32, getAcc(ac_mfhilo)));
3401                break;
3402             }
3403 
3404             case 0x13: {  /* MTLO */
3405                DIP("mtlo ac%u r%u", ac, rs);
3406                t1 = newTemp(Ity_I32);
3407                assign(t1, unop(Iop_64HIto32, getAcc(ac)));
3408                putAcc(ac, binop(Iop_32HLto64, mkexpr(t1), getIReg(rs)));
3409                break;
3410             }
3411 
3412             case 0x18: {  /* MULT */
3413                DIP("mult ac%u r%u, r%u", ac, rs, rt);
3414                t1 = newTemp(Ity_I64);
3415                assign(t1, binop(Iop_MullS32, mkNarrowTo32(Ity_I32, getIReg(rs)),
3416                                 mkNarrowTo32(Ity_I32, getIReg(rt))));
3417                putAcc(ac, mkexpr(t1));
3418                break;
3419             }
3420 
3421             case 0x19: {  /* MULTU */
3422                DIP("multu ac%u r%u, r%u", ac, rs, rt);
3423                t1 = newTemp(Ity_I64);
3424                assign(t1, binop(Iop_MullU32, mkNarrowTo32(Ity_I32, getIReg(rs)),
3425                                              mkNarrowTo32(Ity_I32,
3426                                                           getIReg(rt))));
3427                putAcc(ac, mkexpr(t1));
3428             break;
3429             }
3430          }
3431          break;
3432       }
3433       case 0x1C: {  /* Special2 */
3434          switch (function) {
3435             case 0x00: {  /* MADD */
3436                DIP("madd ac%u, r%u, r%u", ac, rs, rt);
3437                t1 = newTemp(Ity_I64);
3438                t2 = newTemp(Ity_I64);
3439                t3 = newTemp(Ity_I64);
3440 
3441                assign(t1, getAcc(ac));
3442                assign(t2, binop(Iop_MullS32, getIReg(rs), getIReg(rt)));
3443                assign(t3, binop(Iop_Add64, mkexpr(t1), mkexpr(t2)));
3444 
3445                putAcc(ac, mkexpr(t3));
3446                break;
3447             }
3448             case 0x01: {  /* MADDU */
3449                DIP("maddu ac%u r%u, r%u", ac, rs, rt);
3450                t1 = newTemp(Ity_I64);
3451                t2 = newTemp(Ity_I64);
3452                t3 = newTemp(Ity_I64);
3453 
3454                assign(t1, getAcc(ac));
3455                assign(t2, binop(Iop_MullU32, getIReg(rs), getIReg(rt)));
3456                assign(t3, binop(Iop_Add64, mkexpr(t2), mkexpr(t1)));
3457 
3458                putAcc(ac, mkexpr(t3));
3459                break;
3460             }
3461             case 0x04: {  /* MSUB */
3462                DIP("msub ac%u r%u, r%u", ac, rs, rt);
3463                t1 = newTemp(Ity_I64);
3464                t2 = newTemp(Ity_I64);
3465                t3 = newTemp(Ity_I64);
3466 
3467                assign(t1, getAcc(ac));
3468                assign(t2, binop(Iop_MullS32, getIReg(rs), getIReg(rt)));
3469                assign(t3, binop(Iop_Sub64, mkexpr(t1), mkexpr(t2)));
3470 
3471                putAcc(ac, mkexpr(t3));
3472                break;
3473             }
3474             case 0x05: {  /* MSUBU */
3475                DIP("msubu ac%u r%u, r%u", ac, rs, rt);
3476                t1 = newTemp(Ity_I64);
3477                t2 = newTemp(Ity_I64);
3478                t3 = newTemp(Ity_I64);
3479 
3480                assign(t1, getAcc(ac));
3481                assign(t2, binop(Iop_MullU32, getIReg(rs), getIReg(rt)));
3482                assign(t3, binop(Iop_Sub64, mkexpr(t1), mkexpr(t2)));
3483 
3484                putAcc(ac, mkexpr(t3));
3485                break;
3486             }
3487          }
3488          break;
3489       }
3490       case 0x1F: {  /* Special3 */
3491          switch (function) {
3492             case 0x12: {  /* ABSQ_S.PH */
3493                switch (sa) {
3494                   case 0x1: {  /* ABSQ_S.QB */
3495                      DIP("absq_s.qb r%u, r%u", rd, rt);
3496                      vassert(!mode64);
3497                      t0 = newTemp(Ity_I8);
3498                      t1 = newTemp(Ity_I1);
3499                      t2 = newTemp(Ity_I1);
3500                      t3 = newTemp(Ity_I8);
3501                      t4 = newTemp(Ity_I8);
3502                      t5 = newTemp(Ity_I1);
3503                      t6 = newTemp(Ity_I1);
3504                      t7 = newTemp(Ity_I8);
3505                      t8 = newTemp(Ity_I8);
3506                      t9 = newTemp(Ity_I1);
3507                      t10 = newTemp(Ity_I1);
3508                      t11 = newTemp(Ity_I8);
3509                      t12 = newTemp(Ity_I8);
3510                      t13 = newTemp(Ity_I1);
3511                      t14 = newTemp(Ity_I1);
3512                      t15 = newTemp(Ity_I8);
3513                      t16 = newTemp(Ity_I32);
3514                      t17 = newTemp(Ity_I32);
3515 
3516                      /* Absolute value of the rightmost byte (bits 7-0). */
3517                      /* t0 - rightmost byte. */
3518                      assign(t0, unop(Iop_16to8, unop(Iop_32to16, getIReg(rt))));
3519                      /* t1 holds 1 if t0 is equal to 0x80, or 0 otherwise. */
3520                      assign(t1, binop(Iop_CmpEQ32,
3521                                       unop(Iop_8Uto32, mkexpr(t0)),
3522                                       mkU32(0x00000080)));
3523                      /* t2 holds 1 if value in t0 is negative, 0 otherwise. */
3524                      assign(t2, unop(Iop_32to1,
3525                                      binop(Iop_Shr32,
3526                                            binop(Iop_And32,
3527                                                  getIReg(rt),
3528                                                  mkU32(0x00000080)),
3529                                            mkU8(0x7))));
3530                      /* t3 holds abs(t0). */
3531                      assign(t3, IRExpr_ITE(mkexpr(t1),
3532                                            mkU8(0x7F),
3533                                            IRExpr_ITE(mkexpr(t2),
3534                                                       binop(Iop_Add8,
3535                                                             unop(Iop_Not8,
3536                                                                  mkexpr(t0)),
3537                                                             mkU8(0x1)),
3538                                                       mkexpr(t0))));
3539 
3540                      /* Absolute value of bits 15-8. */
3541                      /* t4 - input byte. */
3542                      assign(t4,
3543                             unop(Iop_16HIto8, unop(Iop_32to16, getIReg(rt))));
3544                      /* t5 holds 1 if t4 is equal to 0x80, or 0 otherwise. */
3545                      assign(t5, binop(Iop_CmpEQ32,
3546                                       unop(Iop_8Uto32, mkexpr(t4)),
3547                                       mkU32(0x00000080)));
3548                      /* t6 holds 1 if value in t4 is negative, 0 otherwise. */
3549                      assign(t6, unop(Iop_32to1,
3550                                      binop(Iop_Shr32,
3551                                            binop(Iop_And32,
3552                                                  getIReg(rt),
3553                                                  mkU32(0x00008000)),
3554                                            mkU8(15))));
3555                      /* t3 holds abs(t4). */
3556                      assign(t7, IRExpr_ITE(mkexpr(t5),
3557                                            mkU8(0x7F),
3558                                            IRExpr_ITE(mkexpr(t6),
3559                                                       binop(Iop_Add8,
3560                                                             unop(Iop_Not8,
3561                                                                  mkexpr(t4)),
3562                                                             mkU8(0x1)),
3563                                                       mkexpr(t4))));
3564 
3565                      /* Absolute value of bits 23-15. */
3566                      /* t8 - input byte. */
3567                      assign(t8,
3568                             unop(Iop_16to8, unop(Iop_32HIto16, getIReg(rt))));
3569                      /* t9 holds 1 if t8 is equal to 0x80, or 0 otherwise. */
3570                      assign(t9, binop(Iop_CmpEQ32,
3571                                       unop(Iop_8Uto32, mkexpr(t8)),
3572                                       mkU32(0x00000080)));
3573                      /* t6 holds 1 if value in t8 is negative, 0 otherwise. */
3574                      assign(t10, unop(Iop_32to1,
3575                                       binop(Iop_Shr32,
3576                                             binop(Iop_And32,
3577                                                   getIReg(rt),
3578                                                   mkU32(0x00800000)),
3579                                             mkU8(23))));
3580                      /* t3 holds abs(t8). */
3581                      assign(t11, IRExpr_ITE(mkexpr(t9),
3582                                             mkU8(0x7F),
3583                                             IRExpr_ITE(mkexpr(t10),
3584                                                        binop(Iop_Add8,
3585                                                              unop(Iop_Not8,
3586                                                                   mkexpr(t8)),
3587                                                              mkU8(0x1)),
3588                                                        mkexpr(t8))));
3589 
3590                      /* Absolute value of bits 31-24. */
3591                      /* t12 - input byte. */
3592                      assign(t12,
3593                             unop(Iop_16HIto8, unop(Iop_32HIto16, getIReg(rt))));
3594                      /* t13 holds 1 if t12 is equal to 0x80, or 0 otherwise. */
3595                      assign(t13, binop(Iop_CmpEQ32,
3596                                        unop(Iop_8Uto32, mkexpr(t12)),
3597                                        mkU32(0x00000080)));
3598                      /* t14 holds 1 if value in t12 is negative, 0 otherwise. */
3599                      assign(t14, unop(Iop_32to1,
3600                                       binop(Iop_Shr32,
3601                                             binop(Iop_And32,
3602                                                   getIReg(rt),
3603                                                   mkU32(0x80000000)),
3604                                             mkU8(31))));
3605                      /* t15 holds abs(t12). */
3606                      assign(t15, IRExpr_ITE(mkexpr(t13),
3607                                             mkU8(0x7F),
3608                                             IRExpr_ITE(mkexpr(t14),
3609                                                        binop(Iop_Add8,
3610                                                              unop(Iop_Not8,
3611                                                                   mkexpr(t12)),
3612                                                              mkU8(0x1)),
3613                                                        mkexpr(t12))));
3614 
3615                      /* t16 holds !0 if any of input bytes is 0x80 or 0
3616                         otherwise. */
3617                      assign(t16,
3618                             binop(Iop_Or32,
3619                                   binop(Iop_Or32,
3620                                         binop(Iop_Or32,
3621                                               unop(Iop_1Sto32, mkexpr(t13)),
3622                                               unop(Iop_1Sto32, mkexpr(t9))),
3623                                         unop(Iop_1Sto32, mkexpr(t5))),
3624                                   unop(Iop_1Sto32, mkexpr(t1))));
3625 
3626                      putDSPControl(IRExpr_ITE(binop(Iop_CmpEQ32,
3627                                                     mkexpr(t16),
3628                                                     mkU32(0x0)),
3629                                               getDSPControl(),
3630                                               binop(Iop_Or32,
3631                                                     getDSPControl(),
3632                                                     mkU32(0x00100000))));
3633 
3634                      /* t17 = t15|t11|t7|t3 */
3635                      assign(t17,
3636                             binop(Iop_16HLto32,
3637                                   binop(Iop_8HLto16, mkexpr(t15), mkexpr(t11)),
3638                                   binop(Iop_8HLto16, mkexpr(t7), mkexpr(t3))));
3639 
3640                      putIReg(rd, mkexpr(t17));
3641                      break;
3642                   }
3643                   case 0x2: {  /* REPL.QB */
3644                      DIP("repl.qb r%u, %u", rd, dsp_imm);
3645                      vassert(!mode64);
3646 
3647                      putIReg(rd, mkU32((dsp_imm << 24) | (dsp_imm << 16) |
3648                                        (dsp_imm << 8) | (dsp_imm)));
3649                      break;
3650                   }
3651                   case 0x3: {  /* REPLV.QB */
3652                      DIP("replv.qb r%u, r%u", rd, rt);
3653                      vassert(!mode64);
3654                      t0 = newTemp(Ity_I8);
3655 
3656                      assign(t0, unop(Iop_32to8,
3657                                 binop(Iop_And32, getIReg(rt), mkU32(0xff))));
3658                      putIReg(rd,
3659                              binop(Iop_16HLto32,
3660                                    binop(Iop_8HLto16, mkexpr(t0), mkexpr(t0)),
3661                                    binop(Iop_8HLto16, mkexpr(t0), mkexpr(t0))));
3662                      break;
3663                   }
3664                   case 0x4: {  /* PRECEQU.PH.QBL */
3665                      DIP("precequ.ph.qbl r%u, r%u", rd, rt);
3666                      vassert(!mode64);
3667 
3668                      putIReg(rd, binop(Iop_Or32,
3669                                        binop(Iop_Shr32,
3670                                              binop(Iop_And32,
3671                                                    getIReg(rt),
3672                                                    mkU32(0xff000000)),
3673                                              mkU8(1)),
3674                                        binop(Iop_Shr32,
3675                                              binop(Iop_And32,
3676                                                    getIReg(rt),
3677                                                    mkU32(0x00ff0000)),
3678                                              mkU8(9))));
3679                      break;
3680                   }
3681                   case 0x5: {  /* PRECEQU.PH.QBR */
3682                      DIP("precequ.ph.qbr r%u, r%u", rd, rt);
3683                      vassert(!mode64);
3684 
3685                      putIReg(rd, binop(Iop_Or32,
3686                                        binop(Iop_Shl32,
3687                                              binop(Iop_And32,
3688                                                    getIReg(rt),
3689                                                    mkU32(0x0000ff00)),
3690                                              mkU8(15)),
3691                                        binop(Iop_Shl32,
3692                                              binop(Iop_And32,
3693                                                    getIReg(rt),
3694                                                    mkU32(0x000000ff)),
3695                                              mkU8(7))));
3696                      break;
3697                   }
3698                   case 0x6: {  /* PRECEQU.PH.QBLA */
3699                      DIP("precequ.ph.qbla r%u, r%u", rd, rt);
3700                      vassert(!mode64);
3701 
3702                      putIReg(rd, binop(Iop_Or32,
3703                                        binop(Iop_Shr32,
3704                                              binop(Iop_And32,
3705                                                    getIReg(rt),
3706                                                    mkU32(0xff000000)),
3707                                              mkU8(1)),
3708                                        binop(Iop_Shr32,
3709                                              binop(Iop_And32,
3710                                                    getIReg(rt),
3711                                                    mkU32(0x0000ff00)),
3712                                              mkU8(1))));
3713                      break;
3714                   }
3715                   case 0x7: {  /* PRECEQU.PH.QBRA */
3716                      DIP("precequ.ph.qbra r%u, r%u", rd, rt);
3717                      vassert(!mode64);
3718 
3719                      putIReg(rd, binop(Iop_Or32,
3720                                        binop(Iop_Shl32,
3721                                              binop(Iop_And32,
3722                                                    getIReg(rt),
3723                                                    mkU32(0x00ff0000)),
3724                                              mkU8(7)),
3725                                        binop(Iop_Shl32,
3726                                              binop(Iop_And32,
3727                                                    getIReg(rt),
3728                                                    mkU32(0x000000ff)),
3729                                              mkU8(7))));
3730                      break;
3731                   }
3732                   case 0x9: {  /* ABSQ_S.PH */
3733                      DIP("absq_s.ph r%u, r%u", rd, rt);
3734                      vassert(!mode64);
3735                      t0 = newTemp(Ity_I16);
3736                      t1 = newTemp(Ity_I1);
3737                      t2 = newTemp(Ity_I1);
3738                      t3 = newTemp(Ity_I16);
3739                      t4 = newTemp(Ity_I16);
3740                      t5 = newTemp(Ity_I1);
3741                      t6 = newTemp(Ity_I1);
3742                      t7 = newTemp(Ity_I16);
3743                      t8 = newTemp(Ity_I32);
3744                      t9 = newTemp(Ity_I32);
3745 
3746                      /* t0 holds lower 16 bits of value in rt. */
3747                      assign(t0, unop(Iop_32to16, getIReg(rt)));
3748                      /* t1 holds 1 if t0 is equal to 0x8000. */
3749                      assign(t1, binop(Iop_CmpEQ32,
3750                                       unop(Iop_16Uto32, mkexpr(t0)),
3751                                       mkU32(0x00008000)));
3752                      /* t2 holds 1 if value in t0 is negative, 0 otherwise. */
3753                      assign(t2, unop(Iop_32to1,
3754                                      binop(Iop_Shr32,
3755                                            binop(Iop_And32,
3756                                                  getIReg(rt),
3757                                                  mkU32(0x00008000)),
3758                                            mkU8(15))));
3759                      /* t3 holds abs(t0). */
3760                      assign(t3, IRExpr_ITE(mkexpr(t1),
3761                                            mkU16(0x7FFF),
3762                                            IRExpr_ITE(mkexpr(t2),
3763                                                       binop(Iop_Add16,
3764                                                             unop(Iop_Not16,
3765                                                                  mkexpr(t0)),
3766                                                             mkU16(0x1)),
3767                                                       mkexpr(t0))));
3768 
3769                      /* t4 holds lower 16 bits of value in rt. */
3770                      assign(t4, unop(Iop_32HIto16, getIReg(rt)));
3771                      /* t5 holds 1 if t4 is equal to 0x8000. */
3772                      assign(t5, binop(Iop_CmpEQ32,
3773                                       unop(Iop_16Uto32, mkexpr(t4)),
3774                                       mkU32(0x00008000)));
3775                      /* t6 holds 1 if value in t4 is negative, 0 otherwise. */
3776                      assign(t6, unop(Iop_32to1,
3777                                      binop(Iop_Shr32,
3778                                            binop(Iop_And32,
3779                                                  getIReg(rt),
3780                                                  mkU32(0x80000000)),
3781                                            mkU8(31))));
3782                      /* t7 holds abs(t4). */
3783                      assign(t7, IRExpr_ITE(mkexpr(t5),
3784                                            mkU16(0x7FFF),
3785                                            IRExpr_ITE(mkexpr(t6),
3786                                                       binop(Iop_Add16,
3787                                                             unop(Iop_Not16,
3788                                                                  mkexpr(t4)),
3789                                                             mkU16(0x1)),
3790                                                       mkexpr(t4))));
3791                      /* If any of the two input halfwords is equal 0x8000,
3792                         set bit 20 in DSPControl register. */
3793                      assign(t8, binop(Iop_Or32,
3794                                       unop(Iop_1Sto32, mkexpr(t5)),
3795                                       unop(Iop_1Sto32, mkexpr(t1))));
3796 
3797                      putDSPControl(IRExpr_ITE(binop(Iop_CmpEQ32,
3798                                                     mkexpr(t8),
3799                                                     mkU32(0x0)),
3800                                               getDSPControl(),
3801                                               binop(Iop_Or32,
3802                                                     getDSPControl(),
3803                                                     mkU32(0x00100000))));
3804 
3805                      /* t9 = t7|t3 */
3806                      assign(t9, binop(Iop_16HLto32, mkexpr(t7), mkexpr(t3)));
3807 
3808                      putIReg(rd, mkexpr(t9));
3809                      break;
3810                   }
3811                   case 0xA: {  /* REPL.PH */
3812                      DIP("repl.ph r%u, %u", rd, dsp_imm);
3813                      vassert(!mode64);
3814                      UShort immediate = extend_s_10to16(dsp_imm);
3815 
3816                      putIReg(rd, mkU32(immediate << 16 | immediate));
3817                      break;
3818                   }
3819                   case 0xB: {  /* REPLV.PH */
3820                      DIP("replv.ph r%u, r%u", rd, rt);
3821                      vassert(!mode64);
3822 
3823                      putIReg(rd, binop(Iop_16HLto32,
3824                                        unop(Iop_32to16, getIReg(rt)),
3825                                        unop(Iop_32to16, getIReg(rt))));
3826                      break;
3827                   }
3828                   case 0xC: {  /* PRECEQ.W.PHL */
3829                      DIP("preceq.w.phl r%u, r%u", rd, rt);
3830                      vassert(!mode64);
3831                      putIReg(rd, binop(Iop_And32,
3832                                        getIReg(rt),
3833                                        mkU32(0xffff0000)));
3834                      break;
3835                   }
3836                   case 0xD: {  /* PRECEQ.W.PHR */
3837                      DIP("preceq.w.phr r%u, r%u", rd, rt);
3838                      vassert(!mode64);
3839                      putIReg(rd, binop(Iop_16HLto32,
3840                                        unop(Iop_32to16, getIReg(rt)),
3841                                        mkU16(0x0)));
3842                      break;
3843                   }
3844                   case 0x11: {  /* ABSQ_S.W */
3845                      DIP("absq_s.w r%u, r%u", rd, rt);
3846                      vassert(!mode64);
3847                      t0 = newTemp(Ity_I1);
3848                      t1 = newTemp(Ity_I1);
3849                      t2 = newTemp(Ity_I32);
3850 
3851                      assign(t0,
3852                             binop(Iop_CmpEQ32, getIReg(rt), mkU32(0x80000000)));
3853 
3854                      putDSPControl(IRExpr_ITE(mkexpr(t0),
3855                                               binop(Iop_Or32,
3856                                                     getDSPControl(),
3857                                                     mkU32(0x00100000)),
3858                                               getDSPControl()));
3859 
3860                      assign(t1, binop(Iop_CmpLT32S, getIReg(rt), mkU32(0x0)));
3861 
3862                      assign(t2, IRExpr_ITE(mkexpr(t0),
3863                                            mkU32(0x7FFFFFFF),
3864                                            IRExpr_ITE(mkexpr(t1),
3865                                                       binop(Iop_Add32,
3866                                                             unop(Iop_Not32,
3867                                                                  getIReg(rt)),
3868                                                             mkU32(0x1)),
3869                                                       getIReg(rt))));
3870                      putIReg(rd, mkexpr(t2));
3871                      break;
3872                   }
3873                   case 0x1B: {  /* BITREV */
3874                      DIP("bitrev r%u, r%u", rd, rt);
3875                      vassert(!mode64);
3876                      /* 32bit reversal as seen on Bit Twiddling Hacks site
3877                         http://graphics.stanford.edu/~seander/bithacks.html
3878                         section ReverseParallel */
3879                      t1 = newTemp(Ity_I32);
3880                      t2 = newTemp(Ity_I32);
3881                      t3 = newTemp(Ity_I32);
3882                      t4 = newTemp(Ity_I32);
3883                      t5 = newTemp(Ity_I32);
3884 
3885                      assign(t1, binop(Iop_Or32,
3886                                       binop(Iop_Shr32,
3887                                             binop(Iop_And32,
3888                                                   getIReg(rt),
3889                                                   mkU32(0xaaaaaaaa)),
3890                                             mkU8(0x1)),
3891                                       binop(Iop_Shl32,
3892                                             binop(Iop_And32,
3893                                                   getIReg(rt),
3894                                                   mkU32(0x55555555)),
3895                                             mkU8(0x1))));
3896                      assign(t2, binop(Iop_Or32,
3897                                       binop(Iop_Shr32,
3898                                             binop(Iop_And32,
3899                                                   mkexpr(t1),
3900                                                   mkU32(0xcccccccc)),
3901                                             mkU8(0x2)),
3902                                       binop(Iop_Shl32,
3903                                             binop(Iop_And32,
3904                                                   mkexpr(t1),
3905                                                   mkU32(0x33333333)),
3906                                             mkU8(0x2))));
3907                      assign(t3, binop(Iop_Or32,
3908                                       binop(Iop_Shr32,
3909                                             binop(Iop_And32,
3910                                                   mkexpr(t2),
3911                                                   mkU32(0xf0f0f0f0)),
3912                                             mkU8(0x4)),
3913                                       binop(Iop_Shl32,
3914                                             binop(Iop_And32,
3915                                                   mkexpr(t2),
3916                                                   mkU32(0x0f0f0f0f)),
3917                                             mkU8(0x4))));
3918                      assign(t4, binop(Iop_Or32,
3919                                       binop(Iop_Shr32,
3920                                             binop(Iop_And32,
3921                                                   mkexpr(t3),
3922                                                   mkU32(0xff00ff00)),
3923                                             mkU8(0x8)),
3924                                       binop(Iop_Shl32,
3925                                             binop(Iop_And32,
3926                                                   mkexpr(t3),
3927                                                   mkU32(0x00ff00ff)),
3928                                             mkU8(0x8))));
3929                      assign(t5, binop(Iop_Or32,
3930                                       binop(Iop_Shr32,
3931                                             mkexpr(t4),
3932                                             mkU8(0x10)),
3933                                       binop(Iop_Shl32,
3934                                             mkexpr(t4),
3935                                             mkU8(0x10))));
3936                      putIReg(rd, binop(Iop_Shr32,
3937                                        mkexpr(t5),
3938                                        mkU8(16)));
3939                      break;
3940                   }
3941                   case 0x1C: {  /* PRECEU.PH.QBL */
3942                      DIP("preceu.ph.qbl r%u, r%u", rd, rt);
3943                      vassert(!mode64);
3944 
3945                      putIReg(rd, binop(Iop_Or32,
3946                                        binop(Iop_Shr32,
3947                                              binop(Iop_And32,
3948                                                    getIReg(rt),
3949                                                    mkU32(0xff000000)),
3950                                              mkU8(8)),
3951                                        binop(Iop_Shr32,
3952                                              binop(Iop_And32,
3953                                                    getIReg(rt),
3954                                                    mkU32(0x00ff0000)),
3955                                              mkU8(16))));
3956                      break;
3957                   }
3958                   case 0x1E: {  /* PRECEU.PH.QBLA */
3959                      DIP("preceu.ph.qbla r%u, r%u", rd, rt);
3960                      vassert(!mode64);
3961 
3962                      putIReg(rd, binop(Iop_Or32,
3963                                        binop(Iop_Shr32,
3964                                              binop(Iop_And32,
3965                                                    getIReg(rt),
3966                                                    mkU32(0xff000000)),
3967                                              mkU8(8)),
3968                                        binop(Iop_Shr32,
3969                                              binop(Iop_And32,
3970                                                    getIReg(rt),
3971                                                    mkU32(0x0000ff00)),
3972                                              mkU8(8))));
3973                      break;
3974                   }
3975                   case 0x1D: {  /* PRECEU.PH.QBR */
3976                      DIP("preceu.ph.qbr r%u, r%u", rd, rt);
3977                      vassert(!mode64);
3978 
3979                      putIReg(rd, binop(Iop_Or32,
3980                                        binop(Iop_Shl32,
3981                                              binop(Iop_And32,
3982                                                    getIReg(rt),
3983                                                    mkU32(0x0000ff00)),
3984                                              mkU8(8)),
3985                                        binop(Iop_And32,
3986                                              getIReg(rt),
3987                                              mkU32(0x000000ff))));
3988                      break;
3989                   }
3990                   case 0x1F: {  /* PRECEU.PH.QBRA */
3991                      DIP("preceu.ph.qbra r%u, r%u", rd, rt);
3992                      vassert(!mode64);
3993 
3994                      putIReg(rd, binop(Iop_Or32,
3995                                        binop(Iop_And32,
3996                                              getIReg(rt),
3997                                              mkU32(0x00ff0000)),
3998                                        binop(Iop_And32,
3999                                              getIReg(rt),
4000                                              mkU32(0x000000ff))));
4001                      break;
4002                   }
4003                   default:
4004                      return -1;
4005                }
4006                break;  /* end of ABSQ_S.PH */
4007             }
4008             case 0x38: {  /* EXTR.W */
4009                switch(sa) {
4010                   case 0x0: {  /* EXTR.W */
4011                      DIP("extr.w r%u, ac%u, %u", rt, ac, rs);
4012                      vassert(!mode64);
4013                      t0 = newTemp(Ity_I64);
4014                      t1 = newTemp(Ity_I64);
4015                      t2 = newTemp(Ity_I32);
4016                      t3 = newTemp(Ity_I1);
4017                      t4 = newTemp(Ity_I1);
4018                      t5 = newTemp(Ity_I1);
4019                      t6 = newTemp(Ity_I1);
4020                      t7 = newTemp(Ity_I32);
4021                      t8 = newTemp(Ity_I64);
4022                      t9 = newTemp(Ity_I64);
4023                      t10 = newTemp(Ity_I1);
4024                      t11 = newTemp(Ity_I1);
4025                      t12 = newTemp(Ity_I1);
4026                      t13 = newTemp(Ity_I1);
4027                      t14 = newTemp(Ity_I32);
4028 
4029                      assign(t0, getAcc(ac));
4030                      if (0 == rs) {
4031                         assign(t1, mkexpr(t0));
4032                      } else {
4033                         assign(t1, binop(Iop_Sar64, mkexpr(t0), mkU8(rs)));
4034                      }
4035                      /* Check if bits 63..31 of the result in t1 aren't 0. */
4036                      assign(t3, binop(Iop_CmpNE32,
4037                                       unop(Iop_64HIto32,
4038                                            mkexpr(t1)),
4039                                       mkU32(0)));
4040                      assign(t4, binop(Iop_CmpNE32,
4041                                       binop(Iop_And32,
4042                                             unop(Iop_64to32,
4043                                                  mkexpr(t1)),
4044                                             mkU32(0x80000000)),
4045                                       mkU32(0)));
4046                      /* Check if bits 63..31 of the result in t1 aren't
4047                         0x1ffffffff. */
4048                      assign(t5, binop(Iop_CmpNE32,
4049                                       unop(Iop_64HIto32,
4050                                            mkexpr(t1)),
4051                                       mkU32(0xffffffff)));
4052                      assign(t6, binop(Iop_CmpNE32,
4053                                       binop(Iop_And32,
4054                                             unop(Iop_64to32,
4055                                                  mkexpr(t1)),
4056                                             mkU32(0x80000000)),
4057                                       mkU32(0x80000000)));
4058                      /* If bits 63..31 aren't 0 nor 0x1ffffffff, set DSP
4059                         control register. */
4060                      assign(t7, binop(Iop_And32,
4061                                       binop(Iop_Or32,
4062                                             unop(Iop_1Sto32, mkexpr(t3)),
4063                                             unop(Iop_1Sto32, mkexpr(t4))),
4064                                       binop(Iop_Or32,
4065                                             unop(Iop_1Sto32, mkexpr(t5)),
4066                                             unop(Iop_1Sto32, mkexpr(t6)))));
4067                      putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32,
4068                                                     mkexpr(t7),
4069                                                     mkU32(0)),
4070                                               binop(Iop_Or32,
4071                                                     getDSPControl(),
4072                                                     mkU32(0x00800000)),
4073                                               getDSPControl()));
4074 
4075                      /* If the last discarded bit is 1, there would be carry
4076                         when rounding, otherwise there wouldn't. We use that
4077                         fact and just add the value of the last discarded bit
4078                         to the least sifgnificant bit of the shifted value
4079                         from acc. */
4080                      if (0 == rs) {
4081                         assign(t8, mkU64(0x0ULL));
4082                      } else {
4083                         assign(t8, binop(Iop_And64,
4084                                          binop(Iop_Shr64,
4085                                                mkexpr(t0),
4086                                                mkU8(rs-1)),
4087                                          mkU64(0x1ULL)));
4088                      }
4089                      assign(t9, binop(Iop_Add64, mkexpr(t1), mkexpr(t8)));
4090 
4091                      /* Repeat previous steps for the rounded value. */
4092                      assign(t10, binop(Iop_CmpNE32,
4093                                       unop(Iop_64HIto32,
4094                                            mkexpr(t9)),
4095                                       mkU32(0)));
4096                      assign(t11, binop(Iop_CmpNE32,
4097                                       binop(Iop_And32,
4098                                             unop(Iop_64to32,
4099                                                  mkexpr(t9)),
4100                                             mkU32(0x80000000)),
4101                                       mkU32(0)));
4102 
4103                      assign(t12, binop(Iop_CmpNE32,
4104                                       unop(Iop_64HIto32,
4105                                            mkexpr(t9)),
4106                                       mkU32(0xffffffff)));
4107                      assign(t13, binop(Iop_CmpNE32,
4108                                       binop(Iop_And32,
4109                                             unop(Iop_64to32,
4110                                                  mkexpr(t9)),
4111                                             mkU32(0x80000000)),
4112                                       mkU32(0x80000000)));
4113 
4114                      assign(t14, binop(Iop_And32,
4115                                       binop(Iop_Or32,
4116                                             unop(Iop_1Sto32, mkexpr(t10)),
4117                                             unop(Iop_1Sto32, mkexpr(t11))),
4118                                       binop(Iop_Or32,
4119                                             unop(Iop_1Sto32, mkexpr(t12)),
4120                                             unop(Iop_1Sto32, mkexpr(t13)))));
4121                      putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32,
4122                                                     mkexpr(t14),
4123                                                     mkU32(0)),
4124                                               binop(Iop_Or32,
4125                                                     getDSPControl(),
4126                                                     mkU32(0x00800000)),
4127                                               getDSPControl()));
4128                      if (0 == rs) {
4129                         putIReg(rt, unop(Iop_64to32, mkexpr(t0)));
4130                      } else {
4131                         putIReg(rt, unop(Iop_64to32, mkexpr(t1)));
4132                      }
4133                      break;
4134                   }
4135                   case 0x1: {  /* EXTRV.W */
4136                      DIP("extrv.w r%u, ac%u, r%u", rt, ac, rs);
4137                      vassert(!mode64);
4138                      t0 = newTemp(Ity_I64);
4139                      t1 = newTemp(Ity_I64);
4140                      t2 = newTemp(Ity_I32);
4141                      t3 = newTemp(Ity_I1);
4142                      t4 = newTemp(Ity_I1);
4143                      t5 = newTemp(Ity_I1);
4144                      t6 = newTemp(Ity_I1);
4145                      t7 = newTemp(Ity_I32);
4146                      t8 = newTemp(Ity_I64);
4147                      t9 = newTemp(Ity_I64);
4148                      t10 = newTemp(Ity_I1);
4149                      t11 = newTemp(Ity_I1);
4150                      t12 = newTemp(Ity_I1);
4151                      t13 = newTemp(Ity_I1);
4152                      t14 = newTemp(Ity_I32);
4153                      t15 = newTemp(Ity_I8);
4154 
4155                      assign(t15, unop(Iop_32to8,
4156                                       binop(Iop_And32,
4157                                             getIReg(rs),
4158                                             mkU32(0x1f))));
4159                      assign(t0, getAcc(ac));
4160                      assign(t1, binop(Iop_Sar64, mkexpr(t0), mkexpr(t15)));
4161                      putIReg(rt, IRExpr_ITE(binop(Iop_CmpEQ32,
4162                                                         unop(Iop_8Uto32,
4163                                                              mkexpr(t15)),
4164                                                         mkU32(0)),
4165                                                   unop(Iop_64to32, mkexpr(t0)),
4166                                                   unop(Iop_64to32, mkexpr(t1))));
4167 
4168                      /* Check if bits 63..31 of the result in t1 aren't 0. */
4169                      assign(t3, binop(Iop_CmpNE32,
4170                                       unop(Iop_64HIto32,
4171                                            mkexpr(t1)),
4172                                       mkU32(0)));
4173                      assign(t4, binop(Iop_CmpNE32,
4174                                       binop(Iop_And32,
4175                                             unop(Iop_64to32,
4176                                                  mkexpr(t1)),
4177                                             mkU32(0x80000000)),
4178                                       mkU32(0)));
4179                      /* Check if bits 63..31 of the result in t1 aren't
4180                         0x1ffffffff. */
4181                      assign(t5, binop(Iop_CmpNE32,
4182                                       unop(Iop_64HIto32,
4183                                            mkexpr(t1)),
4184                                       mkU32(0xffffffff)));
4185                      assign(t6, binop(Iop_CmpNE32,
4186                                       binop(Iop_And32,
4187                                             unop(Iop_64to32,
4188                                                  mkexpr(t1)),
4189                                             mkU32(0x80000000)),
4190                                       mkU32(0x80000000)));
4191                      /* If bits 63..31 aren't 0 nor 0x1ffffffff, set DSP
4192                         control register. */
4193                      assign(t7, binop(Iop_And32,
4194                                       binop(Iop_Or32,
4195                                             unop(Iop_1Sto32, mkexpr(t3)),
4196                                             unop(Iop_1Sto32, mkexpr(t4))),
4197                                       binop(Iop_Or32,
4198                                             unop(Iop_1Sto32, mkexpr(t5)),
4199                                             unop(Iop_1Sto32, mkexpr(t6)))));
4200                      putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32,
4201                                                     mkexpr(t7),
4202                                                     mkU32(0)),
4203                                               binop(Iop_Or32,
4204                                                     getDSPControl(),
4205                                                     mkU32(0x00800000)),
4206                                               getDSPControl()));
4207 
4208                      /* If the last discarded bit is 1, there would be carry
4209                         when rounding, otherwise there wouldn't. We use that
4210                         fact and just add the value of the last discarded bit
4211                         to the least sifgnificant bit of the shifted value
4212                         from acc. */
4213                      assign(t8,
4214                             IRExpr_ITE(binop(Iop_CmpEQ32,
4215                                              unop(Iop_8Uto32,
4216                                                   mkexpr(t15)),
4217                                              mkU32(0)),
4218                                        mkU64(0x0ULL),
4219                                        binop(Iop_And64,
4220                                              binop(Iop_Shr64,
4221                                                    mkexpr(t0),
4222                                                    unop(Iop_32to8,
4223                                                         binop(Iop_Sub32,
4224                                                               unop(Iop_8Uto32,
4225                                                                    mkexpr(t15)),
4226                                                                    mkU32(1)))),
4227                                              mkU64(0x1ULL))));
4228 
4229                      assign(t9, binop(Iop_Add64, mkexpr(t1), mkexpr(t8)));
4230 
4231                      /* Repeat previous steps for the rounded value. */
4232                      assign(t10, binop(Iop_CmpNE32,
4233                                       unop(Iop_64HIto32,
4234                                            mkexpr(t9)),
4235                                       mkU32(0)));
4236                      assign(t11, binop(Iop_CmpNE32,
4237                                       binop(Iop_And32,
4238                                             unop(Iop_64to32,
4239                                                  mkexpr(t9)),
4240                                             mkU32(0x80000000)),
4241                                       mkU32(0)));
4242 
4243                      assign(t12, binop(Iop_CmpNE32,
4244                                       unop(Iop_64HIto32,
4245                                            mkexpr(t9)),
4246                                       mkU32(0xffffffff)));
4247                      assign(t13, binop(Iop_CmpNE32,
4248                                       binop(Iop_And32,
4249                                             unop(Iop_64to32,
4250                                                  mkexpr(t9)),
4251                                             mkU32(0x80000000)),
4252                                       mkU32(0x80000000)));
4253 
4254                      assign(t14, binop(Iop_And32,
4255                                       binop(Iop_Or32,
4256                                             unop(Iop_1Sto32, mkexpr(t10)),
4257                                             unop(Iop_1Sto32, mkexpr(t11))),
4258                                       binop(Iop_Or32,
4259                                             unop(Iop_1Sto32, mkexpr(t12)),
4260                                             unop(Iop_1Sto32, mkexpr(t13)))));
4261                      putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32,
4262                                                     mkexpr(t14),
4263                                                     mkU32(0)),
4264                                               binop(Iop_Or32,
4265                                                     getDSPControl(),
4266                                                     mkU32(0x00800000)),
4267                                               getDSPControl()));
4268                      break;
4269                   }
4270                   case 0x2: {  /* EXTP */
4271                      DIP("extp r%u, ac%u, %u", rt, ac, rs);
4272                      vassert(!mode64);
4273                      t0 = newTemp(Ity_I64);
4274                      t1 = newTemp(Ity_I32);
4275                      t2 = newTemp(Ity_I1);
4276                      t3 = newTemp(Ity_I1);
4277                      t4 = newTemp(Ity_I8);
4278                      t5 = newTemp(Ity_I64);
4279                      t6 = newTemp(Ity_I64);
4280                      t7 = newTemp(Ity_I32);
4281 
4282                      assign(t0, getAcc(ac));
4283                      /* Extract pos field of DSPControl register. */
4284                      assign(t1, binop(Iop_And32, getDSPControl(), mkU32(0x3f)));
4285 
4286                      /* Check if (pos - size) >= 0 [size <= pos]
4287                         if (pos < size)
4288                            put 1 to EFI field of DSPControl register
4289                         else
4290                            extract bits from acc and put 0 to EFI field of
4291                            DSPCtrl */
4292                      assign(t2, binop(Iop_CmpLT32U, mkexpr(t1), mkU32(rs)));
4293 
4294                      putDSPControl(IRExpr_ITE(mkexpr(t2),
4295                                               binop(Iop_Or32,
4296                                                     binop(Iop_And32,
4297                                                           getDSPControl(),
4298                                                           mkU32(0xffffbfff)),
4299                                                     mkU32(0x4000)),
4300                                               binop(Iop_And32,
4301                                                     getDSPControl(),
4302                                                     mkU32(0xffffbfff))));
4303 
4304                      /* If pos <= 31, shift right the value from the acc
4305                         (pos-size) times and take (size+1) bits from the least
4306                         significant positions. Otherwise, shift left the value
4307                         (63-pos) times, take (size+1) bits from the most
4308                         significant positions and shift right (31-size) times.*/
4309                      assign(t3, binop(Iop_CmpLE32U, mkexpr(t1), mkU32(31)));
4310 
4311                      assign(t4,
4312                            IRExpr_ITE(mkexpr(t3),
4313                                       unop(Iop_32to8,
4314                                            binop(Iop_Sub32,
4315                                                  mkexpr(t1), mkU32(rs))),
4316                                       unop(Iop_32to8,
4317                                            binop(Iop_Sub32,
4318                                                  mkU32(63), mkexpr(t1)))));
4319 
4320                      assign(t5, IRExpr_ITE(mkexpr(t3),
4321                                            binop(Iop_Shr64,
4322                                                  mkexpr(t0), mkexpr(t4)),
4323                                            binop(Iop_Shl64,
4324                                                  mkexpr(t0), mkexpr(t4))));
4325 
4326                      /* t6 holds a mask for bit extraction */
4327                      assign(t6,
4328                             IRExpr_ITE(mkexpr(t3),
4329                                        unop(Iop_Not64,
4330                                             binop(Iop_Shl64,
4331                                                   mkU64(0xffffffffffffffffULL),
4332                                                   mkU8(rs+1))),
4333                                        unop(Iop_Not64,
4334                                             binop(Iop_Shr64,
4335                                                   mkU64(0xffffffffffffffffULL),
4336                                                   mkU8(rs+1)))));
4337 
4338                      assign(t7, IRExpr_ITE(mkexpr(t3),
4339                                            unop(Iop_64to32,
4340                                                 binop(Iop_And64,
4341                                                       mkexpr(t5),
4342                                                       mkexpr(t6))),
4343                                            binop(Iop_Shr32,
4344                                                  unop(Iop_64HIto32,
4345                                                       binop(Iop_And64,
4346                                                             mkexpr(t5),
4347                                                             mkexpr(t6))),
4348                                                  mkU8(31-rs))));
4349 
4350                      putIReg(rt, mkexpr(t7));
4351                      break;
4352                   }
4353                   case 0x3: {  /* EXTPV */
4354                      DIP("extpv r%u, ac%u, r%u", rt, ac, rs);
4355                      vassert(!mode64);
4356                      t0 = newTemp(Ity_I64);
4357                      t1 = newTemp(Ity_I32);
4358                      t2 = newTemp(Ity_I1);
4359                      t3 = newTemp(Ity_I1);
4360                      t4 = newTemp(Ity_I8);
4361                      t5 = newTemp(Ity_I64);
4362                      t6 = newTemp(Ity_I64);
4363                      t7 = newTemp(Ity_I32);
4364                      t8 = newTemp(Ity_I32);
4365 
4366                      assign(t8, binop(Iop_And32, getIReg(rs), mkU32(0x1f)));
4367                      assign(t0, getAcc(ac));
4368                      /* Extract pos field of DSPControl register. */
4369                      assign(t1, binop(Iop_And32, getDSPControl(), mkU32(0x3f)));
4370 
4371                      /* Check if (pos - size) >= 0 [size <= pos]
4372                         if (pos < size)
4373                            put 1 to EFI field of DSPControl register
4374                         else
4375                            extract bits from acc and put 0 to EFI field of
4376                            DSPCtrl */
4377                      assign(t2, binop(Iop_CmpLT32U, mkexpr(t1), mkexpr(t8)));
4378 
4379                      putDSPControl(IRExpr_ITE(mkexpr(t2),
4380                                               binop(Iop_Or32,
4381                                                     binop(Iop_And32,
4382                                                           getDSPControl(),
4383                                                           mkU32(0xffffbfff)),
4384                                                     mkU32(0x4000)),
4385                                               binop(Iop_And32,
4386                                                     getDSPControl(),
4387                                                     mkU32(0xffffbfff))));
4388 
4389                      /* If pos <= 31, shift right the value from the acc
4390                         (pos-size) times and take (size+1) bits from the least
4391                         significant positions. Otherwise, shift left the value
4392                         (63-pos) times, take (size+1) bits from the most
4393                         significant positions and shift right (31-size)
4394                         times. */
4395                      assign(t3, binop(Iop_CmpLE32U, mkexpr(t1), mkU32(31)));
4396 
4397                      assign(t4,
4398                            IRExpr_ITE(mkexpr(t3),
4399                                       unop(Iop_32to8,
4400                                            binop(Iop_Sub32,
4401                                                  mkexpr(t1), mkexpr(t8))),
4402                                       unop(Iop_32to8,
4403                                            binop(Iop_Sub32,
4404                                                  mkU32(63), mkexpr(t1)))));
4405 
4406                      assign(t5, IRExpr_ITE(mkexpr(t3),
4407                                            binop(Iop_Shr64,
4408                                                  mkexpr(t0), mkexpr(t4)),
4409                                            binop(Iop_Shl64,
4410                                                  mkexpr(t0), mkexpr(t4))));
4411 
4412                      /* t6 holds a mask for bit extraction. */
4413                      assign(t6,
4414                             IRExpr_ITE(mkexpr(t3),
4415                                        unop(Iop_Not64,
4416                                             binop(Iop_Shl64,
4417                                                   mkU64(0xffffffffffffffffULL),
4418                                                   unop(Iop_32to8,
4419                                                        binop(Iop_Add32,
4420                                                              mkexpr(t8),
4421                                                              mkU32(1))))),
4422                                        unop(Iop_Not64,
4423                                             binop(Iop_Shr64,
4424                                                   mkU64(0xffffffffffffffffULL),
4425                                                   unop(Iop_32to8,
4426                                                        binop(Iop_Add32,
4427                                                              mkexpr(t8),
4428                                                              mkU32(1)))))));
4429 
4430                      assign(t7, IRExpr_ITE(mkexpr(t3),
4431                                            unop(Iop_64to32,
4432                                                 binop(Iop_And64,
4433                                                       mkexpr(t5),
4434                                                       mkexpr(t6))),
4435                                            binop(Iop_Shr32,
4436                                                  unop(Iop_64HIto32,
4437                                                       binop(Iop_And64,
4438                                                             mkexpr(t5),
4439                                                             mkexpr(t6))),
4440                                                  unop(Iop_32to8,
4441                                                       binop(Iop_Sub32,
4442                                                             mkU32(31),
4443                                                             mkexpr(t8))))));
4444 
4445                      putIReg(rt, mkexpr(t7));
4446                      break;
4447                   }
4448                   case 0x4: {  /* EXTR_R.W */
4449                      DIP("extr_r.w r%u, ac%u, %u", rt, ac, rs);
4450                      vassert(!mode64);
4451                      t0 = newTemp(Ity_I64);
4452                      t1 = newTemp(Ity_I64);
4453                      t2 = newTemp(Ity_I32);
4454                      t3 = newTemp(Ity_I1);
4455                      t4 = newTemp(Ity_I1);
4456                      t5 = newTemp(Ity_I1);
4457                      t6 = newTemp(Ity_I1);
4458                      t7 = newTemp(Ity_I32);
4459                      t8 = newTemp(Ity_I64);
4460                      t9 = newTemp(Ity_I64);
4461                      t10 = newTemp(Ity_I1);
4462                      t11 = newTemp(Ity_I1);
4463                      t12 = newTemp(Ity_I1);
4464                      t13 = newTemp(Ity_I1);
4465                      t14 = newTemp(Ity_I32);
4466                      t15 = newTemp(Ity_I64);
4467                      t16 = newTemp(Ity_I1);
4468 
4469                      assign(t0, getAcc(ac));
4470                      assign(t16, binop(Iop_CmpEQ32,
4471                                        mkU32(rs),
4472                                        mkU32(0)));
4473                      assign(t1, IRExpr_ITE(mkexpr(t16),
4474                                            mkexpr(t0),
4475                                            binop(Iop_Sar64,
4476                                                  mkexpr(t0),
4477                                                  mkU8(rs))));
4478                      /* If the last discarded bit is 1, there would be carry
4479                         when rounding, otherwise there wouldn't. We use that
4480                         fact and just add the value of the last discarded bit
4481                         to the least significant bit of the shifted value
4482                         from acc. */
4483                      assign(t15, binop(Iop_Shr64,
4484                                        mkexpr(t0),
4485                                        unop(Iop_32to8,
4486                                             binop(Iop_Sub32,
4487                                                   binop(Iop_And32,
4488                                                         mkU32(rs),
4489                                                         mkU32(0x1f)),
4490                                                   mkU32(1)))));
4491 
4492                      assign(t8,
4493                             IRExpr_ITE(mkexpr(t16),
4494                                        mkU64(0x0ULL),
4495                                        binop(Iop_And64,
4496                                              mkexpr(t15),
4497                                              mkU64(0x0000000000000001ULL))));
4498                      assign(t9, binop(Iop_Add64, mkexpr(t1), mkexpr(t8)));
4499                      putIReg(rt, unop(Iop_64to32, mkexpr(t9)));
4500 
4501                      /* Check if bits 63..31 of the result in t1 aren't 0. */
4502                      assign(t3, binop(Iop_CmpNE32,
4503                                       unop(Iop_64HIto32,
4504                                            mkexpr(t1)),
4505                                       mkU32(0)));
4506                      assign(t4, binop(Iop_CmpNE32,
4507                                       binop(Iop_And32,
4508                                             unop(Iop_64to32,
4509                                                  mkexpr(t1)),
4510                                             mkU32(0x80000000)),
4511                                       mkU32(0)));
4512 
4513                      /* Check if bits 63..31 of the result in t1 aren't
4514                         0x1ffffffff. */
4515                      assign(t5, binop(Iop_CmpNE32,
4516                                       unop(Iop_64HIto32,
4517                                            mkexpr(t1)),
4518                                       mkU32(0xffffffff)));
4519                      assign(t6, binop(Iop_CmpNE32,
4520                                       binop(Iop_And32,
4521                                             unop(Iop_64to32,
4522                                                  mkexpr(t1)),
4523                                             mkU32(0x80000000)),
4524                                       mkU32(0x80000000)));
4525                      /* If bits 63..31 aren't 0 nor 0x1ffffffff, set DSP
4526                         control register. */
4527                      assign(t7, binop(Iop_And32,
4528                                       binop(Iop_Or32,
4529                                             unop(Iop_1Sto32, mkexpr(t3)),
4530                                             unop(Iop_1Sto32, mkexpr(t4))),
4531                                       binop(Iop_Or32,
4532                                             unop(Iop_1Sto32, mkexpr(t5)),
4533                                             unop(Iop_1Sto32, mkexpr(t6)))));
4534                      putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32,
4535                                                     mkexpr(t7),
4536                                                     mkU32(0)),
4537                                               binop(Iop_Or32,
4538                                                     getDSPControl(),
4539                                                     mkU32(0x00800000)),
4540                                               getDSPControl()));
4541 
4542                      /* Repeat previous steps for the rounded value. */
4543                      assign(t10, binop(Iop_CmpNE32,
4544                                       unop(Iop_64HIto32,
4545                                            mkexpr(t9)),
4546                                       mkU32(0)));
4547                      assign(t11, binop(Iop_CmpNE32,
4548                                       binop(Iop_And32,
4549                                             unop(Iop_64to32,
4550                                                  mkexpr(t9)),
4551                                             mkU32(0x80000000)),
4552                                       mkU32(0)));
4553 
4554                      assign(t12, binop(Iop_CmpNE32,
4555                                       unop(Iop_64HIto32,
4556                                            mkexpr(t9)),
4557                                       mkU32(0xffffffff)));
4558                      assign(t13, binop(Iop_CmpNE32,
4559                                       binop(Iop_And32,
4560                                             unop(Iop_64to32,
4561                                                  mkexpr(t9)),
4562                                             mkU32(0x80000000)),
4563                                       mkU32(0x80000000)));
4564 
4565                      assign(t14, binop(Iop_And32,
4566                                       binop(Iop_Or32,
4567                                             unop(Iop_1Sto32, mkexpr(t10)),
4568                                             unop(Iop_1Sto32, mkexpr(t11))),
4569                                       binop(Iop_Or32,
4570                                             unop(Iop_1Sto32, mkexpr(t12)),
4571                                             unop(Iop_1Sto32, mkexpr(t13)))));
4572                      putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32,
4573                                                     mkexpr(t14),
4574                                                     mkU32(0)),
4575                                               binop(Iop_Or32,
4576                                                     getDSPControl(),
4577                                                     mkU32(0x00800000)),
4578                                               getDSPControl()));
4579                      break;
4580                   }
4581                   case 0x5: {  /* EXTRV_R.W */
4582                      DIP("extrv_r.w r%u, ac%u, r%u", rt, ac, rs);
4583                      vassert(!mode64);
4584                      t0 = newTemp(Ity_I64);
4585                      t1 = newTemp(Ity_I64);
4586                      t2 = newTemp(Ity_I32);
4587                      t3 = newTemp(Ity_I1);
4588                      t4 = newTemp(Ity_I1);
4589                      t5 = newTemp(Ity_I1);
4590                      t6 = newTemp(Ity_I1);
4591                      t7 = newTemp(Ity_I32);
4592                      t8 = newTemp(Ity_I64);
4593                      t9 = newTemp(Ity_I64);
4594                      t10 = newTemp(Ity_I1);
4595                      t11 = newTemp(Ity_I1);
4596                      t12 = newTemp(Ity_I1);
4597                      t13 = newTemp(Ity_I1);
4598                      t14 = newTemp(Ity_I32);
4599                      t15 = newTemp(Ity_I8);
4600 
4601                      assign(t15, unop(Iop_32to8,
4602                                       binop(Iop_And32,
4603                                             getIReg(rs),
4604                                             mkU32(0x1f))));
4605                      assign(t0, getAcc(ac));
4606                      assign(t1, binop(Iop_Sar64, mkexpr(t0), mkexpr(t15)));
4607 
4608                      /* Check if bits 63..31 of the result in t1 aren't 0. */
4609                      assign(t3, binop(Iop_CmpNE32,
4610                                       unop(Iop_64HIto32,
4611                                            mkexpr(t1)),
4612                                       mkU32(0)));
4613                      assign(t4, binop(Iop_CmpNE32,
4614                                       binop(Iop_And32,
4615                                             unop(Iop_64to32,
4616                                                  mkexpr(t1)),
4617                                             mkU32(0x80000000)),
4618                                       mkU32(0)));
4619                      /* Check if bits 63..31 of the result in t1 aren't
4620                         0x1ffffffff. */
4621                      assign(t5, binop(Iop_CmpNE32,
4622                                       unop(Iop_64HIto32,
4623                                            mkexpr(t1)),
4624                                       mkU32(0xffffffff)));
4625                      assign(t6, binop(Iop_CmpNE32,
4626                                       binop(Iop_And32,
4627                                             unop(Iop_64to32,
4628                                                  mkexpr(t1)),
4629                                             mkU32(0x80000000)),
4630                                       mkU32(0x80000000)));
4631                      /* If bits 63..31 aren't 0 nor 0x1ffffffff, set DSP
4632                         control register. */
4633                      assign(t7, binop(Iop_And32,
4634                                       binop(Iop_Or32,
4635                                             unop(Iop_1Sto32, mkexpr(t3)),
4636                                             unop(Iop_1Sto32, mkexpr(t4))),
4637                                       binop(Iop_Or32,
4638                                             unop(Iop_1Sto32, mkexpr(t5)),
4639                                             unop(Iop_1Sto32, mkexpr(t6)))));
4640                      putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32,
4641                                                     mkexpr(t7),
4642                                                     mkU32(0)),
4643                                               binop(Iop_Or32,
4644                                                     getDSPControl(),
4645                                                     mkU32(0x00800000)),
4646                                               getDSPControl()));
4647 
4648                      /* If the last discarded bit is 1, there would be carry
4649                         when rounding, otherwise there wouldn't. We use that
4650                         fact and just add the value of the last discarded bit
4651                         to the least sifgnificant bit of the shifted value
4652                         from acc. */
4653                      assign(t8,
4654                             IRExpr_ITE(binop(Iop_CmpEQ32,
4655                                              unop(Iop_8Uto32,
4656                                                   mkexpr(t15)),
4657                                              mkU32(0)),
4658                                        mkU64(0x0ULL),
4659                                        binop(Iop_And64,
4660                                              binop(Iop_Shr64,
4661                                                    mkexpr(t0),
4662                                                    unop(Iop_32to8,
4663                                                         binop(Iop_Sub32,
4664                                                               unop(Iop_8Uto32,
4665                                                                    mkexpr(t15)),
4666                                                                    mkU32(1)))),
4667                                              mkU64(0x1ULL))));
4668 
4669                      assign(t9, binop(Iop_Add64, mkexpr(t1), mkexpr(t8)));
4670                      /* Put rounded value in destination register. */
4671                      putIReg(rt, unop(Iop_64to32, mkexpr(t9)));
4672 
4673                      /* Repeat previous steps for the rounded value. */
4674                      assign(t10, binop(Iop_CmpNE32,
4675                                       unop(Iop_64HIto32,
4676                                            mkexpr(t9)),
4677                                       mkU32(0)));
4678                      assign(t11, binop(Iop_CmpNE32,
4679                                       binop(Iop_And32,
4680                                             unop(Iop_64to32,
4681                                                  mkexpr(t9)),
4682                                             mkU32(0x80000000)),
4683                                       mkU32(0)));
4684 
4685                      assign(t12, binop(Iop_CmpNE32,
4686                                       unop(Iop_64HIto32,
4687                                            mkexpr(t9)),
4688                                       mkU32(0xffffffff)));
4689                      assign(t13, binop(Iop_CmpNE32,
4690                                       binop(Iop_And32,
4691                                             unop(Iop_64to32,
4692                                                  mkexpr(t9)),
4693                                             mkU32(0x80000000)),
4694                                       mkU32(0x80000000)));
4695 
4696                      assign(t14, binop(Iop_And32,
4697                                       binop(Iop_Or32,
4698                                             unop(Iop_1Sto32, mkexpr(t10)),
4699                                             unop(Iop_1Sto32, mkexpr(t11))),
4700                                       binop(Iop_Or32,
4701                                             unop(Iop_1Sto32, mkexpr(t12)),
4702                                             unop(Iop_1Sto32, mkexpr(t13)))));
4703                      putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32,
4704                                                     mkexpr(t14),
4705                                                     mkU32(0)),
4706                                               binop(Iop_Or32,
4707                                                     getDSPControl(),
4708                                                     mkU32(0x00800000)),
4709                                               getDSPControl()));
4710                      break;
4711                   }
4712                   case 0x6: {  /* EXTR_RS.W */
4713                      DIP("extr_rs.w r%u, ac%u, %u", rt, ac, rs);
4714                      vassert(!mode64);
4715                      t0 = newTemp(Ity_I64);
4716                      t1 = newTemp(Ity_I64);
4717                      t2 = newTemp(Ity_I32);
4718                      t3 = newTemp(Ity_I1);
4719                      t4 = newTemp(Ity_I1);
4720                      t5 = newTemp(Ity_I1);
4721                      t6 = newTemp(Ity_I1);
4722                      t7 = newTemp(Ity_I32);
4723                      t8 = newTemp(Ity_I64);
4724                      t9 = newTemp(Ity_I64);
4725                      t10 = newTemp(Ity_I1);
4726                      t11 = newTemp(Ity_I1);
4727                      t12 = newTemp(Ity_I1);
4728                      t13 = newTemp(Ity_I1);
4729                      t14 = newTemp(Ity_I32);
4730                      t16 = newTemp(Ity_I32);
4731 
4732                      assign(t0, getAcc(ac));
4733                      if (0 == rs) {
4734                         assign(t1, mkexpr(t0));
4735                      } else {
4736                         assign(t1, binop(Iop_Sar64, mkexpr(t0), mkU8(rs)));
4737                      }
4738 
4739                      /* Check if bits 63..31 of the result in t1 aren't 0. */
4740                      assign(t3, binop(Iop_CmpNE32,
4741                                       unop(Iop_64HIto32,
4742                                            mkexpr(t1)),
4743                                       mkU32(0)));
4744                      assign(t4, binop(Iop_CmpNE32,
4745                                       binop(Iop_And32,
4746                                             unop(Iop_64to32,
4747                                                  mkexpr(t1)),
4748                                             mkU32(0x80000000)),
4749                                       mkU32(0)));
4750                      /* Check if bits 63..31 of the result in t1 aren't
4751                         0x1ffffffff. */
4752                      assign(t5, binop(Iop_CmpNE32,
4753                                       unop(Iop_64HIto32,
4754                                            mkexpr(t1)),
4755                                       mkU32(0xffffffff)));
4756                      assign(t6, binop(Iop_CmpNE32,
4757                                       binop(Iop_And32,
4758                                             unop(Iop_64to32,
4759                                                  mkexpr(t1)),
4760                                             mkU32(0x80000000)),
4761                                       mkU32(0x80000000)));
4762                      /* If bits 63..31 aren't 0 nor 0x1ffffffff, set DSP
4763                         control register. */
4764                      assign(t7, binop(Iop_And32,
4765                                       binop(Iop_Or32,
4766                                             unop(Iop_1Sto32, mkexpr(t3)),
4767                                             unop(Iop_1Sto32, mkexpr(t4))),
4768                                       binop(Iop_Or32,
4769                                             unop(Iop_1Sto32, mkexpr(t5)),
4770                                             unop(Iop_1Sto32, mkexpr(t6)))));
4771                      putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32,
4772                                                     mkexpr(t7),
4773                                                     mkU32(0)),
4774                                               binop(Iop_Or32,
4775                                                     getDSPControl(),
4776                                                     mkU32(0x00800000)),
4777                                               getDSPControl()));
4778 
4779                      /* If the last discarded bit is 1, there would be carry
4780                         when rounding, otherwise there wouldn't. We use that
4781                         fact and just add the value of the last discarded bit
4782                         to the least sifgnificant bit of the shifted value
4783                         from acc. */
4784                      if (0 == rs) {
4785                         assign(t8, mkU64(0x0ULL));
4786                      } else {
4787                         assign(t8, binop(Iop_And64,
4788                                          binop(Iop_Shr64,
4789                                                mkexpr(t0),
4790                                                mkU8(rs-1)),
4791                                          mkU64(0x1ULL)));
4792                      }
4793 
4794                      assign(t9, binop(Iop_Add64, mkexpr(t1), mkexpr(t8)));
4795 
4796                      /* Repeat previous steps for the rounded value. */
4797                      assign(t10, binop(Iop_CmpNE32,
4798                                       unop(Iop_64HIto32,
4799                                            mkexpr(t9)),
4800                                       mkU32(0)));
4801                      assign(t11, binop(Iop_CmpNE32,
4802                                       binop(Iop_And32,
4803                                             unop(Iop_64to32,
4804                                                  mkexpr(t9)),
4805                                             mkU32(0x80000000)),
4806                                       mkU32(0)));
4807 
4808                      assign(t12, binop(Iop_CmpNE32,
4809                                       unop(Iop_64HIto32,
4810                                            mkexpr(t9)),
4811                                       mkU32(0xffffffff)));
4812                      assign(t13, binop(Iop_CmpNE32,
4813                                       binop(Iop_And32,
4814                                             unop(Iop_64to32,
4815                                                  mkexpr(t9)),
4816                                             mkU32(0x80000000)),
4817                                       mkU32(0x80000000)));
4818 
4819                      assign(t14, binop(Iop_And32,
4820                                       binop(Iop_Or32,
4821                                             unop(Iop_1Sto32, mkexpr(t10)),
4822                                             unop(Iop_1Sto32, mkexpr(t11))),
4823                                       binop(Iop_Or32,
4824                                             unop(Iop_1Sto32, mkexpr(t12)),
4825                                             unop(Iop_1Sto32, mkexpr(t13)))));
4826                      putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32,
4827                                                     mkexpr(t14),
4828                                                     mkU32(0)),
4829                                               binop(Iop_Or32,
4830                                                     getDSPControl(),
4831                                                     mkU32(0x00800000)),
4832                                               getDSPControl()));
4833 
4834                      assign(t16, binop(Iop_And32,
4835                                        unop(Iop_64HIto32,
4836                                             mkexpr(t9)),
4837                                        mkU32(0x80000000)));
4838                      putIReg(rt, IRExpr_ITE(binop(Iop_CmpNE32,
4839                                                   mkexpr(t14),
4840                                                   mkU32(0)),
4841                                             IRExpr_ITE(binop(Iop_CmpEQ32,
4842                                                              mkexpr(t16),
4843                                                              mkU32(0)),
4844                                                        mkU32(0x7fffffff),
4845                                                        mkU32(0x80000000)),
4846                                             unop(Iop_64to32, mkexpr(t9))));
4847                      break;
4848                   }
4849                   case 0x7: {  /* EXTRV_RS.W */
4850                      DIP("extrv_rs.w r%u, ac%u, r%u", rt, ac, rs);
4851                      vassert(!mode64);
4852                      t0 = newTemp(Ity_I64);
4853                      t1 = newTemp(Ity_I64);
4854                      t2 = newTemp(Ity_I32);
4855                      t3 = newTemp(Ity_I1);
4856                      t4 = newTemp(Ity_I1);
4857                      t5 = newTemp(Ity_I1);
4858                      t6 = newTemp(Ity_I1);
4859                      t7 = newTemp(Ity_I32);
4860                      t8 = newTemp(Ity_I64);
4861                      t9 = newTemp(Ity_I64);
4862                      t10 = newTemp(Ity_I1);
4863                      t11 = newTemp(Ity_I1);
4864                      t12 = newTemp(Ity_I1);
4865                      t13 = newTemp(Ity_I1);
4866                      t14 = newTemp(Ity_I32);
4867                      t15 = newTemp(Ity_I32);
4868                      t16 = newTemp(Ity_I32);
4869                      t17 = newTemp(Ity_I1);
4870 
4871                      assign(t15, binop(Iop_And32,
4872                                        getIReg(rs),
4873                                        mkU32(0x1f)));
4874                      assign(t17, binop(Iop_CmpEQ32,
4875                                        mkexpr(t15),
4876                                        mkU32(0)));
4877                      assign(t0, getAcc(ac));
4878                      assign(t1, IRExpr_ITE(mkexpr(t17),
4879                                            mkexpr(t0),
4880                                            binop(Iop_Sar64,
4881                                                  mkexpr(t0),
4882                                                  unop(Iop_32to8,
4883                                                       mkexpr(t15)))));
4884 
4885                      /* Check if bits 63..31 of the result in t1 aren't 0. */
4886                      assign(t3, binop(Iop_CmpNE32,
4887                                       unop(Iop_64HIto32,
4888                                            mkexpr(t1)),
4889                                       mkU32(0)));
4890                      assign(t4, binop(Iop_CmpNE32,
4891                                       binop(Iop_And32,
4892                                             unop(Iop_64to32,
4893                                                  mkexpr(t1)),
4894                                             mkU32(0x80000000)),
4895                                       mkU32(0)));
4896                      /* Check if bits 63..31 of the result in t1 aren't
4897                         0x1ffffffff. */
4898                      assign(t5, binop(Iop_CmpNE32,
4899                                       unop(Iop_64HIto32,
4900                                            mkexpr(t1)),
4901                                       mkU32(0xffffffff)));
4902                      assign(t6, binop(Iop_CmpNE32,
4903                                       binop(Iop_And32,
4904                                             unop(Iop_64to32,
4905                                                  mkexpr(t1)),
4906                                             mkU32(0x80000000)),
4907                                       mkU32(0x80000000)));
4908                      /* If bits 63..31 aren't 0 nor 0x1ffffffff, set DSP
4909                         control register. */
4910                      assign(t7, binop(Iop_And32,
4911                                       binop(Iop_Or32,
4912                                             unop(Iop_1Sto32, mkexpr(t3)),
4913                                             unop(Iop_1Sto32, mkexpr(t4))),
4914                                       binop(Iop_Or32,
4915                                             unop(Iop_1Sto32, mkexpr(t5)),
4916                                             unop(Iop_1Sto32, mkexpr(t6)))));
4917                      putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32,
4918                                                     mkexpr(t7),
4919                                                     mkU32(0)),
4920                                               binop(Iop_Or32,
4921                                                     getDSPControl(),
4922                                                     mkU32(0x00800000)),
4923                                               getDSPControl()));
4924 
4925                      /* If the last discarded bit is 1, there would be carry
4926                         when rounding, otherwise there wouldn't. We use that
4927                         fact and just add the value of the last discarded bit
4928                         to the least sifgnificant bit of the shifted value
4929                         from acc. */
4930                      assign(t8,
4931                             IRExpr_ITE(mkexpr(t17),
4932                                        mkU64(0x0ULL),
4933                                        binop(Iop_And64,
4934                                              binop(Iop_Shr64,
4935                                                    mkexpr(t0),
4936                                                    unop(Iop_32to8,
4937                                                         binop(Iop_Sub32,
4938                                                               mkexpr(t15),
4939                                                               mkU32(1)))),
4940                                              mkU64(0x1ULL))));
4941 
4942                      assign(t9, binop(Iop_Add64, mkexpr(t1), mkexpr(t8)));
4943 
4944                      /* Repeat previous steps for the rounded value. */
4945                      assign(t10, binop(Iop_CmpNE32,
4946                                       unop(Iop_64HIto32,
4947                                            mkexpr(t9)),
4948                                       mkU32(0)));
4949                      assign(t11, binop(Iop_CmpNE32,
4950                                       binop(Iop_And32,
4951                                             unop(Iop_64to32,
4952                                                  mkexpr(t9)),
4953                                             mkU32(0x80000000)),
4954                                       mkU32(0)));
4955 
4956                      assign(t12, binop(Iop_CmpNE32,
4957                                       unop(Iop_64HIto32,
4958                                            mkexpr(t9)),
4959                                       mkU32(0xffffffff)));
4960                      assign(t13, binop(Iop_CmpNE32,
4961                                       binop(Iop_And32,
4962                                             unop(Iop_64to32,
4963                                                  mkexpr(t9)),
4964                                             mkU32(0x80000000)),
4965                                       mkU32(0x80000000)));
4966 
4967                      assign(t14, binop(Iop_And32,
4968                                       binop(Iop_Or32,
4969                                             unop(Iop_1Sto32, mkexpr(t10)),
4970                                             unop(Iop_1Sto32, mkexpr(t11))),
4971                                       binop(Iop_Or32,
4972                                             unop(Iop_1Sto32, mkexpr(t12)),
4973                                             unop(Iop_1Sto32, mkexpr(t13)))));
4974                      putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32,
4975                                                     mkexpr(t14),
4976                                                     mkU32(0)),
4977                                               binop(Iop_Or32,
4978                                                     getDSPControl(),
4979                                                     mkU32(0x00800000)),
4980                                               getDSPControl()));
4981 
4982                      assign(t16, binop(Iop_And32,
4983                                        unop(Iop_64HIto32,
4984                                             mkexpr(t9)),
4985                                        mkU32(0x80000000)));
4986                      putIReg(rt, IRExpr_ITE(binop(Iop_CmpNE32,
4987                                                   mkexpr(t14),
4988                                                   mkU32(0)),
4989                                             IRExpr_ITE(binop(Iop_CmpEQ32,
4990                                                              mkexpr(t16),
4991                                                              mkU32(0)),
4992                                                        mkU32(0x7fffffff),
4993                                                        mkU32(0x80000000)),
4994                                             unop(Iop_64to32, mkexpr(t9))));
4995                      break;
4996                   }
4997                   case 0xA: {  /* EXTPDP */
4998                      DIP("extpdp r%u, ac%u, %u", rt, ac, rs);
4999                      vassert(!mode64);
5000                      t0 = newTemp(Ity_I64);
5001                      t1 = newTemp(Ity_I32);
5002                      t2 = newTemp(Ity_I1);
5003                      t3 = newTemp(Ity_I1);
5004                      t4 = newTemp(Ity_I8);
5005                      t5 = newTemp(Ity_I64);
5006                      t6 = newTemp(Ity_I64);
5007                      t7 = newTemp(Ity_I32);
5008                      t8 = newTemp(Ity_I32);
5009 
5010                      assign(t0, getAcc(ac));
5011                      /* Extract pos field of DSPControl register. */
5012                      assign(t1, binop(Iop_And32, getDSPControl(), mkU32(0x3f)));
5013 
5014                      /* Check if (pos - size) >= 0 [size <= pos]
5015                         if (pos < size)
5016                            put 1 to EFI field of DSPControl register
5017                         else
5018                            extract bits from acc and put 0 to EFI field of
5019                            DSPCtrl */
5020                      assign(t2, binop(Iop_CmpLT32U, mkexpr(t1), mkU32(rs)));
5021 
5022                      assign(t8, binop(Iop_Or32,
5023                                       binop(Iop_And32,
5024                                             getDSPControl(),
5025                                             mkU32(0xffffbfc0)),
5026                                       binop(Iop_And32,
5027                                             binop(Iop_Sub32,
5028                                                   binop(Iop_And32,
5029                                                         getDSPControl(),
5030                                                         mkU32(0x3f)),
5031                                                   mkU32(rs+1)),
5032                                             mkU32(0x3f))));
5033                      putDSPControl(IRExpr_ITE(mkexpr(t2),
5034                                               binop(Iop_Or32,
5035                                                      binop(Iop_And32,
5036                                                            getDSPControl(),
5037                                                            mkU32(0xffffbfff)),
5038                                                      mkU32(0x4000)),
5039                                               mkexpr(t8)));
5040 
5041                      /* If pos <= 31, shift right the value from the acc
5042                         (pos-size) times and take (size+1) bits from the least
5043                         significant positions. Otherwise, shift left the value
5044                         (63-pos) times, take (size+1) bits from the most
5045                         significant positions and shift right (31-size) times.
5046                      */
5047                      assign(t3, binop(Iop_CmpLE32U, mkexpr(t1), mkU32(31)));
5048 
5049                      assign(t4,
5050                             IRExpr_ITE(mkexpr(t3),
5051                                        unop(Iop_32to8,
5052                                             binop(Iop_Sub32,
5053                                                   mkexpr(t1), mkU32(rs))),
5054                                        unop(Iop_32to8,
5055                                             binop(Iop_Sub32,
5056                                                   mkU32(63), mkexpr(t1)))));
5057 
5058                      assign(t5, IRExpr_ITE(mkexpr(t3),
5059                                            binop(Iop_Shr64,
5060                                                  mkexpr(t0), mkexpr(t4)),
5061                                            binop(Iop_Shl64,
5062                                                  mkexpr(t0), mkexpr(t4))));
5063 
5064                      /* t6 holds a mask for bit extraction. */
5065                      assign(t6,
5066                             IRExpr_ITE(mkexpr(t3),
5067                                        unop(Iop_Not64,
5068                                             binop(Iop_Shl64,
5069                                                   mkU64(0xffffffffffffffffULL),
5070                                                   mkU8(rs+1))),
5071                                        unop(Iop_Not64,
5072                                             binop(Iop_Shr64,
5073                                                   mkU64(0xffffffffffffffffULL),
5074                                                   mkU8(rs+1)))));
5075 
5076                      assign(t7, IRExpr_ITE(mkexpr(t3),
5077                                            unop(Iop_64to32,
5078                                                 binop(Iop_And64,
5079                                                       mkexpr(t5),
5080                                                       mkexpr(t6))),
5081                                            binop(Iop_Shr32,
5082                                                  unop(Iop_64HIto32,
5083                                                       binop(Iop_And64,
5084                                                             mkexpr(t5),
5085                                                             mkexpr(t6))),
5086                                                  mkU8(31-rs))));
5087 
5088                      putIReg(rt, mkexpr(t7));
5089                      break;
5090                   }
5091                   case 0xB: {  /* EXTPDPV */
5092                      DIP("extpdpv r%u, ac%u, r%u", rt, ac, rs);
5093                      vassert(!mode64);
5094                      t0 = newTemp(Ity_I64);
5095                      t1 = newTemp(Ity_I32);
5096                      t2 = newTemp(Ity_I1);
5097                      t3 = newTemp(Ity_I1);
5098                      t4 = newTemp(Ity_I8);
5099                      t5 = newTemp(Ity_I64);
5100                      t6 = newTemp(Ity_I64);
5101                      t7 = newTemp(Ity_I32);
5102                      t8 = newTemp(Ity_I32);
5103                      t9 = newTemp(Ity_I32);
5104 
5105                      assign(t8, binop(Iop_And32, getIReg(rs), mkU32(0x1f)));
5106                      assign(t0, getAcc(ac));
5107                      /* Extract pos field of DSPControl register. */
5108                      assign(t1, binop(Iop_And32, getDSPControl(), mkU32(0x3f)));
5109 
5110                      /* Check if (pos - size) >= 0 [size <= pos]
5111                         if (pos < size)
5112                            put 1 to EFI field of DSPControl register
5113                         else
5114                            extract bits from acc and put 0 to EFI field of
5115                            DSPCtrl */
5116                      assign(t2, binop(Iop_CmpLT32U, mkexpr(t1), mkexpr(t8)));
5117 
5118                      assign(t9, binop(Iop_Or32,
5119                                       binop(Iop_And32,
5120                                             getDSPControl(),
5121                                             mkU32(0xffffbfc0)),
5122                                       binop(Iop_And32,
5123                                             binop(Iop_Sub32,
5124                                                   binop(Iop_And32,
5125                                                         getDSPControl(),
5126                                                         mkU32(0x3f)),
5127                                                   binop(Iop_Add32,
5128                                                         mkexpr(t8),
5129                                                         mkU32(0x1))),
5130                                             mkU32(0x3f))));
5131                      putDSPControl(IRExpr_ITE(mkexpr(t2),
5132                                               binop(Iop_Or32,
5133                                                     binop(Iop_And32,
5134                                                           getDSPControl(),
5135                                                           mkU32(0xffffbfff)),
5136                                                     mkU32(0x4000)),
5137                                               mkexpr(t9)));
5138 
5139                      /* If pos <= 31, shift right the value from the acc
5140                         (pos-size) times and take (size+1) bits from the least
5141                         significant positions. Otherwise, shift left the value
5142                         (63-pos) times, take (size+1) bits from the most
5143                         significant positions and shift right (31-size) times.
5144                      */
5145                      assign(t3, binop(Iop_CmpLE32U, mkexpr(t1), mkU32(31)));
5146 
5147                      assign(t4,
5148                             IRExpr_ITE(mkexpr(t3),
5149                                       unop(Iop_32to8,
5150                                            binop(Iop_Sub32,
5151                                                  mkexpr(t1), mkexpr(t8))),
5152                                       unop(Iop_32to8,
5153                                            binop(Iop_Sub32,
5154                                                  mkU32(63), mkexpr(t1)))));
5155 
5156                      assign(t5, IRExpr_ITE(mkexpr(t3),
5157                                            binop(Iop_Shr64,
5158                                                  mkexpr(t0), mkexpr(t4)),
5159                                            binop(Iop_Shl64,
5160                                                  mkexpr(t0), mkexpr(t4))));
5161 
5162                      /* t6 holds a mask for bit extraction. */
5163                      assign(t6,
5164                             IRExpr_ITE(mkexpr(t3),
5165                                        unop(Iop_Not64,
5166                                             binop(Iop_Shl64,
5167                                                   mkU64(0xffffffffffffffffULL),
5168                                                   unop(Iop_32to8,
5169                                                        binop(Iop_Add32,
5170                                                              mkexpr(t8),
5171                                                              mkU32(1))))),
5172                                        unop(Iop_Not64,
5173                                             binop(Iop_Shr64,
5174                                                   mkU64(0xffffffffffffffffULL),
5175                                                   unop(Iop_32to8,
5176                                                        binop(Iop_Add32,
5177                                                              mkexpr(t8),
5178                                                              mkU32(1)))))));
5179 
5180                      assign(t7, IRExpr_ITE(mkexpr(t3),
5181                                            unop(Iop_64to32,
5182                                                 binop(Iop_And64,
5183                                                       mkexpr(t5),
5184                                                       mkexpr(t6))),
5185                                            binop(Iop_Shr32,
5186                                                  unop(Iop_64HIto32,
5187                                                       binop(Iop_And64,
5188                                                             mkexpr(t5),
5189                                                             mkexpr(t6))),
5190                                                  unop(Iop_32to8,
5191                                                       binop(Iop_Sub32,
5192                                                             mkU32(31),
5193                                                             mkexpr(t8))))));
5194 
5195                      putIReg(rt, mkexpr(t7));
5196                      break;
5197                   }
5198                   case 0xE: {  /* EXTR_S.H */
5199                      DIP("extr_s.h r%u, ac%u, %u", rt, ac, rs);
5200                      vassert(!mode64);
5201                      t0 = newTemp(Ity_I64);
5202                      t1 = newTemp(Ity_I64);
5203                      t2 = newTemp(Ity_I32);
5204                      t3 = newTemp(Ity_I64);
5205                      t4 = newTemp(Ity_I32);
5206                      t5 = newTemp(Ity_I32);
5207                      t6 = newTemp(Ity_I64);
5208                      t7 = newTemp(Ity_I32);
5209                      t9 = newTemp(Ity_I32);
5210 
5211                      assign(t0, getAcc(ac));
5212 
5213                      assign(t1, binop(Iop_Sar64, mkexpr(t0), mkU8(rs)));
5214 
5215                      assign(t2, binop(Iop_Or32,
5216                                       getDSPControl(), mkU32(0x00800000)));
5217 
5218                      assign(t9, binop(Iop_And32,
5219                                       unop(Iop_64to32,
5220                                            mkexpr(t1)),
5221                                       mkU32(0x80000000)));
5222                      putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32,
5223                                                     mkexpr(t9),
5224                                                     binop(Iop_And32,
5225                                                           unop(Iop_64HIto32,
5226                                                                mkexpr(t0)),
5227                                                           mkU32(0x80000000))),
5228                                               mkexpr(t2),
5229                                               getDSPControl()));
5230 
5231                      /* Check if t1 > 0x7fff ((t1 - 0x7fff) > 0)
5232                         1. subtract 0x7fff from t1
5233                         2. if the resulting number is positive (sign bit = 0)
5234                            and any of the other bits is 1, the value is > 0. */
5235                      assign(t3, binop(Iop_Sub64,
5236                                       mkexpr(t1),
5237                                       mkU64(0x0000000000007fffULL)));
5238                      assign(t4, binop(Iop_And32,
5239                                        binop(Iop_Or32,
5240                                             unop(Iop_1Sto32,
5241                                                  binop(Iop_CmpNE32,
5242                                                        mkU32(0),
5243                                                        binop(Iop_And32,
5244                                                              unop(Iop_64HIto32,
5245                                                                   mkexpr(t3)),
5246                                                              mkU32(0x7fffffff)))),
5247                                             unop(Iop_1Sto32,
5248                                                  binop(Iop_CmpNE32,
5249                                                        mkU32(0),
5250                                                        unop(Iop_64to32,
5251                                                             mkexpr(t3))))),
5252                                        unop(Iop_1Sto32,
5253                                             binop(Iop_CmpEQ32,
5254                                                   binop(Iop_And32,
5255                                                         unop(Iop_64HIto32,
5256                                                                   mkexpr(t3)),
5257                                                              mkU32(0x80000000)),
5258                                                   mkU32(0)))));
5259                      putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32,
5260                                                     mkU32(0),
5261                                                     mkexpr(t4)),
5262                                               binop(Iop_Or32,
5263                                                     getDSPControl(),
5264                                                     mkU32(0x00800000)),
5265                                               getDSPControl()));
5266                      /* Check if t1<0xffffffffffff8000 (0xffffffffffff8000-t1)>0
5267                         1. subtract t1 from 0xffffffffffff8000
5268                         2. if the resulting number is positive (sign bit = 0)
5269                             and any of the other bits is 1, the value is > 0 */
5270                      assign(t6, binop(Iop_Sub64,
5271                                        mkU64(0xffffffffffff8000ULL),
5272                                        mkexpr(t1)));
5273                      assign(t7, binop(Iop_And32,
5274                                       binop(Iop_Or32,
5275                                             unop(Iop_1Sto32,
5276                                                  binop(Iop_CmpNE32,
5277                                                        mkU32(0),
5278                                                        binop(Iop_And32,
5279                                                              unop(Iop_64HIto32,
5280                                                                   mkexpr(t6)),
5281                                                              mkU32(0x7fffffff)))),
5282                                             unop(Iop_1Sto32,
5283                                                  binop(Iop_CmpNE32,
5284                                                        mkU32(0),
5285                                                        unop(Iop_64to32,
5286                                                             mkexpr(t6))))),
5287                                       unop(Iop_1Sto32,
5288                                             binop(Iop_CmpEQ32,
5289                                                   binop(Iop_And32,
5290                                                         unop(Iop_64HIto32,
5291                                                                   mkexpr(t6)),
5292                                                              mkU32(0x80000000)),
5293                                                   mkU32(0)))));
5294                      putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32,
5295                                                     mkU32(0),
5296                                                     mkexpr(t7)),
5297                                               binop(Iop_Or32,
5298                                                     getDSPControl(),
5299                                                     mkU32(0x00800000)),
5300                                               getDSPControl()));
5301                      putIReg(rt, IRExpr_ITE(binop(Iop_CmpNE32,
5302                                                     mkU32(0),
5303                                                     mkexpr(t4)),
5304                                             mkU32(0x00007fff),
5305                                             IRExpr_ITE(binop(Iop_CmpNE32,
5306                                                              mkU32(0),
5307                                                              mkexpr(t7)),
5308                                                        mkU32(0xffff8000),
5309                                                        unop(Iop_64to32,
5310                                                             mkexpr(t1)))));
5311                      break;
5312                   }
5313                   case 0xF: {  /* EXTRV_S.H */
5314                      DIP("extrv_s.h r%u, ac%u, %u", rt, ac, rs);
5315                      vassert(!mode64);
5316                      t0 = newTemp(Ity_I64);
5317                      t1 = newTemp(Ity_I64);
5318                      t2 = newTemp(Ity_I32);
5319                      t3 = newTemp(Ity_I64);
5320                      t4 = newTemp(Ity_I32);
5321                      t5 = newTemp(Ity_I32);
5322                      t6 = newTemp(Ity_I64);
5323                      t7 = newTemp(Ity_I32);
5324                      t9 = newTemp(Ity_I32);
5325 
5326                      assign(t0, getAcc(ac));
5327 
5328                      assign(t1, binop(Iop_Sar64,
5329                                       mkexpr(t0),
5330                                       unop(Iop_32to8,
5331                                            binop(Iop_And32,
5332                                                  getIReg(rs),
5333                                                  mkU32(0x1f)))));
5334 
5335                      assign(t2, binop(Iop_Or32,
5336                                       getDSPControl(), mkU32(0x00800000)));
5337 
5338                      assign(t9, binop(Iop_And32,
5339                                       unop(Iop_64to32,
5340                                            mkexpr(t1)),
5341                                       mkU32(0x80000000)));
5342                      putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32,
5343                                                     mkexpr(t9),
5344                                                     binop(Iop_And32,
5345                                                           unop(Iop_64HIto32,
5346                                                                mkexpr(t0)),
5347                                                           mkU32(0x80000000))),
5348                                               mkexpr(t2),
5349                                               getDSPControl()));
5350 
5351                      /* Check if t1 > 0x7fff ((t1 - 0x7fff) > 0)
5352                         1. subtract 0x7fff from t1
5353                         2. if the resulting number is positive (sign bit = 0)
5354                            and any of the other bits is 1, the value is > 0. */
5355                      assign(t3, binop(Iop_Sub64,
5356                                       mkexpr(t1),
5357                                       mkU64(0x0000000000007fffULL)));
5358                      assign(t4, binop(Iop_And32,
5359                                        binop(Iop_Or32,
5360                                             unop(Iop_1Sto32,
5361                                                  binop(Iop_CmpNE32,
5362                                                        mkU32(0),
5363                                                        binop(Iop_And32,
5364                                                              unop(Iop_64HIto32,
5365                                                                   mkexpr(t3)),
5366                                                              mkU32(0x7fffffff)))),
5367                                             unop(Iop_1Sto32,
5368                                                  binop(Iop_CmpNE32,
5369                                                        mkU32(0),
5370                                                        unop(Iop_64to32,
5371                                                             mkexpr(t3))))),
5372                                        unop(Iop_1Sto32,
5373                                             binop(Iop_CmpEQ32,
5374                                                   binop(Iop_And32,
5375                                                         unop(Iop_64HIto32,
5376                                                                   mkexpr(t3)),
5377                                                              mkU32(0x80000000)),
5378                                                   mkU32(0)))));
5379                      putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32,
5380                                                     mkU32(0),
5381                                                     mkexpr(t4)),
5382                                               binop(Iop_Or32,
5383                                                     getDSPControl(),
5384                                                     mkU32(0x00800000)),
5385                                               getDSPControl()));
5386                      /* Check if t1<0xffffffffffff8000 (0xffffffffffff8000-t1)>0
5387                         1. subtract t1 from 0xffffffffffff8000
5388                         2. if the resulting number is positive (sign bit = 0)
5389                             and any of the other bits is 1, the value is > 0 */
5390                      assign(t6, binop(Iop_Sub64,
5391                                        mkU64(0xffffffffffff8000ULL),
5392                                        mkexpr(t1)));
5393                      assign(t7, binop(Iop_And32,
5394                                       binop(Iop_Or32,
5395                                             unop(Iop_1Sto32,
5396                                                  binop(Iop_CmpNE32,
5397                                                        mkU32(0),
5398                                                        binop(Iop_And32,
5399                                                              unop(Iop_64HIto32,
5400                                                                   mkexpr(t6)),
5401                                                              mkU32(0x7fffffff)))),
5402                                             unop(Iop_1Sto32,
5403                                                  binop(Iop_CmpNE32,
5404                                                        mkU32(0),
5405                                                        unop(Iop_64to32,
5406                                                             mkexpr(t6))))),
5407                                       unop(Iop_1Sto32,
5408                                             binop(Iop_CmpEQ32,
5409                                                   binop(Iop_And32,
5410                                                         unop(Iop_64HIto32,
5411                                                                   mkexpr(t6)),
5412                                                              mkU32(0x80000000)),
5413                                                   mkU32(0)))));
5414                      putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32,
5415                                                     mkU32(0),
5416                                                     mkexpr(t7)),
5417                                               binop(Iop_Or32,
5418                                                     getDSPControl(),
5419                                                     mkU32(0x00800000)),
5420                                               getDSPControl()));
5421                      putIReg(rt, IRExpr_ITE(binop(Iop_CmpNE32,
5422                                                     mkU32(0),
5423                                                     mkexpr(t4)),
5424                                             mkU32(0x00007fff),
5425                                             IRExpr_ITE(binop(Iop_CmpNE32,
5426                                                              mkU32(0),
5427                                                              mkexpr(t7)),
5428                                                        mkU32(0xffff8000),
5429                                                        unop(Iop_64to32,
5430                                                             mkexpr(t1)))));
5431                      break;
5432                   }
5433                   case 0x12: {  /* RDDSP*/
5434                      DIP("rddsp r%u, mask 0x%x", rd, rddsp_mask);
5435                      vassert(!mode64);
5436 
5437                      putIReg(rd, mkU32(0x0));
5438 
5439                      if ((rddsp_mask & 0x1) == 0x1) {
5440                         /* Read pos field (bits 5-0) of DSPControl register. */
5441                         putIReg(rd, binop(Iop_Or32,
5442                                           getIReg(rd),
5443                                           binop(Iop_And32,
5444                                                 getDSPControl(),
5445                                                 mkU32(0x0000003F))));
5446                      }
5447 
5448                      if ((rddsp_mask & 0x2) == 0x2) {
5449                         /* Read scount field (bits 12-7) of DSPControl
5450                            register. */
5451                         putIReg(rd, binop(Iop_Or32,
5452                                           getIReg(rd),
5453                                           binop(Iop_And32,
5454                                                 getDSPControl(),
5455                                                 mkU32(0x00001F80))));
5456                      }
5457 
5458                      if ((rddsp_mask & 0x4) == 0x4) {
5459                         /* Read C field (bit 13) of DSPControl register. */
5460                         putIReg(rd, binop(Iop_Or32,
5461                                           getIReg(rd),
5462                                           binop(Iop_And32,
5463                                                 getDSPControl(),
5464                                                 mkU32(0x00002000))));
5465                      }
5466 
5467                      if ((rddsp_mask & 0x8) == 0x8) {
5468                         /* Read outflag field (bit s 23-16) of DSPControl
5469                            register. */
5470                         putIReg(rd, binop(Iop_Or32,
5471                                           getIReg(rd),
5472                                           binop(Iop_And32,
5473                                                 getDSPControl(),
5474                                                 mkU32(0x00FF0000))));
5475                      }
5476 
5477                      if ((rddsp_mask & 0x10) == 0x10) {
5478                         /* Read ccond field (bits 31-24) of DSPControl
5479                            register. */
5480                         putIReg(rd, binop(Iop_Or32,
5481                                           getIReg(rd),
5482                                           binop(Iop_And32,
5483                                                 getDSPControl(),
5484                                                 mkU32(0xFF000000))));
5485                      }
5486 
5487                      if ((rddsp_mask & 0x20) == 0x20) {
5488                         /* Read EFI field (bit 14) of DSPControl register. */
5489                         putIReg(rd, binop(Iop_Or32,
5490                                           getIReg(rd),
5491                                           binop(Iop_And32,
5492                                                 getDSPControl(),
5493                                                 mkU32(0x00004000))));
5494                      }
5495 
5496                      if ((rddsp_mask & 0x3f) == 0x3f) {
5497                         /* Read all fields of DSPControl register. */
5498                         putIReg(rd, getDSPControl());
5499                      }
5500                      break;
5501                   }
5502                   case 0x13: {  /* WRDSP */
5503                      DIP("wrdsp r%u, mask 0x%x", rs, wrdsp_mask);
5504                      vassert(!mode64);
5505 
5506                      if ((wrdsp_mask & 0x3f) == 0x3f) {
5507                         /* If mips64 put all fields of rs, except bit 15 and bit
5508                            6, to DSPControl register, otherwise put all except
5509                            bits 15, 6 and bits 31..28. */
5510                         putDSPControl(mode64 ?
5511                                       binop(Iop_And32,
5512                                             getIReg(rs),
5513                                             mkU32(0xffff7fbf)) :
5514                                       binop(Iop_And32,
5515                                             getIReg(rs),
5516                                             mkU32(0x0fff7fbf)));
5517                      } else {
5518                         if ((wrdsp_mask & 0x1) == 0x1) {
5519                            /* Put bits 5-0 of rs to DSPControl register pos
5520                               field. */
5521                            putDSPControl(binop(Iop_Or32,
5522                                                binop(Iop_And32,
5523                                                      getDSPControl(),
5524                                                      mkU32(0xFFFF7F40)),
5525                                                binop(Iop_And32,
5526                                                      getIReg(rs),
5527                                                      mkU32(0x0000003F))));
5528                         }
5529 
5530                         if ((wrdsp_mask & 0x2) == 0x2) {
5531                            /* Put bits 12-7 of rs to DSPControl scount field. */
5532                            putDSPControl(binop(Iop_Or32,
5533                                                binop(Iop_And32,
5534                                                      getDSPControl(),
5535                                                      mkU32(0xFFFFE03F)),
5536                                                binop(Iop_And32,
5537                                                      getIReg(rs),
5538                                                      mkU32(0x00001F80))));
5539                         }
5540 
5541                         if ((wrdsp_mask & 0x4) == 0x4) {
5542                            /* Put bit 13 of rs to DSPControl register C
5543                               field. */
5544                            putDSPControl(binop(Iop_Or32,
5545                                                binop(Iop_And32,
5546                                                      getDSPControl(),
5547                                                      mkU32(0xFFFF5FBF)),
5548                                                binop(Iop_And32,
5549                                                      getIReg(rs),
5550                                                      mkU32(0x00002000))));
5551                         }
5552 
5553                         if ((wrdsp_mask & 0x8) == 0x8) {
5554                            /* Put bits 23-16 of rs to DSPControl reg outflag
5555                               field. */
5556                            putDSPControl(binop(Iop_Or32,
5557                                                binop(Iop_And32,
5558                                                      getDSPControl(),
5559                                                      mkU32(0xFF007FBF)),
5560                                                binop(Iop_And32,
5561                                                      getIReg(rs),
5562                                                      mkU32(0x00FF0000))));
5563                         }
5564 
5565                         if ((wrdsp_mask & 0x10) == 0x10) {
5566                            /* Put bits 31-24 of rs to DSPControl reg ccond
5567                               field. */
5568                            putDSPControl(binop(Iop_Or32,
5569                                                binop(Iop_And32,
5570                                                      getDSPControl(),
5571                                                      mkU32(0x00FF7FBF)),
5572                                                binop(Iop_And32,
5573                                                      getIReg(rs),
5574                                                      mode64 ? mkU32(0xFF000000)
5575                                                             : mkU32(0x0F000000))
5576                                                )
5577                                         );
5578                         }
5579 
5580                         if ((wrdsp_mask & 0x20) == 0x20) {
5581                            /* Put bit 14 of rs to DSPControl register EFI
5582                               field. */
5583                            putDSPControl(binop(Iop_Or32,
5584                                                binop(Iop_And32,
5585                                                      getDSPControl(),
5586                                                      mkU32(0xFFFF3FBF)),
5587                                                binop(Iop_And32,
5588                                                      getIReg(rs),
5589                                                      mkU32(0x00004000))));
5590                         }
5591                      }
5592                      break;
5593                   }
5594                   case 0x1A: {  /* SHILO */
5595                      DIP("shilo ac%u, %u", ac, shift);
5596                      vassert(!mode64);
5597                      t0 = newTemp(Ity_I64);
5598                      t1 = newTemp(Ity_I64);
5599 
5600                      assign(t0, getAcc(ac));
5601 
5602                      putAcc(ac, mkexpr(t0));
5603 
5604                      if (0x20 == (shift & 0x3f)) {
5605                         putAcc(ac, binop(Iop_32HLto64,
5606                                          unop(Iop_64to32, mkexpr(t0)),
5607                                          mkU32(0x0)));
5608                      } else if (0x20 == (shift & 0x20)) {
5609                         assign(t1, binop(Iop_Shl64,
5610                                          mkexpr(t0),
5611                                          unop(Iop_32to8,
5612                                               binop(Iop_Add32,
5613                                                     unop(Iop_Not32,
5614                                                          mkU32(shift)),
5615                                                     mkU32(0x1)))));
5616 
5617                         putAcc(ac, mkexpr(t1));
5618                      } else {
5619                         assign(t1, binop(Iop_Shr64, mkexpr(t0), mkU8(shift)));
5620 
5621                         putAcc(ac, mkexpr(t1));
5622                      }
5623                      break;
5624                   }
5625                   case 0x1B: {  /* SHILOV */
5626                      DIP("shilov ac%u, r%u", ac, rs);
5627                      vassert(!mode64);
5628                      t0 = newTemp(Ity_I64);
5629                      t1 = newTemp(Ity_I32);
5630                      t2 = newTemp(Ity_I1);
5631                      t3 = newTemp(Ity_I64);
5632                      t4 = newTemp(Ity_I64);
5633 
5634                      assign(t0, getAcc(ac));
5635                      assign(t1, binop(Iop_And32, getIReg(rs), mkU32(0x3f)));
5636                      assign(t2, binop(Iop_CmpEQ32, mkexpr(t1), mkU32(0x20)));
5637                      assign(t3, binop(Iop_Shl64,
5638                                       mkexpr(t0),
5639                                       unop(Iop_32to8,
5640                                            binop(Iop_Add32,
5641                                                  unop(Iop_Not32,
5642                                                       mkexpr(t1)),
5643                                                  mkU32(0x1)))));
5644                      assign(t4, binop(Iop_Shr64,
5645                                       mkexpr(t0),
5646                                       unop(Iop_32to8,
5647                                            mkexpr(t1))));
5648 
5649                      putAcc(ac,
5650                             IRExpr_ITE(mkexpr(t2),
5651                                        binop(Iop_32HLto64,
5652                                              unop(Iop_64to32, mkexpr(t0)),
5653                                              mkU32(0x0)),
5654                                        IRExpr_ITE(binop(Iop_CmpEQ32,
5655                                                         binop(Iop_And32,
5656                                                               mkexpr(t1),
5657                                                               mkU32(0x20)),
5658                                                         mkU32(0x20)),
5659                                                   mkexpr(t3),
5660                                                   mkexpr(t4))));
5661                      break;
5662                   }
5663                   case 0x1F: {  /* MTHLIP */
5664                      DIP("mthlip r%u, ac%u", rs, ac);
5665                      vassert(!mode64);
5666                      t0 = newTemp(Ity_I64);
5667                      t1 = newTemp(Ity_I32);
5668                      t2 = newTemp(Ity_I32);
5669                      t3 = newTemp(Ity_I1);
5670 
5671                      assign(t0, getAcc(ac));
5672                      putAcc(ac, binop(Iop_32HLto64,
5673                                       unop(Iop_64to32, mkexpr(t0)),
5674                                       getIReg(rs)));
5675                      assign(t1, binop(Iop_And32, getDSPControl(), mkU32(0x3f)));
5676                      putDSPControl(IRExpr_ITE(binop(Iop_CmpLE32U,
5677                                                     mkU32(32),
5678                                                     mkexpr(t1)),
5679                                               binop(Iop_Or32,
5680                                                     binop(Iop_Sub32,
5681                                                           mkexpr(t1),
5682                                                           mkU32(32)),
5683                                                    binop(Iop_And32,
5684                                                          getDSPControl(),
5685                                                          mkU32(0xffffffc0))),
5686                                               binop(Iop_Or32,
5687                                                     binop(Iop_Add32,
5688                                                           mkexpr(t1),
5689                                                           mkU32(32)),
5690                                                     binop(Iop_And32,
5691                                                           getDSPControl(),
5692                                                           mkU32(0xffffffc0)))));
5693                      break;
5694                   }
5695                   default:
5696                      return -1;
5697                }
5698                break;  /* end of EXTR.W */
5699             }
5700             case 0xA: {  /* LX */
5701                switch(sa) {
5702                   case 0x0: {  /* LWX */
5703                      DIP("lwx r%u, r%u(r%u)", rd, rt, rs);
5704                      vassert(!mode64);
5705                      t0 = newTemp(Ity_I32);
5706 
5707                      assign(t0, binop(Iop_Add32, getIReg(rt), getIReg(rs)));
5708 
5709                      putIReg(rd, load(Ity_I32, mkexpr(t0)));
5710                      break;
5711                   }
5712                   case 0x4: {  /* LHX */
5713                      DIP("lhx r%u, r%u(r%u)", rd, rt, rs);
5714                      vassert(!mode64);
5715                      t0 = newTemp(Ity_I32);
5716 
5717                      assign(t0, binop(Iop_Add32, getIReg(rt), getIReg(rs)));
5718 
5719                      putIReg(rd, unop(Iop_16Sto32, load(Ity_I16, mkexpr(t0))));
5720                      break;
5721                   }
5722                   case 0x6: {  /* LBUX */
5723                      DIP("lbux r%u, r%u(r%u)", rd, rt, rs);
5724                      vassert(!mode64);
5725                      t0 = newTemp(Ity_I32);
5726 
5727                      assign(t0, binop(Iop_Add32, getIReg(rt), getIReg(rs)));
5728 
5729                      putIReg(rd, unop(Iop_8Uto32, load(Ity_I8, mkexpr(t0))));
5730                      break;
5731                   }
5732                   default:
5733                      return -1;
5734                }
5735                break;  /* end of LX */
5736             }
5737             case 0xC: {  /* INSV */
5738                switch(sa) {
5739                   case 0x0: {  /* INSV */
5740                      DIP("insv r%u, r%u", rt, rs);
5741                      vassert(!mode64);
5742 
5743                      t0 = newTemp(Ity_I32);
5744                      t1 = newTemp(Ity_I32);
5745                      t2 = newTemp(Ity_I8);
5746                      t3 = newTemp(Ity_I8);
5747                      t4 = newTemp(Ity_I32);
5748                      t5 = newTemp(Ity_I1);
5749                      t6 = newTemp(Ity_I32);
5750                      t7 = newTemp(Ity_I32);
5751                      t8 = newTemp(Ity_I32);
5752                      t9 = newTemp(Ity_I32);
5753 
5754                      /* t0 <- pos field of DSPControl register. */
5755                      assign(t0, binop(Iop_And32, getDSPControl(), mkU32(0x3f)));
5756                      /* t1 <- scount field of DSPControl register. */
5757                      assign(t1, binop(Iop_Shr32,
5758                                       binop(Iop_And32,
5759                                             getDSPControl(),
5760                                             mkU32(0x1f80)),
5761                                       mkU8(7)));
5762 
5763                      assign(t2, unop(Iop_32to8,
5764                                      binop(Iop_Add32,
5765                                            mkexpr(t1),
5766                                            mkexpr(t0))));
5767 
5768                      /* 32-(pos+size) most significant bits of rt. */
5769                      assign(t6, binop(Iop_Shl32,
5770                                       binop(Iop_Shr32,
5771                                             getIReg(rt),
5772                                             mkexpr(t2)),
5773                                       mkexpr(t2)));
5774 
5775                      assign(t3, unop(Iop_32to8,
5776                                      binop(Iop_Sub32,
5777                                            mkU32(32),
5778                                            mkexpr(t0))));
5779                      /* Pos least significant bits of rt. */
5780                      assign(t7, binop(Iop_Shr32,
5781                                       binop(Iop_Shl32,
5782                                             getIReg(rt),
5783                                             mkexpr(t3)),
5784                                       mkexpr(t3)));
5785 
5786                      /* Size least significant bits of rs,
5787                         shifted to appropriate position. */
5788                      assign(t8, binop(Iop_Shl32,
5789                                       binop(Iop_And32,
5790                                             getIReg(rs),
5791                                             unop(Iop_Not32,
5792                                                  binop(Iop_Shl32,
5793                                                        mkU32(0xffffffff),
5794                                                        unop(Iop_32to8,
5795                                                             mkexpr(t1))))),
5796                                       unop(Iop_32to8,
5797                                            mkexpr(t0))));
5798 
5799                      putIReg(rt, IRExpr_ITE(binop(Iop_CmpEQ32,
5800                                                   mkexpr(t0),
5801                                                   mkU32(0)),
5802                                             IRExpr_ITE(binop(Iop_CmpEQ32,
5803                                                              mkexpr(t1),
5804                                                              mkU32(32)),
5805                                                        getIReg(rs),
5806                                                        binop(Iop_Or32,
5807                                                              mkexpr(t6),
5808                                                              mkexpr(t8))),
5809                                             IRExpr_ITE(binop(Iop_CmpEQ32,
5810                                                              unop(Iop_8Uto32,
5811                                                                   mkexpr(t2)),
5812                                                              mkU32(32)),
5813                                                        binop(Iop_Or32,
5814                                                              mkexpr(t7),
5815                                                              mkexpr(t8)),
5816                                                        binop(Iop_Or32,
5817                                                              binop(Iop_Or32,
5818                                                                    mkexpr(t6),
5819                                                                    mkexpr(t7)),
5820                                                              mkexpr(t8)))));
5821                      break;
5822                   }
5823                   default:
5824                      return -1;
5825                }
5826                break;  /* enf of INSV */
5827             }
5828             case 0x10: {  /* ADDU.QB */
5829                switch(sa) {
5830                   case 0x00: {  /* ADDU.QB */
5831                      DIP("addu.qb r%u, r%u, r%u", rd, rs, rt);
5832                      vassert(!mode64);
5833                      t0 = newTemp(Ity_I32);
5834                      t1 = newTemp(Ity_I1);
5835                      t2 = newTemp(Ity_I32);
5836                      t3 = newTemp(Ity_I1);
5837                      t4 = newTemp(Ity_I32);
5838                      t5 = newTemp(Ity_I1);
5839                      t6 = newTemp(Ity_I32);
5840                      t7 = newTemp(Ity_I1);
5841                      t8 = newTemp(Ity_I32);
5842 
5843                      /* Add rightmost bytes of rs and rt. */
5844                      assign(t0,
5845                             binop(Iop_Add32,
5846                                   unop(Iop_8Uto32,
5847                                        unop(Iop_16to8,
5848                                             unop(Iop_32to16, getIReg(rs)))),
5849                                   unop(Iop_8Uto32,
5850                                        unop(Iop_16to8,
5851                                             unop(Iop_32to16, getIReg(rt))))));
5852                      /* t1 will be 1 if there is overflow, 0 otherwise. */
5853                      assign(t1, binop(Iop_CmpEQ32,
5854                                       binop(Iop_And32,
5855                                             mkexpr(t0),
5856                                             mkU32(0x00000100)),
5857                                       mkU32(0x00000100)));
5858 
5859                      /* Add bits 15-8 of rs and rt. */
5860                      assign(t2,
5861                             binop(Iop_Add32,
5862                                   unop(Iop_8Uto32,
5863                                        unop(Iop_16HIto8,
5864                                             unop(Iop_32to16, getIReg(rs)))),
5865                                   unop(Iop_8Uto32,
5866                                        unop(Iop_16HIto8,
5867                                             unop(Iop_32to16, getIReg(rt))))));
5868                      /* t3 will be 1 if there is overflow, 0 otherwise. */
5869                      assign(t3, binop(Iop_CmpEQ32,
5870                                       binop(Iop_And32,
5871                                             mkexpr(t2),
5872                                             mkU32(0x00000100)),
5873                                       mkU32(0x00000100)));
5874 
5875                      /* Add bits 15-8 of rs and rt. */
5876                      assign(t4,
5877                             binop(Iop_Add32,
5878                                   unop(Iop_8Uto32,
5879                                        unop(Iop_16to8,
5880                                             unop(Iop_32HIto16, getIReg(rs)))),
5881                                   unop(Iop_8Uto32,
5882                                        unop(Iop_16to8,
5883                                             unop(Iop_32HIto16, getIReg(rt))))));
5884                      /* t5 will be 1 if there is overflow, 0 otherwise. */
5885                      assign(t5, binop(Iop_CmpEQ32,
5886                                       binop(Iop_And32,
5887                                             mkexpr(t4),
5888                                             mkU32(0x00000100)),
5889                                       mkU32(0x00000100)));
5890 
5891                      /* Add bits 15-8 of rs and rt. */
5892                      assign(t6,
5893                             binop(Iop_Add32,
5894                                   unop(Iop_8Uto32,
5895                                        unop(Iop_16HIto8,
5896                                             unop(Iop_32HIto16, getIReg(rs)))),
5897                                   unop(Iop_8Uto32,
5898                                        unop(Iop_16HIto8,
5899                                             unop(Iop_32HIto16, getIReg(rt))))));
5900                      /* t7 will be 1 if there is overflow, 0 otherwise. */
5901                      assign(t7, binop(Iop_CmpEQ32,
5902                                       binop(Iop_And32,
5903                                             mkexpr(t6),
5904                                             mkU32(0x00000100)),
5905                                       mkU32(0x00000100)));
5906 
5907                      assign(t8,
5908                             binop(Iop_Or32,
5909                                   binop(Iop_Or32,
5910                                         binop(Iop_Or32,
5911                                               unop(Iop_1Sto32, mkexpr(t7)),
5912                                               unop(Iop_1Sto32,  mkexpr(t5))),
5913                                         unop(Iop_1Sto32, mkexpr(t3))),
5914                                   unop(Iop_1Sto32, mkexpr(t1))));
5915 
5916                      putDSPControl(IRExpr_ITE(binop(Iop_CmpEQ32,
5917                                                     mkexpr(t8),
5918                                                     mkU32(0x0)),
5919                                               getDSPControl(),
5920                                               binop(Iop_Or32,
5921                                                     getDSPControl(),
5922                                                     mkU32(0x00100000))));
5923 
5924                      putIReg(rd, binop(Iop_16HLto32,
5925                                        binop(Iop_8HLto16,
5926                                              unop(Iop_32to8, mkexpr(t6)),
5927                                              unop(Iop_32to8, mkexpr(t4))),
5928                                        binop(Iop_8HLto16,
5929                                              unop(Iop_32to8, mkexpr(t2)),
5930                                              unop(Iop_32to8, mkexpr(t0)))));
5931                      break;
5932                   }
5933                   case 0x1: {  /* SUBU.QB */
5934                      DIP("subu.qb r%u, r%u, r%u", rd, rs, rt);
5935                      vassert(!mode64);
5936                      t0 = newTemp(Ity_I32);
5937                      t1 = newTemp(Ity_I1);
5938                      t2 = newTemp(Ity_I32);
5939                      t3 = newTemp(Ity_I1);
5940                      t4 = newTemp(Ity_I32);
5941                      t5 = newTemp(Ity_I1);
5942                      t6 = newTemp(Ity_I32);
5943                      t7 = newTemp(Ity_I1);
5944                      t8 = newTemp(Ity_I32);
5945 
5946                      /* Subtract rightmost bytes of rs and rt. */
5947                      assign(t0,
5948                             binop(Iop_Sub32,
5949                                   unop(Iop_8Uto32,
5950                                        unop(Iop_16to8,
5951                                             unop(Iop_32to16, getIReg(rs)))),
5952                                   unop(Iop_8Uto32,
5953                                        unop(Iop_16to8,
5954                                             unop(Iop_32to16, getIReg(rt))))));
5955                      /* t1 will be 1 if there is overflow, 0 otherwise. */
5956                      assign(t1, binop(Iop_CmpEQ32,
5957                                       binop(Iop_And32,
5958                                             mkexpr(t0),
5959                                             mkU32(0x00000100)),
5960                                       mkU32(0x00000100)));
5961 
5962                      /* Subtract bits 15-8 of rs and rt. */
5963                      assign(t2,
5964                             binop(Iop_Sub32,
5965                                   unop(Iop_8Uto32,
5966                                        unop(Iop_16HIto8,
5967                                             unop(Iop_32to16, getIReg(rs)))),
5968                                   unop(Iop_8Uto32,
5969                                        unop(Iop_16HIto8,
5970                                             unop(Iop_32to16, getIReg(rt))))));
5971                      /* t3 will be 1 if there is overflow, 0 otherwise. */
5972                      assign(t3, binop(Iop_CmpEQ32,
5973                                       binop(Iop_And32,
5974                                             mkexpr(t2),
5975                                             mkU32(0x00000100)),
5976                                       mkU32(0x00000100)));
5977 
5978                      /* Subtract bits 15-8 of rs and rt. */
5979                      assign(t4,
5980                             binop(Iop_Sub32,
5981                                   unop(Iop_8Uto32,
5982                                        unop(Iop_16to8,
5983                                             unop(Iop_32HIto16, getIReg(rs)))),
5984                                   unop(Iop_8Uto32,
5985                                        unop(Iop_16to8,
5986                                             unop(Iop_32HIto16, getIReg(rt))))));
5987                      /* t5 will be 1 if there is overflow, 0 otherwise. */
5988                      assign(t5, binop(Iop_CmpEQ32,
5989                                       binop(Iop_And32,
5990                                             mkexpr(t4),
5991                                             mkU32(0x00000100)),
5992                                       mkU32(0x00000100)));
5993 
5994                      /* Subtract bits 15-8 of rs and rt. */
5995                      assign(t6,
5996                             binop(Iop_Sub32,
5997                                   unop(Iop_8Uto32,
5998                                        unop(Iop_16HIto8,
5999                                             unop(Iop_32HIto16, getIReg(rs)))),
6000                                   unop(Iop_8Uto32,
6001                                        unop(Iop_16HIto8,
6002                                             unop(Iop_32HIto16, getIReg(rt))))));
6003                      /* t7 will be 1 if there is overflow, 0 otherwise. */
6004                      assign(t7, binop(Iop_CmpEQ32,
6005                                       binop(Iop_And32,
6006                                             mkexpr(t6),
6007                                             mkU32(0x00000100)),
6008                                       mkU32(0x00000100)));
6009 
6010                      assign(t8, binop(Iop_Or32,
6011                                       binop(Iop_Or32,
6012                                             binop(Iop_Or32,
6013                                                   unop(Iop_1Sto32, mkexpr(t7)),
6014                                                   unop(Iop_1Sto32, mkexpr(t5))),
6015                                             unop(Iop_1Sto32, mkexpr(t3))),
6016                                       unop(Iop_1Sto32, mkexpr(t1))));
6017 
6018                      putDSPControl(IRExpr_ITE(binop(Iop_CmpEQ32,
6019                                                      mkexpr(t8),
6020                                                      mkU32(0x0)),
6021                                               getDSPControl(),
6022                                               binop(Iop_Or32,
6023                                                     getDSPControl(),
6024                                                     mkU32(0x00100000))));
6025 
6026                      putIReg(rd, binop(Iop_16HLto32,
6027                                        binop(Iop_8HLto16,
6028                                              unop(Iop_32to8, mkexpr(t6)),
6029                                              unop(Iop_32to8, mkexpr(t4))),
6030                                        binop(Iop_8HLto16,
6031                                              unop(Iop_32to8, mkexpr(t2)),
6032                                              unop(Iop_32to8, mkexpr(t0)))));
6033                      break;
6034                   }
6035                   case 0x04: {  /* ADDU_S.QB */
6036                      DIP("addu_s.qb r%u, r%u, r%u", rd, rs, rt);
6037                      vassert(!mode64);
6038                      t0 = newTemp(Ity_I32);
6039                      t1 = newTemp(Ity_I1);
6040                      t2 = newTemp(Ity_I8);
6041                      t3 = newTemp(Ity_I32);
6042                      t4 = newTemp(Ity_I1);
6043                      t5 = newTemp(Ity_I8);
6044                      t6 = newTemp(Ity_I32);
6045                      t7 = newTemp(Ity_I1);
6046                      t8 = newTemp(Ity_I8);
6047                      t9 = newTemp(Ity_I32);
6048                      t10 = newTemp(Ity_I1);
6049                      t11 = newTemp(Ity_I8);
6050                      t12 = newTemp(Ity_I32);
6051 
6052                      /* Add rightmost bytes of rs and rt. */
6053                      assign(t0,
6054                             binop(Iop_Add32,
6055                                   unop(Iop_8Uto32,
6056                                        unop(Iop_16to8,
6057                                             unop(Iop_32to16, getIReg(rs)))),
6058                                   unop(Iop_8Uto32,
6059                                        unop(Iop_16to8,
6060                                             unop(Iop_32to16, getIReg(rt))))));
6061                      /* t1 will be 1 if there is overflow, 0 otherwise. */
6062                      assign(t1, binop(Iop_CmpEQ32,
6063                                       binop(Iop_And32,
6064                                             mkexpr(t0),
6065                                             mkU32(0x00000100)),
6066                                       mkU32(0x00000100)));
6067                      /* Saturate if necessary. */
6068                      assign(t2, IRExpr_ITE(mkexpr(t1),
6069                                            mkU8(0xff),
6070                                            unop(Iop_32to8, mkexpr(t0))));
6071 
6072                      /* Add bits 15-8 of rs and rt. */
6073                      assign(t3,
6074                             binop(Iop_Add32,
6075                                   unop(Iop_8Uto32,
6076                                        unop(Iop_16HIto8,
6077                                             unop(Iop_32to16, getIReg(rs)))),
6078                                   unop(Iop_8Uto32,
6079                                        unop(Iop_16HIto8,
6080                                             unop(Iop_32to16, getIReg(rt))))));
6081                      /* t4 will be 1 if there is overflow, 0 otherwise. */
6082                      assign(t4, binop(Iop_CmpEQ32,
6083                                       binop(Iop_And32,
6084                                             mkexpr(t3),
6085                                             mkU32(0x00000100)),
6086                                       mkU32(0x00000100)));
6087                      /* Saturate if necessary. */
6088                      assign(t5, IRExpr_ITE(mkexpr(t4),
6089                                            mkU8(0xff),
6090                                            unop(Iop_32to8, mkexpr(t3))));
6091 
6092                      /* Add bits 15-8 of rs and rt. */
6093                      assign(t6,
6094                             binop(Iop_Add32,
6095                                   unop(Iop_8Uto32,
6096                                        unop(Iop_16to8,
6097                                             unop(Iop_32HIto16, getIReg(rs)))),
6098                                   unop(Iop_8Uto32,
6099                                        unop(Iop_16to8,
6100                                             unop(Iop_32HIto16, getIReg(rt))))));
6101                      /* t7 will be 1 if there is overflow, 0 otherwise. */
6102                      assign(t7, binop(Iop_CmpEQ32,
6103                                       binop(Iop_And32,
6104                                             mkexpr(t6),
6105                                             mkU32(0x00000100)),
6106                                       mkU32(0x00000100)));
6107                      /* Saturate if necessary. */
6108                      assign(t8, IRExpr_ITE(mkexpr(t7),
6109                                            mkU8(0xff),
6110                                            unop(Iop_32to8, mkexpr(t6))));
6111 
6112                      /* Add bits 15-8 of rs and rt. */
6113                      assign(t9,
6114                             binop(Iop_Add32,
6115                                   unop(Iop_8Uto32,
6116                                        unop(Iop_16HIto8,
6117                                             unop(Iop_32HIto16, getIReg(rs)))),
6118                                   unop(Iop_8Uto32,
6119                                        unop(Iop_16HIto8,
6120                                             unop(Iop_32HIto16, getIReg(rt))))));
6121                      /* t10 will be 1 if there is overflow, 0 otherwise. */
6122                      assign(t10, binop(Iop_CmpEQ32,
6123                                        binop(Iop_And32,
6124                                              mkexpr(t9),
6125                                              mkU32(0x00000100)),
6126                                        mkU32(0x00000100)));
6127                      /* Saturate if necessary. */
6128                      assign(t11, IRExpr_ITE(mkexpr(t10),
6129                                             mkU8(0xff),
6130                                             unop(Iop_32to8, mkexpr(t9))));
6131 
6132                      assign(t12,
6133                             binop(Iop_Or32,
6134                                   binop(Iop_Or32,
6135                                         binop(Iop_Or32,
6136                                               unop(Iop_1Sto32, mkexpr(t10)),
6137                                               unop(Iop_1Sto32, mkexpr(t7))),
6138                                         unop(Iop_1Sto32, mkexpr(t4))),
6139                                   unop(Iop_1Sto32, mkexpr(t1))));
6140 
6141                      putDSPControl(IRExpr_ITE(binop(Iop_CmpEQ32,
6142                                                     mkexpr(t12),
6143                                                     mkU32(0x0)),
6144                                               getDSPControl(),
6145                                               binop(Iop_Or32,
6146                                                     getDSPControl(),
6147                                                     mkU32(0x00100000))));
6148 
6149                      putIReg(rd,
6150                              binop(Iop_16HLto32,
6151                                    binop(Iop_8HLto16, mkexpr(t11), mkexpr(t8)),
6152                                    binop(Iop_8HLto16, mkexpr(t5), mkexpr(t2))));
6153                      break;
6154                   }
6155                   case 0x05: {  /* SUBU_S.QB */
6156                      DIP("subu_s.qb r%u, r%u, r%u", rd, rs, rt);
6157                      vassert(!mode64);
6158                      t1 = newTemp(Ity_I32);
6159                      t2 = newTemp(Ity_I1);
6160                      t3 = newTemp(Ity_I1);
6161                      t4 = newTemp(Ity_I1);
6162                      t5 = newTemp(Ity_I1);
6163                      t6 = newTemp(Ity_I32);
6164                      t7 = newTemp(Ity_I32);
6165                      t8 = newTemp(Ity_I32);
6166                      t9 = newTemp(Ity_I32);
6167 
6168                      /* Use C function to easily calculate the result
6169                         and write it in the register more conveniently
6170                         Underflow is checked using step by step subtraction. */
6171                      assign(t1, binop(Iop_QSub8Ux4, getIReg(rs), getIReg(rt)));
6172 
6173                      /* Subtract each byte of rs and rt. */
6174                      assign(t6,
6175                             binop(Iop_Sub32,
6176                                   unop(Iop_8Uto32,
6177                                        unop(Iop_16to8,
6178                                             unop(Iop_32to16, getIReg(rs)))),
6179                                   unop(Iop_8Uto32,
6180                                        unop(Iop_16to8,
6181                                             unop(Iop_32to16, getIReg(rt))))));
6182                      assign(t7,
6183                             binop(Iop_Sub32,
6184                                   unop(Iop_8Uto32,
6185                                        unop(Iop_16HIto8,
6186                                             unop(Iop_32to16, getIReg(rs)))),
6187                                   unop(Iop_8Uto32,
6188                                        unop(Iop_16HIto8,
6189                                             unop(Iop_32to16, getIReg(rt))))));
6190                      assign(t8,
6191                             binop(Iop_Sub32,
6192                                   unop(Iop_8Uto32,
6193                                        unop(Iop_16to8,
6194                                             unop(Iop_32HIto16, getIReg(rs)))),
6195                                   unop(Iop_8Uto32,
6196                                        unop(Iop_16to8,
6197                                             unop(Iop_32HIto16, getIReg(rt))))));
6198                      assign(t9,
6199                             binop(Iop_Sub32,
6200                                   unop(Iop_8Uto32,
6201                                        unop(Iop_16HIto8,
6202                                             unop(Iop_32HIto16, getIReg(rs)))),
6203                                   unop(Iop_8Uto32,
6204                                        unop(Iop_16HIto8,
6205                                             unop(Iop_32HIto16, getIReg(rt))))));
6206 
6207                      /* Put 1 to bit 20 in DSPControl if there is underflow
6208                         in either byte. */
6209                      assign(t2, binop(Iop_CmpEQ32,
6210                                       binop(Iop_And32,
6211                                             mkexpr(t6),
6212                                             mkU32(0x00000100)),
6213                                       mkU32(0x00000100)));
6214                      putDSPControl(IRExpr_ITE(mkexpr(t2),
6215                                               binop(Iop_Or32,
6216                                                     getDSPControl(),
6217                                                     mkU32(0x00100000)),
6218                                               getDSPControl()));
6219                      assign(t3, binop(Iop_CmpEQ32,
6220                                       binop(Iop_And32,
6221                                             mkexpr(t7),
6222                                             mkU32(0x00000100)),
6223                                       mkU32(0x00000100)));
6224                      putDSPControl(IRExpr_ITE(mkexpr(t3),
6225                                               binop(Iop_Or32,
6226                                                     getDSPControl(),
6227                                                     mkU32(0x00100000)),
6228                                               getDSPControl()));
6229                      assign(t4, binop(Iop_CmpEQ32,
6230                                       binop(Iop_And32,
6231                                             mkexpr(t8),
6232                                             mkU32(0x00000100)),
6233                                       mkU32(0x00000100)));
6234                      putDSPControl(IRExpr_ITE(mkexpr(t4),
6235                                               binop(Iop_Or32,
6236                                                     getDSPControl(),
6237                                                     mkU32(0x00100000)),
6238                                               getDSPControl()));
6239                      assign(t5, binop(Iop_CmpEQ32,
6240                                       binop(Iop_And32,
6241                                             mkexpr(t9),
6242                                             mkU32(0x00000100)),
6243                                       mkU32(0x00000100)));
6244                      putDSPControl(IRExpr_ITE(mkexpr(t5),
6245                                               binop(Iop_Or32,
6246                                                     getDSPControl(),
6247                                                     mkU32(0x00100000)),
6248                                               getDSPControl()));
6249                      putIReg(rd, mkexpr(t1));
6250                      break;
6251                   }
6252                   case 0x6: {  /* MULEU_S.PH.QBL */
6253                      DIP("muleu_s.ph.qbl r%u, r%u, r%u", rd, rs, rt);
6254                      vassert(!mode64);
6255                      t0 = newTemp(Ity_I32);
6256                      t1 = newTemp(Ity_I32);
6257                      t2 = newTemp(Ity_I1);
6258                      t3 = newTemp(Ity_I1);
6259 
6260                      assign(t0,
6261                             unop(Iop_64to32,
6262                                  binop(Iop_MullU32,
6263                                        unop(Iop_8Uto32,
6264                                             unop(Iop_16HIto8,
6265                                                  unop(Iop_32HIto16,
6266                                                       getIReg(rs)))),
6267                                        unop(Iop_16Uto32,
6268                                             unop(Iop_32HIto16, getIReg(rt))))));
6269                      assign(t1,
6270                             unop(Iop_64to32,
6271                                  binop(Iop_MullU32,
6272                                        unop(Iop_8Uto32,
6273                                             unop(Iop_16to8,
6274                                                  unop(Iop_32HIto16,
6275                                                       getIReg(rs)))),
6276                                        unop(Iop_16Uto32,
6277                                             unop(Iop_32to16, getIReg(rt))))));
6278 
6279                      assign(t2, binop(Iop_CmpNE32,
6280                                       mkU32(0x0),
6281                                       binop(Iop_And32,
6282                                             mkexpr(t0),
6283                                             mkU32(0x03ff0000))));
6284                      assign(t3, binop(Iop_CmpNE32,
6285                                       mkU32(0x0),
6286                                       binop(Iop_And32,
6287                                             mkexpr(t1),
6288                                             mkU32(0x03ff0000))));
6289                      putDSPControl(IRExpr_ITE(mkexpr(t2),
6290                                               binop(Iop_Or32,
6291                                                     getDSPControl(),
6292                                                     mkU32(0x200000)),
6293                                               IRExpr_ITE(mkexpr(t3),
6294                                                          binop(Iop_Or32,
6295                                                                getDSPControl(),
6296                                                                mkU32(0x200000)),
6297                                                          getDSPControl())));
6298                      putIReg(rd,
6299                              binop(Iop_16HLto32,
6300                                    IRExpr_ITE(mkexpr(t2),
6301                                               mkU16(0xffff),
6302                                               unop(Iop_32to16, mkexpr(t0))),
6303                                    IRExpr_ITE(mkexpr(t3),
6304                                               mkU16(0xffff),
6305                                               unop(Iop_32to16, mkexpr(t1)))));
6306                      break;
6307                   }
6308                   case 0x7: {  /* MULEU_S.PH.QBR */
6309                      DIP("muleu_s.ph.qbr r%u, r%u, r%u", rd, rs, rt);
6310                      vassert(!mode64);
6311                      t0 = newTemp(Ity_I32);
6312                      t1 = newTemp(Ity_I32);
6313                      t2 = newTemp(Ity_I1);
6314                      t3 = newTemp(Ity_I1);
6315 
6316                      assign(t0, unop(Iop_64to32,
6317                                      binop(Iop_MullU32,
6318                                            unop(Iop_8Uto32,
6319                                                 unop(Iop_16HIto8,
6320                                                      unop(Iop_32to16,
6321                                                           getIReg(rs)))),
6322                                            unop(Iop_16Uto32,
6323                                                 unop(Iop_32HIto16,
6324                                                      getIReg(rt))))));
6325                      assign(t1, unop(Iop_64to32,
6326                                      binop(Iop_MullU32,
6327                                            unop(Iop_8Uto32,
6328                                                 unop(Iop_16to8,
6329                                                      unop(Iop_32to16,
6330                                                           getIReg(rs)))),
6331                                            unop(Iop_16Uto32,
6332                                                 unop(Iop_32to16,
6333                                                      getIReg(rt))))));
6334 
6335                      assign(t2, binop(Iop_CmpNE32,
6336                                       mkU32(0x0),
6337                                       binop(Iop_And32,
6338                                             mkexpr(t0),
6339                                             mkU32(0x03ff0000))));
6340                      assign(t3, binop(Iop_CmpNE32,
6341                                       mkU32(0x0),
6342                                       binop(Iop_And32,
6343                                             mkexpr(t1),
6344                                             mkU32(0x03ff0000))));
6345                      putDSPControl(IRExpr_ITE(mkexpr(t2),
6346                                               binop(Iop_Or32,
6347                                                     getDSPControl(),
6348                                                     mkU32(0x200000)),
6349                                               IRExpr_ITE(mkexpr(t3),
6350                                                          binop(Iop_Or32,
6351                                                                getDSPControl(),
6352                                                                mkU32(0x200000)),
6353                                                          getDSPControl())));
6354                      putIReg(rd, binop(Iop_16HLto32,
6355                                        IRExpr_ITE(mkexpr(t2),
6356                                                   mkU16(0xffff),
6357                                                   unop(Iop_32to16,
6358                                                        mkexpr(t0))),
6359                                        IRExpr_ITE(mkexpr(t3),
6360                                                   mkU16(0xffff),
6361                                                   unop(Iop_32to16,
6362                                                        mkexpr(t1)))));
6363                      break;
6364                   }
6365                   case 0x08: {  /* ADDU.PH */
6366                      DIP("addu.ph r%u, r%u, r%u", rd, rs, rt);
6367                      vassert(!mode64);
6368                      t0 = newTemp(Ity_I32);
6369                      t1 = newTemp(Ity_I1);
6370                      t2 = newTemp(Ity_I32);
6371                      t3 = newTemp(Ity_I1);
6372 
6373                      /* Add lower halves. */
6374                      assign(t0, binop(Iop_Add32,
6375                                       unop(Iop_16Uto32,
6376                                            unop(Iop_32to16, getIReg(rs))),
6377                                       unop(Iop_16Uto32,
6378                                            unop(Iop_32to16, getIReg(rt)))));
6379 
6380                      /* Detect overflow. */
6381                      assign(t1, binop(Iop_CmpLT32U,
6382                                       unop(Iop_16Uto32,
6383                                            unop(Iop_32to16, mkexpr(t0))),
6384                                       unop(Iop_16Uto32,
6385                                            unop(Iop_32to16, getIReg(rs)))));
6386 
6387                      putDSPControl(IRExpr_ITE(mkexpr(t1),
6388                                               binop(Iop_Or32,
6389                                                     getDSPControl(),
6390                                                     mkU32(0x00100000)),
6391                                               getDSPControl()));
6392 
6393                      /* Add higher halves. */
6394                      assign(t2, binop(Iop_Add32,
6395                                       unop(Iop_16Uto32,
6396                                            unop(Iop_32HIto16, getIReg(rs))),
6397                                       unop(Iop_16Uto32,
6398                                            unop(Iop_32HIto16, getIReg(rt)))));
6399 
6400                      /* Detect overflow. */
6401                      assign(t3, binop(Iop_CmpLT32U,
6402                                       unop(Iop_16Uto32,
6403                                            unop(Iop_32to16, mkexpr(t2))),
6404                                       unop(Iop_16Uto32,
6405                                            unop(Iop_32HIto16,
6406                                                 getIReg(rs)))));
6407 
6408                      putDSPControl(IRExpr_ITE(mkexpr(t3),
6409                                               binop(Iop_Or32,
6410                                                     getDSPControl(),
6411                                                     mkU32(0x00100000)),
6412                                               getDSPControl()));
6413 
6414                      putIReg(rd, binop(Iop_16HLto32,
6415                                        unop(Iop_32to16, mkexpr(t2)),
6416                                        unop(Iop_32to16, mkexpr(t0))));
6417                      break;
6418                   }
6419                   case 0x9: {  /* SUBU.PH */
6420                      DIP("subu.ph r%u, r%u, r%u", rd, rs, rt);
6421                      vassert(!mode64);
6422                      t0 = newTemp(Ity_I32);
6423                      t1 = newTemp(Ity_I1);
6424                      t2 = newTemp(Ity_I32);
6425                      t3 = newTemp(Ity_I1);
6426 
6427                      /* Substract lower halves. */
6428                      assign(t0, binop(Iop_Sub32,
6429                                       unop(Iop_16Uto32,
6430                                            unop(Iop_32to16, getIReg(rs))),
6431                                       unop(Iop_16Uto32,
6432                                            unop(Iop_32to16, getIReg(rt)))));
6433 
6434                      /* Detect underflow. */
6435                      assign(t1, binop(Iop_CmpNE32,
6436                                       binop(Iop_And32,
6437                                             mkexpr(t0),
6438                                             mkU32(0x00010000)),
6439                                       mkU32(0x0)));
6440 
6441                      putDSPControl(IRExpr_ITE(mkexpr(t1),
6442                                               binop(Iop_Or32,
6443                                                     getDSPControl(),
6444                                                     mkU32(0x00100000)),
6445                                               getDSPControl()));
6446 
6447                      /* Subtract higher halves. */
6448                      assign(t2, binop(Iop_Sub32,
6449                                       unop(Iop_16Uto32,
6450                                            unop(Iop_32HIto16, getIReg(rs))),
6451                                       unop(Iop_16Uto32,
6452                                            unop(Iop_32HIto16, getIReg(rt)))));
6453 
6454                      /* Detect underflow. */
6455                      assign(t3, binop(Iop_CmpNE32,
6456                                       binop(Iop_And32,
6457                                             mkexpr(t2),
6458                                             mkU32(0x00010000)),
6459                                       mkU32(0x0)));
6460 
6461                      putDSPControl(IRExpr_ITE(mkexpr(t3),
6462                                               binop(Iop_Or32,
6463                                                     getDSPControl(),
6464                                                     mkU32(0x00100000)),
6465                                               getDSPControl()));
6466 
6467                      putIReg(rd, binop(Iop_16HLto32,
6468                                        unop(Iop_32to16, mkexpr(t2)),
6469                                        unop(Iop_32to16, mkexpr(t0))));
6470                      break;
6471                   }
6472                   case 0xA: {  /* ADDQ.PH */
6473                      DIP("addq.ph r%u, r%u, r%u", rd, rs, rt);
6474                      vassert(!mode64);
6475                      t0 = newTemp(Ity_I32);
6476                      t1 = newTemp(Ity_I1);
6477                      t2 = newTemp(Ity_I32);
6478                      t3 = newTemp(Ity_I1);
6479                      t6 = newTemp(Ity_I32);
6480                      t7 = newTemp(Ity_I32);
6481 
6482                      /* Add lower halves. */
6483                      assign(t0, binop(Iop_Add32,
6484                                       unop(Iop_16Sto32,
6485                                            unop(Iop_32to16, getIReg(rs))),
6486                                       unop(Iop_16Sto32,
6487                                            unop(Iop_32to16, getIReg(rt)))));
6488 
6489                      /* Bit 16 of the result. */
6490                      assign(t6, binop(Iop_And32,
6491                                       unop(Iop_16Uto32,
6492                                            unop(Iop_32HIto16, mkexpr(t0))),
6493                                       mkU32(0x1)));
6494                      /* Detect overflow. */
6495                      assign(t1, binop(Iop_CmpNE32,
6496                                       binop(Iop_Shr32,
6497                                             binop(Iop_And32,
6498                                                   mkexpr(t0),
6499                                                   mkU32(0x8000)),
6500                                             mkU8(15)),
6501                                       mkexpr(t6)));
6502 
6503                      putDSPControl(IRExpr_ITE(mkexpr(t1),
6504                                               binop(Iop_Or32,
6505                                                     getDSPControl(),
6506                                                     mkU32(0x00100000)),
6507                                               getDSPControl()));
6508 
6509                      /* Add higher halves. */
6510                      assign(t2, binop(Iop_Add32,
6511                                       unop(Iop_16Sto32,
6512                                            unop(Iop_32HIto16, getIReg(rs))),
6513                                       unop(Iop_16Sto32,
6514                                            unop(Iop_32HIto16, getIReg(rt)))));
6515 
6516                      /* Bit 16 of the result. */
6517                      assign(t7, binop(Iop_And32,
6518                                       unop(Iop_16Uto32,
6519                                            unop(Iop_32HIto16, mkexpr(t2))),
6520                                       mkU32(0x1)));
6521                      /* Detect overflow. */
6522                      assign(t3, binop(Iop_CmpNE32,
6523                                       binop(Iop_Shr32,
6524                                             binop(Iop_And32,
6525                                                   mkexpr(t2),
6526                                                   mkU32(0x00008000)),
6527                                             mkU8(15)),
6528                                       mkexpr(t7)));
6529 
6530                      putDSPControl(IRExpr_ITE(mkexpr(t3),
6531                                               binop(Iop_Or32,
6532                                                     getDSPControl(),
6533                                                     mkU32(0x00100000)),
6534                                               getDSPControl()));
6535 
6536                      putIReg(rd, binop(Iop_16HLto32,
6537                                        unop(Iop_32to16, mkexpr(t2)),
6538                                        unop(Iop_32to16, mkexpr(t0))));
6539                      break;
6540                   }
6541                   case 0xB: {  /* SUBQ.PH */
6542                      DIP("subq.ph r%u, r%u, r%u", rd, rs, rt);
6543                      vassert(!mode64);
6544                      t0 = newTemp(Ity_I32);
6545                      t1 = newTemp(Ity_I1);
6546                      t2 = newTemp(Ity_I32);
6547                      t3 = newTemp(Ity_I1);
6548                      t6 = newTemp(Ity_I32);
6549                      t7 = newTemp(Ity_I32);
6550 
6551                      /* Subtract lower halves. */
6552                      assign(t0, binop(Iop_Sub32,
6553                                       unop(Iop_16Sto32,
6554                                            unop(Iop_32to16, getIReg(rs))),
6555                                       unop(Iop_16Sto32,
6556                                            unop(Iop_32to16, getIReg(rt)))));
6557 
6558                      /* Bit 16 of the result. */
6559                      assign(t6, binop(Iop_And32,
6560                                       unop(Iop_16Uto32,
6561                                            unop(Iop_32HIto16, mkexpr(t0))),
6562                                       mkU32(0x1)));
6563                      /* Compare the signs of input value and the result. */
6564                      assign(t1, binop(Iop_CmpNE32,
6565                                       binop(Iop_Shr32,
6566                                             binop(Iop_And32,
6567                                                   mkexpr(t0),
6568                                                   mkU32(0x8000)),
6569                                             mkU8(15)),
6570                                       mkexpr(t6)));
6571 
6572                      putDSPControl(IRExpr_ITE(mkexpr(t1),
6573                                               binop(Iop_Or32,
6574                                                     getDSPControl(),
6575                                                     mkU32(0x00100000)),
6576                                               getDSPControl()));
6577 
6578                      /* Subtract higher halves. */
6579                      assign(t2, binop(Iop_Sub32,
6580                                       unop(Iop_16Sto32,
6581                                            unop(Iop_32HIto16, getIReg(rs))),
6582                                       unop(Iop_16Sto32,
6583                                            unop(Iop_32HIto16, getIReg(rt)))));
6584 
6585                      /* Bit 16 of the result. */
6586                      assign(t7, binop(Iop_And32,
6587                                       unop(Iop_16Uto32,
6588                                            unop(Iop_32HIto16, mkexpr(t2))),
6589                                       mkU32(0x1)));
6590                      /* Compare the signs of input value and the result. */
6591                      assign(t3, binop(Iop_CmpNE32,
6592                                       binop(Iop_Shr32,
6593                                             binop(Iop_And32,
6594                                                   mkexpr(t2),
6595                                                   mkU32(0x00008000)),
6596                                             mkU8(15)),
6597                                       mkexpr(t7)));
6598 
6599                      putDSPControl(IRExpr_ITE(mkexpr(t3),
6600                                               binop(Iop_Or32,
6601                                                     getDSPControl(),
6602                                                     mkU32(0x00100000)),
6603                                               getDSPControl()));
6604 
6605                      putIReg(rd, binop(Iop_16HLto32,
6606                                        unop(Iop_32to16, mkexpr(t2)),
6607                                        unop(Iop_32to16, mkexpr(t0))));
6608                      break;
6609                   }
6610                   case 0xC: {  /* ADDU_S.PH */
6611                      DIP("addu_s.ph r%u, r%u, r%u", rd, rs, rt);
6612                      vassert(!mode64);
6613                      t0 = newTemp(Ity_I32);
6614                      t1 = newTemp(Ity_I1);
6615                      t2 = newTemp(Ity_I32);
6616                      t3 = newTemp(Ity_I1);
6617 
6618                      /* Add lower halves. */
6619                      assign(t0, binop(Iop_Add32,
6620                                       unop(Iop_16Uto32,
6621                                            unop(Iop_32to16, getIReg(rs))),
6622                                       unop(Iop_16Uto32,
6623                                            unop(Iop_32to16, getIReg(rt)))));
6624 
6625                      /* Detect overflow. */
6626                      assign(t1, binop(Iop_CmpLT32U,
6627                                       unop(Iop_16Uto32,
6628                                            unop(Iop_32to16, mkexpr(t0))),
6629                                       unop(Iop_16Uto32,
6630                                            unop(Iop_32to16, getIReg(rs)))));
6631 
6632                      putDSPControl(IRExpr_ITE(mkexpr(t1),
6633                                               binop(Iop_Or32,
6634                                                     getDSPControl(),
6635                                                     mkU32(0x00100000)),
6636                                               getDSPControl()));
6637 
6638                      /* Add higher halves. */
6639                      assign(t2, binop(Iop_Add32,
6640                                       unop(Iop_16Uto32,
6641                                            unop(Iop_32HIto16, getIReg(rs))),
6642                                       unop(Iop_16Uto32,
6643                                            unop(Iop_32HIto16, getIReg(rt)))));
6644 
6645                      /* Detect overflow. */
6646                      assign(t3, binop(Iop_CmpLT32U,
6647                                       unop(Iop_16Uto32,
6648                                            unop(Iop_32to16, mkexpr(t2))),
6649                                       unop(Iop_16Uto32,
6650                                            unop(Iop_32HIto16, getIReg(rs)))));
6651 
6652                      putDSPControl(IRExpr_ITE(mkexpr(t3),
6653                                               binop(Iop_Or32,
6654                                                     getDSPControl(),
6655                                                     mkU32(0x00100000)),
6656                                               getDSPControl()));
6657 
6658                      putIReg(rd, binop(Iop_16HLto32,
6659                                        IRExpr_ITE(mkexpr(t3),
6660                                                   mkU16(0xffff),
6661                                                   unop(Iop_32to16,
6662                                                        mkexpr(t2))),
6663                                        IRExpr_ITE(mkexpr(t1),
6664                                                   mkU16(0xffff),
6665                                                   unop(Iop_32to16,
6666                                                        mkexpr(t0)))));
6667                      break;
6668                   }
6669                   case 0xD: {  /* SUBU_S.PH */
6670                      DIP("subu_s.ph r%u, r%u, r%u", rd, rs, rt);
6671                      vassert(!mode64);
6672                      t0 = newTemp(Ity_I32);
6673                      t1 = newTemp(Ity_I1);
6674                      t2 = newTemp(Ity_I32);
6675                      t3 = newTemp(Ity_I1);
6676 
6677                      /* Subtract lower halves. */
6678                      assign(t0, binop(Iop_Sub32,
6679                                       unop(Iop_16Uto32,
6680                                            unop(Iop_32to16, getIReg(rs))),
6681                                       unop(Iop_16Uto32,
6682                                            unop(Iop_32to16, getIReg(rt)))));
6683 
6684                      /* Detect underflow. */
6685                      assign(t1, binop(Iop_CmpNE32,
6686                                       binop(Iop_And32,
6687                                             mkexpr(t0), mkU32(0x00010000)),
6688                                       mkU32(0x0)));
6689 
6690                      putDSPControl(IRExpr_ITE(mkexpr(t1),
6691                                               binop(Iop_Or32,
6692                                                     getDSPControl(),
6693                                                     mkU32(0x00100000)),
6694                                               getDSPControl()));
6695 
6696                      /* Subtract higher halves. */
6697                      assign(t2, binop(Iop_Sub32,
6698                                       unop(Iop_16Uto32,
6699                                            unop(Iop_32HIto16, getIReg(rs))),
6700                                       unop(Iop_16Uto32,
6701                                            unop(Iop_32HIto16, getIReg(rt)))));
6702 
6703                      /* Detect underflow. */
6704                      assign(t3, binop(Iop_CmpNE32,
6705                                       binop(Iop_And32,
6706                                             mkexpr(t2), mkU32(0x00010000)),
6707                                       mkU32(0x0)));
6708 
6709                      putDSPControl(IRExpr_ITE(mkexpr(t3),
6710                                               binop(Iop_Or32,
6711                                                     getDSPControl(),
6712                                                     mkU32(0x00100000)),
6713                                               getDSPControl()));
6714 
6715                      putIReg(rd,
6716                              binop(Iop_16HLto32,
6717                                    IRExpr_ITE(mkexpr(t3),
6718                                               mkU16(0x0000),
6719                                               unop(Iop_32to16, mkexpr(t2))),
6720                                    IRExpr_ITE(mkexpr(t1),
6721                                               mkU16(0x0000),
6722                                               unop(Iop_32to16, mkexpr(t0)))));
6723                      break;
6724                   }
6725                   case 0xE: {  /* ADDQ_S.PH */
6726                      DIP("addq_s.ph r%u r%u, r%u", rd, rs, rt);
6727                      vassert(!mode64);
6728                      t0 = newTemp(Ity_I32);
6729                      t1 = newTemp(Ity_I1);
6730                      t2 = newTemp(Ity_I32);
6731                      t3 = newTemp(Ity_I1);
6732                      t4 = newTemp(Ity_I16);
6733                      t5 = newTemp(Ity_I16);
6734                      t6 = newTemp(Ity_I32);
6735                      t7 = newTemp(Ity_I32);
6736 
6737                      /* Add lower halves. */
6738                      assign(t0, binop(Iop_Add32,
6739                                       unop(Iop_16Sto32,
6740                                            unop(Iop_32to16, getIReg(rs))),
6741                                       unop(Iop_16Sto32,
6742                                            unop(Iop_32to16, getIReg(rt)))));
6743 
6744                      /* Bit 16 of the result. */
6745                      assign(t6, binop(Iop_And32,
6746                                       unop(Iop_16Uto32,
6747                                            unop(Iop_32HIto16, mkexpr(t0))),
6748                                       mkU32(0x1)));
6749                      /* Detect overflow. */
6750                      assign(t1, binop(Iop_CmpNE32,
6751                                       binop(Iop_Shr32,
6752                                             binop(Iop_And32,
6753                                                   mkexpr(t0),
6754                                                   mkU32(0x8000)),
6755                                             mkU8(15)),
6756                                       mkexpr(t6)));
6757 
6758                      putDSPControl(IRExpr_ITE(mkexpr(t1),
6759                                               binop(Iop_Or32,
6760                                                     getDSPControl(),
6761                                                     mkU32(0x00100000)),
6762                                               getDSPControl()));
6763                      /* Saturate if needed. */
6764                      assign(t4, IRExpr_ITE(mkexpr(t1),
6765                                            IRExpr_ITE(binop(Iop_CmpEQ32,
6766                                                             mkexpr(t6),
6767                                                             mkU32(0x0)),
6768                                                       mkU16(0x7fff),
6769                                                       mkU16(0x8000)),
6770                                            unop(Iop_32to16, mkexpr(t0))));
6771 
6772                      /* Add higher halves. */
6773                      assign(t2, binop(Iop_Add32,
6774                                       unop(Iop_16Sto32,
6775                                            unop(Iop_32HIto16, getIReg(rs))),
6776                                       unop(Iop_16Sto32,
6777                                            unop(Iop_32HIto16, getIReg(rt)))));
6778 
6779                      /* Bit 16 of the result. */
6780                      assign(t7, binop(Iop_And32,
6781                                       unop(Iop_16Uto32,
6782                                            unop(Iop_32HIto16, mkexpr(t2))),
6783                                       mkU32(0x1)));
6784                      /* Detect overflow. */
6785                      assign(t3, binop(Iop_CmpNE32,
6786                                       binop(Iop_Shr32,
6787                                             binop(Iop_And32,
6788                                                   mkexpr(t2),
6789                                                   mkU32(0x00008000)),
6790                                             mkU8(15)),
6791                                       mkexpr(t7)));
6792 
6793                      putDSPControl(IRExpr_ITE(mkexpr(t3),
6794                                               binop(Iop_Or32,
6795                                                     getDSPControl(),
6796                                                     mkU32(0x00100000)),
6797                                               getDSPControl()));
6798                      /* Saturate if needed. */
6799                      assign(t5, IRExpr_ITE(mkexpr(t3),
6800                                            IRExpr_ITE(binop(Iop_CmpEQ32,
6801                                                             mkexpr(t7),
6802                                                             mkU32(0x0)),
6803                                                       mkU16(0x7fff),
6804                                                       mkU16(0x8000)),
6805                                            unop(Iop_32to16, mkexpr(t2))));
6806 
6807                      putIReg(rd, binop(Iop_16HLto32, mkexpr(t5), mkexpr(t4)));
6808                      break;
6809                   }
6810                   case 0xF: {  /* SUBQ_S.PH */
6811                      DIP("subq_s.ph r%u r%u, r%u", rd, rs, rt);
6812                      vassert(!mode64);
6813                      t0 = newTemp(Ity_I32);
6814                      t1 = newTemp(Ity_I1);
6815                      t2 = newTemp(Ity_I32);
6816                      t3 = newTemp(Ity_I1);
6817                      t4 = newTemp(Ity_I16);
6818                      t5 = newTemp(Ity_I16);
6819                      t6 = newTemp(Ity_I32);
6820                      t7 = newTemp(Ity_I32);
6821 
6822                      /* Subtract lower halves. */
6823                      assign(t0, binop(Iop_Sub32,
6824                                       unop(Iop_16Sto32,
6825                                            unop(Iop_32to16, getIReg(rs))),
6826                                       unop(Iop_16Sto32,
6827                                            unop(Iop_32to16, getIReg(rt)))));
6828 
6829                      /* Bit 16 of the result. */
6830                      assign(t6, binop(Iop_And32,
6831                                       unop(Iop_16Uto32,
6832                                            unop(Iop_32HIto16, mkexpr(t0))),
6833                                       mkU32(0x1)));
6834                      /* Detect overflow or underflow. */
6835                      assign(t1, binop(Iop_CmpNE32,
6836                                       binop(Iop_Shr32,
6837                                             binop(Iop_And32,
6838                                                   mkexpr(t0),
6839                                                   mkU32(0x8000)),
6840                                             mkU8(15)),
6841                                       mkexpr(t6)));
6842 
6843                      putDSPControl(IRExpr_ITE(mkexpr(t1),
6844                                               binop(Iop_Or32,
6845                                                     getDSPControl(),
6846                                                     mkU32(0x00100000)),
6847                                               getDSPControl()));
6848                      /* Saturate if needed. */
6849                      assign(t4, IRExpr_ITE(mkexpr(t1),
6850                                            IRExpr_ITE(binop(Iop_CmpEQ32,
6851                                                             mkexpr(t6),
6852                                                             mkU32(0x0)),
6853                                                       mkU16(0x7fff),
6854                                                       mkU16(0x8000)),
6855                                            unop(Iop_32to16, mkexpr(t0))));
6856 
6857                      /* Subtract higher halves. */
6858                      assign(t2, binop(Iop_Sub32,
6859                                       unop(Iop_16Sto32,
6860                                            unop(Iop_32HIto16, getIReg(rs))),
6861                                       unop(Iop_16Sto32,
6862                                            unop(Iop_32HIto16, getIReg(rt)))));
6863 
6864                      /* Bit 16 of the result. */
6865                      assign(t7, binop(Iop_And32,
6866                                       unop(Iop_16Uto32,
6867                                            unop(Iop_32HIto16, mkexpr(t2))),
6868                                       mkU32(0x1)));
6869                      /* Detect overflow or underflow. */
6870                      assign(t3, binop(Iop_CmpNE32,
6871                                       binop(Iop_Shr32,
6872                                             binop(Iop_And32,
6873                                                   mkexpr(t2),
6874                                                   mkU32(0x00008000)),
6875                                             mkU8(15)),
6876                                       mkexpr(t7)));
6877 
6878                      putDSPControl(IRExpr_ITE(mkexpr(t3),
6879                                               binop(Iop_Or32,
6880                                                     getDSPControl(),
6881                                                     mkU32(0x00100000)),
6882                                               getDSPControl()));
6883                      /* Saturate if needed. */
6884                      assign(t5, IRExpr_ITE(mkexpr(t3),
6885                                            IRExpr_ITE(binop(Iop_CmpEQ32,
6886                                                             mkexpr(t7),
6887                                                             mkU32(0x0)),
6888                                                       mkU16(0x7fff),
6889                                                       mkU16(0x8000)),
6890                                            unop(Iop_32to16, mkexpr(t2))));
6891 
6892                      putIReg(rd, binop(Iop_16HLto32, mkexpr(t5), mkexpr(t4)));
6893                      break;
6894                   }
6895                   case 0x10: {  /* ADDSC */
6896                      DIP("addsc r%u, r%u, r%u", rd, rs, rt);
6897                      vassert(!mode64);
6898                      t0 = newTemp(Ity_I64);
6899                      t1 = newTemp(Ity_I1);
6900 
6901                      /* The carry bit result out of the addition operation is
6902                         written to bit 13(the c field) of the DSPControl reg. */
6903                      assign(t0, binop(Iop_Add64,
6904                                       unop(Iop_32Uto64, getIReg(rs)),
6905                                       unop(Iop_32Uto64, getIReg(rt))));
6906 
6907                      assign(t1, binop(Iop_CmpEQ32,
6908                                       binop(Iop_And32,
6909                                             unop(Iop_64HIto32, mkexpr(t0)),
6910                                             mkU32(0x1)),
6911                                       mkU32(0x1)));
6912                      putDSPControl(IRExpr_ITE(mkexpr(t1),
6913                                               binop(Iop_Or32,
6914                                                     getDSPControl(),
6915                                                     mkU32(0x2000)),
6916                                               binop(Iop_And32,
6917                                                     getDSPControl(),
6918                                                     mkU32(0xffffdfff))));
6919 
6920                      putIReg(rd, unop(Iop_64to32, mkexpr(t0)));
6921                      break;
6922                   }
6923                   case 0x11: {  /* ADDWC */
6924                      DIP("addwc r%u, r%u, r%u", rd, rs, rt);
6925                      vassert(!mode64);
6926                      t0 = newTemp(Ity_I32);
6927                      t1 = newTemp(Ity_I64);
6928                      t2 = newTemp(Ity_I32);
6929                      t3 = newTemp(Ity_I32);
6930                      t4 = newTemp(Ity_I1);
6931 
6932                      /* Get carry bit from DSPControl register. */
6933                      assign(t0, binop(Iop_Shr32,
6934                                        binop(Iop_And32,
6935                                              getDSPControl(),
6936                                              mkU32(0x2000)),
6937                                        mkU8(0xd)));
6938                      assign(t1, binop(Iop_Add64,
6939                                       unop(Iop_32Sto64, getIReg(rs)),
6940                                       unop(Iop_32Sto64,
6941                                            binop(Iop_Add32,
6942                                                  getIReg(rt),
6943                                                  mkexpr(t0)))));
6944 
6945                      /* Extract bits 32 and 31. */
6946                      assign(t2, binop(Iop_And32,
6947                                       unop(Iop_64HIto32, mkexpr(t1)),
6948                                       mkU32(0x1)));
6949                      assign(t3, binop(Iop_Shr32,
6950                                       binop(Iop_And32,
6951                                             unop(Iop_64to32, mkexpr(t1)),
6952                                             mkU32(0x80000000)),
6953                                       mkU8(31)));
6954                      assign(t4, binop(Iop_CmpNE32, mkexpr(t2), mkexpr(t3)));
6955 
6956                      putDSPControl(IRExpr_ITE(mkexpr(t4),
6957                                               binop(Iop_Or32,
6958                                                     getDSPControl(),
6959                                                     mkU32(0x00100000)),
6960                                               getDSPControl()));
6961                      putIReg(rd, unop(Iop_64to32, mkexpr(t1)));
6962                      break;
6963                   }
6964                   case 0x12: {  /* MODSUB */
6965                      DIP("modsub r%u, r%u, r%u", rd, rs, rt);
6966                      vassert(!mode64);
6967                      t0 = newTemp(Ity_I32);
6968                      t1 = newTemp(Ity_I32);
6969                      t2 = newTemp(Ity_I32);
6970 
6971                      /* decr_7..0 */
6972                      assign(t0,
6973                             unop(Iop_8Uto32,
6974                                  unop(Iop_16to8,
6975                                       unop(Iop_32to16, getIReg(rt)))));
6976 
6977                      /* lastindex_15..0 */
6978                      assign(t1,
6979                             unop(Iop_16Uto32,
6980                                  binop(Iop_8HLto16,
6981                                        unop(Iop_16to8,
6982                                             unop(Iop_32HIto16, getIReg(rt))),
6983                                        unop(Iop_16HIto8,
6984                                             unop(Iop_32to16, getIReg(rt))))));
6985                      /* temp_15..0 */
6986                      assign(t2,
6987                             IRExpr_ITE(binop(Iop_CmpEQ32,
6988                                              getIReg(rs),
6989                                              mkU32(0x00000000)),
6990                                        mkexpr(t1),
6991                                        binop(Iop_Sub32,
6992                                              getIReg(rs), mkexpr(t0))));
6993                      putIReg(rd, mkexpr(t2));
6994                      break;
6995                   }
6996                   case 0x14: {  /* RADDU.W.QB */
6997                      DIP("raddu.w.qb r%u, r%u", rd, rs);
6998                      vassert(!mode64);
6999                      putIReg(rd, binop(Iop_Add32,
7000                                        binop(Iop_Add32,
7001                                              unop(Iop_8Uto32,
7002                                                   unop(Iop_16to8,
7003                                                        unop(Iop_32to16,
7004                                                             getIReg(rs)))),
7005                                              unop(Iop_8Uto32,
7006                                                   unop(Iop_16HIto8,
7007                                                        unop(Iop_32to16,
7008                                                             getIReg(rs))))),
7009                                        binop(Iop_Add32,
7010                                              unop(Iop_8Uto32,
7011                                                   unop(Iop_16to8,
7012                                                        unop(Iop_32HIto16,
7013                                                             getIReg(rs)))),
7014                                              unop(Iop_8Uto32,
7015                                                   unop(Iop_16HIto8,
7016                                                        unop(Iop_32HIto16,
7017                                                             getIReg(rs)))))));
7018                      break;
7019                   }
7020                   case 0x16: {  /* ADDQ_S.W */
7021                      DIP("addq_s.w r%u, r%u, r%u", rd, rs, rt);
7022                      vassert(!mode64);
7023                      t0 = newTemp(Ity_I64);
7024                      t1 = newTemp(Ity_I1);
7025                      t2 = newTemp(Ity_I32);
7026                      t3 = newTemp(Ity_I32);
7027 
7028                      assign(t0, binop(Iop_Add64,
7029                                       unop(Iop_32Sto64, getIReg(rs)),
7030                                       unop(Iop_32Sto64, getIReg(rt))));
7031 
7032                      assign(t3, binop(Iop_And32,
7033                                       unop(Iop_64HIto32, mkexpr(t0)),
7034                                       mkU32(0x1)));
7035                      assign(t1, binop(Iop_CmpNE32,
7036                                       binop(Iop_Shr32,
7037                                             binop(Iop_And32,
7038                                                   unop(Iop_64to32, mkexpr(t0)),
7039                                                   mkU32(0x80000000)),
7040                                             mkU8(31)),
7041                                       mkexpr(t3)));
7042 
7043                      putDSPControl(IRExpr_ITE(mkexpr(t1),
7044                                               binop(Iop_Or32,
7045                                                     getDSPControl(),
7046                                                     mkU32(0x00100000)),
7047                                               getDSPControl()));
7048 
7049                      putIReg(rd, IRExpr_ITE(mkexpr(t1),
7050                                             IRExpr_ITE(binop(Iop_CmpEQ32,
7051                                                              mkexpr(t3),
7052                                                              mkU32(0x0)),
7053                                                        mkU32(0x7fffffff),
7054                                                        mkU32(0x80000000)),
7055                                             unop(Iop_64to32, mkexpr(t0))));
7056                      break;
7057                   }
7058                   case 0x17: {  /* SUBQ_S.W */
7059                      DIP("subq_s.w r%u, r%u, r%u", rd, rs, rt);
7060                      vassert(!mode64);
7061                      t0 = newTemp(Ity_I64);
7062                      t1 = newTemp(Ity_I1);
7063                      t2 = newTemp(Ity_I32);
7064                      t3 = newTemp(Ity_I32);
7065 
7066                      assign(t0, binop(Iop_Sub64,
7067                                       unop(Iop_32Sto64, getIReg(rs)),
7068                                       unop(Iop_32Sto64, getIReg(rt))));
7069 
7070                      assign(t3, binop(Iop_And32,
7071                                       unop(Iop_64HIto32, mkexpr(t0)),
7072                                       mkU32(0x1)));
7073                      assign(t1, binop(Iop_CmpNE32,
7074                                       binop(Iop_Shr32,
7075                                             binop(Iop_And32,
7076                                                   unop(Iop_64to32, mkexpr(t0)),
7077                                                   mkU32(0x80000000)),
7078                                             mkU8(31)),
7079                                       mkexpr(t3)));
7080 
7081                      putDSPControl(IRExpr_ITE(mkexpr(t1),
7082                                               binop(Iop_Or32,
7083                                                     getDSPControl(),
7084                                                     mkU32(0x00100000)),
7085                                               getDSPControl()));
7086 
7087                      putIReg(rd, IRExpr_ITE(mkexpr(t1),
7088                                             IRExpr_ITE(binop(Iop_CmpEQ32,
7089                                                              mkexpr(t3),
7090                                                              mkU32(0x0)),
7091                                                        mkU32(0x7fffffff),
7092                                                        mkU32(0x80000000)),
7093                                             unop(Iop_64to32, mkexpr(t0))));
7094                      break;
7095                   }
7096                   case 0x1C: {  /* MULEQ_S.W.PHL */
7097                      DIP("muleq_s.w.phl r%u, r%u, r%u", rd, rs, rt);
7098                      vassert(!mode64);
7099                      t0 = newTemp(Ity_I32);
7100                      t1 = newTemp(Ity_I1);
7101                      t2 = newTemp(Ity_I1);
7102                      t3 = newTemp(Ity_I32);
7103 
7104                      assign(t0,
7105                             binop(Iop_Shl32,
7106                                   binop(Iop_Mul32,
7107                                         unop(Iop_16Sto32,
7108                                              unop(Iop_32HIto16, getIReg(rt))),
7109                                         unop(Iop_16Sto32,
7110                                              unop(Iop_32HIto16, getIReg(rs)))),
7111                                   mkU8(0x1)));
7112                      assign(t1, binop(Iop_CmpEQ32,
7113                                       binop(Iop_And32,
7114                                             getIReg(rt),
7115                                             mkU32(0xffff0000)),
7116                                       mkU32(0x80000000)));
7117                      assign(t2, binop(Iop_CmpEQ32,
7118                                       binop(Iop_And32,
7119                                             getIReg(rs),
7120                                             mkU32(0xffff0000)),
7121                                       mkU32(0x80000000)));
7122                      assign(t3, IRExpr_ITE(mkexpr(t1),
7123                                            IRExpr_ITE(mkexpr(t2),
7124                                                       binop(Iop_Or32,
7125                                                             getDSPControl(),
7126                                                             mkU32(0x00200000)),
7127                                                       getDSPControl()),
7128                                            getDSPControl()));
7129                      putDSPControl(mkexpr(t3));
7130 
7131                      putIReg(rd, IRExpr_ITE(mkexpr(t1),
7132                                             IRExpr_ITE(mkexpr(t2),
7133                                                        mkU32(0x7fffffff),
7134                                                        mkexpr(t0)),
7135                                             mkexpr(t0)));
7136                      break;
7137                   }
7138                   case 0x1D: {  /* MULEQ_S.W.PHR */
7139                      DIP("muleq_s.w.phr r%u, r%u, r%u", rd, rs, rt);
7140                      vassert(!mode64);
7141                      t0 = newTemp(Ity_I32);
7142                      t1 = newTemp(Ity_I1);
7143                      t2 = newTemp(Ity_I1);
7144 
7145                      assign(t0,
7146                             binop(Iop_Shl32,
7147                                   binop(Iop_Mul32,
7148                                         unop(Iop_16Sto32,
7149                                              unop(Iop_32to16, getIReg(rt))),
7150                                         unop(Iop_16Sto32,
7151                                              unop(Iop_32to16, getIReg(rs)))),
7152                                   mkU8(0x1)));
7153                      assign(t1, binop(Iop_CmpEQ32,
7154                                       binop(Iop_And32,
7155                                             getIReg(rt),
7156                                             mkU32(0xffff)),
7157                                       mkU32(0x8000)));
7158                      assign(t2, binop(Iop_CmpEQ32,
7159                                       binop(Iop_And32,
7160                                             getIReg(rs),
7161                                             mkU32(0xffff)),
7162                                       mkU32(0x8000)));
7163                      putDSPControl(IRExpr_ITE(mkexpr(t1),
7164                                               IRExpr_ITE(mkexpr(t2),
7165                                                          binop(Iop_Or32,
7166                                                                getDSPControl(),
7167                                                                mkU32(0x00200000)
7168                                                               ),
7169                                                          getDSPControl()),
7170                                               getDSPControl()));
7171                      putIReg(rd, IRExpr_ITE(mkexpr(t1),
7172                                             IRExpr_ITE(mkexpr(t2),
7173                                                        mkU32(0x7fffffff),
7174                                                        mkexpr(t0)),
7175                                             mkexpr(t0)));
7176                      break;
7177                   }
7178                   case 0x1E: {  /* MULQ_S.PH */
7179                      DIP("mulq_s.ph r%u, r%u, r%u", rd, rs, rt);
7180                      vassert(!mode64);
7181                      t0 = newTemp(Ity_I32);
7182                      t1 = newTemp(Ity_I32);
7183                      t2 = newTemp(Ity_I16);
7184                      t3 = newTemp(Ity_I16);
7185                      t5 = newTemp(Ity_I32);
7186                      t6 = newTemp(Ity_I32);
7187                      t7 = newTemp(Ity_I32);
7188                      t8 = newTemp(Ity_I32);
7189 
7190                      assign(t5,
7191                             unop(Iop_16Sto32, unop(Iop_32to16, getIReg(rs))));
7192                      assign(t6,
7193                             unop(Iop_16Sto32, unop(Iop_32to16, getIReg(rt))));
7194 
7195                      assign(t7,
7196                             unop(Iop_16Sto32, unop(Iop_32HIto16, getIReg(rs))));
7197                      assign(t8,
7198                             unop(Iop_16Sto32, unop(Iop_32HIto16, getIReg(rt))));
7199 
7200                      assign(t0, binop(Iop_And32,
7201                                       unop(Iop_1Sto32,
7202                                            binop(Iop_CmpEQ32,
7203                                                  binop(Iop_And32,
7204                                                        mkexpr(t5),
7205                                                        mkU32(0xffff)),
7206                                                  mkU32(0x8000))),
7207                                       unop(Iop_1Sto32,
7208                                            binop(Iop_CmpEQ32,
7209                                                  binop(Iop_And32,
7210                                                        mkexpr(t6),
7211                                                        mkU32(0xffff)),
7212                                                  mkU32(0x8000)))));
7213                      assign(t1, binop(Iop_And32,
7214                                       unop(Iop_1Sto32,
7215                                            binop(Iop_CmpEQ32,
7216                                                  binop(Iop_And32,
7217                                                        mkexpr(t7),
7218                                                        mkU32(0xffff)),
7219                                                  mkU32(0x8000))),
7220                                       unop(Iop_1Sto32,
7221                                            binop(Iop_CmpEQ32,
7222                                                  binop(Iop_And32,
7223                                                        mkexpr(t8),
7224                                                        mkU32(0xffff)),
7225                                                  mkU32(0x8000)))));
7226 
7227                      putDSPControl(IRExpr_ITE(binop(Iop_CmpEQ32,
7228                                                     binop(Iop_Or32,
7229                                                           mkexpr(t0),
7230                                                           mkexpr(t1)),
7231                                                     mkU32(0x0)),
7232                                               getDSPControl(),
7233                                               binop(Iop_Or32,
7234                                                     getDSPControl(),
7235                                                     mkU32(0x200000))));
7236 
7237                      assign(t2, unop(Iop_32HIto16,
7238                                      binop(Iop_Shl32,
7239                                            unop(Iop_64to32,
7240                                                 binop(Iop_MullS32,
7241                                                       mkexpr(t7),
7242                                                       mkexpr(t8))),
7243                                            mkU8(0x1))));
7244                      assign(t3, unop(Iop_32HIto16,
7245                                      binop(Iop_Shl32,
7246                                            unop(Iop_64to32,
7247                                                 binop(Iop_MullS32,
7248                                                       mkexpr(t5),
7249                                                       mkexpr(t6))),
7250                                            mkU8(0x1))));
7251                      putIReg(rd, binop(Iop_16HLto32,
7252                                        IRExpr_ITE(binop(Iop_CmpEQ32,
7253                                                         mkexpr(t1),
7254                                                         mkU32(0x0)),
7255                                                   mkexpr(t2),
7256                                                   mkU16(0x7fff)),
7257                                        IRExpr_ITE(binop(Iop_CmpEQ32,
7258                                                         mkexpr(t0),
7259                                                         mkU32(0x0)),
7260                                                   mkexpr(t3),
7261                                                   mkU16(0x7fff))));
7262                      break;
7263                   }
7264                   case 0x1F: {  /* MULQ_RS.PH */
7265                      DIP("mulq_rs.ph r%u, r%u, r%u", rd, rs, rt);
7266                      vassert(!mode64);
7267                      t0 = newTemp(Ity_I32);
7268                      t1 = newTemp(Ity_I1);
7269                      t2 = newTemp(Ity_I1);
7270                      t3 = newTemp(Ity_I16);
7271                      t4 = newTemp(Ity_I32);
7272                      t5 = newTemp(Ity_I1);
7273                      t6 = newTemp(Ity_I1);
7274                      t7 = newTemp(Ity_I16);
7275 
7276                      /* Multiply and round lower halfwords. */
7277                      assign(t0, binop(Iop_Add32,
7278                                       binop(Iop_Shl32,
7279                                             binop(Iop_Mul32,
7280                                                   unop(Iop_16Sto32,
7281                                                        unop(Iop_32to16,
7282                                                             getIReg(rt))),
7283                                                   unop(Iop_16Sto32,
7284                                                        unop(Iop_32to16,
7285                                                             getIReg(rs)))),
7286                                             mkU8(0x1)),
7287                                       mkU32(0x00008000)));
7288                      assign(t1, binop(Iop_CmpEQ32,
7289                                       binop(Iop_And32,
7290                                             getIReg(rt), mkU32(0xffff)),
7291                                       mkU32(0x8000)));
7292                      assign(t2, binop(Iop_CmpEQ32,
7293                                       binop(Iop_And32,
7294                                             getIReg(rs), mkU32(0xffff)),
7295                                       mkU32(0x8000)));
7296                      putDSPControl(IRExpr_ITE(mkexpr(t1),
7297                                               IRExpr_ITE(mkexpr(t2),
7298                                                          binop(Iop_Or32,
7299                                                                getDSPControl(),
7300                                                                mkU32(0x00200000)
7301                                                               ),
7302                                                          getDSPControl()),
7303                                               getDSPControl()));
7304                      assign(t3, IRExpr_ITE(mkexpr(t1),
7305                                            IRExpr_ITE(mkexpr(t2),
7306                                                       mkU16(0x7fff),
7307                                                       unop(Iop_32HIto16,
7308                                                            mkexpr(t0))),
7309                                            unop(Iop_32HIto16, mkexpr(t0))));
7310 
7311                      /* Multiply and round higher halfwords. */
7312                      assign(t4, binop(Iop_Add32,
7313                                       binop(Iop_Shl32,
7314                                             binop(Iop_Mul32,
7315                                                   unop(Iop_16Sto32,
7316                                                        unop(Iop_32HIto16,
7317                                                             getIReg(rt))),
7318                                                   unop(Iop_16Sto32,
7319                                                        unop(Iop_32HIto16,
7320                                                             getIReg(rs)))),
7321                                             mkU8(0x1)),
7322                                       mkU32(0x00008000)));
7323                      assign(t5, binop(Iop_CmpEQ32,
7324                                       binop(Iop_And32,
7325                                             getIReg(rt),
7326                                             mkU32(0xffff0000)),
7327                                       mkU32(0x80000000)));
7328                      assign(t6, binop(Iop_CmpEQ32,
7329                                       binop(Iop_And32,
7330                                             getIReg(rs),
7331                                             mkU32(0xffff0000)),
7332                                       mkU32(0x80000000)));
7333                      putDSPControl(IRExpr_ITE(mkexpr(t5),
7334                                              IRExpr_ITE(mkexpr(t6),
7335                                                         binop(Iop_Or32,
7336                                                              getDSPControl(),
7337                                                              mkU32(0x00200000)),
7338                                                         getDSPControl()),
7339                                              getDSPControl()));
7340                      assign(t7, IRExpr_ITE(mkexpr(t5),
7341                                            IRExpr_ITE(mkexpr(t6),
7342                                                       mkU16(0x7fff),
7343                                                       unop(Iop_32HIto16,
7344                                                            mkexpr(t4))),
7345                                            unop(Iop_32HIto16, mkexpr(t4))));
7346 
7347                      putIReg(rd, binop(Iop_16HLto32, mkexpr(t7), mkexpr(t3)));
7348                      break;
7349                   }
7350                   default:
7351                      return -1;
7352                }
7353                break;  /* end of ADDU.QB */
7354             }
7355             case 0x11: {  /* CMPU.EQ.QB */
7356                switch(sa) {
7357                   case 0x0: {  /* CMPU.EQ.QB */
7358                      DIP("cmpu.eq.qb r%u, r%u", rs, rt);
7359                      vassert(!mode64);
7360                      t1 = newTemp(Ity_I1);
7361                      t2 = newTemp(Ity_I1);
7362                      t3 = newTemp(Ity_I1);
7363                      t4 = newTemp(Ity_I1);
7364 
7365                      assign(t1,
7366                             binop(Iop_CmpEQ32,
7367                                   binop(Iop_And32, getIReg(rs), mkU32(0xff)),
7368                                   binop(Iop_And32, getIReg(rt), mkU32(0xff))));
7369                      putDSPControl(IRExpr_ITE(mkexpr(t1),
7370                                               binop(Iop_Or32,
7371                                                     getDSPControl(),
7372                                                     mkU32(0x01000000)),
7373                                               binop(Iop_And32,
7374                                                     getDSPControl(),
7375                                                     mkU32(0xfeffffff))));
7376 
7377                      assign(t2, binop(Iop_CmpEQ32,
7378                                       unop(Iop_8Uto32,
7379                                            unop(Iop_16HIto8,
7380                                                 unop(Iop_32to16,
7381                                                      getIReg(rs)))),
7382                                       unop(Iop_8Uto32,
7383                                            unop(Iop_16HIto8,
7384                                                 unop(Iop_32to16,
7385                                                      getIReg(rt))))));
7386                      putDSPControl(IRExpr_ITE(mkexpr(t2),
7387                                               binop(Iop_Or32,
7388                                                     getDSPControl(),
7389                                                     mkU32(0x02000000)),
7390                                               binop(Iop_And32,
7391                                                     getDSPControl(),
7392                                                     mkU32(0xfdffffff))));
7393 
7394                      assign(t3, binop(Iop_CmpEQ32,
7395                                       unop(Iop_8Uto32,
7396                                            unop(Iop_16to8,
7397                                                 unop(Iop_32HIto16,
7398                                                      getIReg(rs)))),
7399                                       unop(Iop_8Uto32,
7400                                            unop(Iop_16to8,
7401                                                 unop(Iop_32HIto16,
7402                                                      getIReg(rt))))));
7403                      putDSPControl(IRExpr_ITE(mkexpr(t3),
7404                                               binop(Iop_Or32,
7405                                                     getDSPControl(),
7406                                                     mkU32(0x04000000)),
7407                                               binop(Iop_And32,
7408                                                     getDSPControl(),
7409                                                     mkU32(0xfbffffff))));
7410 
7411                      assign(t4, binop(Iop_CmpEQ32,
7412                                       unop(Iop_8Uto32,
7413                                            unop(Iop_16HIto8,
7414                                                 unop(Iop_32HIto16,
7415                                                      getIReg(rs)))),
7416                                       unop(Iop_8Uto32,
7417                                            unop(Iop_16HIto8,
7418                                                 unop(Iop_32HIto16,
7419                                                      getIReg(rt))))));
7420                      putDSPControl(IRExpr_ITE(mkexpr(t4),
7421                                               binop(Iop_Or32,
7422                                                     getDSPControl(),
7423                                                     mkU32(0x08000000)),
7424                                               binop(Iop_And32,
7425                                                     getDSPControl(),
7426                                                     mkU32(0xf7ffffff))));
7427                      break;
7428                   }
7429                   case 0x1: {  /* CMPU.LT.QB */
7430                      DIP("cmpu.lt.qb r%u, r%u", rs, rt);
7431                      vassert(!mode64);
7432                      t1 = newTemp(Ity_I1);
7433                      t2 = newTemp(Ity_I1);
7434                      t3 = newTemp(Ity_I1);
7435                      t4 = newTemp(Ity_I1);
7436 
7437                      assign(t1, binop(Iop_CmpLT32U,
7438                                       unop(Iop_8Uto32,
7439                                            unop(Iop_16to8,
7440                                                 unop(Iop_32to16,
7441                                                      getIReg(rs)))),
7442                                       unop(Iop_8Uto32,
7443                                            unop(Iop_16to8,
7444                                                 unop(Iop_32to16,
7445                                                      getIReg(rt))))));
7446                      putDSPControl(IRExpr_ITE(mkexpr(t1),
7447                                               binop(Iop_Or32,
7448                                                     getDSPControl(),
7449                                                     mkU32(0x01000000)),
7450                                               binop(Iop_And32,
7451                                                     getDSPControl(),
7452                                                     mkU32(0xfeffffff))));
7453 
7454                      assign(t2, binop(Iop_CmpLT32U,
7455                                       unop(Iop_8Uto32,
7456                                            unop(Iop_16HIto8,
7457                                                 unop(Iop_32to16,
7458                                                      getIReg(rs)))),
7459                                       unop(Iop_8Uto32,
7460                                            unop(Iop_16HIto8,
7461                                                 unop(Iop_32to16,
7462                                                      getIReg(rt))))));
7463                      putDSPControl(IRExpr_ITE(mkexpr(t2),
7464                                               binop(Iop_Or32,
7465                                                     getDSPControl(),
7466                                                     mkU32(0x02000000)),
7467                                               binop(Iop_And32,
7468                                                     getDSPControl(),
7469                                                     mkU32(0xfdffffff))));
7470 
7471                      assign(t3, binop(Iop_CmpLT32U,
7472                                       unop(Iop_8Uto32,
7473                                            unop(Iop_16to8,
7474                                                 unop(Iop_32HIto16,
7475                                                      getIReg(rs)))),
7476                                       unop(Iop_8Uto32,
7477                                            unop(Iop_16to8,
7478                                                 unop(Iop_32HIto16,
7479                                                      getIReg(rt))))));
7480                      putDSPControl(IRExpr_ITE(mkexpr(t3),
7481                                               binop(Iop_Or32,
7482                                                     getDSPControl(),
7483                                                     mkU32(0x04000000)),
7484                                               binop(Iop_And32,
7485                                                     getDSPControl(),
7486                                                     mkU32(0xfbffffff))));
7487 
7488                      assign(t4, binop(Iop_CmpLT32U,
7489                                       unop(Iop_8Uto32,
7490                                            unop(Iop_16HIto8,
7491                                                 unop(Iop_32HIto16,
7492                                                      getIReg(rs)))),
7493                                       unop(Iop_8Uto32,
7494                                            unop(Iop_16HIto8,
7495                                                 unop(Iop_32HIto16,
7496                                                      getIReg(rt))))));
7497                      putDSPControl(IRExpr_ITE(mkexpr(t4),
7498                                               binop(Iop_Or32,
7499                                                     getDSPControl(),
7500                                                     mkU32(0x08000000)),
7501                                               binop(Iop_And32,
7502                                                     getDSPControl(),
7503                                                     mkU32(0xf7ffffff))));
7504                      break;
7505                   }
7506                   case 0x2: {  /* CMPU.LE.QB */
7507                      DIP("cmpu.le.qb r%u, r%u", rs, rt);
7508                      vassert(!mode64);
7509                      t1 = newTemp(Ity_I1);
7510                      t2 = newTemp(Ity_I1);
7511                      t3 = newTemp(Ity_I1);
7512                      t4 = newTemp(Ity_I1);
7513 
7514                      assign(t1, binop(Iop_CmpLE32U,
7515                                       unop(Iop_8Uto32,
7516                                            unop(Iop_16to8,
7517                                                 unop(Iop_32to16,
7518                                                      getIReg(rs)))),
7519                                       unop(Iop_8Uto32,
7520                                            unop(Iop_16to8,
7521                                                 unop(Iop_32to16,
7522                                                      getIReg(rt))))));
7523                      putDSPControl(IRExpr_ITE(mkexpr(t1),
7524                                               binop(Iop_Or32,
7525                                                     getDSPControl(),
7526                                                     mkU32(0x01000000)),
7527                                               binop(Iop_And32,
7528                                                     getDSPControl(),
7529                                                     mkU32(0xfeffffff))));
7530 
7531                      assign(t2, binop(Iop_CmpLE32U,
7532                                       unop(Iop_8Uto32,
7533                                            unop(Iop_16HIto8,
7534                                                 unop(Iop_32to16,
7535                                                      getIReg(rs)))),
7536                                       unop(Iop_8Uto32,
7537                                            unop(Iop_16HIto8,
7538                                                 unop(Iop_32to16,
7539                                                      getIReg(rt))))));
7540                      putDSPControl(IRExpr_ITE(mkexpr(t2),
7541                                               binop(Iop_Or32,
7542                                                     getDSPControl(),
7543                                                     mkU32(0x02000000)),
7544                                               binop(Iop_And32,
7545                                                     getDSPControl(),
7546                                                     mkU32(0xfdffffff))));
7547 
7548                      assign(t3, binop(Iop_CmpLE32U,
7549                                       unop(Iop_8Uto32,
7550                                            unop(Iop_16to8,
7551                                                 unop(Iop_32HIto16,
7552                                                      getIReg(rs)))),
7553                                       unop(Iop_8Uto32,
7554                                            unop(Iop_16to8,
7555                                                 unop(Iop_32HIto16,
7556                                                      getIReg(rt))))));
7557                      putDSPControl(IRExpr_ITE(mkexpr(t3),
7558                                               binop(Iop_Or32,
7559                                                     getDSPControl(),
7560                                                     mkU32(0x04000000)),
7561                                               binop(Iop_And32,
7562                                                     getDSPControl(),
7563                                                     mkU32(0xfbffffff))));
7564 
7565                      assign(t4, binop(Iop_CmpLE32U,
7566                                       unop(Iop_8Uto32,
7567                                            unop(Iop_16HIto8,
7568                                                 unop(Iop_32HIto16,
7569                                                      getIReg(rs)))),
7570                                       unop(Iop_8Uto32,
7571                                            unop(Iop_16HIto8,
7572                                                 unop(Iop_32HIto16,
7573                                                      getIReg(rt))))));
7574                      putDSPControl(IRExpr_ITE(mkexpr(t4),
7575                                               binop(Iop_Or32,
7576                                                     getDSPControl(),
7577                                                     mkU32(0x08000000)),
7578                                               binop(Iop_And32,
7579                                                     getDSPControl(),
7580                                                     mkU32(0xf7ffffff))));
7581                      break;
7582                   }
7583                   case 0x3: {  /* PICK.QB */
7584                      DIP("pick.qb r%u, r%u, r%u", rd, rs, rt);
7585                      vassert(!mode64);
7586                      t0 = newTemp(Ity_I32);
7587                      t1 = newTemp(Ity_I8);
7588                      t2 = newTemp(Ity_I8);
7589                      t3 = newTemp(Ity_I8);
7590                      t4 = newTemp(Ity_I8);
7591 
7592                      assign(t0, getDSPControl());
7593                      assign(t1, IRExpr_ITE(binop(Iop_CmpNE32,
7594                                                  binop(Iop_And32,
7595                                                        mkexpr(t0),
7596                                                        mkU32(0x01000000)),
7597                                                  mkU32(0x0)),
7598                                            unop(Iop_16to8,
7599                                                  unop(Iop_32to16,
7600                                                       getIReg(rs))),
7601                                            unop(Iop_16to8,
7602                                                 unop(Iop_32to16,
7603                                                      getIReg(rt)))));
7604                      assign(t2, IRExpr_ITE(binop(Iop_CmpNE32,
7605                                                  binop(Iop_And32,
7606                                                        mkexpr(t0),
7607                                                        mkU32(0x02000000)),
7608                                                  mkU32(0x0)),
7609                                            unop(Iop_16HIto8,
7610                                                 unop(Iop_32to16, getIReg(rs))),
7611                                            unop(Iop_16HIto8,
7612                                                 unop(Iop_32to16,
7613                                                      getIReg(rt)))));
7614                      assign(t3, IRExpr_ITE(binop(Iop_CmpNE32,
7615                                                  binop(Iop_And32,
7616                                                        mkexpr(t0),
7617                                                        mkU32(0x04000000)),
7618                                                  mkU32(0x0)),
7619                                            unop(Iop_16to8,
7620                                                 unop(Iop_32HIto16,
7621                                                      getIReg(rs))),
7622                                            unop(Iop_16to8,
7623                                                 unop(Iop_32HIto16,
7624                                                      getIReg(rt)))));
7625                      assign(t4, IRExpr_ITE(binop(Iop_CmpNE32,
7626                                                  binop(Iop_And32,
7627                                                        mkexpr(t0),
7628                                                        mkU32(0x08000000)),
7629                                                  mkU32(0x0)),
7630                                            unop(Iop_16HIto8,
7631                                                 unop(Iop_32HIto16,
7632                                                      getIReg(rs))),
7633                                            unop(Iop_16HIto8,
7634                                                 unop(Iop_32HIto16,
7635                                                      getIReg(rt)))));
7636                      putIReg(rd,
7637                              binop(Iop_16HLto32,
7638                                    binop(Iop_8HLto16, mkexpr(t4), mkexpr(t3)),
7639                                    binop(Iop_8HLto16, mkexpr(t2), mkexpr(t1))));
7640                      break;
7641                   }
7642                   case 0x4: {  /* CMPGU.EQ.QB */
7643                      DIP("cmpgu.eq.qb r%u, r%u, r%u", rd, rs, rt);
7644                      vassert(!mode64);
7645                      t1 = newTemp(Ity_I1);
7646                      t2 = newTemp(Ity_I1);
7647                      t3 = newTemp(Ity_I1);
7648                      t4 = newTemp(Ity_I1);
7649                      t5 = newTemp(Ity_I32);
7650                      t6 = newTemp(Ity_I32);
7651                      t7 = newTemp(Ity_I32);
7652                      t8 = newTemp(Ity_I32);
7653 
7654                      assign(t1, binop(Iop_CmpEQ32,
7655                                       unop(Iop_8Uto32,
7656                                            unop(Iop_16to8,
7657                                                 unop(Iop_32to16, getIReg(rs)))),
7658                                       unop(Iop_8Uto32,
7659                                            unop(Iop_16to8,
7660                                                 unop(Iop_32to16,
7661                                                      getIReg(rt))))));
7662                      assign(t5, IRExpr_ITE(mkexpr(t1),
7663                                            mkU32(0x00000001), mkU32(0)));
7664 
7665                      assign(t2, binop(Iop_CmpEQ32,
7666                                       unop(Iop_8Uto32,
7667                                            unop(Iop_16HIto8,
7668                                                 unop(Iop_32to16, getIReg(rs)))),
7669                                       unop(Iop_8Uto32,
7670                                            unop(Iop_16HIto8,
7671                                                 unop(Iop_32to16,
7672                                                      getIReg(rt))))));
7673                      assign(t6, IRExpr_ITE(mkexpr(t2),
7674                                            mkU32(0x00000002), mkU32(0)));
7675 
7676                      assign(t3, binop(Iop_CmpEQ32,
7677                                       unop(Iop_8Uto32,
7678                                            unop(Iop_16to8,
7679                                                 unop(Iop_32HIto16,
7680                                                      getIReg(rs)))),
7681                                       unop(Iop_8Uto32,
7682                                            unop(Iop_16to8,
7683                                                 unop(Iop_32HIto16,
7684                                                      getIReg(rt))))));
7685                      assign(t7, IRExpr_ITE(mkexpr(t3),
7686                                            mkU32(0x00000004), mkU32(0)));
7687 
7688                      assign(t4, binop(Iop_CmpEQ32,
7689                                       unop(Iop_8Uto32,
7690                                            unop(Iop_16HIto8,
7691                                                 unop(Iop_32HIto16,
7692                                                      getIReg(rs)))),
7693                                       unop(Iop_8Uto32,
7694                                            unop(Iop_16HIto8,
7695                                                 unop(Iop_32HIto16,
7696                                                      getIReg(rt))))));
7697                      assign(t8, IRExpr_ITE(mkexpr(t4),
7698                                            mkU32(0x00000008), mkU32(0)));
7699 
7700                      putIReg(rd, binop(Iop_Or32,
7701                                        binop(Iop_Or32,
7702                                              binop(Iop_Or32,
7703                                                    mkexpr(t5), mkexpr(t6)),
7704                                              mkexpr(t7)),
7705                                        mkexpr(t8)));
7706                      break;
7707                   }
7708                   case 0x5: {  /* CMPGU.LT.QB */
7709                      DIP("cmpgu.lt.qb r%u, r%u, r%u", rd, rs, rt);
7710                      vassert(!mode64);
7711                      t1 = newTemp(Ity_I1);
7712                      t2 = newTemp(Ity_I1);
7713                      t3 = newTemp(Ity_I1);
7714                      t4 = newTemp(Ity_I1);
7715                      t5 = newTemp(Ity_I32);
7716                      t6 = newTemp(Ity_I32);
7717                      t7 = newTemp(Ity_I32);
7718                      t8 = newTemp(Ity_I32);
7719 
7720                      assign(t1, binop(Iop_CmpLT32U,
7721                                       unop(Iop_8Uto32,
7722                                            unop(Iop_16to8,
7723                                                 unop(Iop_32to16, getIReg(rs)))),
7724                                       unop(Iop_8Uto32,
7725                                            unop(Iop_16to8,
7726                                                 unop(Iop_32to16,
7727                                                      getIReg(rt))))));
7728                      assign(t5, IRExpr_ITE(mkexpr(t1),
7729                                            mkU32(0x00000001), mkU32(0)));
7730 
7731                      assign(t2, binop(Iop_CmpLT32U,
7732                                       unop(Iop_8Uto32,
7733                                            unop(Iop_16HIto8,
7734                                                 unop(Iop_32to16, getIReg(rs)))),
7735                                       unop(Iop_8Uto32,
7736                                            unop(Iop_16HIto8,
7737                                                 unop(Iop_32to16,
7738                                                      getIReg(rt))))));
7739                      assign(t6, IRExpr_ITE(mkexpr(t2),
7740                                            mkU32(0x00000002), mkU32(0)));
7741 
7742                      assign(t3, binop(Iop_CmpLT32U,
7743                                       unop(Iop_8Uto32,
7744                                            unop(Iop_16to8,
7745                                                 unop(Iop_32HIto16,
7746                                                      getIReg(rs)))),
7747                                       unop(Iop_8Uto32,
7748                                            unop(Iop_16to8,
7749                                                 unop(Iop_32HIto16,
7750                                                      getIReg(rt))))));
7751                      assign(t7, IRExpr_ITE(mkexpr(t3),
7752                                            mkU32(0x00000004), mkU32(0)));
7753 
7754                      assign(t4, binop(Iop_CmpLT32U,
7755                                       unop(Iop_8Uto32,
7756                                            unop(Iop_16HIto8,
7757                                                 unop(Iop_32HIto16,
7758                                                      getIReg(rs)))),
7759                                       unop(Iop_8Uto32,
7760                                            unop(Iop_16HIto8,
7761                                                 unop(Iop_32HIto16,
7762                                                      getIReg(rt))))));
7763                      assign(t8, IRExpr_ITE(mkexpr(t4),
7764                                            mkU32(0x00000008), mkU32(0)));
7765                      putIReg(rd, binop(Iop_Or32,
7766                                        binop(Iop_Or32,
7767                                              binop(Iop_Or32,
7768                                                    mkexpr(t5), mkexpr(t6)),
7769                                              mkexpr(t7)),
7770                                        mkexpr(t8)));
7771                      break;
7772                   }
7773                   case 0x6: {  /* CMPGU.LE.QB */
7774                      DIP("cmpgu.le.qb r%u, r%u, r%u", rd, rs, rt);
7775                      vassert(!mode64);
7776                      t1 = newTemp(Ity_I1);
7777                      t2 = newTemp(Ity_I1);
7778                      t3 = newTemp(Ity_I1);
7779                      t4 = newTemp(Ity_I1);
7780                      t5 = newTemp(Ity_I32);
7781                      t6 = newTemp(Ity_I32);
7782                      t7 = newTemp(Ity_I32);
7783                      t8 = newTemp(Ity_I32);
7784 
7785                      assign(t1, binop(Iop_CmpLE32U,
7786                                       unop(Iop_8Uto32,
7787                                            unop(Iop_16to8,
7788                                                 unop(Iop_32to16, getIReg(rs)))),
7789                                       unop(Iop_8Uto32,
7790                                            unop(Iop_16to8,
7791                                                 unop(Iop_32to16,
7792                                                      getIReg(rt))))));
7793                      assign(t5, IRExpr_ITE(mkexpr(t1),
7794                                            mkU32(0x00000001), mkU32(0)));
7795 
7796                      assign(t2, binop(Iop_CmpLE32U,
7797                                       unop(Iop_8Uto32,
7798                                            unop(Iop_16HIto8,
7799                                                 unop(Iop_32to16, getIReg(rs)))),
7800                                       unop(Iop_8Uto32,
7801                                            unop(Iop_16HIto8,
7802                                                 unop(Iop_32to16,
7803                                                      getIReg(rt))))));
7804                      assign(t6, IRExpr_ITE(mkexpr(t2),
7805                                            mkU32(0x00000002), mkU32(0)));
7806 
7807                      assign(t3, binop(Iop_CmpLE32U,
7808                                       unop(Iop_8Uto32,
7809                                            unop(Iop_16to8,
7810                                                 unop(Iop_32HIto16,
7811                                                      getIReg(rs)))),
7812                                       unop(Iop_8Uto32,
7813                                            unop(Iop_16to8,
7814                                                 unop(Iop_32HIto16,
7815                                                      getIReg(rt))))));
7816                      assign(t7, IRExpr_ITE(mkexpr(t3),
7817                                            mkU32(0x00000004), mkU32(0)));
7818 
7819                      assign(t4, binop(Iop_CmpLE32U,
7820                                       unop(Iop_8Uto32,
7821                                            unop(Iop_16HIto8,
7822                                                 unop(Iop_32HIto16,
7823                                                      getIReg(rs)))),
7824                                       unop(Iop_8Uto32,
7825                                            unop(Iop_16HIto8,
7826                                                 unop(Iop_32HIto16,
7827                                                      getIReg(rt))))));
7828                      assign(t8, IRExpr_ITE(mkexpr(t4),
7829                                            mkU32(0x00000008), mkU32(0)));
7830                      putIReg(rd, binop(Iop_Or32,
7831                                        binop(Iop_Or32,
7832                                              binop(Iop_Or32,
7833                                                    mkexpr(t5), mkexpr(t6)),
7834                                              mkexpr(t7)),
7835                                        mkexpr(t8)));
7836                      break;
7837                   }
7838                   case 0x8: {  /* CMP.EQ.PH */
7839                      DIP("cmp.eq.ph r%u, r%u", rs, rt);
7840                      vassert(!mode64);
7841                      t1 = newTemp(Ity_I1);
7842                      t2 = newTemp(Ity_I1);
7843 
7844                      assign(t1, binop(Iop_CmpEQ16,
7845                                       unop(Iop_32to16, getIReg(rs)),
7846                                       unop(Iop_32to16, getIReg(rt))));
7847                      putDSPControl(IRExpr_ITE(mkexpr(t1),
7848                                               binop(Iop_Or32,
7849                                                     getDSPControl(),
7850                                                     mkU32(0x01000000)),
7851                                               binop(Iop_And32,
7852                                                     getDSPControl(),
7853                                                     mkU32(0xfeffffff))));
7854                      assign(t2, binop(Iop_CmpEQ16,
7855                                       unop(Iop_32HIto16, getIReg(rs)),
7856                                       unop(Iop_32HIto16, getIReg(rt))));
7857                      putDSPControl(IRExpr_ITE(mkexpr(t2),
7858                                               binop(Iop_Or32,
7859                                                     getDSPControl(),
7860                                                     mkU32(0x02000000)),
7861                                               binop(Iop_And32,
7862                                                     getDSPControl(),
7863                                                     mkU32(0xfdffffff))));
7864                      break;
7865                   }
7866                   case 0x9: {  /* CMP.LT.PH */
7867                      DIP("cmp.lt.ph r%u, r%u", rs, rt);
7868                      vassert(!mode64);
7869                      t1 = newTemp(Ity_I1);
7870                      t2 = newTemp(Ity_I1);
7871 
7872                      assign(t1, binop(Iop_CmpLT32S,
7873                                       unop(Iop_16Sto32,
7874                                            unop(Iop_32to16, getIReg(rs))),
7875                                       unop(Iop_16Sto32,
7876                                            unop(Iop_32to16, getIReg(rt)))));
7877                      putDSPControl(IRExpr_ITE(mkexpr(t1),
7878                                               binop(Iop_Or32,
7879                                                     getDSPControl(),
7880                                                     mkU32(0x01000000)),
7881                                               binop(Iop_And32,
7882                                                     getDSPControl(),
7883                                                     mkU32(0xfeffffff))));
7884 
7885                      assign(t2, binop(Iop_CmpLT32S,
7886                                       unop(Iop_16Sto32,
7887                                            unop(Iop_32HIto16, getIReg(rs))),
7888                                       unop(Iop_16Sto32,
7889                                            unop(Iop_32HIto16, getIReg(rt)))));
7890                      putDSPControl(IRExpr_ITE(mkexpr(t2),
7891                                               binop(Iop_Or32,
7892                                                     getDSPControl(),
7893                                                     mkU32(0x02000000)),
7894                                               binop(Iop_And32,
7895                                                     getDSPControl(),
7896                                                     mkU32(0xfdffffff))));
7897                      break;
7898                   }
7899                   case 0xA: {  /* CMP.LE.PH */
7900                      DIP("cmp.le.ph r%u, r%u", rs, rt);
7901                      vassert(!mode64);
7902                      t1 = newTemp(Ity_I1);
7903                      t2 = newTemp(Ity_I1);
7904 
7905                      assign(t1, binop(Iop_CmpLE32S,
7906                                       unop(Iop_16Sto32,
7907                                            unop(Iop_32to16, getIReg(rs))),
7908                                       unop(Iop_16Sto32,
7909                                            unop(Iop_32to16, getIReg(rt)))));
7910                      putDSPControl(IRExpr_ITE(mkexpr(t1),
7911                                               binop(Iop_Or32,
7912                                                     getDSPControl(),
7913                                                     mkU32(0x01000000)),
7914                                               binop(Iop_And32,
7915                                                     getDSPControl(),
7916                                                     mkU32(0xfeffffff))));
7917 
7918                      assign(t2, binop(Iop_CmpLE32S,
7919                                       unop(Iop_16Sto32,
7920                                            unop(Iop_32HIto16, getIReg(rs))),
7921                                       unop(Iop_16Sto32,
7922                                            unop(Iop_32HIto16, getIReg(rt)))));
7923                      putDSPControl(IRExpr_ITE(mkexpr(t2),
7924                                               binop(Iop_Or32,
7925                                                     getDSPControl(),
7926                                                     mkU32(0x02000000)),
7927                                               binop(Iop_And32,
7928                                                     getDSPControl(),
7929                                                     mkU32(0xfdffffff))));
7930                      break;
7931                   }
7932                   case 0xB: {  /* PICK.PH */
7933                      DIP("pick.qb r%u, r%u, r%u", rd, rs, rt);
7934                      vassert(!mode64);
7935                      t0 = newTemp(Ity_I32);
7936                      t1 = newTemp(Ity_I16);
7937                      t2 = newTemp(Ity_I16);
7938 
7939                      assign(t0, getDSPControl());
7940 
7941                      assign(t1, IRExpr_ITE(binop(Iop_CmpNE32,
7942                                                  binop(Iop_And32,
7943                                                        mkexpr(t0),
7944                                                        mkU32(0x01000000)),
7945                                                  mkU32(0x0)),
7946                                            unop(Iop_32to16, getIReg(rs)),
7947                                            unop(Iop_32to16, getIReg(rt))));
7948 
7949                      assign(t2, IRExpr_ITE(binop(Iop_CmpNE32,
7950                                                  binop(Iop_And32,
7951                                                        mkexpr(t0),
7952                                                        mkU32(0x02000000)),
7953                                                  mkU32(0x0)),
7954                                            unop(Iop_32HIto16, getIReg(rs)),
7955                                            unop(Iop_32HIto16, getIReg(rt))));
7956 
7957                      putIReg(rd, binop(Iop_16HLto32, mkexpr(t2), mkexpr(t1)));
7958                      break;
7959                   }
7960                   case 0xC: {  /* PRECRQ.QB.PH */
7961                      DIP("precrq.qb.ph r%u, r%u, %u", rd, rs, rt);
7962                      vassert(!mode64);
7963                      putIReg(rd,
7964                              binop(Iop_16HLto32,
7965                                    binop(Iop_8HLto16,
7966                                          unop(Iop_16HIto8,
7967                                               unop(Iop_32HIto16, getIReg(rs))),
7968                                          unop(Iop_16HIto8,
7969                                               unop(Iop_32to16, getIReg(rs)))),
7970                                    binop(Iop_8HLto16,
7971                                          unop(Iop_16HIto8,
7972                                               unop(Iop_32HIto16, getIReg(rt))),
7973                                          unop(Iop_16HIto8,
7974                                               unop(Iop_32to16, getIReg(rt))))));
7975                      break;
7976                   }
7977                   case 0xD: {  /* PRECR.QB.PH */
7978                      DIP("precr.qb.ph r%u, r%u, r%u", rd, rs, rt);
7979                      vassert(!mode64);
7980 
7981                      putIReg(rd,
7982                              binop(Iop_16HLto32,
7983                                    binop(Iop_8HLto16,
7984                                          unop(Iop_16to8,
7985                                               unop(Iop_32HIto16, getIReg(rs))),
7986                                          unop(Iop_16to8,
7987                                               unop(Iop_32to16, getIReg(rs)))),
7988                                    binop(Iop_8HLto16,
7989                                          unop(Iop_16to8,
7990                                               unop(Iop_32HIto16, getIReg(rt))),
7991                                          unop(Iop_16to8,
7992                                               unop(Iop_32to16, getIReg(rt))))));
7993                      break;
7994                   }
7995                   case 0xF: {  /* PRECRQU_S.QB.PH */
7996                      DIP("precrqu_s.qb.ph r%u, r%u, %u", rd, rs, rt);
7997                      vassert(!mode64);
7998                      t0 = newTemp(Ity_I8);
7999                      t1 = newTemp(Ity_I8);
8000                      t2 = newTemp(Ity_I8);
8001                      t3 = newTemp(Ity_I8);
8002                      t4 = newTemp(Ity_I8);
8003                      t5 = newTemp(Ity_I32);
8004                      t6 = newTemp(Ity_I1);
8005                      t7 = newTemp(Ity_I8);
8006                      t8 = newTemp(Ity_I1);
8007                      t9 = newTemp(Ity_I32);
8008                      t10 = newTemp(Ity_I8);
8009                      t11 = newTemp(Ity_I1);
8010                      t12 = newTemp(Ity_I32);
8011                      t13 = newTemp(Ity_I8);
8012                      t14 = newTemp(Ity_I1);
8013                      t15 = newTemp(Ity_I32);
8014 
8015                      assign(t4, IRExpr_ITE(binop(Iop_CmpLT32U,
8016                                                  mkU32(0x7f80),
8017                                                  binop(Iop_And32,
8018                                                        unop(Iop_16Uto32,
8019                                                             unop(Iop_32to16,
8020                                                             getIReg(rs))),
8021                                                        mkU32(0x7fff))),
8022                                            mkU8(0xff),
8023                                            unop(Iop_16HIto8,
8024                                                 unop(Iop_32to16,
8025                                                      binop(Iop_Shl32,
8026                                                            getIReg(rs),
8027                                                            mkU8(1))))));
8028                      assign(t0, IRExpr_ITE(binop(Iop_CmpEQ32,
8029                                                  binop(Iop_And32,
8030                                                        unop(Iop_16Uto32,
8031                                                             unop(Iop_32to16,
8032                                                                  getIReg(rs))),
8033                                                        mkU32(0x00008000)),
8034                                                  mkU32(0x0)),
8035                                            mkexpr(t4),
8036                                            mkU8(0x0)));
8037                      assign(t5, binop(Iop_And32,
8038                                       unop(Iop_16Uto32,
8039                                             unop(Iop_32to16,
8040                                                  getIReg(rs))),
8041                                       mkU32(0x00008000)));
8042                      assign(t6, binop(Iop_CmpLT32U,
8043                                       mkU32(0x7f80),
8044                                       binop(Iop_And32,
8045                                             unop(Iop_16Uto32,
8046                                                  unop(Iop_32to16,
8047                                                  getIReg(rs))),
8048                                             mkU32(0x7fff))));
8049                      putDSPControl(IRExpr_ITE(binop(Iop_CmpEQ32,
8050                                                     mkexpr(t5),
8051                                                     mkU32(0x0)),
8052                                               IRExpr_ITE(mkexpr(t6),
8053                                                          binop(Iop_Or32,
8054                                                                getDSPControl(),
8055                                                                mkU32(0x00400000)
8056                                                               ),
8057                                                          getDSPControl()),
8058                                               binop(Iop_Or32,
8059                                                     getDSPControl(),
8060                                                     mkU32(0x00400000))));
8061 
8062                      assign(t7, IRExpr_ITE(binop(Iop_CmpLT32U,
8063                                                  mkU32(0x7f80),
8064                                                  binop(Iop_And32,
8065                                                        unop(Iop_16Uto32,
8066                                                             unop(Iop_32HIto16,
8067                                                                  getIReg(rs))),
8068                                                        mkU32(0x7fff))),
8069                                            mkU8(0xff),
8070                                            unop(Iop_16HIto8,
8071                                                 unop(Iop_32HIto16,
8072                                                      binop(Iop_Shl32,
8073                                                            getIReg(rs),
8074                                                            mkU8(1))))));
8075                      assign(t1, IRExpr_ITE(binop(Iop_CmpEQ32,
8076                                                  binop(Iop_And32,
8077                                                        unop(Iop_16Uto32,
8078                                                             unop(Iop_32HIto16,
8079                                                                  getIReg(rs))),
8080                                                        mkU32(0x00008000)),
8081                                                  mkU32(0x0)),
8082                                            mkexpr(t7),
8083                                            mkU8(0x0)));
8084                      assign(t8, binop(Iop_CmpEQ32,
8085                                       binop(Iop_And32,
8086                                             unop(Iop_16Uto32,
8087                                                  unop(Iop_32HIto16,
8088                                                       getIReg(rs))),
8089                                             mkU32(0x00008000)),
8090                                       mkU32(0x0)));
8091                      assign(t9, IRExpr_ITE(binop(Iop_CmpLT32U,
8092                                                  mkU32(0x7f80),
8093                                                  binop(Iop_And32,
8094                                                        unop(Iop_16Uto32,
8095                                                             unop(Iop_32HIto16,
8096                                                                  getIReg(rs))),
8097                                                        mkU32(0x7fff))),
8098                                            binop(Iop_Or32,
8099                                                  getDSPControl(),
8100                                                  mkU32(0x00400000)),
8101                                            getDSPControl()));
8102                      putDSPControl(IRExpr_ITE(mkexpr(t8),
8103                                               mkexpr(t9),
8104                                               binop(Iop_Or32,
8105                                                     getDSPControl(),
8106                                                     mkU32(0x00400000))));
8107 
8108                      assign(t10, IRExpr_ITE(binop(Iop_CmpLT32U,
8109                                                   mkU32(0x7f80),
8110                                                   binop(Iop_And32,
8111                                                         unop(Iop_16Uto32,
8112                                                              unop(Iop_32to16,
8113                                                              getIReg(rt))),
8114                                                         mkU32(0x7fff))),
8115                                             mkU8(0xff),
8116                                             unop(Iop_16HIto8,
8117                                                  unop(Iop_32to16,
8118                                                       binop(Iop_Shl32,
8119                                                             getIReg(rt),
8120                                                             mkU8(1))))));
8121                      assign(t2, IRExpr_ITE(binop(Iop_CmpEQ32,
8122                                                  binop(Iop_And32,
8123                                                        unop(Iop_16Uto32,
8124                                                             unop(Iop_32to16,
8125                                                                  getIReg(rt))),
8126                                                        mkU32(0x00008000)),
8127                                                  mkU32(0x0)),
8128                                            mkexpr(t10),
8129                                            mkU8(0x0)));
8130                      assign(t11, binop(Iop_CmpEQ32,
8131                                        binop(Iop_And32,
8132                                              unop(Iop_16Uto32,
8133                                                   unop(Iop_32to16,
8134                                                        getIReg(rt))),
8135                                              mkU32(0x00008000)),
8136                                        mkU32(0x0)));
8137                      assign(t12, IRExpr_ITE(binop(Iop_CmpLT32U,
8138                                                   mkU32(0x7f80),
8139                                                   binop(Iop_And32,
8140                                                         unop(Iop_16Uto32,
8141                                                              unop(Iop_32to16,
8142                                                              getIReg(rt))),
8143                                                         mkU32(0x7fff))),
8144                                             binop(Iop_Or32,
8145                                                   getDSPControl(),
8146                                                   mkU32(0x00400000)),
8147                                             getDSPControl()));
8148                      putDSPControl(IRExpr_ITE(mkexpr(t11),
8149                                               mkexpr(t12),
8150                                               binop(Iop_Or32,
8151                                                     getDSPControl(),
8152                                                     mkU32(0x00400000))));
8153 
8154                      assign(t13, IRExpr_ITE(binop(Iop_CmpLT32U,
8155                                                   mkU32(0x7f80),
8156                                                   binop(Iop_And32,
8157                                                         unop(Iop_16Uto32,
8158                                                              unop(Iop_32HIto16,
8159                                                                   getIReg(rt))),
8160                                                         mkU32(0x7fff))),
8161                                             mkU8(0xff),
8162                                             unop(Iop_16HIto8,
8163                                                  unop(Iop_32HIto16,
8164                                                       binop(Iop_Shl32,
8165                                                             getIReg(rt),
8166                                                             mkU8(1))))));
8167                      assign(t3, IRExpr_ITE(binop(Iop_CmpEQ32,
8168                                                  binop(Iop_And32,
8169                                                        unop(Iop_16Uto32,
8170                                                             unop(Iop_32HIto16,
8171                                                                  getIReg(rt))),
8172                                                        mkU32(0x00008000)),
8173                                                  mkU32(0x0)),
8174                                            mkexpr(t13),
8175                                            mkU8(0x0)));
8176                      assign(t14, binop(Iop_CmpEQ32,
8177                                        binop(Iop_And32,
8178                                              unop(Iop_16Uto32,
8179                                                   unop(Iop_32HIto16,
8180                                                        getIReg(rt))),
8181                                              mkU32(0x00008000)),
8182                                        mkU32(0x0)));
8183                      assign(t15, IRExpr_ITE(binop(Iop_CmpLT32U,
8184                                                   mkU32(0x7f80),
8185                                                   binop(Iop_And32,
8186                                                         unop(Iop_16Uto32,
8187                                                              unop(Iop_32HIto16,
8188                                                                   getIReg(rt))),
8189                                                         mkU32(0x7fff))),
8190                                             binop(Iop_Or32,
8191                                                   getDSPControl(),
8192                                                   mkU32(0x00400000)),
8193                                             getDSPControl()));
8194                      putDSPControl(IRExpr_ITE(mkexpr(t14),
8195                                               mkexpr(t15),
8196                                               binop(Iop_Or32,
8197                                                     getDSPControl(),
8198                                                     mkU32(0x00400000))));
8199 
8200                      putIReg(rd, binop(Iop_16HLto32,
8201                                        binop(Iop_8HLto16,
8202                                              mkexpr(t1), mkexpr(t0)),
8203                                        binop(Iop_8HLto16,
8204                                              mkexpr(t3), mkexpr(t2))));
8205                      break;
8206                   }
8207                   case 0x14: {  /* PRECRQ.PH.W */
8208                      DIP("precrq.ph.w r%u, r%u, %u", rd, rs, rt);
8209                      vassert(!mode64);
8210                      putIReg(rd, binop(Iop_16HLto32,
8211                                        unop(Iop_32HIto16, getIReg(rs)),
8212                                        unop(Iop_32HIto16, getIReg(rt))));
8213                      break;
8214                   }
8215                   case 0x15: {  /* PRECRQ_RS.PH.W */
8216                      DIP("precrq_rs.ph.w r%u, r%u, %u", rd, rs, rt);
8217                      vassert(!mode64);
8218                      t0 = newTemp(Ity_I64);
8219                      t1 = newTemp(Ity_I1);
8220                      t2 = newTemp(Ity_I32);
8221                      t3 = newTemp(Ity_I64);
8222                      t4 = newTemp(Ity_I1);
8223                      t5 = newTemp(Ity_I32);
8224 
8225                      assign(t0, binop(Iop_Add64,
8226                                       binop(Iop_32HLto64,
8227                                             binop(Iop_Shr32,
8228                                                   binop(Iop_And32,
8229                                                         getIReg(rs),
8230                                                         mkU32(0x80000000)),
8231                                                   mkU8(31)),
8232                                             getIReg(rs)),
8233                                       mkU64(0x0000000000008000ULL)));
8234                      assign(t1, binop(Iop_CmpNE32,
8235                                       binop(Iop_And32,
8236                                             unop(Iop_64HIto32, mkexpr(t0)),
8237                                             mkU32(0x1)),
8238                                       binop(Iop_And32,
8239                                             binop(Iop_Shr32,
8240                                                   unop(Iop_64to32, mkexpr(t0)),
8241                                                   mkU8(31)),
8242                                             mkU32(0x1))));
8243                      assign(t2, IRExpr_ITE(mkexpr(t1),
8244                                            mkU32(0x7fffffff),
8245                                            unop(Iop_64to32, mkexpr(t0))));
8246                      putDSPControl(IRExpr_ITE(mkexpr(t1),
8247                                               binop(Iop_Or32,
8248                                                     getDSPControl(),
8249                                                     mkU32(0x400000)),
8250                                               getDSPControl()));
8251                      assign(t3, binop(Iop_Add64,
8252                                       binop(Iop_32HLto64,
8253                                             binop(Iop_Shr32,
8254                                                   binop(Iop_And32,
8255                                                         getIReg(rt),
8256                                                         mkU32(0x80000000)),
8257                                                   mkU8(31)),
8258                                             getIReg(rt)),
8259                                       mkU64(0x0000000000008000ULL)));
8260                      assign(t4, binop(Iop_CmpNE32,
8261                                       binop(Iop_And32,
8262                                             unop(Iop_64HIto32, mkexpr(t3)),
8263                                             mkU32(0x1)),
8264                                       binop(Iop_And32,
8265                                             binop(Iop_Shr32,
8266                                                   unop(Iop_64to32, mkexpr(t3)),
8267                                                   mkU8(31)),
8268                                             mkU32(0x1))));
8269                      assign(t5, IRExpr_ITE(mkexpr(t4),
8270                                            mkU32(0x7fffffff),
8271                                            unop(Iop_64to32, mkexpr(t3))));
8272                      putDSPControl(IRExpr_ITE(mkexpr(t4),
8273                                               binop(Iop_Or32,
8274                                                     getDSPControl(),
8275                                                     mkU32(0x400000)),
8276                                               getDSPControl()));
8277                      putIReg(rd, binop(Iop_16HLto32,
8278                                        unop(Iop_32HIto16, mkexpr(t2)),
8279                                        unop(Iop_32HIto16, mkexpr(t5))));
8280                      break;
8281                   }
8282                   case 0x1E: {  /* PRECR_SRA.PH.W */
8283                      DIP("precr_sra.ph.w r%u, r%u, %u", rt, rs, rd);
8284                      vassert(!mode64);
8285 
8286                      if (0 == rd) {
8287                         putIReg(rt, binop(Iop_16HLto32,
8288                                           unop(Iop_32to16, getIReg(rt)),
8289                                           unop(Iop_32to16, getIReg(rs))));
8290                      } else {
8291                         putIReg(rt, binop(Iop_16HLto32,
8292                                           unop(Iop_32to16, binop(Iop_Sar32,
8293                                                                  getIReg(rt),
8294                                                                  mkU8(rd))),
8295                                           unop(Iop_32to16, binop(Iop_Sar32,
8296                                                                  getIReg(rs),
8297                                                                  mkU8(rd)))));
8298                      }
8299                      break;
8300                   }
8301                   case 0x1F: {  /* PRECR_SRA_R.PH.W */
8302                      DIP("precr_sra_r.ph.w r%u, r%u, %u", rt, rs, rd);
8303                      vassert(!mode64);
8304 
8305                      t0 = newTemp(Ity_I32);
8306                      t1 = newTemp(Ity_I32);
8307 
8308                      if (0 == rd) {
8309                         putIReg(rt, binop(Iop_16HLto32,
8310                                           unop(Iop_32to16, getIReg(rt)),
8311                                           unop(Iop_32to16, getIReg(rs))));
8312                      } else {
8313                         assign(t0, binop(Iop_Shr32,
8314                                          binop(Iop_Add32,
8315                                                binop(Iop_Sar32,
8316                                                      getIReg(rt),
8317                                                      mkU8(rd-1)),
8318                                                mkU32(0x1)),
8319                                          mkU8(0x1)));
8320                         assign(t1, binop(Iop_Shr32,
8321                                          binop(Iop_Add32,
8322                                                binop(Iop_Sar32,
8323                                                      getIReg(rs),
8324                                                      mkU8(rd-1)),
8325                                                mkU32(0x1)),
8326                                          mkU8(0x1)));
8327                         putIReg(rt, binop(Iop_16HLto32,
8328                                           unop(Iop_32to16, mkexpr(t0)),
8329                                           unop(Iop_32to16, mkexpr(t1))));
8330                      };
8331                      break;
8332                   }
8333                   case 0xE: {  /* PACKRL.PH */
8334                      DIP("packrl.ph r%u, r%u, r%u", rd, rs, rt);
8335                      vassert(!mode64);
8336 
8337                      putIReg(rd, binop(Iop_16HLto32,
8338                                        unop(Iop_32to16, getIReg(rs)),
8339                                        unop(Iop_32HIto16, getIReg(rt))));
8340                      break;
8341                   }
8342                   case 0x18: {  /* CMPGDU.EQ.QB */
8343                      DIP("cmpgdu.eq.qb r%u, r%u, r%u", rd, rs, rt);
8344                      vassert(!mode64);
8345                      t1 = newTemp(Ity_I1);
8346                      t2 = newTemp(Ity_I1);
8347                      t3 = newTemp(Ity_I1);
8348                      t4 = newTemp(Ity_I1);
8349                      t5 = newTemp(Ity_I32);
8350                      t6 = newTemp(Ity_I32);
8351                      t7 = newTemp(Ity_I32);
8352                      t8 = newTemp(Ity_I32);
8353 
8354                      assign(t1,
8355                             binop(Iop_CmpEQ32,
8356                                   unop(Iop_8Uto32,
8357                                        unop(Iop_16to8,
8358                                             unop(Iop_32to16, getIReg(rs)))),
8359                                   unop(Iop_8Uto32,
8360                                        unop(Iop_16to8,
8361                                             unop(Iop_32to16, getIReg(rt))))));
8362                      assign(t5, IRExpr_ITE(mkexpr(t1),
8363                                            mkU32(0x00000001), mkU32(0)));
8364                      putDSPControl(IRExpr_ITE(mkexpr(t1),
8365                                               binop(Iop_Or32,
8366                                                     getDSPControl(),
8367                                                     mkU32(0x01000000)),
8368                                               binop(Iop_And32,
8369                                                     getDSPControl(),
8370                                                     mkU32(0xfeffffff))));
8371 
8372                      assign(t2, binop(Iop_CmpEQ32,
8373                                       unop(Iop_8Uto32,
8374                                            unop(Iop_16HIto8,
8375                                                 unop(Iop_32to16, getIReg(rs)))),
8376                                       unop(Iop_8Uto32,
8377                                            unop(Iop_16HIto8,
8378                                                 unop(Iop_32to16,
8379                                                      getIReg(rt))))));
8380                      assign(t6, IRExpr_ITE(mkexpr(t2),
8381                                            mkU32(0x00000002), mkU32(0)));
8382                      putDSPControl(IRExpr_ITE(mkexpr(t2),
8383                                               binop(Iop_Or32,
8384                                                     getDSPControl(),
8385                                                     mkU32(0x02000000)),
8386                                               binop(Iop_And32,
8387                                                     getDSPControl(),
8388                                                     mkU32(0xfdffffff))));
8389 
8390                      assign(t3, binop(Iop_CmpEQ32,
8391                                       unop(Iop_8Uto32,
8392                                            unop(Iop_16to8,
8393                                                 unop(Iop_32HIto16,
8394                                                      getIReg(rs)))),
8395                                       unop(Iop_8Uto32,
8396                                            unop(Iop_16to8,
8397                                                 unop(Iop_32HIto16,
8398                                                      getIReg(rt))))));
8399                      assign(t7, IRExpr_ITE(mkexpr(t3),
8400                                            mkU32(0x00000004), mkU32(0)));
8401                      putDSPControl(IRExpr_ITE(mkexpr(t3),
8402                                               binop(Iop_Or32,
8403                                                     getDSPControl(),
8404                                                     mkU32(0x04000000)),
8405                                               binop(Iop_And32,
8406                                                     getDSPControl(),
8407                                                     mkU32(0xfbffffff))));
8408 
8409                      assign(t4, binop(Iop_CmpEQ32,
8410                                       unop(Iop_8Uto32,
8411                                            unop(Iop_16HIto8,
8412                                                 unop(Iop_32HIto16,
8413                                                      getIReg(rs)))),
8414                                       unop(Iop_8Uto32,
8415                                            unop(Iop_16HIto8,
8416                                                 unop(Iop_32HIto16,
8417                                                      getIReg(rt))))));
8418                      assign(t8, IRExpr_ITE(mkexpr(t4),
8419                                            mkU32(0x00000008), mkU32(0)));
8420                      putDSPControl(IRExpr_ITE(mkexpr(t4),
8421                                               binop(Iop_Or32,
8422                                                     getDSPControl(),
8423                                                     mkU32(0x08000000)),
8424                                               binop(Iop_And32,
8425                                                     getDSPControl(),
8426                                                     mkU32(0xf7ffffff))));
8427 
8428                      putIReg(rd, binop(Iop_Or32,
8429                                        binop(Iop_Or32,
8430                                              binop(Iop_Or32,
8431                                                    mkexpr(t5), mkexpr(t6)),
8432                                              mkexpr(t7)),
8433                                        mkexpr(t8)));
8434                      break;
8435                   }
8436                   case 0x19: {  /* CMPGDU.LT.QB */
8437                      DIP("cmpgdu.lt.qb r%u, r%u, r%u", rd, rs, rt);
8438                      vassert(!mode64);
8439                      t1 = newTemp(Ity_I1);
8440                      t2 = newTemp(Ity_I1);
8441                      t3 = newTemp(Ity_I1);
8442                      t4 = newTemp(Ity_I1);
8443                      t5 = newTemp(Ity_I32);
8444                      t6 = newTemp(Ity_I32);
8445                      t7 = newTemp(Ity_I32);
8446                      t8 = newTemp(Ity_I32);
8447 
8448                      assign(t1, binop(Iop_CmpLT32U,
8449                                       unop(Iop_8Uto32,
8450                                            unop(Iop_16to8,
8451                                                 unop(Iop_32to16, getIReg(rs)))),
8452                                       unop(Iop_8Uto32,
8453                                            unop(Iop_16to8,
8454                                                 unop(Iop_32to16,
8455                                                      getIReg(rt))))));
8456                      assign(t5, IRExpr_ITE(mkexpr(t1),
8457                                            mkU32(0x00000001), mkU32(0)));
8458                      putDSPControl(IRExpr_ITE(mkexpr(t1),
8459                                               binop(Iop_Or32,
8460                                                     getDSPControl(),
8461                                                     mkU32(0x01000000)),
8462                                               binop(Iop_And32,
8463                                                     getDSPControl(),
8464                                                     mkU32(0xfeffffff))));
8465 
8466                      assign(t2, binop(Iop_CmpLT32U,
8467                                       unop(Iop_8Uto32,
8468                                            unop(Iop_16HIto8,
8469                                                 unop(Iop_32to16, getIReg(rs)))),
8470                                       unop(Iop_8Uto32,
8471                                            unop(Iop_16HIto8,
8472                                                 unop(Iop_32to16,
8473                                                      getIReg(rt))))));
8474                      assign(t6, IRExpr_ITE(mkexpr(t2),
8475                                            mkU32(0x00000002), mkU32(0)));
8476                      putDSPControl(IRExpr_ITE(mkexpr(t2),
8477                                               binop(Iop_Or32,
8478                                                     getDSPControl(),
8479                                                     mkU32(0x02000000)),
8480                                               binop(Iop_And32,
8481                                                     getDSPControl(),
8482                                                     mkU32(0xfdffffff))));
8483 
8484                      assign(t3, binop(Iop_CmpLT32U,
8485                                       unop(Iop_8Uto32,
8486                                            unop(Iop_16to8,
8487                                                 unop(Iop_32HIto16,
8488                                                      getIReg(rs)))),
8489                                       unop(Iop_8Uto32,
8490                                            unop(Iop_16to8,
8491                                                 unop(Iop_32HIto16,
8492                                                      getIReg(rt))))));
8493                      assign(t7, IRExpr_ITE(mkexpr(t3),
8494                                            mkU32(0x00000004), mkU32(0)));
8495                      putDSPControl(IRExpr_ITE(mkexpr(t3),
8496                                               binop(Iop_Or32,
8497                                                     getDSPControl(),
8498                                                     mkU32(0x04000000)),
8499                                               binop(Iop_And32,
8500                                                     getDSPControl(),
8501                                                     mkU32(0xfbffffff))));
8502 
8503                      assign(t4, binop(Iop_CmpLT32U,
8504                                       unop(Iop_8Uto32,
8505                                            unop(Iop_16HIto8,
8506                                                 unop(Iop_32HIto16,
8507                                                      getIReg(rs)))),
8508                                       unop(Iop_8Uto32,
8509                                            unop(Iop_16HIto8,
8510                                                 unop(Iop_32HIto16,
8511                                                      getIReg(rt))))));
8512                      assign(t8, IRExpr_ITE(mkexpr(t4),
8513                                            mkU32(0x00000008), mkU32(0)));
8514                      putDSPControl(IRExpr_ITE(mkexpr(t4),
8515                                               binop(Iop_Or32,
8516                                                     getDSPControl(),
8517                                                     mkU32(0x08000000)),
8518                                               binop(Iop_And32,
8519                                                     getDSPControl(),
8520                                                     mkU32(0xf7ffffff))));
8521 
8522                      putIReg(rd, binop(Iop_Or32,
8523                                        binop(Iop_Or32,
8524                                              binop(Iop_Or32,
8525                                                    mkexpr(t5), mkexpr(t6)),
8526                                              mkexpr(t7)),
8527                                        mkexpr(t8)));
8528                      break;
8529                   }
8530                   case 0x1A: {  /* CMPGDU.LE.QB */
8531                      DIP("cmpgdu.le.qb r%u, r%u, r%u", rd, rs, rt);
8532                      vassert(!mode64);
8533                      t1 = newTemp(Ity_I1);
8534                      t2 = newTemp(Ity_I1);
8535                      t3 = newTemp(Ity_I1);
8536                      t4 = newTemp(Ity_I1);
8537                      t5 = newTemp(Ity_I32);
8538                      t6 = newTemp(Ity_I32);
8539                      t7 = newTemp(Ity_I32);
8540                      t8 = newTemp(Ity_I32);
8541 
8542                      assign(t1, binop(Iop_CmpLE32U,
8543                                       unop(Iop_8Uto32,
8544                                            unop(Iop_16to8,
8545                                                 unop(Iop_32to16, getIReg(rs)))),
8546                                       unop(Iop_8Uto32,
8547                                            unop(Iop_16to8,
8548                                                 unop(Iop_32to16,
8549                                                      getIReg(rt))))));
8550                      assign(t5, IRExpr_ITE(mkexpr(t1),
8551                                            mkU32(0x00000001),
8552                                            mkU32(0)));
8553                      putDSPControl(IRExpr_ITE(mkexpr(t1),
8554                                               binop(Iop_Or32,
8555                                                     getDSPControl(),
8556                                                     mkU32(0x01000000)),
8557                                               binop(Iop_And32,
8558                                                     getDSPControl(),
8559                                                     mkU32(0xfeffffff))));
8560 
8561                      assign(t2, binop(Iop_CmpLE32U,
8562                                       unop(Iop_8Uto32,
8563                                            unop(Iop_16HIto8,
8564                                                 unop(Iop_32to16, getIReg(rs)))),
8565                                       unop(Iop_8Uto32,
8566                                            unop(Iop_16HIto8,
8567                                                 unop(Iop_32to16,
8568                                                      getIReg(rt))))));
8569                      assign(t6, IRExpr_ITE(mkexpr(t2),
8570                                            mkU32(0x00000002), mkU32(0)));
8571                      putDSPControl(IRExpr_ITE(mkexpr(t2),
8572                                               binop(Iop_Or32,
8573                                                     getDSPControl(),
8574                                                     mkU32(0x02000000)),
8575                                               binop(Iop_And32,
8576                                                     getDSPControl(),
8577                                                     mkU32(0xfdffffff))));
8578 
8579                      assign(t3, binop(Iop_CmpLE32U,
8580                                       unop(Iop_8Uto32,
8581                                            unop(Iop_16to8,
8582                                                 unop(Iop_32HIto16,
8583                                                      getIReg(rs)))),
8584                                       unop(Iop_8Uto32,
8585                                            unop(Iop_16to8,
8586                                                 unop(Iop_32HIto16,
8587                                                      getIReg(rt))))));
8588                      assign(t7, IRExpr_ITE(mkexpr(t3),
8589                                            mkU32(0x00000004), mkU32(0)));
8590                      putDSPControl(IRExpr_ITE(mkexpr(t3),
8591                                               binop(Iop_Or32,
8592                                                     getDSPControl(),
8593                                                     mkU32(0x04000000)),
8594                                               binop(Iop_And32,
8595                                                     getDSPControl(),
8596                                                     mkU32(0xfbffffff))));
8597 
8598                      assign(t4, binop(Iop_CmpLE32U,
8599                                       unop(Iop_8Uto32,
8600                                            unop(Iop_16HIto8,
8601                                                 unop(Iop_32HIto16,
8602                                                      getIReg(rs)))),
8603                                       unop(Iop_8Uto32,
8604                                            unop(Iop_16HIto8,
8605                                                 unop(Iop_32HIto16,
8606                                                      getIReg(rt))))));
8607                      assign(t8, IRExpr_ITE(mkexpr(t4),
8608                                            mkU32(0x00000008), mkU32(0)));
8609                      putDSPControl(IRExpr_ITE(mkexpr(t4),
8610                                               binop(Iop_Or32,
8611                                                     getDSPControl(),
8612                                                     mkU32(0x08000000)),
8613                                               binop(Iop_And32,
8614                                                     getDSPControl(),
8615                                                     mkU32(0xf7ffffff))));
8616 
8617                      putIReg(rd, binop(Iop_Or32,
8618                                        binop(Iop_Or32,
8619                                              binop(Iop_Or32,
8620                                                    mkexpr(t5), mkexpr(t6)),
8621                                              mkexpr(t7)),
8622                                        mkexpr(t8)));
8623                      break;
8624                   }
8625                   default:
8626                      return -1;
8627                }
8628                break;  /* end of CMPU.EQ.QB */
8629             }
8630             case 0x13: {  /* SHLL.QB */
8631                switch(sa) {
8632                   case 0x0: {  /* SHLL.QB */
8633                      DIP("shll.qb r%u, r%u, %u", rd, rt, rs);
8634                      vassert(!mode64);
8635                      t0 = newTemp(Ity_I32);
8636                      t1 = newTemp(Ity_I1);
8637                      t2 = newTemp(Ity_I1);
8638                      t3 = newTemp(Ity_I32);
8639                      t4 = newTemp(Ity_I1);
8640                      t5 = newTemp(Ity_I1);
8641                      t6 = newTemp(Ity_I32);
8642                      t7 = newTemp(Ity_I1);
8643                      t8 = newTemp(Ity_I1);
8644                      t9 = newTemp(Ity_I1);
8645                      t10 = newTemp(Ity_I1);
8646 
8647                      if (0 == rs) {
8648                         putIReg(rd, getIReg(rt));
8649                      } else {
8650                         /* Shift bits 7..0 and 23..16. */
8651                         assign(t0, binop(Iop_Shl32,
8652                                          binop(Iop_And32,
8653                                                getIReg(rt),
8654                                                mkU32(0x00ff00ff)),
8655                                          mkU8(rs)));
8656                         assign(t1, binop(Iop_CmpNE32,
8657                                         binop(Iop_And32,
8658                                               mkexpr(t0),
8659                                               mkU32(0xff000000)),
8660                                         mkU32(0x00000000)));
8661                         assign(t2, binop(Iop_CmpNE32,
8662                                         binop(Iop_And32,
8663                                               mkexpr(t0),
8664                                               mkU32(0xff000000)),
8665                                         mkU32(0xff000000)));
8666                         assign(t7, binop(Iop_CmpNE32,
8667                                         binop(Iop_And32,
8668                                               mkexpr(t0),
8669                                               mkU32(0x0000ff00)),
8670                                         mkU32(0x00000000)));
8671                         assign(t8, binop(Iop_CmpNE32,
8672                                         binop(Iop_And32,
8673                                               mkexpr(t0),
8674                                               mkU32(0x0000ff00)),
8675                                         mkU32(0x000ff00)));
8676                         /* Shift bits 15..8 and 31..24. */
8677                         assign(t3, binop(Iop_Shl32,
8678                                          binop(Iop_Shr32,
8679                                                binop(Iop_And32,
8680                                                      getIReg(rt),
8681                                                      mkU32(0xff00ff00)),
8682                                                mkU8(8)),
8683                                          mkU8(rs)));
8684                         assign(t4, binop(Iop_CmpNE32,
8685                                         binop(Iop_And32,
8686                                               mkexpr(t3),
8687                                               mkU32(0xff000000)),
8688                                         mkU32(0x00000000)));
8689                         assign(t5, binop(Iop_CmpNE32,
8690                                         binop(Iop_And32,
8691                                               mkexpr(t3),
8692                                               mkU32(0xff000000)),
8693                                         mkU32(0xff000000)));
8694                         assign(t9, binop(Iop_CmpNE32,
8695                                         binop(Iop_And32,
8696                                               mkexpr(t3),
8697                                               mkU32(0x0000ff00)),
8698                                         mkU32(0x00000000)));
8699                         assign(t10, binop(Iop_CmpNE32,
8700                                         binop(Iop_And32,
8701                                               mkexpr(t3),
8702                                               mkU32(0x0000ff00)),
8703                                         mkU32(0x0000ff00)));
8704 
8705                         assign(t6, binop(Iop_Or32,
8706                                          binop(Iop_Or32,
8707                                                binop(Iop_And32,
8708                                                      unop(Iop_1Uto32,
8709                                                           mkexpr(t1)),
8710                                                      unop(Iop_1Uto32,
8711                                                           mkexpr(t2))),
8712                                                binop(Iop_And32,
8713                                                      unop(Iop_1Uto32,
8714                                                           mkexpr(t7)),
8715                                                      unop(Iop_1Uto32,
8716                                                           mkexpr(t8)))),
8717                                          binop(Iop_Or32,
8718                                                binop(Iop_And32,
8719                                                      unop(Iop_1Uto32,
8720                                                           mkexpr(t4)),
8721                                                      unop(Iop_1Uto32,
8722                                                           mkexpr(t5))),
8723                                                binop(Iop_And32,
8724                                                      unop(Iop_1Uto32,
8725                                                           mkexpr(t9)),
8726                                                      unop(Iop_1Uto32,
8727                                                           mkexpr(t10))))));
8728 
8729                         putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32,
8730                                                        mkexpr(t6),
8731                                                        mkU32(0x0)),
8732                                                  binop(Iop_Or32,
8733                                                        getDSPControl(),
8734                                                        mkU32(0x400000)),
8735                                                  getDSPControl()));
8736                         putIReg(rd, binop(Iop_Or32,
8737                                           binop(Iop_Shl32,
8738                                                 binop(Iop_And32,
8739                                                       mkexpr(t3),
8740                                                       mkU32(0x00ff00ff)),
8741                                                 mkU8(8)),
8742                                           binop(Iop_And32,
8743                                                 mkexpr(t0),
8744                                                 mkU32(0x00ff00ff))));
8745                      }
8746                      break;
8747                   }
8748                   case 0x3: {  /* SHRL.QB */
8749                      DIP("shrl.qb r%u, r%u, %u", rd, rt, rs);
8750                      vassert(!mode64);
8751                      t0 = newTemp(Ity_I32);
8752                      t1 = newTemp(Ity_I8);
8753                      t2 = newTemp(Ity_I32);
8754                      t3 = newTemp(Ity_I8);
8755                      t4 = newTemp(Ity_I32);
8756                      t5 = newTemp(Ity_I8);
8757                      t6 = newTemp(Ity_I32);
8758                      t7 = newTemp(Ity_I8);
8759                      t9 = newTemp(Ity_I32);
8760 
8761                      assign(t9, binop(Iop_And32, getIReg(rs), mkU32(0x7)));
8762                      assign(t0, unop(Iop_8Uto32,
8763                                      unop(Iop_16to8,
8764                                           unop(Iop_32to16, getIReg(rt)))));
8765                      assign(t1, unop(Iop_32to8,
8766                                      binop(Iop_Shr32,
8767                                            mkexpr(t0),
8768                                            unop(Iop_32to8, mkexpr(t9)))));
8769 
8770                      assign(t2, unop(Iop_8Uto32,
8771                                      unop(Iop_16HIto8,
8772                                           unop(Iop_32to16, getIReg(rt)))));
8773                      assign(t3, unop(Iop_32to8,
8774                                      binop(Iop_Shr32,
8775                                            mkexpr(t2),
8776                                            unop(Iop_32to8, mkexpr(t9)))));
8777 
8778                      assign(t4, unop(Iop_8Uto32,
8779                                      unop(Iop_16to8,
8780                                           unop(Iop_32HIto16, getIReg(rt)))));
8781                      assign(t5, unop(Iop_32to8,
8782                                      binop(Iop_Shr32,
8783                                            mkexpr(t4),
8784                                            unop(Iop_32to8, mkexpr(t9)))));
8785 
8786                      assign(t6, unop(Iop_8Uto32,
8787                                      unop(Iop_16HIto8,
8788                                           unop(Iop_32HIto16, getIReg(rt)))));
8789                      assign(t7, unop(Iop_32to8,
8790                                      binop(Iop_Shr32,
8791                                            mkexpr(t6),
8792                                            unop(Iop_32to8, mkexpr(t9)))));
8793                      putIReg(rd, IRExpr_ITE(binop(Iop_CmpEQ32,
8794                                                   mkexpr(t9),
8795                                                   mkU32(0x0)),
8796                                             getIReg(rt),
8797                                             binop(Iop_16HLto32,
8798                                                   binop(Iop_8HLto16,
8799                                                         mkexpr(t7),
8800                                                         mkexpr(t5)),
8801                                                   binop(Iop_8HLto16,
8802                                                         mkexpr(t3),
8803                                                         mkexpr(t1)))));
8804                      break;
8805                   }
8806                   case 0x2: {  /* SHLLV.QB */
8807                      DIP("shllv.qb r%u, r%u, r%u", rd, rt, rs);
8808                      vassert(!mode64);
8809                      t0 = newTemp(Ity_I32);
8810                      t1 = newTemp(Ity_I1);
8811                      t2 = newTemp(Ity_I1);
8812                      t3 = newTemp(Ity_I32);
8813                      t4 = newTemp(Ity_I1);
8814                      t5 = newTemp(Ity_I1);
8815                      t6 = newTemp(Ity_I32);
8816                      t7 = newTemp(Ity_I1);
8817                      t8 = newTemp(Ity_I1);
8818                      t9 = newTemp(Ity_I1);
8819                      t10 = newTemp(Ity_I1);
8820                      t11 = newTemp(Ity_I8);
8821 
8822                      assign(t11, unop(Iop_32to8,
8823                                       binop(Iop_And32,
8824                                             getIReg(rs),
8825                                             mkU32(0x7))));
8826                      /* Shift bits 7..0 and 23..16. */
8827                      assign(t0, binop(Iop_Shl32,
8828                                       binop(Iop_And32,
8829                                             getIReg(rt),
8830                                             mkU32(0x00ff00ff)),
8831                                       mkexpr(t11)));
8832                      assign(t1, binop(Iop_CmpNE32,
8833                                      binop(Iop_And32,
8834                                            mkexpr(t0),
8835                                            mkU32(0xff000000)),
8836                                      mkU32(0x00000000)));
8837                      assign(t2, binop(Iop_CmpNE32,
8838                                      binop(Iop_And32,
8839                                            mkexpr(t0),
8840                                            mkU32(0xff000000)),
8841                                      mkU32(0xff000000)));
8842                      assign(t7, binop(Iop_CmpNE32,
8843                                      binop(Iop_And32,
8844                                            mkexpr(t0),
8845                                            mkU32(0x0000ff00)),
8846                                      mkU32(0x00000000)));
8847                      assign(t8, binop(Iop_CmpNE32,
8848                                      binop(Iop_And32,
8849                                            mkexpr(t0),
8850                                            mkU32(0x0000ff00)),
8851                                      mkU32(0x000ff00)));
8852                      /* Shift bits 15..8 and 31..24. */
8853                      assign(t3, binop(Iop_Shl32,
8854                                       binop(Iop_Shr32,
8855                                             binop(Iop_And32,
8856                                                   getIReg(rt),
8857                                                   mkU32(0xff00ff00)),
8858                                             mkU8(8)),
8859                                       mkexpr(t11)));
8860                      assign(t4, binop(Iop_CmpNE32,
8861                                      binop(Iop_And32,
8862                                            mkexpr(t3),
8863                                            mkU32(0xff000000)),
8864                                      mkU32(0x00000000)));
8865                      assign(t5, binop(Iop_CmpNE32,
8866                                      binop(Iop_And32,
8867                                            mkexpr(t3),
8868                                            mkU32(0xff000000)),
8869                                      mkU32(0xff000000)));
8870                      assign(t9, binop(Iop_CmpNE32,
8871                                      binop(Iop_And32,
8872                                            mkexpr(t3),
8873                                            mkU32(0x0000ff00)),
8874                                      mkU32(0x00000000)));
8875                      assign(t10, binop(Iop_CmpNE32,
8876                                      binop(Iop_And32,
8877                                            mkexpr(t3),
8878                                            mkU32(0x0000ff00)),
8879                                      mkU32(0x0000ff00)));
8880 
8881                      assign(t6, binop(Iop_Or32,
8882                                       binop(Iop_Or32,
8883                                             binop(Iop_And32,
8884                                                   unop(Iop_1Uto32,
8885                                                        mkexpr(t1)),
8886                                                   unop(Iop_1Uto32,
8887                                                        mkexpr(t2))),
8888                                             binop(Iop_And32,
8889                                                   unop(Iop_1Uto32,
8890                                                        mkexpr(t7)),
8891                                                   unop(Iop_1Uto32,
8892                                                        mkexpr(t8)))),
8893                                       binop(Iop_Or32,
8894                                             binop(Iop_And32,
8895                                                   unop(Iop_1Uto32,
8896                                                        mkexpr(t4)),
8897                                                   unop(Iop_1Uto32,
8898                                                        mkexpr(t5))),
8899                                             binop(Iop_And32,
8900                                                   unop(Iop_1Uto32,
8901                                                        mkexpr(t9)),
8902                                                   unop(Iop_1Uto32,
8903                                                        mkexpr(t10))))));
8904 
8905                      putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32,
8906                                                     mkexpr(t6),
8907                                                     mkU32(0x0)),
8908                                               binop(Iop_Or32,
8909                                                     getDSPControl(),
8910                                                     mkU32(0x400000)),
8911                                               getDSPControl()));
8912                      putIReg(rd, IRExpr_ITE(binop(Iop_CmpEQ32,
8913                                                   unop(Iop_8Uto32, mkexpr(t11)),
8914                                                   mkU32(0)),
8915                                             getIReg(rt),
8916                                             binop(Iop_Or32,
8917                                                   binop(Iop_Shl32,
8918                                                         binop(Iop_And32,
8919                                                               mkexpr(t3),
8920                                                               mkU32(0xff00ff)),
8921                                                         mkU8(8)),
8922                                                   binop(Iop_And32,
8923                                                         mkexpr(t0),
8924                                                         mkU32(0x00ff00ff)))));
8925                      break;
8926                   }
8927                   case 0x1: {  /* SHRLV.QB */
8928                      DIP("shrlv.qb r%u, r%u, r%u", rd, rt, rs);
8929                      vassert(!mode64);
8930                      t0 = newTemp(Ity_I8);
8931                      t1 = newTemp(Ity_I8);
8932                      t2 = newTemp(Ity_I8);
8933                      t3 = newTemp(Ity_I8);
8934 
8935                      assign(t0, unop(Iop_32to8,
8936                                      binop(Iop_Shr32,
8937                                            unop(Iop_8Uto32,
8938                                                 unop(Iop_32to8, getIReg(rt))),
8939                                            mkU8(rs))));
8940                      assign(t1, unop(Iop_32to8,
8941                                      binop(Iop_Shr32,
8942                                            unop(Iop_8Uto32,
8943                                                 unop(Iop_16HIto8,
8944                                                      unop(Iop_32to16,
8945                                                           getIReg(rt)))),
8946                                            mkU8(rs))));
8947                      assign(t2, unop(Iop_32to8,
8948                                       binop(Iop_Shr32,
8949                                             unop(Iop_8Uto32,
8950                                                  unop(Iop_16to8,
8951                                                       unop(Iop_32HIto16,
8952                                                            getIReg(rt)))),
8953                                             mkU8(rs))));
8954                      assign(t3, unop(Iop_32to8,
8955                                      binop(Iop_Shr32,
8956                                            unop(Iop_8Uto32,
8957                                                 unop(Iop_16HIto8,
8958                                                      unop(Iop_32HIto16,
8959                                                           getIReg(rt)))),
8960                                            mkU8(rs))));
8961                      putIReg(rd,
8962                              binop(Iop_16HLto32,
8963                                    binop(Iop_8HLto16, mkexpr(t3), mkexpr(t2)),
8964                                    binop(Iop_8HLto16, mkexpr(t1), mkexpr(t0))));
8965                      break;
8966                   }
8967                   case 0x4: {  /* SHRA.QB */
8968                      DIP("shra.qb r%u, r%u, %u", rd, rt, rs);
8969                      vassert(!mode64);
8970                      t0 = newTemp(Ity_I32);
8971                      t1 = newTemp(Ity_I32);
8972                      t2 = newTemp(Ity_I32);
8973                      t3 = newTemp(Ity_I32);
8974                      t4 = newTemp(Ity_I32);
8975                      t5 = newTemp(Ity_I32);
8976                      t6 = newTemp(Ity_I32);
8977                      t7 = newTemp(Ity_I32);
8978                      t8 = newTemp(Ity_I32);
8979                      t9 = newTemp(Ity_I32);
8980                      t10 = newTemp(Ity_I32);
8981                      t11 = newTemp(Ity_I32);
8982 
8983                      /* ========== GPR[rt]_31..24 ========== */
8984                      assign(t1,
8985                             unop(Iop_8Uto32,
8986                                  unop(Iop_16HIto8,
8987                                       unop(Iop_32HIto16, getIReg(rt)))));
8988                      assign(t2,
8989                             binop(Iop_Shr32, mkexpr(t1), mkU8(rs)));
8990                      /* tempD_7..0 */
8991                      assign(t0,
8992                             binop(Iop_Or32,
8993                                   mkexpr(t2),
8994                                   binop(Iop_Shl32,
8995                                         IRExpr_ITE(binop(Iop_CmpEQ32,
8996                                                          binop(Iop_And32,
8997                                                                mkexpr(t1),
8998                                                                mkU32(0x00000080)
8999                                                               ),
9000                                                          mkU32(0x00000080)),
9001                                                    mkU32(0xFFFFFFFF),
9002                                                    mkU32(0x00000000)),
9003                                         binop(Iop_Sub8, mkU8(0x8), mkU8(rs)))));
9004 
9005                      /* ========== GPR[rt]_23..16 ========== */
9006                      assign(t4,
9007                             unop(Iop_8Uto32,
9008                                  unop(Iop_16to8,
9009                                       unop(Iop_32HIto16, getIReg(rt)))));
9010                      assign(t5, binop(Iop_Shr32, mkexpr(t4), mkU8(rs)));
9011                      /* tempC_7..0 */
9012                      assign(t3,
9013                             binop(Iop_Or32,
9014                                   mkexpr(t5),
9015                                   binop(Iop_Shl32,
9016                                         IRExpr_ITE(binop(Iop_CmpEQ32,
9017                                                          binop(Iop_And32,
9018                                                                mkexpr(t4),
9019                                                                mkU32(0x00000080)
9020                                                               ),
9021                                                          mkU32(0x00000080)),
9022                                                    mkU32(0xFFFFFFFF),
9023                                                    mkU32(0x00000000)),
9024                                         binop(Iop_Sub8, mkU8(0x8), mkU8(rs)))));
9025 
9026                      /* ========== GPR[rt]_15..8 ========== */
9027                      assign(t7,
9028                             unop(Iop_8Uto32,
9029                                  unop(Iop_16HIto8,
9030                                       unop(Iop_32to16, getIReg(rt)))));
9031                      assign(t8, binop(Iop_Shr32, mkexpr(t7), mkU8(rs)));
9032                      /* tempB_7..0 */
9033                      assign(t6,
9034                             binop(Iop_Or32,
9035                                   mkexpr(t8),
9036                                   binop(Iop_Shl32,
9037                                         IRExpr_ITE(binop(Iop_CmpEQ32,
9038                                                          binop(Iop_And32,
9039                                                                mkexpr(t7),
9040                                                                mkU32(0x00000080)
9041                                                               ),
9042                                                          mkU32(0x00000080)),
9043                                                    mkU32(0xFFFFFFFF),
9044                                                    mkU32(0x00000000)),
9045                                         binop(Iop_Sub8, mkU8(0x8), mkU8(rs)))));
9046 
9047                      /* ========== GPR[rt]_7..0 ========== */
9048                      assign(t10,
9049                             unop(Iop_8Uto32,
9050                                  unop(Iop_16to8,
9051                                       unop(Iop_32to16, getIReg(rt)))));
9052                      assign(t11, binop(Iop_Shr32, mkexpr(t10), mkU8(rs)));
9053                      /* tempB_7..0 */
9054                      assign(t9,
9055                             binop(Iop_Or32,
9056                                   mkexpr(t11),
9057                                   binop(Iop_Shl32,
9058                                         IRExpr_ITE(binop(Iop_CmpEQ32,
9059                                                          binop(Iop_And32,
9060                                                                mkexpr(t10),
9061                                                                mkU32(0x00000080)
9062                                                               ),
9063                                                          mkU32(0x00000080)),
9064                                                    mkU32(0xFFFFFFFF),
9065                                                    mkU32(0x00000000)),
9066                                         binop(Iop_Sub8, mkU8(0x8), mkU8(rs)))));
9067 
9068                      putIReg(rd,
9069                              binop(Iop_16HLto32,
9070                                    binop(Iop_8HLto16,
9071                                          unop(Iop_32to8, mkexpr(t0)),
9072                                          unop(Iop_32to8, mkexpr(t3))),
9073                                    binop(Iop_8HLto16,
9074                                          unop(Iop_32to8, mkexpr(t6)),
9075                                          unop(Iop_32to8, mkexpr(t9)))));
9076                      break;
9077                   }
9078                   case 0x5: {  /* SHRA_R.QB */
9079                      DIP("shra_r.qb r%u, r%u, %u", rd, rt, rs);
9080                      vassert(!mode64);
9081                      t0 = newTemp(Ity_I32);
9082                      t1 = newTemp(Ity_I8);
9083                      t2 = newTemp(Ity_I32);
9084                      t3 = newTemp(Ity_I8);
9085                      t4 = newTemp(Ity_I32);
9086                      t5 = newTemp(Ity_I8);
9087                      t6 = newTemp(Ity_I32);
9088                      t7 = newTemp(Ity_I8);
9089 
9090                      if (0 == rs) {
9091                         putIReg(rd, getIReg(rt));
9092                      } else {
9093                         assign(t0, unop(Iop_8Sto32,
9094                                         unop(Iop_16to8,
9095                                              unop(Iop_32to16, getIReg(rt)))));
9096                         assign(t1, unop(Iop_32to8,
9097                                         binop(Iop_Sar32,
9098                                               binop(Iop_Add32,
9099                                                     mkexpr(t0),
9100                                                     binop(Iop_Shl32,
9101                                                           mkU32(0x1),
9102                                                           mkU8(rs-1))),
9103                                               mkU8(rs))));
9104 
9105                         assign(t2, unop(Iop_8Sto32,
9106                                         unop(Iop_16HIto8,
9107                                              unop(Iop_32to16, getIReg(rt)))));
9108                         assign(t3, unop(Iop_32to8,
9109                                         binop(Iop_Sar32,
9110                                               binop(Iop_Add32,
9111                                                     mkexpr(t2),
9112                                                     binop(Iop_Shl32,
9113                                                           mkU32(0x1),
9114                                                           mkU8(rs-1))),
9115                                               mkU8(rs))));
9116 
9117                         assign(t4, unop(Iop_8Sto32,
9118                                         unop(Iop_16to8,
9119                                              unop(Iop_32HIto16, getIReg(rt)))));
9120                         assign(t5, unop(Iop_32to8,
9121                                         binop(Iop_Sar32,
9122                                               binop(Iop_Add32,
9123                                                     mkexpr(t4),
9124                                                     binop(Iop_Shl32,
9125                                                           mkU32(0x1),
9126                                                           mkU8(rs-1))),
9127                                               mkU8(rs))));
9128 
9129                         assign(t6, unop(Iop_8Sto32,
9130                                         unop(Iop_16HIto8,
9131                                              unop(Iop_32HIto16, getIReg(rt)))));
9132                         assign(t7, unop(Iop_32to8,
9133                                         binop(Iop_Sar32,
9134                                               binop(Iop_Add32,
9135                                                     mkexpr(t6),
9136                                                     binop(Iop_Shl32,
9137                                                           mkU32(0x1),
9138                                                           mkU8(rs-1))),
9139                                               mkU8(rs))));
9140                         putIReg(rd, binop(Iop_16HLto32,
9141                                          binop(Iop_8HLto16,
9142                                                mkexpr(t7), mkexpr(t5)),
9143                                          binop(Iop_8HLto16,
9144                                                mkexpr(t3), mkexpr(t1))));
9145                      }
9146                      break;
9147                   }
9148                   case 0x6: {  /* SHRAV.QB */
9149                      DIP("shrav.qb r%u, r%u, %u", rd, rt, rs);
9150                      vassert(!mode64);
9151 
9152                      t0 = newTemp(Ity_I32);
9153                      t1 = newTemp(Ity_I32);
9154                      t2 = newTemp(Ity_I32);
9155 
9156                      t3 = newTemp(Ity_I32);
9157                      t4 = newTemp(Ity_I32);
9158                      t5 = newTemp(Ity_I32);
9159 
9160                      t6 = newTemp(Ity_I32);
9161                      t7 = newTemp(Ity_I32);
9162                      t8 = newTemp(Ity_I32);
9163 
9164                      t9 = newTemp(Ity_I32);
9165                      t10 = newTemp(Ity_I32);
9166                      t11 = newTemp(Ity_I32);
9167 
9168                      /* ========== GPR[rt]_31..24 ========== */
9169                      assign(t1,
9170                             unop(Iop_8Uto32,
9171                                  unop(Iop_16HIto8,
9172                                       unop(Iop_32HIto16, getIReg(rt)))));
9173                      assign(t2,
9174                             binop(Iop_Shr32,
9175                                   mkexpr(t1),
9176                                   unop(Iop_32to8, binop(Iop_And32,
9177                                                         getIReg(rs),
9178                                                         mkU32(0x7)))));
9179                      /* tempD_7..0 */
9180                      assign(t0,
9181                             binop(Iop_Or32,
9182                                   mkexpr(t2),
9183                                   binop(Iop_Shl32,
9184                                         IRExpr_ITE(binop(Iop_CmpEQ32,
9185                                                          binop(Iop_And32,
9186                                                                mkexpr(t1),
9187                                                                mkU32(0x00000080)
9188                                                               ),
9189                                                          mkU32(0x00000080)),
9190                                                    mkU32(0xFFFFFFFF),
9191                                                    mkU32(0x00000000)),
9192                                         binop(Iop_Sub8,
9193                                               mkU8(0x8),
9194                                               unop(Iop_32to8, binop(Iop_And32,
9195                                                                     getIReg(rs),
9196                                                                     mkU32(0x7)))
9197                                               ))));
9198 
9199                      /* ========== GPR[rt]_23..16 ========== */
9200                      assign(t4,
9201                             unop(Iop_8Uto32,
9202                                  unop(Iop_16to8,
9203                                       unop(Iop_32HIto16, getIReg(rt)))));
9204                      assign(t5,
9205                             binop(Iop_Shr32,
9206                                   mkexpr(t4),
9207                                   unop(Iop_32to8, binop(Iop_And32,
9208                                                         getIReg(rs),
9209                                                         mkU32(0x7)))));
9210                      /* tempC_7..0 */
9211                      assign(t3,
9212                             binop(Iop_Or32,
9213                                   mkexpr(t5),
9214                                   binop(Iop_Shl32,
9215                                         IRExpr_ITE(binop(Iop_CmpEQ32,
9216                                                          binop(Iop_And32,
9217                                                                mkexpr(t4),
9218                                                                mkU32(0x00000080)
9219                                                               ),
9220                                                          mkU32(0x00000080)),
9221                                                    mkU32(0xFFFFFFFF),
9222                                                    mkU32(0x00000000)),
9223                                         binop(Iop_Sub8,
9224                                               mkU8(0x8),
9225                                               unop(Iop_32to8, binop(Iop_And32,
9226                                                                     getIReg(rs),
9227                                                                     mkU32(0x7)))
9228                                               ))));
9229 
9230                      /* ========== GPR[rt]_15..8 ========== */
9231                      assign(t7,
9232                             unop(Iop_8Uto32,
9233                                  unop(Iop_16HIto8,
9234                                       unop(Iop_32to16, getIReg(rt)))));
9235                      assign(t8,
9236                             binop(Iop_Shr32,
9237                                   mkexpr(t7),
9238                                   unop(Iop_32to8, binop(Iop_And32,
9239                                                         getIReg(rs),
9240                                                         mkU32(0x7)))));
9241                      /* tempB_7..0 */
9242                      assign(t6,
9243                             binop(Iop_Or32,
9244                                   mkexpr(t8),
9245                                   binop(Iop_Shl32,
9246                                         IRExpr_ITE(binop(Iop_CmpEQ32,
9247                                                          binop(Iop_And32,
9248                                                                mkexpr(t7),
9249                                                                mkU32(0x00000080)
9250                                                               ),
9251                                                          mkU32(0x00000080)),
9252                                                    mkU32(0xFFFFFFFF),
9253                                                    mkU32(0x00000000)),
9254                                         binop(Iop_Sub8,
9255                                               mkU8(0x8),
9256                                               unop(Iop_32to8, binop(Iop_And32,
9257                                                                     getIReg(rs),
9258                                                                     mkU32(0x7)))
9259                                               ))));
9260 
9261                      /* ========== GPR[rt]_7..0 ========== */
9262                      assign(t10,
9263                             unop(Iop_8Uto32,
9264                                  unop(Iop_16to8,
9265                                       unop(Iop_32to16, getIReg(rt)))));
9266                      assign(t11,
9267                             binop(Iop_Shr32,
9268                                   mkexpr(t10),
9269                                   unop(Iop_32to8, binop(Iop_And32,
9270                                                         getIReg(rs),
9271                                                         mkU32(0x7)))));
9272                      /* tempB_7..0 */
9273                      assign(t9,
9274                             binop(Iop_Or32,
9275                                   mkexpr(t11),
9276                                   binop(Iop_Shl32,
9277                                         IRExpr_ITE(binop(Iop_CmpEQ32,
9278                                                          binop(Iop_And32,
9279                                                                mkexpr(t10),
9280                                                                mkU32(0x00000080)
9281                                                               ),
9282                                                          mkU32(0x00000080)),
9283                                                    mkU32(0xFFFFFFFF),
9284                                                    mkU32(0x00000000)),
9285                                         binop(Iop_Sub8,
9286                                               mkU8(0x8),
9287                                               unop(Iop_32to8, binop(Iop_And32,
9288                                                                     getIReg(rs),
9289                                                                     mkU32(0x7)))
9290                                               ))));
9291 
9292                      putIReg(rd,
9293                              binop(Iop_16HLto32,
9294                                    binop(Iop_8HLto16,
9295                                          unop(Iop_32to8,
9296                                               IRExpr_ITE(binop(Iop_CmpEQ32,
9297                                                                binop(Iop_And32,
9298                                                                      mkU32(rs),
9299                                                                      mkU32(0x7)
9300                                                                     ),
9301                                                                mkU32(0x0)),
9302                                                          mkexpr(t1),
9303                                                          mkexpr(t0))),
9304                                          unop(Iop_32to8,
9305                                               IRExpr_ITE(binop(Iop_CmpEQ32,
9306                                                                binop(Iop_And32,
9307                                                                      mkU32(rs),
9308                                                                      mkU32(0x7)
9309                                                                     ),
9310                                                                mkU32(0x0)),
9311                                                          mkexpr(t2),
9312                                                          mkexpr(t3)))),
9313                                    binop(Iop_8HLto16,
9314                                          unop(Iop_32to8,
9315                                               IRExpr_ITE(binop(Iop_CmpEQ32,
9316                                                                binop(Iop_And32,
9317                                                                      mkU32(rs),
9318                                                                      mkU32(0x7)
9319                                                                     ),
9320                                                                mkU32(0x0)),
9321                                                          mkexpr(t5),
9322                                                          mkexpr(t6))),
9323                                          unop(Iop_32to8,
9324                                               IRExpr_ITE(binop(Iop_CmpEQ32,
9325                                                                binop(Iop_And32,
9326                                                                      mkU32(rs),
9327                                                                      mkU32(0x7)
9328                                                                     ),
9329                                                                mkU32(0x0)),
9330                                                          mkexpr(t8),
9331                                                          mkexpr(t9))))));
9332                      break;
9333                   }
9334                   case 0x7: {  /* SHRAV_R.QB */
9335                      DIP("shrav_r.qb r%u, r%u, r%u", rd, rt, rs);
9336                      vassert(!mode64);
9337                      t0 = newTemp(Ity_I32);
9338                      t1 = newTemp(Ity_I8);
9339                      t2 = newTemp(Ity_I32);
9340                      t3 = newTemp(Ity_I8);
9341                      t4 = newTemp(Ity_I32);
9342                      t5 = newTemp(Ity_I8);
9343                      t6 = newTemp(Ity_I32);
9344                      t7 = newTemp(Ity_I8);
9345                      t8 = newTemp(Ity_I8);
9346                      t9 = newTemp(Ity_I32);
9347 
9348                      assign(t9, binop(Iop_And32, getIReg(rs), mkU32(0x7)));
9349                      assign(t8, unop(Iop_32to8,
9350                                      binop(Iop_Sub32, mkexpr(t9), mkU32(0x1))));
9351                      assign(t0, unop(Iop_8Sto32,
9352                                      unop(Iop_16to8,
9353                                           unop(Iop_32to16, getIReg(rt)))));
9354                      assign(t1, unop(Iop_32to8,
9355                                      binop(Iop_Sar32,
9356                                            binop(Iop_Add32,
9357                                                  mkexpr(t0),
9358                                                  binop(Iop_Shl32,
9359                                                        mkU32(0x1),
9360                                                        mkexpr(t8))),
9361                                            unop(Iop_32to8,
9362                                                 mkexpr(t9)))));
9363 
9364                      assign(t2, unop(Iop_8Sto32,
9365                                      unop(Iop_16HIto8,
9366                                           unop(Iop_32to16, getIReg(rt)))));
9367                      assign(t3, unop(Iop_32to8,
9368                                      binop(Iop_Sar32,
9369                                            binop(Iop_Add32,
9370                                                  mkexpr(t2),
9371                                                  binop(Iop_Shl32,
9372                                                        mkU32(0x1),
9373                                                        mkexpr(t8))),
9374                                            unop(Iop_32to8, mkexpr(t9)))));
9375 
9376                      assign(t4, unop(Iop_8Sto32,
9377                                      unop(Iop_16to8,
9378                                           unop(Iop_32HIto16, getIReg(rt)))));
9379                      assign(t5, unop(Iop_32to8,
9380                                      binop(Iop_Sar32,
9381                                            binop(Iop_Add32,
9382                                                  mkexpr(t4),
9383                                                  binop(Iop_Shl32,
9384                                                        mkU32(0x1),
9385                                                        mkexpr(t8))),
9386                                            unop(Iop_32to8, mkexpr(t9)))));
9387 
9388                      assign(t6, unop(Iop_8Sto32,
9389                                      unop(Iop_16HIto8,
9390                                           unop(Iop_32HIto16, getIReg(rt)))));
9391                      assign(t7, unop(Iop_32to8,
9392                                      binop(Iop_Sar32,
9393                                            binop(Iop_Add32,
9394                                                  mkexpr(t6),
9395                                                  binop(Iop_Shl32,
9396                                                        mkU32(0x1),
9397                                                        mkexpr(t8))),
9398                                            unop(Iop_32to8, mkexpr(t9)))));
9399                      putIReg(rd, IRExpr_ITE(binop(Iop_CmpEQ32,
9400                                                   mkexpr(t9),
9401                                                   mkU32(0x0)),
9402                                             getIReg(rt),
9403                                             binop(Iop_16HLto32,
9404                                                   binop(Iop_8HLto16,
9405                                                         mkexpr(t7),
9406                                                         mkexpr(t5)),
9407                                                   binop(Iop_8HLto16,
9408                                                         mkexpr(t3),
9409                                                         mkexpr(t1)))));
9410                      break;
9411                   }
9412                   case 0x8: {  /* SHLL.PH */
9413                      DIP("shll.ph r%u, r%u, %u", rd, rt, rs);
9414                      vassert(!mode64);
9415                      t0 = newTemp(Ity_I32);
9416                      t1 = newTemp(Ity_I32);
9417                      t2 = newTemp(Ity_I32);
9418                      t3 = newTemp(Ity_I32);
9419                      t4 = newTemp(Ity_I32);
9420                      t5 = newTemp(Ity_I32);
9421                      t6 = newTemp(Ity_I32);
9422                      t7 = newTemp(Ity_I32);
9423 
9424                      if (0 == rs) {
9425                         putIReg(rd, getIReg(rt));
9426                      } else {
9427                         /* Shift lower 16 bits. */
9428                         assign(t0, binop(Iop_Shl32,
9429                                          unop(Iop_16Sto32,
9430                                               unop(Iop_32to16, getIReg(rt))),
9431                                          mkU8(rs)));
9432 
9433                         assign(t1, unop(Iop_1Uto32,
9434                                         binop(Iop_CmpNE32,
9435                                                binop(Iop_Sar32,
9436                                                      mkexpr(t0),
9437                                                      mkU8(16)),
9438                                                mkU32(0))));
9439                         assign(t2, unop(Iop_1Uto32,
9440                                         binop(Iop_CmpNE32,
9441                                               binop(Iop_Sar32,
9442                                                     mkexpr(t0),
9443                                                     mkU8(16)),
9444                                               mkU32(0xffffffff))));
9445                         assign(t3, binop(Iop_And32,
9446                                          mkexpr(t1),
9447                                          mkexpr(t2)));
9448                         putDSPControl(IRExpr_ITE(binop(Iop_CmpEQ32,
9449                                                        mkexpr(t3),
9450                                                        mkU32(0x1)),
9451                                                  binop(Iop_Or32,
9452                                                        getDSPControl(),
9453                                                        mkU32(0x400000)),
9454                                                  getDSPControl()));
9455                         putDSPControl(IRExpr_ITE(binop(Iop_CmpEQ32,
9456                                                        binop(Iop_And32,
9457                                                              getIReg(rt),
9458                                                              mkU32(0x00008000)),
9459                                                        binop(Iop_And32,
9460                                                              mkexpr(t0),
9461                                                              mkU32(0x00008000))
9462                                                       ),
9463                                                  getDSPControl(),
9464                                                  binop(Iop_Or32,
9465                                                        getDSPControl(),
9466                                                        mkU32(0x400000))));
9467                         /* Shift higher 16 bits. */
9468                         assign(t4, binop(Iop_Shl32,
9469                                          unop(Iop_16Sto32,
9470                                               unop(Iop_32HIto16, getIReg(rt))),
9471                                          mkU8(rs)));
9472 
9473                         assign(t5, unop(Iop_1Uto32,
9474                                         binop(Iop_CmpNE32,
9475                                                binop(Iop_Sar32,
9476                                                      mkexpr(t4),
9477                                                      mkU8(16)),
9478                                                mkU32(0))));
9479                         assign(t6, unop(Iop_1Uto32,
9480                                         binop(Iop_CmpNE32,
9481                                               binop(Iop_Sar32,
9482                                                     mkexpr(t4),
9483                                                     mkU8(16)),
9484                                               mkU32(0xffffffff))));
9485                         assign(t7, binop(Iop_And32,
9486                                          mkexpr(t5),
9487                                          mkexpr(t6)));
9488                         putDSPControl(IRExpr_ITE(binop(Iop_CmpEQ32,
9489                                                        mkexpr(t7),
9490                                                        mkU32(0x1)),
9491                                                  binop(Iop_Or32,
9492                                                        getDSPControl(),
9493                                                        mkU32(0x400000)),
9494                                                  getDSPControl()));
9495                         putDSPControl(IRExpr_ITE(binop(Iop_CmpEQ32,
9496                                                        mkexpr(t7),
9497                                                        mkU32(0x1)),
9498                                                  binop(Iop_Or32,
9499                                                        getDSPControl(),
9500                                                        mkU32(0x400000)),
9501                                                  getDSPControl()));
9502                         putDSPControl(IRExpr_ITE(binop(Iop_CmpEQ32,
9503                                                        binop(Iop_And32,
9504                                                              getIReg(rt),
9505                                                              mkU32(0x80000000)),
9506                                                        binop(Iop_Shl32,
9507                                                              binop(Iop_And32,
9508                                                                    mkexpr(t4),
9509                                                                    mkU32(0x00008000)),
9510                                                              mkU8(16))
9511                                                       ),
9512                                                  getDSPControl(),
9513                                                  binop(Iop_Or32,
9514                                                        getDSPControl(),
9515                                                        mkU32(0x400000))));
9516                         putIReg(rd, binop(Iop_16HLto32,
9517                                           unop(Iop_32to16, mkexpr(t4)),
9518                                           unop(Iop_32to16, mkexpr(t0))));
9519                      }
9520                      break;
9521                   }
9522                   case 0x9: {  /* SHRA.PH */
9523                      DIP("shra.ph r%u, r%u, %u", rd, rt, rs);
9524                      vassert(!mode64);
9525                      t0 = newTemp(Ity_I32);
9526                      t1 = newTemp(Ity_I32);
9527                      if (0 == rs) {
9528                         putIReg(rd, getIReg(rt));
9529                      } else {
9530                         assign(t0, binop(Iop_Sar32,
9531                                          unop(Iop_16Sto32,
9532                                               unop(Iop_32to16, getIReg(rt))),
9533                                          mkU8(rs)));
9534                         assign(t1, binop(Iop_Sar32,
9535                                          unop(Iop_16Sto32,
9536                                               unop(Iop_32HIto16, getIReg(rt))),
9537                                          mkU8(rs)));
9538                         putIReg(rd, binop(Iop_16HLto32,
9539                                           unop(Iop_32to16, mkexpr(t1)),
9540                                           unop(Iop_32to16, mkexpr(t0))));
9541                      }
9542                      break;
9543                   }
9544                   case 0xA: {  /* SHLLV.PH */
9545                      DIP("shllv.ph r%u, r%u, r%u", rd, rt, rs);
9546                      vassert(!mode64);
9547                      t0 = newTemp(Ity_I32);
9548                      t2 = newTemp(Ity_I32);
9549                      t3 = newTemp(Ity_I1);
9550                      t4 = newTemp(Ity_I1);
9551                      t5 = newTemp(Ity_I32);
9552                      t6 = newTemp(Ity_I32);
9553                      t7 = newTemp(Ity_I1);
9554                      t8 = newTemp(Ity_I1);
9555                      t9 = newTemp(Ity_I32);
9556                      t10 = newTemp(Ity_I32);
9557                      t11 = newTemp(Ity_I32);
9558                      t12 = newTemp(Ity_I1);
9559                      t13 = newTemp(Ity_I1);
9560 
9561                      assign(t0, binop(Iop_And32, getIReg(rs), mkU32(0x0f)));
9562 
9563                      /* Shift lower 16 bits. */
9564                      assign(t2, binop(Iop_Shl32,
9565                                       unop(Iop_16Sto32,
9566                                            unop(Iop_32to16, getIReg(rt))),
9567                                       unop(Iop_32to8, mkexpr(t0))));
9568 
9569                      assign(t3, binop(Iop_CmpNE32,
9570                                       unop(Iop_16Sto32,
9571                                            unop(Iop_32HIto16, mkexpr(t2))),
9572                                       mkU32(0x00000000)));
9573                      assign(t4, binop(Iop_CmpNE32,
9574                                       unop(Iop_16Sto32,
9575                                            unop(Iop_32HIto16, mkexpr(t2))),
9576                                       mkU32(0xffffffff)));
9577                      assign(t10, binop(Iop_And32,
9578                                        unop(Iop_1Sto32, mkexpr(t3)),
9579                                        unop(Iop_1Sto32, mkexpr(t4))));
9580                      assign(t5, binop(Iop_Shr32,
9581                                       binop(Iop_And32,
9582                                             getIReg(rt),
9583                                             mkU32(0x00008000)),
9584                                       mkU8(15)));
9585                      assign(t12, binop(Iop_CmpEQ32,
9586                                        mkexpr(t5),
9587                                        binop(Iop_Shr32,
9588                                              binop(Iop_And32,
9589                                                    mkexpr(t2),
9590                                                    mkU32(0x00008000)),
9591                                              mkU8(15))));
9592 
9593                      putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32,
9594                                                     mkexpr(t10),
9595                                                     mkU32(0x0)),
9596                                               binop(Iop_Or32,
9597                                                     getDSPControl(),
9598                                                     mkU32(0x400000)),
9599                                               IRExpr_ITE(mkexpr(t12),
9600                                                          getDSPControl(),
9601                                                          binop(Iop_Or32,
9602                                                                getDSPControl(),
9603                                                                mkU32(0x400000)))
9604                                              ));
9605                      /* Shift higher 16 bits. */
9606                      assign(t6, binop(Iop_Shl32,
9607                                       unop(Iop_16Sto32,
9608                                            unop(Iop_32HIto16, getIReg(rt))),
9609                                       unop(Iop_32to8, mkexpr(t0))));
9610 
9611                      assign(t7, binop(Iop_CmpNE32,
9612                                       unop(Iop_16Sto32,
9613                                            unop(Iop_32HIto16, mkexpr(t6))),
9614                                       mkU32(0x00000000)));
9615                      assign(t8, binop(Iop_CmpNE32,
9616                                       unop(Iop_16Sto32,
9617                                            unop(Iop_32HIto16, mkexpr(t6))),
9618                                       mkU32(0xffffffff)));
9619                      assign(t11, binop(Iop_And32,
9620                                        unop(Iop_1Sto32, mkexpr(t7)),
9621                                        unop(Iop_1Sto32, mkexpr(t8))));
9622 
9623                      assign(t9, binop(Iop_Shr32,
9624                                       binop(Iop_And32,
9625                                             getIReg(rt),
9626                                             mkU32(0x80000000)),
9627                                       mkU8(31)));
9628                      assign(t13, binop(Iop_CmpEQ32,
9629                                        mkexpr(t9),
9630                                        binop(Iop_Shr32,
9631                                              binop(Iop_And32,
9632                                                    mkexpr(t6),
9633                                                    mkU32(0x00008000)),
9634                                              mkU8(15))));
9635 
9636                      putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32,
9637                                                     mkexpr(t11),
9638                                                     mkU32(0x0)),
9639                                               binop(Iop_Or32,
9640                                                     getDSPControl(),
9641                                                     mkU32(0x400000)),
9642                                               IRExpr_ITE(mkexpr(t13),
9643                                                          getDSPControl(),
9644                                                          binop(Iop_Or32,
9645                                                                getDSPControl(),
9646                                                                mkU32(0x400000)))
9647                                              ));
9648 
9649                      putIReg(rd, binop(Iop_16HLto32,
9650                                        unop(Iop_32to16, mkexpr(t6)),
9651                                        unop(Iop_32to16, mkexpr(t2))));
9652                      break;
9653                   }
9654                   case 0xB: {  /* SHRAV.PH */
9655                      DIP("shrav.ph r%u, r%u, r%u", rd, rt, rs);
9656                      vassert(!mode64);
9657                      t0 = newTemp(Ity_I32);
9658                      t1 = newTemp(Ity_I1);
9659                      t2 = newTemp(Ity_I32);
9660                      t3 = newTemp(Ity_I32);
9661 
9662                      assign(t0, binop(Iop_And32, getIReg(rs), mkU32(0x0f)));
9663                      assign(t1, binop(Iop_CmpEQ32, mkexpr(t0), mkU32(0x0)));
9664                      assign(t2, binop(Iop_Sar32,
9665                                       unop(Iop_16Sto32,
9666                                            unop(Iop_32to16, getIReg(rt))),
9667                                       unop(Iop_32to8, mkexpr(t0))));
9668                      assign(t3, binop(Iop_Sar32,
9669                                       unop(Iop_16Sto32,
9670                                            unop(Iop_32HIto16, getIReg(rt))),
9671                                       unop(Iop_32to8, mkexpr(t0))));
9672                      putIReg(rd,
9673                              binop(Iop_16HLto32,
9674                                    IRExpr_ITE(mkexpr(t1),
9675                                               unop(Iop_32HIto16, getIReg(rt)),
9676                                               unop(Iop_32to16, mkexpr(t3))),
9677                                    IRExpr_ITE(mkexpr(t1),
9678                                               unop(Iop_32to16, getIReg(rt)),
9679                                               unop(Iop_32to16, mkexpr(t2)))));
9680                      break;
9681                   }
9682                   case 0xC: {  /* SHLL_S.PH */
9683                      DIP("shll_s.ph r%u, r%u, %u", rd, rt, rs);
9684                      vassert(!mode64);
9685                      t0 = newTemp(Ity_I32);
9686                      t1 = newTemp(Ity_I32);
9687                      t2 = newTemp(Ity_I32);
9688                      t3 = newTemp(Ity_I32);
9689                      t4 = newTemp(Ity_I32);
9690                      t5 = newTemp(Ity_I32);
9691                      t6 = newTemp(Ity_I32);
9692                      t7 = newTemp(Ity_I32);
9693                      t8 = newTemp(Ity_I32);
9694                      t9 = newTemp(Ity_I32);
9695                      t10 = newTemp(Ity_I32);
9696                      t11 = newTemp(Ity_I32);
9697                      t12 = newTemp(Ity_I32);
9698                      t13 = newTemp(Ity_I32);
9699                      t14 = newTemp(Ity_I32);
9700 
9701                      if (0 == rs) {
9702                         putIReg(rd, getIReg(rt));
9703                      } else {
9704                         /* Shift lower 16 bits. */
9705                         assign(t0, binop(Iop_Shl32,
9706                                          unop(Iop_16Sto32,
9707                                               unop(Iop_32to16, getIReg(rt))),
9708                                          mkU8(rs)));
9709 
9710                         assign(t1, unop(Iop_1Uto32,
9711                                         binop(Iop_CmpNE32,
9712                                                binop(Iop_Sar32,
9713                                                      mkexpr(t0),
9714                                                      mkU8(16)),
9715                                                mkU32(0))));
9716                         assign(t2, unop(Iop_1Uto32,
9717                                         binop(Iop_CmpNE32,
9718                                               binop(Iop_Sar32,
9719                                                     mkexpr(t0),
9720                                                     mkU8(16)),
9721                                               mkU32(0xffffffff))));
9722                         assign(t3, binop(Iop_And32,
9723                                          mkexpr(t1),
9724                                          mkexpr(t2)));
9725                         putDSPControl(IRExpr_ITE(binop(Iop_CmpEQ32,
9726                                                        mkexpr(t3),
9727                                                        mkU32(0x1)),
9728                                                  binop(Iop_Or32,
9729                                                        getDSPControl(),
9730                                                        mkU32(0x400000)),
9731                                                  getDSPControl()));
9732                         putDSPControl(IRExpr_ITE(binop(Iop_CmpEQ32,
9733                                                        binop(Iop_And32,
9734                                                              getIReg(rt),
9735                                                              mkU32(0x00008000)),
9736                                                        binop(Iop_And32,
9737                                                              mkexpr(t0),
9738                                                              mkU32(0x00008000))
9739                                                       ),
9740                                                  getDSPControl(),
9741                                                  binop(Iop_Or32,
9742                                                        getDSPControl(),
9743                                                        mkU32(0x400000))));
9744                         assign(t8,
9745                                IRExpr_ITE(binop(Iop_CmpEQ32,
9746                                                 mkexpr(t3),
9747                                                 mkU32(0x1)),
9748                                           IRExpr_ITE(binop(Iop_CmpEQ32,
9749                                                            binop(Iop_And32,
9750                                                                  getIReg(rt),
9751                                                                  mkU32(0x8000)),
9752                                                            mkU32(0)),
9753                                                      mkU32(0x00007fff),
9754                                                      mkU32(0x00008000)),
9755                                           binop(Iop_And32,
9756                                                 mkexpr(t0),
9757                                                 mkU32(0x0000ffff))));
9758                         assign(t10,
9759                                IRExpr_ITE(binop(Iop_CmpEQ32,
9760                                                 binop(Iop_And32,
9761                                                       getIReg(rt),
9762                                                       mkU32(0x00008000)),
9763                                                 binop(Iop_And32,
9764                                                       mkexpr(t0),
9765                                                       mkU32(0x00008000))),
9766                                           mkexpr(t8),
9767                                           IRExpr_ITE(binop(Iop_CmpEQ32,
9768                                                            binop(Iop_And32,
9769                                                                  getIReg(rt),
9770                                                                  mkU32(0x8000)),
9771                                                            mkU32(0)),
9772                                                      mkU32(0x00007fff),
9773                                                      mkU32(0x00008000))));
9774                         /* Shift higher 16 bits. */
9775                         assign(t4, binop(Iop_Shl32,
9776                                          unop(Iop_16Sto32,
9777                                               unop(Iop_32HIto16, getIReg(rt))),
9778                                          mkU8(rs)));
9779 
9780                         assign(t5, unop(Iop_1Uto32,
9781                                         binop(Iop_CmpNE32,
9782                                                binop(Iop_Sar32,
9783                                                      mkexpr(t4),
9784                                                      mkU8(16)),
9785                                                mkU32(0))));
9786                         assign(t6, unop(Iop_1Uto32,
9787                                         binop(Iop_CmpNE32,
9788                                               binop(Iop_Sar32,
9789                                                     mkexpr(t4),
9790                                                     mkU8(16)),
9791                                               mkU32(0xffffffff))));
9792                         assign(t7, binop(Iop_And32,
9793                                          mkexpr(t5),
9794                                          mkexpr(t6)));
9795                         putDSPControl(IRExpr_ITE(binop(Iop_CmpEQ32,
9796                                                        mkexpr(t7),
9797                                                        mkU32(0x1)),
9798                                                  binop(Iop_Or32,
9799                                                        getDSPControl(),
9800                                                        mkU32(0x400000)),
9801                                                  getDSPControl()));
9802                         putDSPControl(IRExpr_ITE(binop(Iop_CmpEQ32,
9803                                                        mkexpr(t7),
9804                                                        mkU32(0x1)),
9805                                                  binop(Iop_Or32,
9806                                                        getDSPControl(),
9807                                                        mkU32(0x400000)),
9808                                                  getDSPControl()));
9809                         assign(t12, binop(Iop_Shl32,
9810                                           binop(Iop_And32,
9811                                                 mkexpr(t4),
9812                                                 mkU32(0x8000)),
9813                                           mkU8(16)));
9814                         putDSPControl(IRExpr_ITE(binop(Iop_CmpEQ32,
9815                                                        binop(Iop_And32,
9816                                                              getIReg(rt),
9817                                                              mkU32(0x80000000)),
9818                                                        mkexpr(t12)),
9819                                                  getDSPControl(),
9820                                                  binop(Iop_Or32,
9821                                                        getDSPControl(),
9822                                                        mkU32(0x400000))));
9823                         assign(t13, IRExpr_ITE(binop(Iop_CmpEQ32,
9824                                                      binop(Iop_And32,
9825                                                            getIReg(rt),
9826                                                            mkU32(0x80000000)),
9827                                                      mkU32(0)),
9828                                                mkU32(0x7fff0000),
9829                                                mkU32(0x80000000)));
9830                         assign(t9,
9831                                IRExpr_ITE(binop(Iop_CmpEQ32,
9832                                                 mkexpr(t7),
9833                                                 mkU32(0x1)),
9834                                           mkexpr(t13),
9835                                           binop(Iop_Shl32,
9836                                                 binop(Iop_And32,
9837                                                       mkexpr(t4),
9838                                                       mkU32(0x0000ffff)),
9839                                                 mkU8(16))));
9840                         assign(t14, IRExpr_ITE(binop(Iop_CmpEQ32,
9841                                                      binop(Iop_And32,
9842                                                            getIReg(rt),
9843                                                            mkU32(0x80000000)),
9844                                                      mkU32(0)),
9845                                                mkU32(0x7fff0000),
9846                                                mkU32(0x80000000)));
9847                         assign(t11,
9848                                IRExpr_ITE(binop(Iop_CmpEQ32,
9849                                                 binop(Iop_And32,
9850                                                       getIReg(rt),
9851                                                       mkU32(0x80000000)),
9852                                                 binop(Iop_Shl32,
9853                                                       binop(Iop_And32,
9854                                                             mkexpr(t4),
9855                                                             mkU32(0x00008000)),
9856                                                       mkU8(16))),
9857                                           mkexpr(t9),
9858                                           mkexpr(t14)));
9859                         putIReg(rd, binop(Iop_Or32,
9860                                           mkexpr(t10),
9861                                           mkexpr(t11)));
9862                      }
9863                      break;
9864                   }
9865                   case 0xD: {  /* SHRA_R.PH */
9866                      DIP("shra.ph r%u, r%u, %u", rd, rt, rs);
9867                      vassert(!mode64);
9868                      t0 = newTemp(Ity_I32);
9869                      t1 = newTemp(Ity_I32);
9870                      if (0 == rs) {
9871                         putIReg(rd, getIReg(rt));
9872                      } else {
9873                         assign(t0, binop(Iop_Sar32,
9874                                          binop(Iop_Add32,
9875                                                unop(Iop_16Sto32,
9876                                                     unop(Iop_32to16,
9877                                                          getIReg(rt))),
9878                                                binop(Iop_Shl32,
9879                                                      mkU32(0x1),
9880                                                      mkU8(rs-1))),
9881                                          mkU8(rs)));
9882                         assign(t1, binop(Iop_Sar32,
9883                                          binop(Iop_Add32,
9884                                                unop(Iop_16Sto32,
9885                                                     unop(Iop_32HIto16,
9886                                                          getIReg(rt))),
9887                                                binop(Iop_Shl32,
9888                                                      mkU32(0x1),
9889                                                      mkU8(rs-1))),
9890                                          mkU8(rs)));
9891                         putIReg(rd, binop(Iop_16HLto32,
9892                                           unop(Iop_32to16, mkexpr(t1)),
9893                                           unop(Iop_32to16, mkexpr(t0))));
9894                      }
9895                      break;
9896                   }
9897                   case 0xE: {  /* SHLLV_S.PH */
9898                      DIP("shllv_s.ph r%u, r%u, r%u", rd, rt, rs);
9899                      vassert(!mode64);
9900                      t0 = newTemp(Ity_I32);
9901                      t2 = newTemp(Ity_I32);
9902                      t3 = newTemp(Ity_I1);
9903                      t4 = newTemp(Ity_I1);
9904                      t5 = newTemp(Ity_I32);
9905                      t6 = newTemp(Ity_I32);
9906                      t7 = newTemp(Ity_I1);
9907                      t8 = newTemp(Ity_I1);
9908                      t9 = newTemp(Ity_I32);
9909                      t10 = newTemp(Ity_I32);
9910                      t11 = newTemp(Ity_I32);
9911                      t12 = newTemp(Ity_I1);
9912                      t13 = newTemp(Ity_I1);
9913                      t14 = newTemp(Ity_I16);
9914                      t15 = newTemp(Ity_I16);
9915                      t16 = newTemp(Ity_I16);
9916                      t17 = newTemp(Ity_I16);
9917 
9918                      assign(t0, binop(Iop_And32, getIReg(rs), mkU32(0x0f)));
9919 
9920                      /* Shift lower 16 bits. */
9921                      assign(t2, binop(Iop_Shl32,
9922                                       unop(Iop_16Sto32,
9923                                            unop(Iop_32to16, getIReg(rt))),
9924                                       unop(Iop_32to8, mkexpr(t0))));
9925 
9926                      assign(t3, binop(Iop_CmpNE32,
9927                                       unop(Iop_16Sto32,
9928                                            unop(Iop_32HIto16, mkexpr(t2))),
9929                                       mkU32(0x00000000)));
9930                      assign(t4, binop(Iop_CmpNE32,
9931                                       unop(Iop_16Sto32,
9932                                            unop(Iop_32HIto16, mkexpr(t2))),
9933                                       mkU32(0xffffffff)));
9934                      assign(t10, binop(Iop_And32,
9935                                        unop(Iop_1Sto32, mkexpr(t3)),
9936                                        unop(Iop_1Sto32, mkexpr(t4))));
9937                      assign(t5, binop(Iop_Shr32,
9938                                        binop(Iop_And32,
9939                                              getIReg(rt),
9940                                              mkU32(0x00008000)),
9941                                        mkU8(15)));
9942                      assign(t12, binop(Iop_CmpEQ32,
9943                                        mkexpr(t5),
9944                                        binop(Iop_Shr32,
9945                                              binop(Iop_And32,
9946                                                    mkexpr(t2),
9947                                                    mkU32(0x00008000)),
9948                                              mkU8(15))));
9949 
9950                      putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32,
9951                                                     mkexpr(t10),
9952                                                     mkU32(0x0)),
9953                                               binop(Iop_Or32,
9954                                                     getDSPControl(),
9955                                                     mkU32(0x400000)),
9956                                               IRExpr_ITE(mkexpr(t12),
9957                                                          getDSPControl(),
9958                                                          binop(Iop_Or32,
9959                                                                getDSPControl(),
9960                                                                mkU32(0x400000)))
9961                                              ));
9962                      assign(t14, IRExpr_ITE(binop(Iop_CmpNE32,
9963                                                   mkexpr(t5),
9964                                                   mkU32(0x0)),
9965                                             mkU16(0x8000),
9966                                             mkU16(0x7fff)));
9967                      assign(t15, IRExpr_ITE(binop(Iop_CmpNE32,
9968                                                   mkexpr(t10),
9969                                                   mkU32(0x0)),
9970                                             mkexpr(t14),
9971                                             IRExpr_ITE(mkexpr(t12),
9972                                                        unop(Iop_32to16,
9973                                                             mkexpr(t2)),
9974                                                        mkexpr(t14))));
9975                      /* Shift higher 16 bits. */
9976                      assign(t6, binop(Iop_Shl32,
9977                                       unop(Iop_16Sto32,
9978                                            unop(Iop_32HIto16, getIReg(rt))),
9979                                       unop(Iop_32to8, mkexpr(t0))));
9980 
9981                      assign(t7, binop(Iop_CmpNE32,
9982                                       unop(Iop_16Sto32,
9983                                            unop(Iop_32HIto16, mkexpr(t6))),
9984                                       mkU32(0x00000000)));
9985                      assign(t8, binop(Iop_CmpNE32,
9986                                       unop(Iop_16Sto32,
9987                                            unop(Iop_32HIto16, mkexpr(t6))),
9988                                       mkU32(0xffffffff)));
9989                      assign(t11, binop(Iop_And32,
9990                                        unop(Iop_1Sto32, mkexpr(t7)),
9991                                        unop(Iop_1Sto32, mkexpr(t8))));
9992 
9993                      assign(t9, binop(Iop_Shr32,
9994                                       binop(Iop_And32,
9995                                             getIReg(rt),
9996                                             mkU32(0x80000000)),
9997                                       mkU8(31)));
9998                      assign(t13, binop(Iop_CmpEQ32,
9999                                        mkexpr(t9),
10000                                        binop(Iop_Shr32,
10001                                              binop(Iop_And32,
10002                                                    mkexpr(t6),
10003                                                    mkU32(0x00008000)),
10004                                              mkU8(15))));
10005 
10006                      putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32,
10007                                                     mkexpr(t11),
10008                                                     mkU32(0x0)),
10009                                               binop(Iop_Or32,
10010                                                     getDSPControl(),
10011                                                     mkU32(0x400000)),
10012                                               IRExpr_ITE(mkexpr(t13),
10013                                                          getDSPControl(),
10014                                                          binop(Iop_Or32,
10015                                                                getDSPControl(),
10016                                                                mkU32(0x400000)))
10017                                              ));
10018 
10019                      assign(t16, IRExpr_ITE(binop(Iop_CmpNE32,
10020                                                   mkexpr(t9),
10021                                                   mkU32(0x0)),
10022                                             mkU16(0x8000),
10023                                             mkU16(0x7fff)));
10024                      assign(t17, IRExpr_ITE(binop(Iop_CmpNE32,
10025                                                   mkexpr(t11),
10026                                                   mkU32(0x0)),
10027                                             mkexpr(t16),
10028                                             IRExpr_ITE(mkexpr(t13),
10029                                                        unop(Iop_32to16,
10030                                                             mkexpr(t6)),
10031                                                        mkexpr(t16))));
10032 
10033                      putIReg(rd, binop(Iop_16HLto32, mkexpr(t17), mkexpr(t15)));
10034                      break;
10035                   }
10036                   case 0xF: {  /* SHRAV_R.PH */
10037                      DIP("shrav_r.ph r%u, r%u, r%u", rd, rt, rs);
10038                      vassert(!mode64);
10039                      t0 = newTemp(Ity_I32);
10040                      t1 = newTemp(Ity_I1);
10041                      t2 = newTemp(Ity_I8);
10042                      t3 = newTemp(Ity_I32);
10043                      t4 = newTemp(Ity_I32);
10044 
10045                      assign(t0, binop(Iop_And32, getIReg(rs), mkU32(0x0f)));
10046                      assign(t1, binop(Iop_CmpEQ32, mkexpr(t0), mkU32(0x0)));
10047                      assign(t2, unop(Iop_32to8,
10048                                      binop(Iop_Sub32, mkexpr(t0), mkU32(1))));
10049 
10050                      assign(t3, binop(Iop_Sar32,
10051                                       binop(Iop_Add32,
10052                                             unop(Iop_16Sto32,
10053                                                  unop(Iop_32to16, getIReg(rt))),
10054                                             binop(Iop_Shl32,
10055                                                   mkU32(0x1),
10056                                                   mkexpr(t2))),
10057                                       unop(Iop_32to8, mkexpr(t0))));
10058                      assign(t4, binop(Iop_Sar32,
10059                                       binop(Iop_Add32,
10060                                             unop(Iop_16Sto32,
10061                                                  unop(Iop_32HIto16,
10062                                                       getIReg(rt))),
10063                                             binop(Iop_Shl32,
10064                                                   mkU32(0x1),
10065                                                   mkexpr(t2))),
10066                                       unop(Iop_32to8, mkexpr(t0))));
10067 
10068                      putIReg(rd, binop(Iop_16HLto32,
10069                                        IRExpr_ITE(mkexpr(t1),
10070                                                   unop(Iop_32HIto16,
10071                                                        getIReg(rt)),
10072                                                   unop(Iop_32to16,
10073                                                        mkexpr(t4))),
10074                                        IRExpr_ITE(mkexpr(t1),
10075                                                   unop(Iop_32to16, getIReg(rt)),
10076                                                   unop(Iop_32to16,
10077                                                        mkexpr(t3)))));
10078                      break;
10079                   }
10080                   case 0x14: {  /* SHLL_S.W */
10081                      DIP("shll_s.w r%u, r%u, %u", rd, rt, rs);
10082                      vassert(!mode64);
10083                      t0 = newTemp(Ity_I32);
10084                      t1 = newTemp(Ity_I32);
10085                      t2 = newTemp(Ity_I32);
10086                      t3 = newTemp(Ity_I32);
10087                      t4 = newTemp(Ity_I32);
10088                      t5 = newTemp(Ity_I32);
10089 
10090                      if (0 == rs) {
10091                         putIReg(rd, getIReg(rt));
10092                      } else {
10093                         /* t0-bits that will be discarded, sign extended to
10094                            32bits. */
10095                         assign(t0, binop(Iop_Sar32,
10096                                          binop(Iop_And32,
10097                                                getIReg(rt),
10098                                                binop(Iop_Sar32,
10099                                                      mkU32(0x80000000),
10100                                                      mkU8(rs-1))),
10101                                          mkU8(32-rs)));
10102 
10103                         assign(t1, IRExpr_ITE(binop(Iop_CmpEQ32,
10104                                                     binop(Iop_And32,
10105                                                           getIReg(rt),
10106                                                           mkU32(0x80000000)),
10107                                                     mkU32(0x0)),
10108                                               mkU32(0x7fffffff),
10109                                               mkU32(0x80000000)));
10110 
10111                         assign(t2, binop(Iop_Shl32, getIReg(rt), mkU8(rs)));
10112                         assign(t3, IRExpr_ITE(binop(Iop_CmpEQ32,
10113                                                     binop(Iop_And32,
10114                                                           getIReg(rt),
10115                                                           mkU32(0x80000000)),
10116                                                     binop(Iop_And32,
10117                                                           mkexpr(t2),
10118                                                           mkU32(0x80000000))),
10119                                               mkexpr(t2),
10120                                               mkexpr(t1)));
10121 
10122                         assign(t4, IRExpr_ITE(binop(Iop_CmpNE32,
10123                                                     mkexpr(t0),
10124                                                     mkU32(0x0)),
10125                                               IRExpr_ITE(binop(Iop_CmpNE32,
10126                                                                mkexpr(t0),
10127                                                                mkU32(0xffffffff)
10128                                                               ),
10129                                                          mkexpr(t1),
10130                                                          mkexpr(t3)),
10131                                               mkexpr(t3)));
10132                         assign(t5, IRExpr_ITE(binop(Iop_CmpNE32,
10133                                                     mkexpr(t0),
10134                                                     mkU32(0xffffffff)),
10135                                               binop(Iop_Or32,
10136                                                     getDSPControl(),
10137                                                     mkU32(0x400000)),
10138                                               getDSPControl()));
10139                         putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32,
10140                                                        mkexpr(t0),
10141                                                        mkU32(0x0)),
10142                                                  mkexpr(t5),
10143                                                  getDSPControl()));
10144                         putDSPControl(IRExpr_ITE(binop(Iop_CmpEQ32,
10145                                                        binop(Iop_And32,
10146                                                              getIReg(rt),
10147                                                              mkU32(0x80000000)),
10148                                                        binop(Iop_And32,
10149                                                              mkexpr(t2),
10150                                                              mkU32(0x80000000))
10151                                                             ),
10152                                                  getDSPControl(),
10153                                                  binop(Iop_Or32,
10154                                                        getDSPControl(),
10155                                                        mkU32(0x400000))));
10156                         putIReg(rd, mkexpr(t4));
10157                      }
10158                      break;
10159                   }
10160                   case 0x15: {  /* SHRA_R.W */
10161                      DIP("shra_r.w r%u, r%u, %u", rd, rt, rs);
10162                      vassert(!mode64);
10163                      if (0 == rs) {
10164                         putIReg(rd, getIReg(rt));
10165                      } else {
10166                         putIReg(rd, binop(Iop_Add32,
10167                                           binop(Iop_Sar32,
10168                                                 getIReg(rt), mkU8(rs)),
10169                                           binop(Iop_Shr32,
10170                                                 binop(Iop_And32,
10171                                                       getIReg(rt),
10172                                                       binop(Iop_Shl32,
10173                                                             mkU32(0x1),
10174                                                             mkU8(rs-1))),
10175                                                 mkU8(rs-1))));
10176                      }
10177                      break;
10178                   }
10179                   case 0x16: {  /* SHLLV_S.W */
10180                      DIP("shllv_s.w r%u, r%u, r%u", rd, rt, rs);
10181                      vassert(!mode64);
10182                      t0 = newTemp(Ity_I32);
10183                      t1 = newTemp(Ity_I1);
10184                      t2 = newTemp(Ity_I32);
10185                      t3 = newTemp(Ity_I64);
10186                      t4 = newTemp(Ity_I1);
10187                      t5 = newTemp(Ity_I1);
10188                      t6 = newTemp(Ity_I32);
10189                      t7 = newTemp(Ity_I1);
10190                      t8 = newTemp(Ity_I32);
10191 
10192                      /* Check if shift amount is zero. */
10193                      assign(t0, binop(Iop_And32, getIReg(rs), mkU32(0x1f)));
10194                      assign(t1, binop(Iop_CmpEQ32, mkexpr(t0), mkU32(0x0)));
10195 
10196                      /* t2 = sign of the input value. */
10197                      assign(t2, binop(Iop_Shr32,
10198                                       binop(Iop_And32,
10199                                             getIReg(rt),
10200                                             mkU32(0x80000000)),
10201                                       mkU8(31)));
10202                      /* Shift left input value and check for overflow. */
10203                      assign(t3, binop(Iop_Shl64,
10204                                       unop(Iop_32Sto64, getIReg(rt)),
10205                                       unop(Iop_32to8, mkexpr(t0))));
10206                      assign(t4, binop(Iop_CmpNE32,
10207                                       unop(Iop_64HIto32, mkexpr(t3)),
10208                                       mkU32(0x00000000)));
10209                      assign(t5, binop(Iop_CmpNE32,
10210                                       unop(Iop_64HIto32, mkexpr(t3)),
10211                                       mkU32(0xffffffff)));
10212                      assign(t6, binop(Iop_And32,
10213                                       unop(Iop_1Uto32, mkexpr(t4)),
10214                                       unop(Iop_1Uto32, mkexpr(t5))));
10215                      assign(t7, binop(Iop_CmpEQ32,
10216                                       binop(Iop_Shr32,
10217                                             binop(Iop_And32,
10218                                                   getIReg(rt),
10219                                                   mkU32(0x80000000)),
10220                                             mkU8(31)),
10221                                       binop(Iop_Shr32,
10222                                             binop(Iop_And32,
10223                                                   unop(Iop_64to32, mkexpr(t3)),
10224                                                   mkU32(0x80000000)),
10225                                             mkU8(31))));
10226 
10227                      putDSPControl(IRExpr_ITE(unop(Iop_32to1, mkexpr(t6)),
10228                                                    binop(Iop_Or32,
10229                                                          getDSPControl(),
10230                                                          mkU32(0x400000)),
10231                                               IRExpr_ITE(mkexpr(t7),
10232                                                          getDSPControl(),
10233                                                          binop(Iop_Or32,
10234                                                                getDSPControl(),
10235                                                                mkU32(0x400000)))
10236                                              ));
10237 
10238                      assign(t8, IRExpr_ITE(unop(Iop_32to1,
10239                                                 mkexpr(t2)),
10240                                            mkU32(0x80000000),
10241                                            mkU32(0x7fffffff)));
10242                      putIReg(rd, IRExpr_ITE(unop(Iop_32to1, mkexpr(t6)),
10243                                             IRExpr_ITE(unop(Iop_32to1,
10244                                                             mkexpr(t2)),
10245                                                        mkU32(0x80000000),
10246                                                        mkU32(0x7fffffff)),
10247                                             IRExpr_ITE(mkexpr(t7),
10248                                                        unop(Iop_64to32,
10249                                                             mkexpr(t3)),
10250                                                        mkexpr(t8))));
10251                      break;
10252                   }
10253                   case 0x17: {  /* SHRAV_R.W */
10254                      DIP("shrav_r.w r%u, r%u, r%u", rd, rt, rs);
10255                      vassert(!mode64);
10256                      t0 = newTemp(Ity_I32);
10257                      t1 = newTemp(Ity_I1);
10258                      t2 = newTemp(Ity_I8);
10259                      t3 = newTemp(Ity_I32);
10260 
10261                      assign(t0, binop(Iop_And32, getIReg(rs), mkU32(0x1f)));
10262                      assign(t1, binop(Iop_CmpEQ32, mkexpr(t0), mkU32(0x0)));
10263                      assign(t2, unop(Iop_32to8,
10264                                      binop(Iop_Sub32, mkexpr(t0), mkU32(1))));
10265 
10266                      putIReg(rd, IRExpr_ITE(mkexpr(t1),
10267                                             getIReg(rt),
10268                                             binop(Iop_Sar32,
10269                                                   binop(Iop_Add32,
10270                                                         binop(Iop_Sar32,
10271                                                               getIReg(rt),
10272                                                               mkexpr(t2)),
10273                                                         mkU32(0x1)),
10274                                                   mkU8(1))));
10275                      break;
10276                   }
10277                   case 0x19: {  /* SHRL.PH */
10278                      DIP("shrl.ph r%u, r%u, %u", rd, rt, rs);
10279                      vassert(!mode64);
10280                      t0 = newTemp(Ity_I32);
10281                      t1 = newTemp(Ity_I32);
10282                      assign(t0, binop(Iop_Shr32,
10283                                       unop(Iop_16Uto32,
10284                                            unop(Iop_32to16, getIReg(rt))),
10285                                       mkU8(rs)));
10286                      assign(t1, binop(Iop_Shr32,
10287                                       unop(Iop_16Uto32,
10288                                            unop(Iop_32HIto16, getIReg(rt))),
10289                                       mkU8(rs)));
10290                      putIReg(rd, binop(Iop_16HLto32,
10291                                        unop(Iop_32to16, mkexpr(t1)),
10292                                        unop(Iop_32to16, mkexpr(t0))));
10293                      break;
10294                   }
10295                   case 0x1B: {  /* SHRLV.PH */
10296                      DIP("shrlv.ph r%u, r%u, r%u", rd, rt, rs);
10297                      vassert(!mode64);
10298                      t0 = newTemp(Ity_I32);
10299                      t1 = newTemp(Ity_I1);
10300                      t2 = newTemp(Ity_I32);
10301                      t3 = newTemp(Ity_I32);
10302                      t4 = newTemp(Ity_I16);
10303                      t5 = newTemp(Ity_I16);
10304 
10305                      /* Get shift amount from lower 5 bits of rs
10306                         and check if it is zero. */
10307                      assign(t0, binop(Iop_And32, getIReg(rs), mkU32(0x0f)));
10308                      assign(t1, binop(Iop_CmpEQ32, mkexpr(t0), mkU32(0x0)));
10309 
10310                      assign(t2, binop(Iop_Shr32,
10311                                       unop(Iop_16Uto32,
10312                                            unop(Iop_32to16, getIReg(rt))),
10313                                       unop(Iop_32to8, mkexpr(t0))));
10314                      assign(t3, binop(Iop_Shr32,
10315                                       unop(Iop_16Uto32,
10316                                            unop(Iop_32HIto16, getIReg(rt))),
10317                                       unop(Iop_32to8, mkexpr(t0))));
10318 
10319                      assign(t4, IRExpr_ITE(mkexpr(t1),
10320                                            unop(Iop_32HIto16, getIReg(rt)),
10321                                            unop(Iop_32to16, mkexpr(t3))));
10322                      assign(t5, IRExpr_ITE(mkexpr(t1),
10323                                            unop(Iop_32to16, getIReg(rt)),
10324                                            unop(Iop_32to16, mkexpr(t2))));
10325                      putIReg(rd, binop(Iop_16HLto32, mkexpr(t4), mkexpr(t5)));
10326                      break;
10327                   }
10328                   default:
10329                      return -1;
10330                }
10331                break;  /* end of SHLL.QB */
10332             }
10333             case 0x18: {  /* ADDUH.QB/MUL.PH */
10334                switch(sa) {
10335                   case 0x00: {  /* ADDUH.QB */
10336                      DIP("adduh.qb r%u, r%u, r%u", rd, rs, rt);
10337                      vassert(!mode64);
10338                      t0 = newTemp(Ity_I32);
10339 
10340                      assign(t0, binop(Iop_HAdd8Ux4, getIReg(rs), getIReg(rt)));
10341 
10342                      putIReg(rd, mkexpr(t0));
10343                      break;
10344                   }
10345                   case 0x1: {  /* SUBUH.QB */
10346                      DIP("subuh.qb r%u, r%u, r%u", rd, rs, rt);
10347                      vassert(!mode64);
10348                      t0 = newTemp(Ity_I32);
10349 
10350                      assign(t0, binop(Iop_HSub8Ux4, getIReg(rs), getIReg(rt)));
10351 
10352                      putIReg(rd, mkexpr(t0));
10353                      break;
10354                   }
10355                   case 0x02: {  /* ADDUH_R.QB */
10356                      DIP("adduh_r.qb r%u, r%u, r%u", rd, rs, rt);
10357                      vassert(!mode64);
10358                      t0 = newTemp(Ity_I32);
10359                      t1 = newTemp(Ity_I32);
10360                      t2 = newTemp(Ity_I8);
10361                      t3 = newTemp(Ity_I32);
10362                      t4 = newTemp(Ity_I32);
10363                      t5 = newTemp(Ity_I8);
10364                      t6 = newTemp(Ity_I32);
10365                      t7 = newTemp(Ity_I32);
10366                      t8 = newTemp(Ity_I8);
10367                      t9 = newTemp(Ity_I32);
10368                      t10 = newTemp(Ity_I32);
10369                      t11 = newTemp(Ity_I8);
10370 
10371                      /* Extract input bytes, add values, add 1 and half the
10372                         result. */
10373                      assign(t0, unop(Iop_8Uto32,
10374                                      unop(Iop_16to8,
10375                                           unop(Iop_32to16, getIReg(rs)))));
10376                      assign(t1, unop(Iop_8Uto32,
10377                                      unop(Iop_16to8,
10378                                           unop(Iop_32to16, getIReg(rt)))));
10379                      assign(t2, unop(Iop_16to8,
10380                                      unop(Iop_32to16,
10381                                           binop(Iop_Shr32,
10382                                                 binop(Iop_Add32,
10383                                                       binop(Iop_Add32,
10384                                                             mkexpr(t0),
10385                                                             mkexpr(t1)),
10386                                                       mkU32(0x00000001)),
10387                                                 mkU8(0x01)))));
10388 
10389                      assign(t3, unop(Iop_8Uto32,
10390                                      unop(Iop_16HIto8,
10391                                           unop(Iop_32to16, getIReg(rs)))));
10392                      assign(t4, unop(Iop_8Uto32,
10393                                      unop(Iop_16HIto8,
10394                                           unop(Iop_32to16, getIReg(rt)))));
10395                      assign(t5, unop(Iop_16to8,
10396                                      unop(Iop_32to16,
10397                                           binop(Iop_Shr32,
10398                                                 binop(Iop_Add32,
10399                                                       binop(Iop_Add32,
10400                                                             mkexpr(t3),
10401                                                             mkexpr(t4)),
10402                                                       mkU32(0x00000001)),
10403                                                 mkU8(0x01)))));
10404 
10405                      assign(t6, unop(Iop_8Uto32,
10406                                      unop(Iop_16to8,
10407                                           unop(Iop_32HIto16, getIReg(rs)))));
10408                      assign(t7, unop(Iop_8Uto32,
10409                                      unop(Iop_16to8,
10410                                           unop(Iop_32HIto16, getIReg(rt)))));
10411                      assign(t8, unop(Iop_16to8,
10412                                      unop(Iop_32to16,
10413                                           binop(Iop_Shr32,
10414                                                 binop(Iop_Add32,
10415                                                       binop(Iop_Add32,
10416                                                             mkexpr(t7),
10417                                                             mkexpr(t6)),
10418                                                       mkU32(0x00000001)),
10419                                                 mkU8(0x01)))));
10420 
10421                      assign(t9, unop(Iop_8Uto32,
10422                                      unop(Iop_16HIto8,
10423                                           unop(Iop_32HIto16, getIReg(rs)))));
10424                      assign(t10, unop(Iop_8Uto32,
10425                                       unop(Iop_16HIto8,
10426                                            unop(Iop_32HIto16, getIReg(rt)))));
10427                      assign(t11, unop(Iop_16to8,
10428                                       unop(Iop_32to16,
10429                                            binop(Iop_Shr32,
10430                                                  binop(Iop_Add32,
10431                                                        binop(Iop_Add32,
10432                                                              mkexpr(t9),
10433                                                              mkexpr(t10)),
10434                                                        mkU32(0x00000001)),
10435                                                  mkU8(0x01)))));
10436 
10437                      putIReg(rd, binop(Iop_16HLto32,
10438                                        binop(Iop_8HLto16,
10439                                              mkexpr(t11), mkexpr(t8)),
10440                                        binop(Iop_8HLto16,
10441                                              mkexpr(t5), mkexpr(t2))));
10442                      break;
10443                   }
10444                   case 0x3: {  /* SUBUH_R.QB */
10445                      DIP("subuh_r.qb r%u, r%u, r%u", rd, rs, rt);
10446                      vassert(!mode64);
10447                      t1 = newTemp(Ity_I32);
10448                      t2 = newTemp(Ity_I32);
10449                      t3 = newTemp(Ity_I32);
10450                      t4 = newTemp(Ity_I32);
10451                      t5 = newTemp(Ity_I32);
10452                      t6 = newTemp(Ity_I32);
10453                      t7 = newTemp(Ity_I32);
10454                      t8 = newTemp(Ity_I32);
10455                      t9 = newTemp(Ity_I8);
10456                      t10 = newTemp(Ity_I8);
10457                      t11 = newTemp(Ity_I8);
10458                      t12 = newTemp(Ity_I8);
10459 
10460                      /* Extract each byte of rs and rt. */
10461                      assign(t1, unop(Iop_8Uto32,
10462                                      unop(Iop_16to8,
10463                                           unop(Iop_32to16, getIReg(rs)))));
10464                      assign(t2, unop(Iop_8Uto32,
10465                                      unop(Iop_16HIto8,
10466                                           unop(Iop_32to16, getIReg(rs)))));
10467                      assign(t3, unop(Iop_8Uto32,
10468                                      unop(Iop_16to8,
10469                                           unop(Iop_32HIto16, getIReg(rs)))));
10470                      assign(t4, unop(Iop_8Uto32,
10471                                      unop(Iop_16HIto8,
10472                                           unop(Iop_32HIto16, getIReg(rs)))));
10473 
10474                      assign(t5, unop(Iop_8Uto32,
10475                                      unop(Iop_16to8,
10476                                           unop(Iop_32to16, getIReg(rt)))));
10477                      assign(t6, unop(Iop_8Uto32,
10478                                      unop(Iop_16HIto8,
10479                                           unop(Iop_32to16, getIReg(rt)))));
10480                      assign(t7, unop(Iop_8Uto32,
10481                                      unop(Iop_16to8,
10482                                           unop(Iop_32HIto16, getIReg(rt)))));
10483                      assign(t8, unop(Iop_8Uto32,
10484                                      unop(Iop_16HIto8,
10485                                           unop(Iop_32HIto16, getIReg(rt)))));
10486 
10487                      /* Add 1 to each resulting byte and half the results. */
10488                      assign(t9, unop(Iop_16to8,
10489                                      unop(Iop_32to16,
10490                                           binop(Iop_Shr32,
10491                                                 binop(Iop_Add32,
10492                                                       binop(Iop_Sub32,
10493                                                             mkexpr(t1),
10494                                                             mkexpr(t5)),
10495                                                       mkU32(0x00000001)),
10496                                                 mkU8(0x01)))));
10497                      assign(t10, unop(Iop_16to8,
10498                                       unop(Iop_32to16,
10499                                            binop(Iop_Shr32,
10500                                                  binop(Iop_Add32,
10501                                                        binop(Iop_Sub32,
10502                                                              mkexpr(t2),
10503                                                              mkexpr(t6)),
10504                                                        mkU32(0x00000001)),
10505                                                  mkU8(0x01)))));
10506                      assign(t11, unop(Iop_16to8,
10507                                       unop(Iop_32to16,
10508                                             binop(Iop_Shr32,
10509                                                   binop(Iop_Add32,
10510                                                         binop(Iop_Sub32,
10511                                                               mkexpr(t3),
10512                                                               mkexpr(t7)),
10513                                                         mkU32(0x00000001)),
10514                                                   mkU8(0x01)))));
10515                      assign(t12, unop(Iop_16to8,
10516                                       unop(Iop_32to16,
10517                                            binop(Iop_Shr32,
10518                                                  binop(Iop_Add32,
10519                                                        binop(Iop_Sub32,
10520                                                              mkexpr(t4),
10521                                                              mkexpr(t8)),
10522                                                        mkU32(0x00000001)),
10523                                                  mkU8(0x01)))));
10524 
10525                      putIReg(rd, binop(Iop_16HLto32,
10526                                        binop(Iop_8HLto16,
10527                                              mkexpr(t12), mkexpr(t11)),
10528                                        binop(Iop_8HLto16,
10529                                              mkexpr(t10), mkexpr(t9))));
10530                      break;
10531                   }
10532                   case 0x8: {  /* ADDQH.PH */
10533                      DIP("addqh.ph r%u, r%u, r%u", rd, rs, rt);
10534                      vassert(!mode64);
10535                      t0 = newTemp(Ity_I32);
10536                      t1 = newTemp(Ity_I16);
10537                      t2 = newTemp(Ity_I32);
10538                      t3 = newTemp(Ity_I16);
10539 
10540                      /* Add lower halfs of rs and rt
10541                         and right shift the result by 1. */
10542                      assign(t0, binop(Iop_Add32,
10543                                       unop(Iop_16Sto32,
10544                                            unop(Iop_32to16, getIReg(rs))),
10545                                       unop(Iop_16Sto32,
10546                                            unop(Iop_32to16, getIReg(rt)))));
10547                      assign(t1, unop(Iop_32to16,
10548                                      binop(Iop_Shr32,
10549                                            binop(Iop_And32,
10550                                                  mkexpr(t0),
10551                                                  mkU32(0x0001fffe)),
10552                                            mkU8(0x1))));
10553                      /* Add higher halfs of rs and rt
10554                         and right shift the result by 1. */
10555                      assign(t2, binop(Iop_Add32,
10556                                       unop(Iop_16Sto32,
10557                                            unop(Iop_32HIto16, getIReg(rs))),
10558                                       unop(Iop_16Sto32,
10559                                            unop(Iop_32HIto16, getIReg(rt)))));
10560                      assign(t3, unop(Iop_32to16,
10561                                      binop(Iop_Shr32,
10562                                            binop(Iop_And32,
10563                                                  mkexpr(t2),
10564                                                  mkU32(0x0001fffe)),
10565                                            mkU8(0x1))));
10566                      putIReg(rd, binop(Iop_16HLto32, mkexpr(t3), mkexpr(t1)));
10567                      break;
10568                   }
10569                   case 0x9: {  /* SUBQH.PH */
10570                      DIP("subqh.ph r%u, r%u, r%u", rd, rs, rt);
10571                      vassert(!mode64);
10572 
10573                      putIReg(rd, binop(Iop_HSub16Sx2,
10574                                        getIReg(rs), getIReg(rt)));
10575                      break;
10576                   }
10577                   case 0xA: {/* ADDQH_R.PH */
10578                      DIP("addqh_r.ph r%u, r%u, r%u", rd, rs, rt);
10579                      vassert(!mode64);
10580                      t0 = newTemp(Ity_I32);
10581                      t1 = newTemp(Ity_I16);
10582                      t2 = newTemp(Ity_I32);
10583                      t3 = newTemp(Ity_I16);
10584 
10585                      /* Add lower halfs of rs and rt, add 1
10586                         and right shift the result by 1. */
10587                      assign(t0, binop(Iop_Add32,
10588                                       unop(Iop_16Sto32,
10589                                            unop(Iop_32to16, getIReg(rs))),
10590                                       unop(Iop_16Sto32,
10591                                            unop(Iop_32to16, getIReg(rt)))));
10592                      assign(t1, unop(Iop_32to16,
10593                                      binop(Iop_Shr32,
10594                                            binop(Iop_And32,
10595                                                  binop(Iop_Add32,
10596                                                        mkexpr(t0),
10597                                                        mkU32(0x1)),
10598                                                  mkU32(0x0001fffe)),
10599                                            mkU8(0x1))));
10600                      /* Add higher halfs of rs and rt, add 1
10601                         and right shift the result by 1. */
10602                      assign(t2, binop(Iop_Add32,
10603                                       unop(Iop_16Sto32,
10604                                            unop(Iop_32HIto16, getIReg(rs))),
10605                                       unop(Iop_16Sto32,
10606                                            unop(Iop_32HIto16, getIReg(rt)))));
10607                      assign(t3, unop(Iop_32to16,
10608                                      binop(Iop_Shr32,
10609                                            binop(Iop_And32,
10610                                                  binop(Iop_Add32,
10611                                                        mkexpr(t2),
10612                                                        mkU32(0x1)),
10613                                                  mkU32(0x0001fffe)),
10614                                            mkU8(0x1))));
10615 
10616                      putIReg(rd, binop(Iop_16HLto32, mkexpr(t3), mkexpr(t1)));
10617                      break;
10618                   }
10619                   case 0xB: {  /* SUBQH_R.PH */
10620                      DIP("subqh_r.ph r%u, r%u, r%u", rd, rs, rt);
10621                      vassert(!mode64);
10622                      t0 = newTemp(Ity_I32);
10623                      t1 = newTemp(Ity_I16);
10624                      t2 = newTemp(Ity_I32);
10625                      t3 = newTemp(Ity_I16);
10626 
10627                      /* Sub lower halfs of rs and rt, add 1
10628                         and right shift the result by 1. */
10629                      assign(t0, binop(Iop_Sub32,
10630                                       unop(Iop_16Sto32,
10631                                            unop(Iop_32to16, getIReg(rs))),
10632                                       unop(Iop_16Sto32,
10633                                            unop(Iop_32to16, getIReg(rt)))));
10634                      assign(t1, unop(Iop_32to16,
10635                                      binop(Iop_Shr32,
10636                                            binop(Iop_And32,
10637                                                  binop(Iop_Add32,
10638                                                        mkexpr(t0),
10639                                                        mkU32(0x1)),
10640                                                  mkU32(0x0001fffe)),
10641                                            mkU8(0x1))));
10642                      /* Sub higher halfs of rs and rt, add 1
10643                         and right shift the result by 1. */
10644                      assign(t2, binop(Iop_Sub32,
10645                                       unop(Iop_16Sto32,
10646                                            unop(Iop_32HIto16, getIReg(rs))),
10647                                       unop(Iop_16Sto32,
10648                                            unop(Iop_32HIto16, getIReg(rt)))));
10649                      assign(t3, unop(Iop_32to16,
10650                                      binop(Iop_Shr32,
10651                                            binop(Iop_And32,
10652                                                  binop(Iop_Add32,
10653                                                        mkexpr(t2),
10654                                                        mkU32(0x1)),
10655                                                  mkU32(0x0001fffe)),
10656                                            mkU8(0x1))));
10657 
10658                      putIReg(rd, binop(Iop_16HLto32, mkexpr(t3), mkexpr(t1)));
10659                      break;
10660                   }
10661                   case 0xC: {  /* MUL.PH */
10662                      DIP("mul.ph r%u, r%u, r%u", rd, rs, rt);
10663                      vassert(!mode64);
10664                      t0 = newTemp(Ity_I32);
10665                      t1 = newTemp(Ity_I32);
10666                      t2 = newTemp(Ity_I32);
10667 
10668                      assign(t0,
10669                             binop(Iop_Mul32,
10670                                   unop(Iop_16Sto32,
10671                                        unop(Iop_32HIto16, getIReg(rs))),
10672                                   unop(Iop_16Sto32,
10673                                        unop(Iop_32HIto16, getIReg(rt)))));
10674                      /* DSP Control flag. */
10675                      putDSPControl(IRExpr_ITE(unop(Iop_Not1,
10676                                                    binop(Iop_CmpLE32S,
10677                                                          mkexpr(t0),
10678                                                          mkU32(0x7FFF))),
10679                                               binop(Iop_Or32,
10680                                                     getDSPControl(),
10681                                                     mkU32(0x00200000)),
10682                                               IRExpr_ITE(binop(Iop_CmpLT32S,
10683                                                                mkexpr(t0),
10684                                                                mkU32(0xFFFF8000)
10685                                                              ),
10686                                                          binop(Iop_Or32,
10687                                                                getDSPControl(),
10688                                                                mkU32(0x00200000)
10689                                                               ),
10690                                                          getDSPControl())));
10691 
10692                      assign(t1,
10693                             binop(Iop_Mul32,
10694                                   unop(Iop_16Sto32,
10695                                        unop(Iop_32to16, getIReg(rs))),
10696                                   unop(Iop_16Sto32,
10697                                        unop(Iop_32to16, getIReg(rt)))));
10698                      /* DSP Control flag. */
10699                      putDSPControl(IRExpr_ITE(unop(Iop_Not1,
10700                                                    binop(Iop_CmpLE32S,
10701                                                          mkexpr(t1),
10702                                                          mkU32(0x7FFF))),
10703                                               binop(Iop_Or32,
10704                                                     getDSPControl(),
10705                                                     mkU32(0x00200000)),
10706                                               IRExpr_ITE(binop(Iop_CmpLT32S,
10707                                                                mkexpr(t1),
10708                                                                mkU32(0xFFFF8000)
10709                                                               ),
10710                                                          binop(Iop_Or32,
10711                                                                getDSPControl(),
10712                                                                mkU32(0x00200000)
10713                                                               ),
10714                                                          getDSPControl())));
10715 
10716                      assign(t2, binop(Iop_16HLto32,
10717                                       unop(Iop_32to16, mkexpr(t0)),
10718                                       unop(Iop_32to16, mkexpr(t1))));
10719                      putIReg(rd, mkexpr(t2));
10720                      break;
10721                   }
10722                   case 0xE: {  /* MUL_S.PH */
10723                      DIP("mul_s.ph r%u r%u, r%u", rd, rs, rt);
10724                      vassert(!mode64);
10725 
10726                      t0 = newTemp(Ity_I32);
10727                      t1 = newTemp(Ity_I32);
10728                      t2 = newTemp(Ity_I32);
10729                      t3 = newTemp(Ity_I32);
10730                      t4 = newTemp(Ity_I32);
10731 
10732                      /* t0 - signed intermediate result. */
10733                      assign(t0,
10734                            binop(Iop_Mul32,
10735                                  unop(Iop_16Sto32,
10736                                       unop(Iop_32HIto16, getIReg(rs))),
10737                                  unop(Iop_16Sto32,
10738                                       unop(Iop_32HIto16, getIReg(rt)))));
10739 
10740                      assign(t1,
10741                             IRExpr_ITE(unop(Iop_Not1,
10742                                             binop(Iop_CmpLE32S,
10743                                                   mkexpr(t0),
10744                                                   mkU32(0x7FFF))),
10745                                        mkU32(0x00007FFF),
10746                                        IRExpr_ITE(binop(Iop_CmpLT32S,
10747                                                         mkexpr(t0),
10748                                                         mkU32(0xFFFF8000)),
10749                                                   mkU32(0xFFFF8000),
10750                                                   mkexpr(t0))));
10751 
10752                      /* DSP Control flag. */
10753                      putDSPControl(IRExpr_ITE(unop(Iop_Not1,
10754                                                    binop(Iop_CmpLE32S,
10755                                                          mkexpr(t0),
10756                                                          mkU32(0x7FFF))),
10757                                               binop(Iop_Or32,
10758                                                     getDSPControl(),
10759                                                     mkU32(0x00200000)),
10760                                               IRExpr_ITE(binop(Iop_CmpLT32S,
10761                                                                mkexpr(t0),
10762                                                                mkU32(0xFFFF8000)
10763                                                               ),
10764                                                          binop(Iop_Or32,
10765                                                                getDSPControl(),
10766                                                                mkU32(0x00200000)
10767                                                               ),
10768                                                          getDSPControl())));
10769 
10770                      /* t2 - signed intermediate result. */
10771                      assign(t2, binop(Iop_Mul32,
10772                                       unop(Iop_16Sto32,
10773                                            unop(Iop_32to16, getIReg(rs))),
10774                                       unop(Iop_16Sto32,
10775                                            unop(Iop_32to16, getIReg(rt)))));
10776 
10777                      assign(t3, IRExpr_ITE(unop(Iop_Not1,
10778                                                 binop(Iop_CmpLE32S,
10779                                                       mkexpr(t2),
10780                                                       mkU32(0x7FFF))),
10781                                            mkU32(0x00007FFF),
10782                                            IRExpr_ITE(binop(Iop_CmpLT32S,
10783                                                             mkexpr(t2),
10784                                                             mkU32(0xFFFF8000)),
10785                                                       mkU32(0xFFFF8000),
10786                                                       mkexpr(t2))));
10787 
10788                      /* DSP Control flag. */
10789                      putDSPControl(IRExpr_ITE(unop(Iop_Not1,
10790                                                    binop(Iop_CmpLE32S,
10791                                                          mkexpr(t2),
10792                                                          mkU32(0x7FFF))),
10793                                               binop(Iop_Or32,
10794                                                     getDSPControl(),
10795                                                     mkU32(0x00200000)),
10796                                               IRExpr_ITE(binop(Iop_CmpLT32S,
10797                                                                mkexpr(t2),
10798                                                                mkU32(0xFFFF8000)
10799                                                               ),
10800                                                          binop(Iop_Or32,
10801                                                                getDSPControl(),
10802                                                                mkU32(0x00200000)
10803                                                               ),
10804                                                          getDSPControl())));
10805 
10806                      assign(t4, binop(Iop_16HLto32,
10807                                       unop(Iop_32to16, mkexpr(t1)),
10808                                       unop(Iop_32to16, mkexpr(t3))));
10809                      putIReg(rd, mkexpr(t4));
10810                      break;
10811                   }
10812                   case 0x10: {  /* ADDQH.W */
10813                      DIP("addqh.w r%u, r%u, r%u", rd, rs, rt);
10814                      vassert(!mode64);
10815                      t0 = newTemp(Ity_I64);
10816                      t1 = newTemp(Ity_I64);
10817 
10818                      assign(t0, binop(Iop_Add64,
10819                                       unop(Iop_32Sto64, getIReg(rs)),
10820                                       unop(Iop_32Sto64, getIReg(rt))));
10821                      assign(t1, binop(Iop_And64,
10822                                       mkexpr(t0),
10823                                       mkU64(0x00000001fffffffeULL)));
10824                      putIReg(rd, unop(Iop_64to32,
10825                                       binop(Iop_Shr64, mkexpr(t1), mkU8(0x1))));
10826                      break;
10827                   }
10828                   case 0x11: {  /* SUBQH.W */
10829                      DIP("subqh.w r%u, r%u, r%u", rd, rs, rt);
10830                      vassert(!mode64);
10831                      t0 = newTemp(Ity_I64);
10832                      t1 = newTemp(Ity_I64);
10833 
10834                      assign(t0, binop(Iop_Sub64,
10835                                       unop(Iop_32Sto64, getIReg(rs)),
10836                                       unop(Iop_32Sto64, getIReg(rt))));
10837                      assign(t1, binop(Iop_And64,
10838                                       mkexpr(t0),
10839                                       mkU64(0x00000001fffffffeULL)));
10840                      putIReg(rd, unop(Iop_64to32,
10841                                       binop(Iop_Shr64, mkexpr(t1), mkU8(0x1))));
10842                      break;
10843                   }
10844                   case 0x12: {  /* ADDQH_R.W */
10845                      DIP("addqh_r.w r%u, r%u, r%u", rd, rs, rt);
10846                      vassert(!mode64);
10847                      t0 = newTemp(Ity_I64);
10848                      t1 = newTemp(Ity_I64);
10849                      t2 = newTemp(Ity_I64);
10850 
10851                      assign(t0, binop(Iop_Add64,
10852                                       unop(Iop_32Sto64, getIReg(rs)),
10853                                       unop(Iop_32Sto64, getIReg(rt))));
10854                      assign(t1, binop(Iop_Add64,
10855                                       mkexpr(t0),
10856                                       mkU64(0x0000000000000001ULL)));
10857                      assign(t2, binop(Iop_And64,
10858                                       mkexpr(t1),
10859                                       mkU64(0x00000001fffffffeULL)));
10860                      putIReg(rd, unop(Iop_64to32,
10861                                       binop(Iop_Shr64, mkexpr(t2), mkU8(0x1))));
10862                      break;
10863                   }
10864                   case 0x13: {  /* SUBQH_R.W */
10865                      DIP("subqh_r.w r%u, r%u, r%u", rd, rs, rt);
10866                      vassert(!mode64);
10867                      t0 = newTemp(Ity_I64);
10868                      t1 = newTemp(Ity_I64);
10869                      t2 = newTemp(Ity_I64);
10870 
10871                      assign(t0, binop(Iop_Sub64,
10872                                       unop(Iop_32Sto64, getIReg(rs)),
10873                                       unop(Iop_32Sto64, getIReg(rt))));
10874                      assign(t1, binop(Iop_Add64,
10875                                       mkexpr(t0),
10876                                       mkU64(0x0000000000000001ULL)));
10877                      assign(t2, binop(Iop_And64,
10878                                       mkexpr(t1),
10879                                       mkU64(0x00000001fffffffeULL)));
10880                      putIReg(rd, unop(Iop_64to32,
10881                                       binop(Iop_Shr64, mkexpr(t2), mkU8(0x1))));
10882                      break;
10883                   }
10884                   case 0x16: {  /* MULQ_S.W */
10885                      DIP("mulq_s.w r%u, r%u, r%u", rd, rs, rt);
10886                      vassert(!mode64);
10887                      t0 = newTemp(Ity_I64);
10888                      t1 = newTemp(Ity_I1);
10889                      t2 = newTemp(Ity_I1);
10890 
10891                      assign(t0, binop(Iop_Shl64,
10892                                       binop(Iop_MullS32,
10893                                             getIReg(rt), getIReg(rs)),
10894                                       mkU8(0x1)));
10895                      assign(t1, binop(Iop_CmpEQ32,
10896                                       getIReg(rt), mkU32(0x80000000)));
10897                      assign(t2, binop(Iop_CmpEQ32,
10898                                       getIReg(rs), mkU32(0x80000000)));
10899 
10900                      putDSPControl(IRExpr_ITE(mkexpr(t1),
10901                                               IRExpr_ITE(mkexpr(t2),
10902                                                          binop(Iop_Or32,
10903                                                                getDSPControl(),
10904                                                                mkU32(0x00200000)
10905                                                               ),
10906                                                          getDSPControl()),
10907                                               getDSPControl()));
10908                      putIReg(rd, IRExpr_ITE(mkexpr(t1),
10909                                             IRExpr_ITE(mkexpr(t2),
10910                                                        mkU32(0x7fffffff),
10911                                                        unop(Iop_64HIto32,
10912                                                             mkexpr(t0))),
10913                                             unop(Iop_64HIto32, mkexpr(t0))));
10914                      break;
10915                   }
10916                   case 0x17: {  /* MULQ_RS.W */
10917                      DIP("mulq_rs.w r%u, r%u, r%u", rd, rs, rt);
10918                      vassert(!mode64);
10919                      t0 = newTemp(Ity_I64);
10920                      t1 = newTemp(Ity_I1);
10921                      t2 = newTemp(Ity_I1);
10922 
10923                      assign(t0, binop(Iop_Add64,
10924                                       binop(Iop_Shl64,
10925                                             binop(Iop_MullS32,
10926                                                   getIReg(rt),
10927                                                   getIReg(rs)),
10928                                             mkU8(0x1)),
10929                                       mkU64(0x0000000080000000ULL)));
10930                      assign(t1,
10931                             binop(Iop_CmpEQ32, getIReg(rt), mkU32(0x80000000)));
10932                      assign(t2,
10933                             binop(Iop_CmpEQ32, getIReg(rs), mkU32(0x80000000)));
10934                      putDSPControl(IRExpr_ITE(mkexpr(t1),
10935                                               IRExpr_ITE(mkexpr(t2),
10936                                                          binop(Iop_Or32,
10937                                                                getDSPControl(),
10938                                                                mkU32(0x00200000)
10939                                                               ),
10940                                                          getDSPControl()),
10941                                               getDSPControl()));
10942                      putIReg(rd, IRExpr_ITE(mkexpr(t1),
10943                                             IRExpr_ITE(mkexpr(t2),
10944                                                        mkU32(0x7fffffff),
10945                                                        unop(Iop_64HIto32,
10946                                                             mkexpr(t0))),
10947                                             unop(Iop_64HIto32, mkexpr(t0))));
10948                      break;
10949                   }
10950                   default:
10951                      return -1;
10952                }
10953                break;  /* end of ADDUH.QB/MUL.PH */
10954             }
10955             case 0x30: {  /* DPAQ.W.PH */
10956                switch(sa) {
10957                   case 0x0: {  /* DPA.W.PH */
10958                      DIP("dpa.w.ph ac%u, r%u, r%u", ac, rs, rt);
10959                      vassert(!mode64);
10960 
10961                      t0 = newTemp(Ity_I64);
10962                      t1 = newTemp(Ity_I64);
10963                      t2 = newTemp(Ity_I64);
10964 
10965                      assign(t0,
10966                             unop(Iop_32Sto64,
10967                                  binop(Iop_Mul32,
10968                                        unop(Iop_16Sto32,
10969                                             unop(Iop_32HIto16, getIReg(rs))),
10970                                        unop(Iop_16Sto32,
10971                                             unop(Iop_32HIto16, getIReg(rt))))));
10972                      assign(t1,
10973                             unop(Iop_32Sto64,
10974                                  binop(Iop_Mul32,
10975                                        unop(Iop_16Sto32,
10976                                             unop(Iop_32to16, getIReg(rs))),
10977                                        unop(Iop_16Sto32,
10978                                             unop(Iop_32to16, getIReg(rt))))));
10979                      assign(t2,
10980                             binop(Iop_Add64,
10981                                   getAcc(ac),
10982                                   binop(Iop_Add64, mkexpr(t0), mkexpr(t1))));
10983                      putAcc(ac, mkexpr(t2));
10984                      break;
10985                   }
10986                   case 0x1: {  /* DPS.W.PH */
10987                      DIP("dps.w.ph ac%u, r%u, r%u", ac, rs, rt);
10988                      vassert(!mode64);
10989 
10990                      t0 = newTemp(Ity_I64);
10991                      t1 = newTemp(Ity_I64);
10992                      t2 = newTemp(Ity_I64);
10993 
10994                      assign(t0,
10995                             unop(Iop_32Sto64,
10996                                  binop(Iop_Mul32,
10997                                        unop(Iop_16Sto32,
10998                                             unop(Iop_32HIto16, getIReg(rs))),
10999                                        unop(Iop_16Sto32,
11000                                             unop(Iop_32HIto16, getIReg(rt))))));
11001                      assign(t1,
11002                             unop(Iop_32Sto64,
11003                                  binop(Iop_Mul32,
11004                                        unop(Iop_16Sto32,
11005                                             unop(Iop_32to16, getIReg(rs))),
11006                                        unop(Iop_16Sto32,
11007                                             unop(Iop_32to16, getIReg(rt))))));
11008                      assign(t2,
11009                             binop(Iop_Sub64,
11010                                   getAcc(ac),
11011                                   binop(Iop_Add64, mkexpr(t0), mkexpr(t1))));
11012                      putAcc(ac, mkexpr(t2));
11013                      break;
11014                   }
11015                   case 0x2: {  /* MULSA.W.PH */
11016                      DIP("mulsa.w.ph ac%u, r%u, r%u", ac, rs, rt);
11017                      vassert(!mode64);
11018                      t0 = newTemp(Ity_I32);
11019                      t1 = newTemp(Ity_I32);
11020                      t2 = newTemp(Ity_I32);
11021                      t3 = newTemp(Ity_I1);
11022                      t4 = newTemp(Ity_I64);
11023 
11024                      assign(t4, getAcc(ac));
11025                      assign(t0, binop(Iop_Mul32,
11026                                       unop(Iop_16Sto32,
11027                                            unop(Iop_32to16, getIReg(rt))),
11028                                       unop(Iop_16Sto32,
11029                                            unop(Iop_32to16, getIReg(rs)))));
11030                      assign(t1, binop(Iop_Mul32,
11031                                       unop(Iop_16Sto32,
11032                                            unop(Iop_32HIto16, getIReg(rt))),
11033                                       unop(Iop_16Sto32,
11034                                            unop(Iop_32HIto16, getIReg(rs)))));
11035                      assign(t2, binop(Iop_Sub32, mkexpr(t1), mkexpr(t0)));
11036                      putAcc(ac, binop(Iop_Add64,
11037                                       mkexpr(t4),
11038                                       unop(Iop_32Sto64, mkexpr(t2))));
11039                      break;
11040                   }
11041                   case 0x3: {  /* DPAU.H.QBL */
11042                      DIP("dpau.h.qbl ac%u, r%u, r%u", ac, rs, rt);
11043                      vassert(!mode64);
11044                      t0 = newTemp(Ity_I32);
11045                      t1 = newTemp(Ity_I32);
11046                      t2 = newTemp(Ity_I64);
11047                      t3 = newTemp(Ity_I64);
11048 
11049                      assign(t0,
11050                             binop(Iop_Mul32,
11051                                   unop(Iop_8Uto32,
11052                                        unop(Iop_16HIto8,
11053                                             unop(Iop_32HIto16, getIReg(rs)))),
11054                                   unop(Iop_8Uto32,
11055                                        unop(Iop_16HIto8,
11056                                             unop(Iop_32HIto16, getIReg(rt))))));
11057                      assign(t1,
11058                             binop(Iop_Mul32,
11059                                   unop(Iop_8Uto32,
11060                                        unop(Iop_16to8,
11061                                             unop(Iop_32HIto16, getIReg(rs)))),
11062                                   unop(Iop_8Uto32,
11063                                        unop(Iop_16to8,
11064                                             unop(Iop_32HIto16, getIReg(rt))))));
11065                      assign(t2,
11066                             unop(Iop_32Uto64,
11067                                  binop(Iop_Add32,
11068                                        mkexpr(t0),
11069                                        mkexpr(t1))));
11070                      assign(t3,
11071                             binop(Iop_Add64, getAcc(ac), mkexpr(t2)));
11072                      putAcc(ac, mkexpr(t3));
11073                      break;
11074                   }
11075                   case 0x4: {  /* DPAQ_S.W.PH */
11076                      DIP("dpaq_s.w.ph ac%u, r%u, r%u", ac, rs, rt);
11077                      vassert(!mode64);
11078                      t0 = newTemp(Ity_I64);
11079                      t1 = newTemp(Ity_I64);
11080                      t2 = newTemp(Ity_I1);
11081                      t3 = newTemp(Ity_I1);
11082                      t4 = newTemp(Ity_I64);
11083                      t5 = newTemp(Ity_I64);
11084                      t6 = newTemp(Ity_I1);
11085                      t7 = newTemp(Ity_I1);
11086                      t8 = newTemp(Ity_I64);
11087                      t9 = newTemp(Ity_I64);
11088 
11089                      assign(t0, getAcc(ac));
11090 
11091                      assign(t1, binop(Iop_Shl64,
11092                                       binop(Iop_MullS32,
11093                                             unop(Iop_16Sto32,
11094                                                  unop(Iop_32HIto16,
11095                                                       getIReg(rs))),
11096                                             unop(Iop_16Sto32,
11097                                                  unop(Iop_32HIto16,
11098                                                       getIReg(rt)))),
11099                                       mkU8(0x1)));
11100                      assign(t2, binop(Iop_CmpEQ32,
11101                                       unop(Iop_16Uto32,
11102                                            unop(Iop_32HIto16, getIReg(rs))),
11103                                       mkU32(0x00008000)));
11104                      assign(t3, binop(Iop_CmpEQ32,
11105                                       unop(Iop_16Uto32,
11106                                            unop(Iop_32HIto16, getIReg(rt))),
11107                                       mkU32(0x00008000)));
11108                      assign(t4,
11109                             IRExpr_ITE(mkexpr(t2),
11110                                        IRExpr_ITE(mkexpr(t3),
11111                                                   mkU64(0x000000007fffffffULL),
11112                                                   mkexpr(t1)),
11113                                        mkexpr(t1)));
11114 
11115                      putDSPControl(IRExpr_ITE(mkexpr(t2),
11116                                               IRExpr_ITE(mkexpr(t3),
11117                                                          binop(Iop_Or32,
11118                                                                getDSPControl(),
11119                                                                binop(Iop_Shl32,
11120                                                                      mkU32(0x1),
11121                                                                      mkU8(ac+16)
11122                                                                     )
11123                                                               ),
11124                                                          getDSPControl()),
11125                                               getDSPControl()));
11126 
11127                      assign(t5, binop(Iop_Shl64,
11128                                       binop(Iop_MullS32,
11129                                             unop(Iop_16Sto32,
11130                                                  unop(Iop_32to16, getIReg(rs))),
11131                                             unop(Iop_16Sto32,
11132                                                  unop(Iop_32to16, getIReg(rt)))
11133                                            ),
11134                                       mkU8(0x1)));
11135                      assign(t6, binop(Iop_CmpEQ32,
11136                                       unop(Iop_16Uto32,
11137                                            unop(Iop_32to16, getIReg(rs))),
11138                                       mkU32(0x00008000)));
11139                      assign(t7, binop(Iop_CmpEQ32,
11140                                       unop(Iop_16Uto32,
11141                                            unop(Iop_32to16, getIReg(rt))),
11142                                       mkU32(0x00008000)));
11143                      assign(t8,
11144                             IRExpr_ITE(mkexpr(t6),
11145                                        IRExpr_ITE(mkexpr(t7),
11146                                                   mkU64(0x000000007fffffffULL),
11147                                                   mkexpr(t5)),
11148                                        mkexpr(t5)));
11149 
11150                      putDSPControl(IRExpr_ITE(mkexpr(t6),
11151                                               IRExpr_ITE(mkexpr(t7),
11152                                                          binop(Iop_Or32,
11153                                                                getDSPControl(),
11154                                                                binop(Iop_Shl32,
11155                                                                      mkU32(0x1),
11156                                                                      mkU8(ac+16)
11157                                                                     )
11158                                                               ),
11159                                                          getDSPControl()),
11160                                               getDSPControl()));
11161 
11162                      assign(t9, binop(Iop_Add64,
11163                                       binop(Iop_Add64, mkexpr(t4), mkexpr(t8)),
11164                                       mkexpr(t0)));
11165                      putAcc(ac, mkexpr(t9));
11166                      break;
11167                   }
11168                   case 0x5: {  /* DPSQ_S.W.PH */
11169                      DIP("dpsq_s.w.ph ac%u r%u, r%u", ac, rs, rt);
11170                      vassert(!mode64);
11171                      t0 = newTemp(Ity_I64);
11172                      t1 = newTemp(Ity_I64);
11173                      t2 = newTemp(Ity_I1);
11174                      t3 = newTemp(Ity_I1);
11175                      t4 = newTemp(Ity_I64);
11176                      t5 = newTemp(Ity_I64);
11177                      t6 = newTemp(Ity_I1);
11178                      t7 = newTemp(Ity_I1);
11179                      t8 = newTemp(Ity_I64);
11180                      t9 = newTemp(Ity_I64);
11181 
11182                      assign(t0, getAcc(ac));
11183 
11184                      assign(t1, binop(Iop_Shl64,
11185                                       binop(Iop_MullS32,
11186                                             unop(Iop_16Sto32,
11187                                                  unop(Iop_32HIto16,
11188                                                       getIReg(rs))),
11189                                             unop(Iop_16Sto32,
11190                                                  unop(Iop_32HIto16,
11191                                                       getIReg(rt)))),
11192                                       mkU8(0x1)));
11193                      assign(t2, binop(Iop_CmpEQ32,
11194                                       unop(Iop_16Uto32,
11195                                            unop(Iop_32HIto16, getIReg(rs))),
11196                                       mkU32(0x00008000)));
11197                      assign(t3, binop(Iop_CmpEQ32,
11198                                       unop(Iop_16Uto32,
11199                                            unop(Iop_32HIto16, getIReg(rt))),
11200                                       mkU32(0x00008000)));
11201                      assign(t4,
11202                             IRExpr_ITE(mkexpr(t2),
11203                                        IRExpr_ITE(mkexpr(t3),
11204                                                   mkU64(0x000000007fffffffULL),
11205                                                   mkexpr(t1)),
11206                                        mkexpr(t1)));
11207 
11208                      putDSPControl(IRExpr_ITE(mkexpr(t2),
11209                                               IRExpr_ITE(mkexpr(t3),
11210                                                          binop(Iop_Or32,
11211                                                                getDSPControl(),
11212                                                                binop(Iop_Shl32,
11213                                                                      mkU32(0x1),
11214                                                                      mkU8(ac+16)
11215                                                                     )
11216                                                               ),
11217                                                          getDSPControl()),
11218                                               getDSPControl()));
11219 
11220                      assign(t5,
11221                             binop(Iop_Shl64,
11222                                   binop(Iop_MullS32,
11223                                         unop(Iop_16Sto32,
11224                                              unop(Iop_32to16, getIReg(rs))),
11225                                         unop(Iop_16Sto32,
11226                                              unop(Iop_32to16, getIReg(rt)))),
11227                                   mkU8(0x1)));
11228                      assign(t6, binop(Iop_CmpEQ32,
11229                                       unop(Iop_16Uto32,
11230                                            unop(Iop_32to16, getIReg(rs))),
11231                                       mkU32(0x00008000)));
11232                      assign(t7, binop(Iop_CmpEQ32,
11233                                       unop(Iop_16Uto32,
11234                                            unop(Iop_32to16, getIReg(rt))),
11235                                       mkU32(0x00008000)));
11236                      assign(t8,
11237                             IRExpr_ITE(mkexpr(t6),
11238                                        IRExpr_ITE(mkexpr(t7),
11239                                                   mkU64(0x000000007fffffffULL),
11240                                                   mkexpr(t5)),
11241                                        mkexpr(t5)));
11242 
11243                      putDSPControl(IRExpr_ITE(mkexpr(t6),
11244                                               IRExpr_ITE(mkexpr(t7),
11245                                                          binop(Iop_Or32,
11246                                                                getDSPControl(),
11247                                                                binop(Iop_Shl32,
11248                                                                      mkU32(0x1),
11249                                                                      mkU8(ac+16)
11250                                                                     )
11251                                                               ),
11252                                                          getDSPControl()),
11253                                               getDSPControl()));
11254 
11255                      assign(t9,
11256                             binop(Iop_Sub64,
11257                                   mkexpr(t0),
11258                                   binop(Iop_Add64, mkexpr(t4), mkexpr(t8))));
11259                      putAcc(ac, mkexpr(t9));
11260                      break;
11261                   }
11262                   case 0x6: {  /* MULSAQ_S.W.PH */
11263                      DIP("mulsaq_s.w.ph ac%u r%u, r%u", ac, rs, rt);
11264                      vassert(!mode64);
11265 
11266                      t0 = newTemp(Ity_I32);
11267                      t1 = newTemp(Ity_I32);
11268                      t2 = newTemp(Ity_I32);
11269                      t3 = newTemp(Ity_I32);
11270                      t4 = newTemp(Ity_I32);
11271                      t5 = newTemp(Ity_I32);
11272                      t6 = newTemp(Ity_I64);
11273                      t7 = newTemp(Ity_I64);
11274                      t8 = newTemp(Ity_I32);
11275                      t9 = newTemp(Ity_I32);
11276 
11277                      assign(t0, unop(Iop_16Sto32,
11278                                      unop(Iop_32HIto16, getIReg(rs))));
11279                      assign(t1, unop(Iop_16Sto32,
11280                                      unop(Iop_32HIto16, getIReg(rt))));
11281 
11282                      assign(t8, binop(Iop_And32,
11283                                       unop(Iop_1Sto32,
11284                                            binop(Iop_CmpEQ32,
11285                                                  unop(Iop_16Uto32,
11286                                                       unop(Iop_32HIto16,
11287                                                            getIReg(rs))),
11288                                                  mkU32(0x8000))),
11289                                     unop(Iop_1Sto32,
11290                                          binop(Iop_CmpEQ32,
11291                                                unop(Iop_16Uto32,
11292                                                     unop(Iop_32HIto16,
11293                                                          getIReg(rt))),
11294                                                mkU32(0x8000)))));
11295                      /* DSPControl_outflag:16+acc <- 1 */
11296                      putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32,
11297                                                     mkexpr(t8),
11298                                                     mkU32(0x0)),
11299                                               binop(Iop_Or32,
11300                                                     getDSPControl(),
11301                                                     binop(Iop_Shl32,
11302                                                           mkU32(0x00010000),
11303                                                           mkU8(ac))),
11304                                               getDSPControl()));
11305 
11306                      /* tempB_31..0 */
11307                      assign(t2,
11308                             IRExpr_ITE(binop(Iop_CmpNE32,
11309                                              mkexpr(t8), mkU32(0x0)),
11310                                        mkU32(0x7FFFFFFF),
11311                                        binop(Iop_Shl32,
11312                                              binop(Iop_Mul32,
11313                                                    mkexpr(t0), mkexpr(t1)),
11314                                              mkU8(1))));
11315 
11316                      assign(t3, unop(Iop_16Sto32,
11317                                      unop(Iop_32to16, getIReg(rs))));
11318                      assign(t4, unop(Iop_16Sto32,
11319                                      unop(Iop_32to16, getIReg(rt))));
11320 
11321                      assign(t9, binop(Iop_And32,
11322                                       unop(Iop_1Sto32,
11323                                            binop(Iop_CmpEQ32,
11324                                                  unop(Iop_16Uto32,
11325                                                       unop(Iop_32to16,
11326                                                            getIReg(rs))),
11327                                                  mkU32(0x8000))),
11328                                       unop(Iop_1Sto32,
11329                                            binop(Iop_CmpEQ32,
11330                                                  unop(Iop_16Uto32,
11331                                                       unop(Iop_32to16,
11332                                                            getIReg(rt))),
11333                                                  mkU32(0x8000)))));
11334                      /* DSPControl_outflag:16+acc <- 1 */
11335                      putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32,
11336                                                     mkexpr(t9),
11337                                                     mkU32(0x0)),
11338                                               binop(Iop_Or32,
11339                                                     getDSPControl(),
11340                                                     binop(Iop_Shl32,
11341                                                           mkU32(0x00010000),
11342                                                           mkU8(ac))),
11343                                               getDSPControl()));
11344                      /* tempA_31..0 */
11345                      assign(t5,
11346                             IRExpr_ITE(binop(Iop_CmpNE32,
11347                                              mkexpr(t9),
11348                                              mkU32(0x0)),
11349                                        mkU32(0x7FFFFFFF),
11350                                        binop(Iop_Shl32,
11351                                              binop(Iop_Mul32,
11352                                                    mkexpr(t3),
11353                                                    mkexpr(t4)),
11354                                              mkU8(1))));
11355                      /* dotp_63..0 */
11356                      assign(t6,
11357                             binop(Iop_Sub64,
11358                                   unop(Iop_32Sto64, mkexpr(t2)),
11359                                   unop(Iop_32Sto64, mkexpr(t5))));
11360                      /* tempC_63..0 */
11361                      assign(t7, binop(Iop_Add64, getAcc(ac), mkexpr(t6)));
11362 
11363                      putAcc(ac, mkexpr(t7));
11364                      break;
11365                   }
11366                   case 0x7: {  /* DPAU.H.QBR */
11367                      DIP("dpau.h.qbr ac%u, r%u, r%u", ac, rs, rt);
11368                      vassert(!mode64);
11369                      t0 = newTemp(Ity_I32);
11370                      t1 = newTemp(Ity_I32);
11371                      t2 = newTemp(Ity_I64);
11372                      t3 = newTemp(Ity_I64);
11373 
11374                      assign(t0,
11375                             binop(Iop_Mul32,
11376                                   unop(Iop_8Uto32,
11377                                        unop(Iop_16HIto8,
11378                                             unop(Iop_32to16, getIReg(rs)))),
11379                                   unop(Iop_8Uto32,
11380                                        unop(Iop_16HIto8,
11381                                             unop(Iop_32to16, getIReg(rt))))));
11382                      assign(t1,
11383                             binop(Iop_Mul32,
11384                                   unop(Iop_8Uto32,
11385                                        unop(Iop_16to8,
11386                                             unop(Iop_32to16, getIReg(rs)))),
11387                                   unop(Iop_8Uto32,
11388                                        unop(Iop_16to8,
11389                                             unop(Iop_32to16, getIReg(rt))))));
11390                      assign(t2, unop(Iop_32Uto64,
11391                                      binop(Iop_Add32, mkexpr(t0), mkexpr(t1))));
11392                      assign(t3, binop(Iop_Add64, getAcc(ac), mkexpr(t2)));
11393                      putAcc(ac, mkexpr(t3));
11394                      break;
11395                   }
11396                   case 0x8: {  /* DPAX.W.PH */
11397                      DIP("dpax.w.ph ac%u, r%u, r%u", ac, rs, rt);
11398                      vassert(!mode64);
11399                      t0 = newTemp(Ity_I64);
11400                      t1 = newTemp(Ity_I64);
11401                      t2 = newTemp(Ity_I64);
11402 
11403                      assign(t0,
11404                             unop(Iop_32Sto64,
11405                                  binop(Iop_Mul32,
11406                                        unop(Iop_16Sto32,
11407                                             unop(Iop_32HIto16, getIReg(rs))),
11408                                        unop(Iop_16Sto32,
11409                                             unop(Iop_32to16, getIReg(rt))))));
11410                      assign(t1,
11411                             unop(Iop_32Sto64,
11412                                  binop(Iop_Mul32,
11413                                        unop(Iop_16Sto32,
11414                                             unop(Iop_32to16, getIReg(rs))),
11415                                        unop(Iop_16Sto32,
11416                                             unop(Iop_32HIto16, getIReg(rt))))));
11417                      assign(t2,
11418                             binop(Iop_Add64,
11419                                   getAcc(ac),
11420                                   binop(Iop_Add64, mkexpr(t0), mkexpr(t1))));
11421                      putAcc(ac, mkexpr(t2));
11422                      break;
11423                   }
11424                   case 0x9: {  /* DPSX.W.PH */
11425                      DIP("dpsx.w.ph ac%u r%u, r%u", ac, rs, rt);
11426                      vassert(!mode64);
11427 
11428                      t0 = newTemp(Ity_I64);
11429                      t1 = newTemp(Ity_I64);
11430                      t2 = newTemp(Ity_I64);
11431 
11432                      assign(t0,
11433                             unop(Iop_32Sto64,
11434                                  binop(Iop_Mul32,
11435                                        unop(Iop_16Sto32,
11436                                             unop(Iop_32HIto16, getIReg(rs))),
11437                                        unop(Iop_16Sto32,
11438                                             unop(Iop_32to16, getIReg(rt))))));
11439                      assign(t1,
11440                             unop(Iop_32Sto64,
11441                                  binop(Iop_Mul32,
11442                                        unop(Iop_16Sto32,
11443                                             unop(Iop_32to16, getIReg(rs))),
11444                                        unop(Iop_16Sto32,
11445                                             unop(Iop_32HIto16, getIReg(rt))))));
11446                      assign(t2,
11447                             binop(Iop_Sub64,
11448                                   getAcc(ac),
11449                                   binop(Iop_Add64, mkexpr(t0), mkexpr(t1))));
11450                      putAcc(ac, mkexpr(t2));
11451                      break;
11452                   }
11453                   case 0xB: {  /* DPSU.H.QBL */
11454                      DIP("dpsu.h.qbl ac%u, r%u, r%u", ac, rs, rt);
11455                      vassert(!mode64);
11456 
11457                      t0 = newTemp(Ity_I32);
11458                      t1 = newTemp(Ity_I32);
11459                      t2 = newTemp(Ity_I64);
11460                      t3 = newTemp(Ity_I64);
11461 
11462                      assign(t0,
11463                             binop(Iop_Mul32,
11464                                   unop(Iop_8Uto32,
11465                                        unop(Iop_16HIto8,
11466                                             unop(Iop_32HIto16, getIReg(rs)))),
11467                                   unop(Iop_8Uto32,
11468                                        unop(Iop_16HIto8,
11469                                             unop(Iop_32HIto16, getIReg(rt))))));
11470                      assign(t1,
11471                             binop(Iop_Mul32,
11472                                   unop(Iop_8Uto32,
11473                                        unop(Iop_16to8,
11474                                             unop(Iop_32HIto16, getIReg(rs)))),
11475                                   unop(Iop_8Uto32,
11476                                        unop(Iop_16to8,
11477                                             unop(Iop_32HIto16, getIReg(rt))))));
11478                      assign(t2,
11479                             unop(Iop_32Uto64,
11480                                  binop(Iop_Add32, mkexpr(t0), mkexpr(t1))));
11481                      assign(t3,
11482                             binop(Iop_Sub64, getAcc(ac), mkexpr(t2)));
11483                      putAcc(ac, mkexpr(t3));
11484                      break;
11485                   }
11486                   case 0xC: {  /* DPAQ_SA.L.W */
11487                      DIP("dpaq_sa.l.w ac%u, r%u, r%u", ac, rs, rt);
11488                      vassert(!mode64);
11489                      t0 = newTemp(Ity_I64);
11490                      t1 = newTemp(Ity_I64);
11491                      t2 = newTemp(Ity_I1);
11492                      t3 = newTemp(Ity_I1);
11493                      t4 = newTemp(Ity_I64);
11494                      t5 = newTemp(Ity_I64);
11495                      t6 = newTemp(Ity_I64);
11496                      t7 = newTemp(Ity_I64);
11497                      t8 = newTemp(Ity_I1);
11498                      t9 = newTemp(Ity_I1);
11499 
11500                      assign(t0, getAcc(ac));
11501 
11502                      assign(t1, binop(Iop_Shl64,
11503                                       binop(Iop_MullS32,
11504                                             getIReg(rs), getIReg(rt)),
11505                                       mkU8(0x1)));
11506 
11507                      assign(t2, binop(Iop_CmpEQ32,
11508                                       getIReg(rs),
11509                                       mkU32(0x80000000)));
11510                      assign(t3, binop(Iop_CmpEQ32,
11511                                       getIReg(rt),
11512                                       mkU32(0x80000000)));
11513 
11514                      assign(t4,
11515                             IRExpr_ITE(mkexpr(t2),
11516                                        IRExpr_ITE(mkexpr(t3),
11517                                                   mkU64(0x7fffffffffffffffULL),
11518                                                   mkexpr(t1)),
11519                                        mkexpr(t1)));
11520 
11521                      putDSPControl(IRExpr_ITE(mkexpr(t2),
11522                                               IRExpr_ITE(mkexpr(t3),
11523                                                          binop(Iop_Or32,
11524                                                                getDSPControl(),
11525                                                                binop(Iop_Shl32,
11526                                                                      mkU32(0x1),
11527                                                                      mkU8(ac+16)
11528                                                                     )
11529                                                               ),
11530                                                          getDSPControl()),
11531                                               getDSPControl()));
11532 
11533                      assign(t5, binop(Iop_Add64,
11534                                       unop(Iop_32Uto64,
11535                                            unop(Iop_64to32, mkexpr(t0))),
11536                                       unop(Iop_32Uto64,
11537                                            unop(Iop_64to32, mkexpr(t4)))));
11538                      assign(t6,
11539                             binop(Iop_Add64,
11540                                   binop(Iop_Add64,
11541                                         unop(Iop_32Sto64,
11542                                              unop(Iop_64HIto32, mkexpr(t0))),
11543                                         unop(Iop_32Sto64,
11544                                              unop(Iop_64HIto32, mkexpr(t4)))),
11545                                   unop(Iop_32Uto64,
11546                                        binop(Iop_And32,
11547                                              unop(Iop_64HIto32, mkexpr(t5)),
11548                                              mkU32(0x1)))));
11549                      assign(t7, binop(Iop_32HLto64,
11550                                       unop(Iop_64to32, mkexpr(t6)),
11551                                       unop(Iop_64to32, mkexpr(t5))));
11552                      assign(t8, binop(Iop_CmpEQ32,
11553                                       binop(Iop_Shr32,
11554                                             binop(Iop_And32,
11555                                                   unop(Iop_64to32, mkexpr(t6)),
11556                                                   mkU32(0x80000000)),
11557                                             mkU8(31)),
11558                                       binop(Iop_And32,
11559                                             unop(Iop_64HIto32, mkexpr(t6)),
11560                                             mkU32(0x00000001))));
11561                      assign(t9, binop(Iop_CmpEQ32,
11562                                       binop(Iop_And32,
11563                                             unop(Iop_64HIto32,
11564                                                  mkexpr(t6)),
11565                                             mkU32(0x00000001)),
11566                                       mkU32(0x1)));
11567                      putDSPControl(IRExpr_ITE(mkexpr(t8),
11568                                               getDSPControl(),
11569                                               binop(Iop_Or32,
11570                                                     getDSPControl(),
11571                                                     binop(Iop_Shl32,
11572                                                           mkU32(0x1),
11573                                                           mkU8(ac+16)))));
11574                      putAcc(ac,
11575                             IRExpr_ITE(mkexpr(t8),
11576                                        mkexpr(t7),
11577                                        IRExpr_ITE(mkexpr(t9),
11578                                                   mkU64(0x8000000000000000ULL),
11579                                                   mkU64(0x7fffffffffffffffULL)))
11580                            );
11581                      break;
11582                   }
11583                   case 0xD: {  /* DPSQ_SA.L.W */
11584                      DIP("dpsq_sa.l.w ac%u, r%u, r%u", ac, rs, rt);
11585                      vassert(!mode64);
11586                      t0 = newTemp(Ity_I64);
11587                      t1 = newTemp(Ity_I64);
11588                      t2 = newTemp(Ity_I1);
11589                      t3 = newTemp(Ity_I1);
11590                      t4 = newTemp(Ity_I64);
11591                      t5 = newTemp(Ity_I64);
11592                      t6 = newTemp(Ity_I64);
11593                      t7 = newTemp(Ity_I64);
11594                      t8 = newTemp(Ity_I1);
11595                      t9 = newTemp(Ity_I1);
11596 
11597                      assign(t0, getAcc(ac));
11598 
11599                      assign(t1, binop(Iop_Shl64,
11600                                       binop(Iop_MullS32,
11601                                             getIReg(rs), getIReg(rt)),
11602                                       mkU8(0x1)));
11603 
11604                      assign(t2, binop(Iop_CmpEQ32,
11605                                       getIReg(rs),
11606                                       mkU32(0x80000000)));
11607                      assign(t3, binop(Iop_CmpEQ32,
11608                                       getIReg(rt),
11609                                       mkU32(0x80000000)));
11610 
11611                      assign(t4,
11612                             IRExpr_ITE(mkexpr(t2),
11613                                        IRExpr_ITE(mkexpr(t3),
11614                                                   mkU64(0x7fffffffffffffffULL),
11615                                                   mkexpr(t1)),
11616                                        mkexpr(t1)));
11617 
11618                      putDSPControl(IRExpr_ITE(mkexpr(t2),
11619                                               IRExpr_ITE(mkexpr(t3),
11620                                                          binop(Iop_Or32,
11621                                                                getDSPControl(),
11622                                                                binop(Iop_Shl32,
11623                                                                      mkU32(0x1),
11624                                                                      mkU8(ac+16)
11625                                                                     )
11626                                                               ),
11627                                                          getDSPControl()),
11628                                               getDSPControl()));
11629 
11630                      assign(t5, binop(Iop_Sub64,
11631                                       unop(Iop_32Uto64,
11632                                            unop(Iop_64to32, mkexpr(t0))),
11633                                       unop(Iop_32Uto64,
11634                                            unop(Iop_64to32, mkexpr(t4)))));
11635                      assign(t6, binop(Iop_Sub64,
11636                                       binop(Iop_Add64,
11637                                             unop(Iop_32Sto64,
11638                                                  unop(Iop_64HIto32, mkexpr(t0))
11639                                                 ),
11640                                             unop(Iop_32Sto64,
11641                                                  unop(Iop_1Sto32,
11642                                                       binop(Iop_CmpLT32U,
11643                                                             unop(Iop_64to32,
11644                                                                  mkexpr(t0)),
11645                                                             unop(Iop_64to32,
11646                                                                 mkexpr(t4)))))),
11647                                       unop(Iop_32Sto64,
11648                                            unop(Iop_64HIto32, mkexpr(t4)))));
11649                      assign(t7, binop(Iop_32HLto64,
11650                                       unop(Iop_64to32, mkexpr(t6)),
11651                                       unop(Iop_64to32, mkexpr(t5))));
11652                      assign(t8, binop(Iop_CmpEQ32,
11653                                       binop(Iop_Shr32,
11654                                             binop(Iop_And32,
11655                                                   unop(Iop_64to32, mkexpr(t6)),
11656                                                   mkU32(0x80000000)),
11657                                             mkU8(31)),
11658                                       binop(Iop_And32,
11659                                             unop(Iop_64HIto32, mkexpr(t6)),
11660                                             mkU32(0x00000001))));
11661                      assign(t9, binop(Iop_CmpEQ32,
11662                                       binop(Iop_And32,
11663                                             unop(Iop_64HIto32, mkexpr(t6)),
11664                                             mkU32(0x00000001)),
11665                                       mkU32(0x1)));
11666                      putDSPControl(IRExpr_ITE(mkexpr(t8),
11667                                               getDSPControl(),
11668                                               binop(Iop_Or32,
11669                                                     getDSPControl(),
11670                                                     binop(Iop_Shl32,
11671                                                           mkU32(0x1),
11672                                                           mkU8(ac+16)))));
11673                      putAcc(ac,
11674                             IRExpr_ITE(mkexpr(t8),
11675                                        mkexpr(t7),
11676                                        IRExpr_ITE(mkexpr(t9),
11677                                                   mkU64(0x8000000000000000ULL),
11678                                                   mkU64(0x7fffffffffffffffULL)))
11679                            );
11680                      break;
11681                   }
11682                   case 0xF: {  /* DPSU.H.QBR */
11683                      DIP("dpsu.h.qbr ac%u r%u, r%u", ac, rs, rt);
11684                      vassert(!mode64);
11685 
11686                      t0 = newTemp(Ity_I32);
11687                      t1 = newTemp(Ity_I32);
11688                      t2 = newTemp(Ity_I64);
11689                      t3 = newTemp(Ity_I64);
11690 
11691                      assign(t0,
11692                             binop(Iop_Mul32,
11693                                   unop(Iop_8Uto32,
11694                                        unop(Iop_16HIto8,
11695                                             unop(Iop_32to16, getIReg(rs)))),
11696                                   unop(Iop_8Uto32,
11697                                        unop(Iop_16HIto8,
11698                                             unop(Iop_32to16, getIReg(rt))))));
11699                      assign(t1,
11700                             binop(Iop_Mul32,
11701                                   unop(Iop_8Uto32,
11702                                        unop(Iop_16to8,
11703                                             unop(Iop_32to16, getIReg(rs)))),
11704                                   unop(Iop_8Uto32,
11705                                        unop(Iop_16to8,
11706                                             unop(Iop_32to16, getIReg(rt))))));
11707                      assign(t2, unop(Iop_32Uto64,
11708                                      binop(Iop_Add32, mkexpr(t0), mkexpr(t1))));
11709                      assign(t3, binop(Iop_Sub64, getAcc(ac), mkexpr(t2)));
11710                      putAcc(ac, mkexpr(t3));
11711 
11712                      break;
11713                   }
11714                   case 0x10: {  /* MAQ_SA.W.PHL */
11715                      DIP("maq_sa.w.phl ac%u, r%u, r%u", ac, rs, rt);
11716                      vassert(!mode64);
11717                      t0 = newTemp(Ity_I64);
11718                      t1 = newTemp(Ity_I64);
11719                      t2 = newTemp(Ity_I1);
11720                      t3 = newTemp(Ity_I1);
11721                      t4 = newTemp(Ity_I64);
11722                      t5 = newTemp(Ity_I64);
11723                      t6 = newTemp(Ity_I1);
11724                      t7 = newTemp(Ity_I64);
11725 
11726                      assign(t0, getAcc(ac));
11727                      assign(t1, unop(Iop_32Sto64,
11728                                      binop(Iop_Shl32,
11729                                            binop(Iop_Mul32,
11730                                                  unop(Iop_16Sto32,
11731                                                       unop(Iop_32HIto16,
11732                                                            getIReg(rs))),
11733                                                  unop(Iop_16Sto32,
11734                                                       unop(Iop_32HIto16,
11735                                                            getIReg(rt)))),
11736                                            mkU8(0x1))));
11737 
11738                      /* If both input arguments are equal 0x8000, saturate
11739                         intermediate product and write to DSPControl register.
11740                      */
11741                      assign(t2, binop(Iop_CmpEQ32,
11742                                       unop(Iop_16Uto32,
11743                                            unop(Iop_32HIto16, getIReg(rs))),
11744                                       mkU32(0x00008000)));
11745                      assign(t3, binop(Iop_CmpEQ32,
11746                                       unop(Iop_16Uto32,
11747                                            unop(Iop_32HIto16, getIReg(rt))),
11748                                       mkU32(0x00008000)));
11749 
11750                      assign(t4,
11751                             IRExpr_ITE(mkexpr(t2),
11752                                        IRExpr_ITE(mkexpr(t3),
11753                                                   mkU64(0x000000007fffffffULL),
11754                                                   mkexpr(t1)),
11755                                        mkexpr(t1)));
11756 
11757                      putDSPControl(IRExpr_ITE(mkexpr(t2),
11758                                               IRExpr_ITE(mkexpr(t3),
11759                                                          binop(Iop_Or32,
11760                                                                getDSPControl(),
11761                                                                binop(Iop_Shl32,
11762                                                                      mkU32(0x1),
11763                                                                      mkU8(ac+16)
11764                                                                     )
11765                                                               ),
11766                                                          getDSPControl()),
11767                                               getDSPControl()));
11768                      /* Add intermediate product and value in the
11769                         accumulator. */
11770                      assign(t5, binop(Iop_Add64, mkexpr(t0), mkexpr(t4)));
11771 
11772                      /* Compare bits 31 and 32 of the value in t5. */
11773                      assign(t6, binop(Iop_CmpEQ32,
11774                                       binop(Iop_Shr32,
11775                                             binop(Iop_And32,
11776                                                   unop(Iop_64to32, mkexpr(t5)),
11777                                                   mkU32(0x80000000)),
11778                                             mkU8(31)),
11779                                       binop(Iop_And32,
11780                                             unop(Iop_64HIto32, mkexpr(t5)),
11781                                             mkU32(1))));
11782                      putDSPControl(IRExpr_ITE(mkexpr(t6),
11783                                               getDSPControl(),
11784                                               binop(Iop_Or32,
11785                                                     getDSPControl(),
11786                                                     binop(Iop_Shl32,
11787                                                           mkU32(0x1),
11788                                                           mkU8(ac+16)))));
11789                      assign(t7,
11790                             IRExpr_ITE(mkexpr(t6),
11791                                        mkexpr(t5),
11792                                        IRExpr_ITE(binop(Iop_CmpEQ32,
11793                                                         binop(Iop_And32,
11794                                                               unop(Iop_64HIto32,
11795                                                                    mkexpr(t5)),
11796                                                               mkU32(1)),
11797                                                         mkU32(0x0)),
11798                                                   mkU64(0x000000007fffffffULL),
11799                                                   mkU64(0xffffffff80000000ULL)))
11800                            );
11801                      putAcc(ac, mkexpr(t7));
11802                      break;
11803                   }
11804                   case 0x12: {  /* MAQ_SA.W.PHR */
11805                      DIP("maq_sa.w.phr ac%u, r%u, r%u", ac, rs, rt);
11806                      vassert(!mode64);
11807                      t0 = newTemp(Ity_I64);
11808                      t1 = newTemp(Ity_I64);
11809                      t2 = newTemp(Ity_I1);
11810                      t3 = newTemp(Ity_I1);
11811                      t4 = newTemp(Ity_I64);
11812                      t5 = newTemp(Ity_I64);
11813                      t6 = newTemp(Ity_I1);
11814                      t7 = newTemp(Ity_I64);
11815 
11816                      assign(t0, getAcc(ac));
11817                      assign(t1, unop(Iop_32Sto64,
11818                                      binop(Iop_Shl32,
11819                                            binop(Iop_Mul32,
11820                                                  unop(Iop_16Sto32,
11821                                                       unop(Iop_32to16,
11822                                                            getIReg(rs))),
11823                                                  unop(Iop_16Sto32,
11824                                                       unop(Iop_32to16,
11825                                                            getIReg(rt)))),
11826                                            mkU8(0x1))));
11827 
11828                      /* If both input arguments are equal 0x8000, saturate
11829                         intermediate product and write to DSPControl
11830                         register. */
11831                      assign(t2, binop(Iop_CmpEQ32,
11832                                       unop(Iop_16Uto32,
11833                                            unop(Iop_32to16, getIReg(rs))),
11834                                       mkU32(0x00008000)));
11835                      assign(t3, binop(Iop_CmpEQ32,
11836                                       unop(Iop_16Uto32,
11837                                            unop(Iop_32to16, getIReg(rt))),
11838                                       mkU32(0x00008000)));
11839 
11840                      assign(t4,
11841                             IRExpr_ITE(mkexpr(t2),
11842                                        IRExpr_ITE(mkexpr(t3),
11843                                                   mkU64(0x000000007fffffffULL),
11844                                                   mkexpr(t1)),
11845                                        mkexpr(t1)));
11846 
11847                      putDSPControl(IRExpr_ITE(mkexpr(t2),
11848                                               IRExpr_ITE(mkexpr(t3),
11849                                                          binop(Iop_Or32,
11850                                                                getDSPControl(),
11851                                                                binop(Iop_Shl32,
11852                                                                      mkU32(0x1),
11853                                                                      mkU8(ac+16)
11854                                                                     )
11855                                                               ),
11856                                                          getDSPControl()),
11857                                               getDSPControl()));
11858                      /* Add intermediate product and value in the
11859                         accumulator. */
11860                      assign(t5, binop(Iop_Add64, mkexpr(t0), mkexpr(t4)));
11861 
11862                      /* Compare bits 31 and 32 of the value in t5. */
11863                      assign(t6, binop(Iop_CmpEQ32,
11864                                       binop(Iop_Shr32,
11865                                             binop(Iop_And32,
11866                                                   unop(Iop_64to32, mkexpr(t5)),
11867                                                   mkU32(0x80000000)),
11868                                             mkU8(31)),
11869                                       binop(Iop_And32,
11870                                             unop(Iop_64HIto32, mkexpr(t5)),
11871                                             mkU32(1))));
11872                      putDSPControl(IRExpr_ITE(mkexpr(t6),
11873                                               getDSPControl(),
11874                                               binop(Iop_Or32,
11875                                                     getDSPControl(),
11876                                                     binop(Iop_Shl32,
11877                                                           mkU32(0x1),
11878                                                           mkU8(ac+16)))));
11879                      assign(t7,
11880                             IRExpr_ITE(mkexpr(t6),
11881                                        mkexpr(t5),
11882                                        IRExpr_ITE(binop(Iop_CmpEQ32,
11883                                                         binop(Iop_And32,
11884                                                               unop(Iop_64HIto32,
11885                                                                    mkexpr(t5)),
11886                                                               mkU32(1)),
11887                                                         mkU32(0x0)),
11888                                                   mkU64(0x000000007fffffffULL),
11889                                                   mkU64(0xffffffff80000000ULL)))
11890                            );
11891                      putAcc(ac, mkexpr(t7));
11892                      break;
11893                   }
11894                   case 0x14: {  /* MAQ_S.W.PHL */
11895                      DIP("maq_s.w.phl ac%u, r%u, r%u", ac, rs, rt);
11896                      vassert(!mode64);
11897                      t0 = newTemp(Ity_I32);
11898                      t1 = newTemp(Ity_I32);
11899                      t2 = newTemp(Ity_I32);
11900                      t3 = newTemp(Ity_I1);
11901                      t4 = newTemp(Ity_I32);
11902                      t5 = newTemp(Ity_I64);
11903 
11904                      assign(t5, getAcc(ac));
11905 
11906                      assign(t0, unop(Iop_16Sto32,
11907                                      unop(Iop_32HIto16, getIReg(rs))));
11908                      assign(t1, unop(Iop_16Sto32,
11909                                      unop(Iop_32HIto16, getIReg(rt))));
11910 
11911                      assign(t2, binop(Iop_And32,
11912                                       unop(Iop_1Sto32,
11913                                            binop(Iop_CmpEQ32,
11914                                                  binop(Iop_And32,
11915                                                        mkexpr(t0),
11916                                                        mkU32(0xffff)),
11917                                                  mkU32(0x8000))),
11918                                       unop(Iop_1Sto32,
11919                                            binop(Iop_CmpEQ32,
11920                                                  binop(Iop_And32,
11921                                                        mkexpr(t1),
11922                                                        mkU32(0xffff)),
11923                                                  mkU32(0x8000)))));
11924 
11925                      assign(t3, binop(Iop_CmpEQ32, mkexpr(t2), mkU32(0x0)));
11926 
11927                      putDSPControl(IRExpr_ITE(mkexpr(t3),
11928                                               getDSPControl(),
11929                                               binop(Iop_Or32,
11930                                                     getDSPControl(),
11931                                                     binop(Iop_Shl32,
11932                                                           mkU32(0x1),
11933                                                           mkU8(ac+16)))));
11934 
11935                      assign(t4, unop(Iop_64to32,
11936                                      binop(Iop_MullS32,
11937                                            mkexpr(t0), mkexpr(t1))));
11938                      putAcc(ac, IRExpr_ITE(mkexpr(t3),
11939                                            binop(Iop_Add64,
11940                                                  unop(Iop_32Sto64,
11941                                                       binop(Iop_Shl32,
11942                                                             mkexpr(t4),
11943                                                             mkU8(0x1))),
11944                                                  mkexpr(t5)),
11945                                            binop(Iop_Add64,
11946                                                  mkexpr(t5),
11947                                                  unop(Iop_32Sto64,
11948                                                       mkU32(0x7fffffff)))));
11949                      break;
11950                   }
11951                   case 0x16: {  /* MAQ_S.W.PHR */
11952                      DIP("maq_s.w.phr ac%u, r%u, r%u", ac, rs, rt);
11953                      vassert(!mode64);
11954                      t0 = newTemp(Ity_I32);
11955                      t1 = newTemp(Ity_I32);
11956                      t2 = newTemp(Ity_I32);
11957                      t3 = newTemp(Ity_I1);
11958                      t4 = newTemp(Ity_I32);
11959                      t5 = newTemp(Ity_I64);
11960 
11961                      assign(t5, getAcc(ac));
11962 
11963                      assign(t0, unop(Iop_16Sto32,
11964                                      unop(Iop_32to16, getIReg(rs))));
11965                      assign(t1, unop(Iop_16Sto32,
11966                                      unop(Iop_32to16, getIReg(rt))));
11967 
11968                      assign(t2, binop(Iop_And32,
11969                                       unop(Iop_1Sto32,
11970                                            binop(Iop_CmpEQ32,
11971                                                  binop(Iop_And32,
11972                                                        mkexpr(t0),
11973                                                        mkU32(0xffff)),
11974                                                  mkU32(0x8000))),
11975                                       unop(Iop_1Sto32,
11976                                            binop(Iop_CmpEQ32,
11977                                                  binop(Iop_And32,
11978                                                        mkexpr(t1),
11979                                                        mkU32(0xffff)),
11980                                                  mkU32(0x8000)))));
11981 
11982                      assign(t3, binop(Iop_CmpEQ32, mkexpr(t2), mkU32(0x0)));
11983 
11984                      putDSPControl(IRExpr_ITE(mkexpr(t3),
11985                                               getDSPControl(),
11986                                               binop(Iop_Or32,
11987                                                     getDSPControl(),
11988                                                     binop(Iop_Shl32,
11989                                                           mkU32(0x1),
11990                                                           mkU8(ac+16)))));
11991 
11992                      assign(t4, unop(Iop_64to32,
11993                                      binop(Iop_MullS32,
11994                                            mkexpr(t0), mkexpr(t1))));
11995                      putAcc(ac, IRExpr_ITE(mkexpr(t3),
11996                                            binop(Iop_Add64,
11997                                                  unop(Iop_32Sto64,
11998                                                       binop(Iop_Shl32,
11999                                                             mkexpr(t4),
12000                                                             mkU8(0x1))),
12001                                                  mkexpr(t5)),
12002                                            binop(Iop_Add64,
12003                                                  mkexpr(t5),
12004                                                  unop(Iop_32Sto64,
12005                                                       mkU32(0x7fffffff)))));
12006                      break;
12007                   }
12008                   case 0x18: {  /* DPAQX_S.W.PH */
12009                      DIP("dpaqx_s.w.ph ac%u, r%u, r%u", ac, rs, rt);
12010                      vassert(!mode64);
12011                      t0 = newTemp(Ity_I64);
12012                      t1 = newTemp(Ity_I64);
12013                      t2 = newTemp(Ity_I1);
12014                      t3 = newTemp(Ity_I1);
12015                      t4 = newTemp(Ity_I64);
12016                      t5 = newTemp(Ity_I64);
12017                      t6 = newTemp(Ity_I1);
12018                      t7 = newTemp(Ity_I1);
12019                      t8 = newTemp(Ity_I64);
12020                      t9 = newTemp(Ity_I64);
12021 
12022                      assign(t0, getAcc(ac));
12023 
12024                      assign(t1, binop(Iop_Shl64,
12025                                       binop(Iop_MullS32,
12026                                             unop(Iop_16Sto32,
12027                                                  unop(Iop_32HIto16,
12028                                                       getIReg(rs))),
12029                                             unop(Iop_16Sto32,
12030                                                  unop(Iop_32to16,
12031                                                       getIReg(rt)))),
12032                                       mkU8(0x1)));
12033                      assign(t2, binop(Iop_CmpEQ32,
12034                                       unop(Iop_16Uto32,
12035                                            unop(Iop_32HIto16, getIReg(rs))),
12036                                       mkU32(0x00008000)));
12037                      assign(t3, binop(Iop_CmpEQ32,
12038                                       unop(Iop_16Uto32,
12039                                            unop(Iop_32to16, getIReg(rt))),
12040                                       mkU32(0x00008000)));
12041                      assign(t4,
12042                             IRExpr_ITE(mkexpr(t2),
12043                                        IRExpr_ITE(mkexpr(t3),
12044                                                   mkU64(0x000000007fffffffULL),
12045                                                   mkexpr(t1)),
12046                                        mkexpr(t1)));
12047 
12048                      putDSPControl(IRExpr_ITE(mkexpr(t2),
12049                                               IRExpr_ITE(mkexpr(t3),
12050                                                          binop(Iop_Or32,
12051                                                                getDSPControl(),
12052                                                                binop(Iop_Shl32,
12053                                                                   mkU32(0x1),
12054                                                                   mkU8(ac+16))),
12055                                                          getDSPControl()),
12056                                               getDSPControl()));
12057 
12058                      assign(t5, binop(Iop_Shl64,
12059                                       binop(Iop_MullS32,
12060                                             unop(Iop_16Sto32,
12061                                                  unop(Iop_32to16,
12062                                                       getIReg(rs))),
12063                                             unop(Iop_16Sto32,
12064                                                  unop(Iop_32HIto16,
12065                                                       getIReg(rt)))),
12066                                       mkU8(0x1)));
12067                      assign(t6, binop(Iop_CmpEQ32,
12068                                       unop(Iop_16Uto32,
12069                                            unop(Iop_32to16, getIReg(rs))),
12070                                       mkU32(0x00008000)));
12071                      assign(t7, binop(Iop_CmpEQ32,
12072                                       unop(Iop_16Uto32,
12073                                            unop(Iop_32HIto16, getIReg(rt))),
12074                                       mkU32(0x00008000)));
12075                      assign(t8,
12076                             IRExpr_ITE(mkexpr(t6),
12077                                        IRExpr_ITE(mkexpr(t7),
12078                                                   mkU64(0x000000007fffffffULL),
12079                                                   mkexpr(t5)),
12080                                        mkexpr(t5)));
12081 
12082                      putDSPControl(IRExpr_ITE(mkexpr(t6),
12083                                               IRExpr_ITE(mkexpr(t7),
12084                                                          binop(Iop_Or32,
12085                                                                getDSPControl(),
12086                                                                binop(Iop_Shl32,
12087                                                                      mkU32(0x1),
12088                                                                      mkU8(ac+16)
12089                                                                     )
12090                                                               ),
12091                                                          getDSPControl()),
12092                                               getDSPControl()));
12093 
12094                      assign(t9, binop(Iop_Add64,
12095                                       binop(Iop_Add64, mkexpr(t4), mkexpr(t8)),
12096                                       mkexpr(t0)));
12097                      putAcc(ac, mkexpr(t9));
12098                      break;
12099                   }
12100                   case 0x19: {  /* DPSQX_S.W.PH */
12101                      DIP("dpsqx_s.w.ph ac%u, r%u, r%u", ac, rs, rt);
12102                      vassert(!mode64);
12103                      t0 = newTemp(Ity_I64);
12104                      t1 = newTemp(Ity_I64);
12105                      t2 = newTemp(Ity_I1);
12106                      t3 = newTemp(Ity_I1);
12107                      t4 = newTemp(Ity_I64);
12108                      t5 = newTemp(Ity_I64);
12109                      t6 = newTemp(Ity_I1);
12110                      t7 = newTemp(Ity_I1);
12111                      t8 = newTemp(Ity_I64);
12112                      t9 = newTemp(Ity_I64);
12113 
12114                      assign(t0, getAcc(ac));
12115 
12116                      assign(t1, binop(Iop_Shl64,
12117                                       binop(Iop_MullS32,
12118                                             unop(Iop_16Sto32,
12119                                                  unop(Iop_32HIto16,
12120                                                       getIReg(rs))),
12121                                             unop(Iop_16Sto32,
12122                                                  unop(Iop_32to16,
12123                                                       getIReg(rt)))),
12124                                       mkU8(0x1)));
12125                      assign(t2, binop(Iop_CmpEQ32,
12126                                       unop(Iop_16Uto32,
12127                                            unop(Iop_32HIto16, getIReg(rs))),
12128                                       mkU32(0x00008000)));
12129                      assign(t3, binop(Iop_CmpEQ32,
12130                                       unop(Iop_16Uto32,
12131                                            unop(Iop_32to16, getIReg(rt))),
12132                                       mkU32(0x00008000)));
12133                      assign(t4,
12134                             IRExpr_ITE(mkexpr(t2),
12135                                        IRExpr_ITE(mkexpr(t3),
12136                                                   mkU64(0x000000007fffffffULL),
12137                                                   mkexpr(t1)),
12138                                        mkexpr(t1)));
12139 
12140                      putDSPControl(IRExpr_ITE(mkexpr(t2),
12141                                               IRExpr_ITE(mkexpr(t3),
12142                                                          binop(Iop_Or32,
12143                                                                getDSPControl(),
12144                                                                binop(Iop_Shl32,
12145                                                                      mkU32(0x1),
12146                                                                      mkU8(ac+16)
12147                                                                     )
12148                                                               ),
12149                                                          getDSPControl()),
12150                                               getDSPControl()));
12151 
12152                      assign(t5, binop(Iop_Shl64,
12153                                       binop(Iop_MullS32,
12154                                             unop(Iop_16Sto32,
12155                                                  unop(Iop_32to16,
12156                                                       getIReg(rs))),
12157                                             unop(Iop_16Sto32,
12158                                                  unop(Iop_32HIto16,
12159                                                       getIReg(rt)))),
12160                                       mkU8(0x1)));
12161                      assign(t6, binop(Iop_CmpEQ32,
12162                                       unop(Iop_16Uto32,
12163                                            unop(Iop_32to16, getIReg(rs))),
12164                                       mkU32(0x00008000)));
12165                      assign(t7, binop(Iop_CmpEQ32,
12166                                       unop(Iop_16Uto32,
12167                                            unop(Iop_32HIto16, getIReg(rt))),
12168                                       mkU32(0x00008000)));
12169                      assign(t8,
12170                             IRExpr_ITE(mkexpr(t6),
12171                                        IRExpr_ITE(mkexpr(t7),
12172                                                   mkU64(0x000000007fffffffULL),
12173                                                   mkexpr(t5)),
12174                                        mkexpr(t5)));
12175 
12176                      putDSPControl(IRExpr_ITE(mkexpr(t6),
12177                                               IRExpr_ITE(mkexpr(t7),
12178                                                          binop(Iop_Or32,
12179                                                                getDSPControl(),
12180                                                                binop(Iop_Shl32,
12181                                                                      mkU32(0x1),
12182                                                                      mkU8(ac+16)
12183                                                                     )
12184                                                               ),
12185                                                          getDSPControl()),
12186                                               getDSPControl()));
12187 
12188                      assign(t9, binop(Iop_Sub64,
12189                                      mkexpr(t0),
12190                                      binop(Iop_Add64, mkexpr(t4), mkexpr(t8))));
12191                      putAcc(ac, mkexpr(t9));
12192                      break;
12193                   }
12194                   case 0x1A: {  /* DPAQX_SA.W.PH */
12195                      DIP("dpaqx_sa.w.ph ac%u, r%u, r%u", ac, rs, rt);
12196                      vassert(!mode64);
12197                      t0 = newTemp(Ity_I64);
12198                      t1 = newTemp(Ity_I64);
12199                      t2 = newTemp(Ity_I1);
12200                      t3 = newTemp(Ity_I1);
12201                      t4 = newTemp(Ity_I64);
12202                      t5 = newTemp(Ity_I64);
12203                      t6 = newTemp(Ity_I1);
12204                      t7 = newTemp(Ity_I1);
12205                      t8 = newTemp(Ity_I64);
12206                      t9 = newTemp(Ity_I64);
12207                      t10 = newTemp(Ity_I32);
12208 
12209                      assign(t0, getAcc(ac));
12210                      /* Calculate the first cross dot product and saturate if
12211                         needed. */
12212                      assign(t1, unop(Iop_32Sto64,
12213                                      binop(Iop_Shl32,
12214                                            binop(Iop_Mul32,
12215                                                  unop(Iop_16Sto32,
12216                                                       unop(Iop_32HIto16,
12217                                                            getIReg(rs))),
12218                                                  unop(Iop_16Sto32,
12219                                                       unop(Iop_32to16,
12220                                                            getIReg(rt)))),
12221                                            mkU8(0x1))));
12222 
12223                      /* If both input arguments are equal 0x8000, saturate
12224                         intermediate product and write to DSPControl
12225                         register. */
12226                      assign(t2, binop(Iop_CmpEQ32,
12227                                       unop(Iop_16Uto32,
12228                                            unop(Iop_32HIto16, getIReg(rs))),
12229                                       mkU32(0x00008000)));
12230                      assign(t3, binop(Iop_CmpEQ32,
12231                                       unop(Iop_16Uto32,
12232                                            unop(Iop_32to16, getIReg(rt))),
12233                                       mkU32(0x00008000)));
12234 
12235                      assign(t4, IRExpr_ITE(binop(Iop_CmpNE32,
12236                                                  binop(Iop_And32,
12237                                                        unop(Iop_1Sto32,
12238                                                             mkexpr(t2)),
12239                                                        unop(Iop_1Sto32,
12240                                                             mkexpr(t3))),
12241                                                  mkU32(0)),
12242                                            mkU64(0x000000007fffffffULL),
12243                                            mkexpr(t1)));
12244 
12245                      putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32,
12246                                                     binop(Iop_And32,
12247                                                           unop(Iop_1Sto32,
12248                                                                mkexpr(t2)),
12249                                                           unop(Iop_1Sto32,
12250                                                                mkexpr(t3))),
12251                                                     mkU32(0)),
12252                                               binop(Iop_Or32,
12253                                                     getDSPControl(),
12254                                                     binop(Iop_Shl32,
12255                                                           mkU32(0x1),
12256                                                           mkU8(ac+16))),
12257                                               getDSPControl()));
12258                      /* Calculate second cross dot product and saturate if
12259                         needed. */
12260                      assign(t5, unop(Iop_32Sto64,
12261                                      binop(Iop_Shl32,
12262                                            binop(Iop_Mul32,
12263                                                  unop(Iop_16Sto32,
12264                                                       unop(Iop_32to16,
12265                                                            getIReg(rs))),
12266                                                  unop(Iop_16Sto32,
12267                                                       unop(Iop_32HIto16,
12268                                                            getIReg(rt)))),
12269                                            mkU8(0x1))));
12270 
12271                      /* If both input arguments are equal 0x8000, saturate
12272                         intermediate product and write to DSPControl
12273                         register. */
12274                      assign(t6, binop(Iop_CmpEQ32,
12275                                       unop(Iop_16Uto32,
12276                                            unop(Iop_32to16, getIReg(rs))),
12277                                       mkU32(0x00008000)));
12278                      assign(t7, binop(Iop_CmpEQ32,
12279                                       unop(Iop_16Uto32,
12280                                            unop(Iop_32HIto16, getIReg(rt))),
12281                                       mkU32(0x00008000)));
12282 
12283                      assign(t8, IRExpr_ITE(binop(Iop_CmpNE32,
12284                                                  binop(Iop_And32,
12285                                                        unop(Iop_1Sto32,
12286                                                             mkexpr(t6)),
12287                                                        unop(Iop_1Sto32,
12288                                                             mkexpr(t7))),
12289                                                  mkU32(0)),
12290                                            mkU64(0x000000007fffffffULL),
12291                                            mkexpr(t5)));
12292 
12293                      putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32,
12294                                                     binop(Iop_And32,
12295                                                           unop(Iop_1Sto32,
12296                                                                mkexpr(t6)),
12297                                                           unop(Iop_1Sto32,
12298                                                                mkexpr(t7))),
12299                                                     mkU32(0)),
12300                                               binop(Iop_Or32,
12301                                                     getDSPControl(),
12302                                                     binop(Iop_Shl32,
12303                                                           mkU32(0x1),
12304                                                           mkU8(ac+16))),
12305                                               getDSPControl()));
12306                      /* Subtract intermediate products from value in the
12307                         accumulator. */
12308                      assign(t9,
12309                             binop(Iop_Add64,
12310                                   mkexpr(t0),
12311                                   binop(Iop_Add64, mkexpr(t8), mkexpr(t4))));
12312 
12313                      putAcc(ac,
12314                             IRExpr_ITE(binop(Iop_CmpEQ32,
12315                                              binop(Iop_And32,
12316                                                    unop(Iop_64HIto32,
12317                                                         mkexpr(t9)),
12318                                                    mkU32(0x80000000)),
12319                                              mkU32(0x0)),
12320                                        IRExpr_ITE(binop(Iop_CmpNE32,
12321                                                         unop(Iop_64HIto32,
12322                                                              binop(Iop_Shl64,
12323                                                                    mkexpr(t9),
12324                                                                    mkU8(1))),
12325                                                         mkU32(0x0)),
12326                                                   mkU64(0x000000007fffffffULL),
12327                                                   mkexpr(t9)),
12328                                        IRExpr_ITE(binop(Iop_CmpNE32,
12329                                                         unop(Iop_64HIto32,
12330                                                              binop(Iop_Shl64,
12331                                                                    mkexpr(t9),
12332                                                                    mkU8(1))),
12333                                                         mkU32(0xffffffff)),
12334                                                   mkU64(0xffffffff80000000ULL),
12335                                                   mkexpr(t9))));
12336                      assign(t10, IRExpr_ITE(binop(Iop_CmpEQ32,
12337                                                   unop(Iop_64to32,
12338                                                        mkexpr(t9)),
12339                                                   unop(Iop_64to32,
12340                                                        getAcc(ac))),
12341                                            getDSPControl(),
12342                                            binop(Iop_Or32,
12343                                                  getDSPControl(),
12344                                                  binop(Iop_Shl32,
12345                                                        mkU32(0x1),
12346                                                        mkU8(ac+16)))));
12347                      putDSPControl(IRExpr_ITE(binop(Iop_CmpEQ32,
12348                                                     unop(Iop_64HIto32,
12349                                                          mkexpr(t9)),
12350                                                     unop(Iop_64HIto32,
12351                                                          getAcc(ac))),
12352                                               mkexpr(t10),
12353                                               binop(Iop_Or32,
12354                                                     getDSPControl(),
12355                                                     binop(Iop_Shl32,
12356                                                           mkU32(0x1),
12357                                                           mkU8(ac+16)))));
12358                      break;
12359                   }
12360                   case 0x1B: {  /* DPSQX_SA.W.PH */
12361                      DIP("dpsqx_sa.w.ph ac%u, r%u, r%u", ac, rs, rt);
12362                      vassert(!mode64);
12363                      t0 = newTemp(Ity_I64);
12364                      t1 = newTemp(Ity_I64);
12365                      t2 = newTemp(Ity_I1);
12366                      t3 = newTemp(Ity_I1);
12367                      t4 = newTemp(Ity_I64);
12368                      t5 = newTemp(Ity_I64);
12369                      t6 = newTemp(Ity_I1);
12370                      t7 = newTemp(Ity_I1);
12371                      t8 = newTemp(Ity_I64);
12372                      t9 = newTemp(Ity_I64);
12373                      t10 = newTemp(Ity_I32);
12374 
12375                      assign(t0, getAcc(ac));
12376                      /* Calculate the first cross dot product and saturate if
12377                         needed. */
12378                      assign(t1, unop(Iop_32Sto64,
12379                                      binop(Iop_Shl32,
12380                                            binop(Iop_Mul32,
12381                                                  unop(Iop_16Sto32,
12382                                                       unop(Iop_32HIto16,
12383                                                            getIReg(rs))),
12384                                                  unop(Iop_16Sto32,
12385                                                       unop(Iop_32to16,
12386                                                            getIReg(rt)))),
12387                                            mkU8(0x1))));
12388 
12389                      /* If both input arguments are equal 0x8000, saturate
12390                         intermediate product and write to DSPControl
12391                         register. */
12392                      assign(t2, binop(Iop_CmpEQ32,
12393                                       unop(Iop_16Uto32,
12394                                            unop(Iop_32HIto16, getIReg(rs))),
12395                                       mkU32(0x00008000)));
12396                      assign(t3, binop(Iop_CmpEQ32,
12397                                       unop(Iop_16Uto32,
12398                                            unop(Iop_32to16, getIReg(rt))),
12399                                       mkU32(0x00008000)));
12400 
12401                      assign(t4, IRExpr_ITE(binop(Iop_CmpNE32,
12402                                                  binop(Iop_And32,
12403                                                        unop(Iop_1Sto32,
12404                                                             mkexpr(t2)),
12405                                                        unop(Iop_1Sto32,
12406                                                             mkexpr(t3))),
12407                                                  mkU32(0)),
12408                                            mkU64(0x000000007fffffffULL),
12409                                            mkexpr(t1)));
12410 
12411                      putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32,
12412                                                     binop(Iop_And32,
12413                                                           unop(Iop_1Sto32,
12414                                                                mkexpr(t2)),
12415                                                           unop(Iop_1Sto32,
12416                                                                mkexpr(t3))),
12417                                                     mkU32(0)),
12418                                               binop(Iop_Or32,
12419                                                     getDSPControl(),
12420                                                     binop(Iop_Shl32,
12421                                                           mkU32(0x1),
12422                                                           mkU8(ac+16))),
12423                                               getDSPControl()));
12424                      /* Calculate second cross dot product and saturate if
12425                         needed. */
12426                      assign(t5, unop(Iop_32Sto64,
12427                                      binop(Iop_Shl32,
12428                                            binop(Iop_Mul32,
12429                                                  unop(Iop_16Sto32,
12430                                                       unop(Iop_32to16,
12431                                                            getIReg(rs))),
12432                                                  unop(Iop_16Sto32,
12433                                                       unop(Iop_32HIto16,
12434                                                            getIReg(rt)))),
12435                                            mkU8(0x1))));
12436 
12437                      /* If both input arguments are equal 0x8000, saturate
12438                         intermediate product and write to DSPControl
12439                         register. */
12440                      assign(t6, binop(Iop_CmpEQ32,
12441                                       unop(Iop_16Uto32,
12442                                            unop(Iop_32to16, getIReg(rs))),
12443                                       mkU32(0x00008000)));
12444                      assign(t7, binop(Iop_CmpEQ32,
12445                                       unop(Iop_16Uto32,
12446                                            unop(Iop_32HIto16, getIReg(rt))),
12447                                       mkU32(0x00008000)));
12448 
12449                      assign(t8, IRExpr_ITE(binop(Iop_CmpNE32,
12450                                                  binop(Iop_And32,
12451                                                        unop(Iop_1Sto32,
12452                                                             mkexpr(t6)),
12453                                                        unop(Iop_1Sto32,
12454                                                             mkexpr(t7))),
12455                                                  mkU32(0)),
12456                                            mkU64(0x000000007fffffffULL),
12457                                            mkexpr(t5)));
12458 
12459                      putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32,
12460                                                     binop(Iop_And32,
12461                                                           unop(Iop_1Sto32,
12462                                                                mkexpr(t6)),
12463                                                           unop(Iop_1Sto32,
12464                                                                mkexpr(t7))),
12465                                                     mkU32(0)),
12466                                               binop(Iop_Or32,
12467                                                     getDSPControl(),
12468                                                     binop(Iop_Shl32,
12469                                                           mkU32(0x1),
12470                                                           mkU8(ac+16))),
12471                                               getDSPControl()));
12472                      /* Subtract intermediate products from value in the
12473                         accumulator. */
12474                      assign(t9,
12475                             binop(Iop_Sub64,
12476                                   mkexpr(t0),
12477                                   binop(Iop_Add64, mkexpr(t8), mkexpr(t4))));
12478 
12479                      putAcc(ac,
12480                             IRExpr_ITE(binop(Iop_CmpEQ32,
12481                                              binop(Iop_And32,
12482                                                    unop(Iop_64HIto32,
12483                                                         mkexpr(t9)),
12484                                                    mkU32(0x80000000)),
12485                                              mkU32(0x0)),
12486                                        IRExpr_ITE(binop(Iop_CmpNE32,
12487                                                         unop(Iop_64HIto32,
12488                                                              binop(Iop_Shl64,
12489                                                                    mkexpr(t9),
12490                                                                    mkU8(1))),
12491                                                         mkU32(0x0)),
12492                                                   mkU64(0x000000007fffffffULL),
12493                                                   mkexpr(t9)),
12494                                        IRExpr_ITE(binop(Iop_CmpNE32,
12495                                                         unop(Iop_64HIto32,
12496                                                              binop(Iop_Shl64,
12497                                                                    mkexpr(t9),
12498                                                                    mkU8(1))),
12499                                                         mkU32(0xffffffff)),
12500                                                   mkU64(0xffffffff80000000ULL),
12501                                                   mkexpr(t9))));
12502                      assign(t10, IRExpr_ITE(binop(Iop_CmpEQ32,
12503                                                   unop(Iop_64to32,
12504                                                        mkexpr(t9)),
12505                                                   unop(Iop_64to32,
12506                                                        getAcc(ac))),
12507                                            getDSPControl(),
12508                                            binop(Iop_Or32,
12509                                                  getDSPControl(),
12510                                                  binop(Iop_Shl32,
12511                                                        mkU32(0x1),
12512                                                        mkU8(ac+16)))));
12513                      putDSPControl(IRExpr_ITE(binop(Iop_CmpEQ32,
12514                                                     unop(Iop_64HIto32,
12515                                                          mkexpr(t9)),
12516                                                     unop(Iop_64HIto32,
12517                                                          getAcc(ac))),
12518                                               mkexpr(t10),
12519                                               binop(Iop_Or32,
12520                                                     getDSPControl(),
12521                                                     binop(Iop_Shl32,
12522                                                           mkU32(0x1),
12523                                                           mkU8(ac+16)))));
12524                      break;
12525                   }
12526                   default:
12527                      return -1;
12528                }
12529                break;  /* end of DPAQ.W.PH */
12530             }
12531             case 0x31: {  /* APPEND */
12532                switch(sa) {
12533                   case 0x0: {  /* APPEND */
12534                      DIP("append r%u, r%u, %u", rt, rs, rd);
12535                      vassert(!mode64);
12536                      t1 = newTemp(Ity_I32);
12537                      t2 = newTemp(Ity_I32);
12538                      t3 = newTemp(Ity_I32);
12539 
12540                      assign(t1, binop(Iop_Shl32, getIReg(rt), mkU8(rd)));
12541 
12542                      if (31 == rd) {
12543                         putIReg(rt, binop(Iop_Or32,
12544                                           mkexpr(t1),
12545                                           binop(Iop_And32,
12546                                                 getIReg(rs),
12547                                                 mkU32(0x7fffffff))));
12548                      } else if (1 == rd) {
12549                         putIReg(rt,
12550                                 binop(Iop_Or32,
12551                                       mkexpr(t1),
12552                                       binop(Iop_And32,
12553                                             getIReg(rs), mkU32(0x1))));
12554                      } else {
12555                         assign(t2,
12556                                unop(Iop_Not32,
12557                                     binop(Iop_Shl32,
12558                                           mkU32(0xffffffff), mkU8(rd))));
12559 
12560                         putIReg(rt, binop(Iop_Or32,
12561                                           mkexpr(t1),
12562                                           binop(Iop_And32,
12563                                                 getIReg(rs), mkexpr(t2))));
12564                      }
12565                      break;
12566                   }
12567                   case 0x1: {  /* PREPEND */
12568                      DIP("prepend r%u, r%u, %u", rt, rs, rd);
12569                      vassert(!mode64);
12570                      t1 = newTemp(Ity_I32);
12571                      t2 = newTemp(Ity_I32);
12572                      t3 = newTemp(Ity_I32);
12573 
12574                      if (0 != rd) {
12575                         assign(t1, binop(Iop_Shr32, getIReg(rt), mkU8(rd)));
12576 
12577                         if (31 == rd) {
12578                            putIReg(rt, binop(Iop_Or32,
12579                                              mkexpr(t1),
12580                                              binop(Iop_Shl32,
12581                                                    binop(Iop_And32,
12582                                                          getIReg(rs),
12583                                                          mkU32(0x7fffffff)),
12584                                                    mkU8(1))));
12585                         } else if (1 == rd) {
12586                            putIReg(rt, binop(Iop_Or32,
12587                                              mkexpr(t1),
12588                                              binop(Iop_Shl32,
12589                                                    binop(Iop_And32,
12590                                                          getIReg(rs),
12591                                                          mkU32(0x1)),
12592                                                    mkU8(31))));
12593                         } else {
12594                            assign(t2, binop(Iop_Add32, mkU32(rd), mkU32(0x1)));
12595 
12596                            assign(t3, unop(Iop_Not32,
12597                                            binop(Iop_Shl32,
12598                                                  mkU32(0xffffffff),
12599                                                  unop(Iop_32to8, mkexpr(t2)))));
12600 
12601                            putIReg(rt, binop(Iop_Or32,
12602                                              mkexpr(t1),
12603                                              binop(Iop_Shl32,
12604                                                    binop(Iop_And32,
12605                                                          getIReg(rs),
12606                                                          mkexpr(t3)),
12607                                                    mkU8(32-rd))));
12608                         }
12609                      }
12610                      break;
12611                   }
12612                   case 0x10: {  /* BALIGN */
12613                      DIP("balign r%u, r%u, %u", rt, rs, rd);
12614                      vassert(!mode64);
12615                      t1 = newTemp(Ity_I32);
12616                      t2 = newTemp(Ity_I32);
12617                      t3 = newTemp(Ity_I32);
12618 
12619                      if ((2 != rd) && (0 != rd)) {
12620                         assign(t1, binop(Iop_Shl32,
12621                                          binop(Iop_And32,
12622                                                mkU32(rd), mkU32(0x3)),
12623                                          mkU8(0x3)));
12624                         assign(t2, binop(Iop_Shl32,
12625                                          getIReg(rt),
12626                                          unop(Iop_32to8, mkexpr(t1))));
12627                         assign(t3, binop(Iop_Shr32,
12628                                          getIReg(rs),
12629                                          unop(Iop_32to8,
12630                                               binop(Iop_Shl32,
12631                                                     binop(Iop_Sub32,
12632                                                           mkU32(0x4),
12633                                                           binop(Iop_And32,
12634                                                                 mkU32(rd),
12635                                                                 mkU32(0x3))),
12636                                                     mkU8(0x3)))));
12637                         putIReg(rt, binop(Iop_Or32, mkexpr(t2), mkexpr(t3)));
12638                      }
12639                      break;
12640                   }
12641                   default:
12642                      return -1;
12643                }
12644                break;  /* end of APPEND */
12645             }
12646             default:
12647                return -1;
12648          }
12649          break;
12650       }
12651       default:
12652             return -1;
12653    }
12654    return 0;
12655 }
12656 
msa_I8_logical(UInt cins,UChar wd,UChar ws)12657 static Int msa_I8_logical(UInt cins, UChar wd, UChar ws) {
12658    IRTemp t1, t2;
12659    UShort operation;
12660    UChar i8;
12661 
12662    operation = (cins >> 24) & 3;
12663    i8 = (cins & 0x00FF0000) >> 16;
12664    switch (operation) {
12665       case 0x00: {  /* ANDI.B */
12666             DIP("ANDI.B w%d, w%d, %d", wd, ws, i8);
12667             t1 = newTemp(Ity_V128);
12668             t2 = newTemp(Ity_V128);
12669             ULong tmp = i8;
12670             tmp |= (tmp << 56) | (tmp << 48) | (tmp << 40) |
12671                    (tmp << 32) | (tmp << 24) | (tmp << 16) |
12672                    (tmp << 8);
12673             assign(t1, getWReg(ws));
12674             assign(t2, binop(Iop_64HLtoV128, mkU64(tmp), mkU64(tmp)));
12675             putWReg(wd, binop(Iop_AndV128, mkexpr(t1), mkexpr(t2)));
12676             break;
12677          }
12678 
12679       case 0x01: { /* ORI.B */
12680             DIP("ORI.B w%d, w%d, %d", wd, ws, i8);
12681             t1 = newTemp(Ity_V128);
12682             t2 = newTemp(Ity_V128);
12683             ULong tmp = i8;
12684             tmp |= (tmp << 56) | (tmp << 48) | (tmp << 40) |
12685                    (tmp << 32) | (tmp << 24) | (tmp << 16) |
12686                    (tmp << 8);
12687             assign(t1, getWReg(ws));
12688             assign(t2, binop(Iop_64HLtoV128, mkU64(tmp), mkU64(tmp)));
12689             putWReg(wd, binop(Iop_OrV128, mkexpr(t1), mkexpr(t2)));
12690             break;
12691          }
12692 
12693       case 0x02: { /* NORI.B */
12694             DIP("NORI.B w%d, w%d, %d", wd, ws, i8);
12695             t1 = newTemp(Ity_V128);
12696             t2 = newTemp(Ity_V128);
12697             ULong tmp = i8;
12698             tmp |= (tmp << 56) | (tmp << 48) | (tmp << 40) |
12699                    (tmp << 32) | (tmp << 24) | (tmp << 16) |
12700                    (tmp << 8);
12701             assign(t1, getWReg(ws));
12702             assign(t2, binop(Iop_64HLtoV128, mkU64(tmp), mkU64(tmp)));
12703             putWReg(wd, unop(Iop_NotV128, binop(Iop_OrV128,
12704                                                 mkexpr(t1), mkexpr(t2))));
12705             break;
12706          }
12707 
12708       case 0x03: {  /* XORI.B */
12709             DIP("XORI.B w%d, w%d, %d", wd, ws, i8);
12710             t1 = newTemp(Ity_V128);
12711             t2 = newTemp(Ity_V128);
12712             ULong tmp = i8;
12713             tmp |= (tmp << 56) | (tmp << 48) | (tmp << 40) |
12714                    (tmp << 32) | (tmp << 24) | (tmp << 16) |
12715                    (tmp << 8);
12716             assign(t1, getWReg(ws));
12717             assign(t2, binop(Iop_64HLtoV128, mkU64(tmp), mkU64(tmp)));
12718             putWReg(wd, binop(Iop_XorV128, mkexpr(t1), mkexpr(t2)));
12719             break;
12720          }
12721 
12722       default:
12723          return -1;
12724    }
12725 
12726    return 0;
12727 }
12728 
msa_I8_branch(UInt cins,UChar wd,UChar ws)12729 static Int msa_I8_branch(UInt cins, UChar wd, UChar ws) {
12730    IRTemp t1, t2, t3, t4;
12731    UShort operation;
12732    UChar i8;
12733 
12734    operation = (cins >> 24) & 3;
12735    i8 = (cins & 0x00FF0000) >> 16;
12736    switch (operation) {
12737       case 0x00: { /* BMNZI.B */
12738             DIP("BMNZI.B w%d, w%d, %d", wd, ws, i8);
12739             t1 = newTemp(Ity_V128);
12740             t2 = newTemp(Ity_V128);
12741             t3 = newTemp(Ity_V128);
12742             t4 = newTemp(Ity_V128);
12743             ULong tmp = i8;
12744             tmp |= (tmp << 56) | (tmp << 48) | (tmp << 40) |
12745                    (tmp << 32) | (tmp << 24) | (tmp << 16) |
12746                    (tmp << 8);
12747             assign(t4, binop(Iop_64HLtoV128, mkU64(tmp), mkU64(tmp)));
12748             assign(t1, binop(Iop_AndV128, getWReg(ws), mkexpr(t4)));
12749             assign(t2, binop(Iop_AndV128, getWReg(wd),
12750                                           unop(Iop_NotV128, mkexpr(t4))));
12751             assign(t3, binop(Iop_OrV128, mkexpr(t1), mkexpr(t2)));
12752             putWReg(wd, mkexpr(t3));
12753             break;
12754          }
12755 
12756       case 0x01: { /* BMZI.B */
12757             DIP("BMZI.B w%d, w%d, %d", wd, ws, i8);
12758             t1 = newTemp(Ity_V128);
12759             t2 = newTemp(Ity_V128);
12760             t3 = newTemp(Ity_V128);
12761             t4 = newTemp(Ity_V128);
12762             ULong tmp = i8;
12763             tmp |= (tmp << 56) | (tmp << 48) | (tmp << 40) |
12764                    (tmp << 32) | (tmp << 24) | (tmp << 16) |
12765                    (tmp << 8);
12766             assign(t4, binop(Iop_64HLtoV128, mkU64(tmp), mkU64(tmp)));
12767             assign(t1, binop(Iop_AndV128, getWReg(wd), mkexpr(t4)));
12768             assign(t2, binop(Iop_AndV128, getWReg(ws),
12769                              unop(Iop_NotV128, mkexpr(t4))));
12770             assign(t3, binop(Iop_OrV128, mkexpr(t1), mkexpr(t2)));
12771             putWReg(wd, mkexpr(t3));
12772             break;
12773          }
12774 
12775       case 0x02: { /* BSELI.B */
12776             DIP("BSELI.B w%d, w%d, %d", wd, ws, i8);
12777             t1 = newTemp(Ity_V128);
12778             t2 = newTemp(Ity_V128);
12779             t3 = newTemp(Ity_V128);
12780             t4 = newTemp(Ity_V128);
12781             ULong tmp = i8;
12782             tmp |= (tmp << 56) | (tmp << 48) | (tmp << 40) |
12783                    (tmp << 32) | (tmp << 24) | (tmp << 16) |
12784                    (tmp << 8);
12785             assign(t4, binop(Iop_64HLtoV128, mkU64(tmp), mkU64(tmp)));
12786             assign(t1, binop(Iop_AndV128, getWReg(wd), mkexpr(t4)));
12787             assign(t2, binop(Iop_AndV128, getWReg(ws),
12788                              unop(Iop_NotV128, getWReg(wd))));
12789             assign(t3, binop(Iop_OrV128, mkexpr(t1), mkexpr(t2)));
12790             putWReg(wd, mkexpr(t3));
12791             break;
12792          }
12793 
12794       default:
12795          return -1;
12796    }
12797 
12798    return 0;
12799 }
12800 
msa_I8_shift(UInt cins,UChar wd,UChar ws)12801 static Int msa_I8_shift(UInt cins, UChar wd, UChar ws) {
12802    IRTemp t1, t2;
12803    UShort operation;
12804    UChar i8;
12805 
12806    operation = (cins >> 24) & 3;
12807    i8 = (cins & 0x00FF0000) >> 16;
12808    switch (operation) {
12809       case 0x00: { /* SHF.B */
12810             DIP("SHF.B w%d, w%d, %d", wd, ws, i8);
12811             t1 = newTemp(Ity_V128);
12812             t2 = newTemp(Ity_V128);
12813             assign(t1, getWReg(wd));
12814             assign(t2, getWReg(ws));
12815             Int i;
12816             IRTemp tmp[16];
12817 
12818             for (i = 0; i < 16; i++) {
12819                tmp[i] = newTemp(Ity_I8);
12820                assign(tmp[i],
12821                       binop(Iop_GetElem8x16, mkexpr(t2),
12822                             mkU8(i - (i % 4) +
12823                                  ((i8 >> (i % 4) * 2) & 0x03))));
12824             }
12825 
12826             putWReg(wd, binop(Iop_64HLtoV128,
12827                               binop(Iop_32HLto64,
12828                                     binop(Iop_16HLto32,
12829                                           binop(Iop_8HLto16,
12830                                                 mkexpr(tmp[15]),
12831                                                 mkexpr(tmp[14])),
12832                                           binop(Iop_8HLto16,
12833                                                 mkexpr(tmp[13]),
12834                                                 mkexpr(tmp[12]))),
12835                                     binop(Iop_16HLto32,
12836                                           binop(Iop_8HLto16,
12837                                                 mkexpr(tmp[11]),
12838                                                 mkexpr(tmp[10])),
12839                                           binop(Iop_8HLto16,
12840                                                 mkexpr(tmp[9]),
12841                                                 mkexpr(tmp[8])))),
12842                               binop(Iop_32HLto64,
12843                                     binop(Iop_16HLto32,
12844                                           binop(Iop_8HLto16,
12845                                                 mkexpr(tmp[7]),
12846                                                 mkexpr(tmp[6])),
12847                                           binop(Iop_8HLto16,
12848                                                 mkexpr(tmp[5]),
12849                                                 mkexpr(tmp[4]))),
12850                                     binop(Iop_16HLto32,
12851                                           binop(Iop_8HLto16,
12852                                                 mkexpr(tmp[3]),
12853                                                 mkexpr(tmp[2])),
12854                                           binop(Iop_8HLto16,
12855                                                 mkexpr(tmp[1]),
12856                                                 mkexpr(tmp[0]))))));
12857             break;
12858          }
12859 
12860       case 0x01: { /* SHF.H */
12861             DIP("SHF.H w%d, w%d, %d", wd, ws, i8);
12862             t1 = newTemp(Ity_V128);
12863             t2 = newTemp(Ity_V128);
12864             assign(t1, getWReg(wd));
12865             assign(t2, getWReg(ws));
12866             Int i;
12867             IRTemp tmp[8];
12868 
12869             for (i = 0; i < 8; i++) {
12870                tmp[i] = newTemp(Ity_I16);
12871                assign(tmp[i],
12872                       binop(Iop_GetElem16x8, mkexpr(t2),
12873                             mkU8(i - (i % 4) +
12874                                  ((i8 >> (i % 4) * 2) & 0x03))));
12875             }
12876 
12877             putWReg(wd, binop(Iop_64HLtoV128,
12878                               binop(Iop_32HLto64,
12879                                     binop(Iop_16HLto32,
12880                                           mkexpr(tmp[7]), mkexpr(tmp[6])),
12881                                     binop(Iop_16HLto32,
12882                                           mkexpr(tmp[5]), mkexpr(tmp[4]))),
12883                               binop(Iop_32HLto64,
12884                                     binop(Iop_16HLto32,
12885                                           mkexpr(tmp[3]), mkexpr(tmp[2])),
12886                                     binop(Iop_16HLto32,
12887                                           mkexpr(tmp[1]), mkexpr(tmp[0])))));
12888             break;
12889          }
12890 
12891       case 0x02: { /* SHF.W */
12892             DIP("SHF.W w%d, w%d, %d", wd, ws, i8);
12893             t1 = newTemp(Ity_V128);
12894             t2 = newTemp(Ity_V128);
12895             assign(t1, getWReg(wd));
12896             assign(t2, getWReg(ws));
12897             Int i;
12898             IRTemp tmp[4];
12899 
12900             for (i = 0; i < 4; i++) {
12901                tmp[i] = newTemp(Ity_I32);
12902                assign(tmp[i],
12903                       binop(Iop_GetElem32x4, mkexpr(t2),
12904                             mkU8(i - (i % 4) +
12905                                  ((i8 >> (i % 4) * 2) & 0x03))));
12906             }
12907 
12908             putWReg(wd, binop(Iop_64HLtoV128,
12909                               binop(Iop_32HLto64,
12910                                     mkexpr(tmp[3]), mkexpr(tmp[2])),
12911                               binop(Iop_32HLto64,
12912                                     mkexpr(tmp[1]), mkexpr(tmp[0]))));
12913             break;
12914          }
12915 
12916       default:
12917          return -1;
12918    }
12919 
12920    return 0;
12921 }
12922 
msa_I5_06(UInt cins,UChar wd,UChar ws)12923 static Int msa_I5_06(UInt cins, UChar wd, UChar ws) { /* I5 (0x06) */
12924    IRTemp t1, t2, t3;
12925    UShort operation;
12926    UChar df, wt;
12927 
12928    operation = (cins & 0x03800000) >> 23;
12929    df = (cins & 0x00600000) >> 21;
12930    wt = (cins & 0x001F0000) >> 16;
12931 
12932    switch (operation) {
12933       case 0x00: { /* ADDVI */
12934             ULong tmp = wt;
12935 
12936             switch (df) {
12937                case 0x00: { /* ADDVI.B */
12938                      DIP("ADDVI.B w%d, w%d, %d", wd, ws, wt);
12939                      t1 = newTemp(Ity_V128);
12940                      t2 = newTemp(Ity_V128);
12941                      t3 = newTemp(Ity_V128);
12942                      tmp |= (tmp << 56) | (tmp << 48) | (tmp << 40) |
12943                             (tmp << 32) | (tmp << 24) | (tmp << 16) |
12944                             (tmp << 8);
12945                      assign(t1, getWReg(ws));
12946                      assign(t2, binop(Iop_64HLtoV128, mkU64(tmp), mkU64(tmp)));
12947                      assign(t3, binop(Iop_Add8x16, mkexpr(t1), mkexpr(t2)));
12948                      putWReg(wd, mkexpr(t3));
12949                      break;
12950                   }
12951 
12952                case 0x01: { /* ADDVI.H */
12953                      DIP("ADDVI.H w%d, w%d, %d", wd, ws, wt);
12954                      t1 = newTemp(Ity_V128);
12955                      t2 = newTemp(Ity_V128);
12956                      t3 = newTemp(Ity_V128);
12957                      tmp |= (tmp << 48) | (tmp << 32) | (tmp << 16);
12958                      assign(t1, getWReg(ws));
12959                      assign(t2, binop(Iop_64HLtoV128, mkU64(tmp), mkU64(tmp)));
12960                      assign(t3, binop(Iop_Add16x8, mkexpr(t1), mkexpr(t2)));
12961                      putWReg(wd, mkexpr(t3));
12962                      break;
12963                   }
12964 
12965                case 0x02: { /* ADDVI.W */
12966                      DIP("ADDVI.W w%d, w%d, %d", wd, ws, wt);
12967                      t1 = newTemp(Ity_V128);
12968                      t2 = newTemp(Ity_V128);
12969                      t3 = newTemp(Ity_V128);
12970                      tmp |= (tmp << 32);
12971                      assign(t1, getWReg(ws));
12972                      assign(t2, binop(Iop_64HLtoV128, mkU64(tmp), mkU64(tmp)));
12973                      assign(t3, binop(Iop_Add32x4, mkexpr(t1), mkexpr(t2)));
12974                      putWReg(wd, mkexpr(t3));
12975                      break;
12976                   }
12977 
12978                case 0x03: { /* ADDVI.D */
12979                      DIP("ADDVI.D w%d, w%d, %d", wd, ws, wt);
12980                      t1 = newTemp(Ity_V128);
12981                      t2 = newTemp(Ity_V128);
12982                      t3 = newTemp(Ity_V128);
12983                      assign(t1, getWReg(ws));
12984                      assign(t2, binop(Iop_64HLtoV128, mkU64(tmp), mkU64(tmp)));
12985                      assign(t3, binop(Iop_Add64x2, mkexpr(t1), mkexpr(t2)));
12986                      putWReg(wd, mkexpr(t3));
12987                      break;
12988                   }
12989             }
12990 
12991             break;
12992          }
12993 
12994       case 0x01: { /* SUBVI */
12995             ULong tmp = wt;
12996 
12997             switch (df) {
12998                case 0x00: { /* SUBVI.B */
12999                      DIP("SUBVI.B w%d, w%d, %d", wd, ws, wt);
13000                      t1 = newTemp(Ity_V128);
13001                      t2 = newTemp(Ity_V128);
13002                      t3 = newTemp(Ity_V128);
13003                      tmp |= (tmp << 56) | (tmp << 48) | (tmp << 40) |
13004                             (tmp << 32) | (tmp << 24) | (tmp << 16) |
13005                             (tmp << 8);
13006                      assign(t1, getWReg(ws));
13007                      assign(t2, binop(Iop_64HLtoV128, mkU64(tmp), mkU64(tmp)));
13008                      assign(t3, binop(Iop_Sub8x16, mkexpr(t1), mkexpr(t2)));
13009                      putWReg(wd, mkexpr(t3));
13010                      break;
13011                   }
13012 
13013                case 0x01: { /* SUBVI.H */
13014                      DIP("SUBVI.H w%d, w%d, %d", wd, ws, wt);
13015                      t1 = newTemp(Ity_V128);
13016                      t2 = newTemp(Ity_V128);
13017                      t3 = newTemp(Ity_V128);
13018                      tmp |= (tmp << 48) | (tmp << 32) | (tmp << 16);
13019                      assign(t1, getWReg(ws));
13020                      assign(t2, binop(Iop_64HLtoV128, mkU64(tmp), mkU64(tmp)));
13021                      assign(t3, binop(Iop_Sub16x8, mkexpr(t1), mkexpr(t2)));
13022                      putWReg(wd, mkexpr(t3));
13023                      break;
13024                   }
13025 
13026                case 0x02: { /* SUBVI.W */
13027                      DIP("SUBVI.W w%d, w%d, %d", wd, ws, wt);
13028                      t1 = newTemp(Ity_V128);
13029                      t2 = newTemp(Ity_V128);
13030                      t3 = newTemp(Ity_V128);
13031                      tmp |= (tmp << 32);
13032                      assign(t1, getWReg(ws));
13033                      assign(t2, binop(Iop_64HLtoV128, mkU64(tmp), mkU64(tmp)));
13034                      assign(t3, binop(Iop_Sub32x4, mkexpr(t1), mkexpr(t2)));
13035                      putWReg(wd, mkexpr(t3));
13036                      break;
13037                   }
13038 
13039                case 0x03: { /* SUBVI.D */
13040                      DIP("SUBVI.D w%d, w%d, %d", wd, ws, wt);
13041                      t1 = newTemp(Ity_V128);
13042                      t2 = newTemp(Ity_V128);
13043                      t3 = newTemp(Ity_V128);
13044                      assign(t1, getWReg(ws));
13045                      assign(t2, binop(Iop_64HLtoV128, mkU64(tmp), mkU64(tmp)));
13046                      assign(t3, binop(Iop_Sub64x2, mkexpr(t1), mkexpr(t2)));
13047                      putWReg(wd, mkexpr(t3));
13048                      break;
13049                   }
13050             }
13051 
13052             break;
13053          }
13054 
13055       case 0x02: { /* MAXI_S */
13056             ULong tmp = wt;
13057 
13058             switch (df) {
13059                case 0x00: { /* MAXI_S.B */
13060                      DIP("MAXI_S.B w%d, w%d, %d", wd, ws, wt);
13061                      t1 = newTemp(Ity_V128);
13062                      t2 = newTemp(Ity_V128);
13063                      t3 = newTemp(Ity_V128);
13064                      char stemp = ((int)tmp << 27) >> 27;
13065                      tmp = (UChar)stemp;
13066                      tmp |= (tmp << 56) | (tmp << 48) | (tmp << 40) |
13067                             (tmp << 32) | (tmp << 24) | (tmp << 16) |
13068                             (tmp << 8);
13069                      assign(t1, getWReg(ws));
13070                      assign(t2,binop(Iop_64HLtoV128, mkU64(tmp), mkU64(tmp)));
13071                      assign(t3, binop(Iop_Max8Sx16, mkexpr(t1), mkexpr(t2)));
13072                      putWReg(wd, mkexpr(t3));
13073                      break;
13074                   }
13075 
13076                case 0x01: { /* MAXI_S.H */
13077                      DIP("MAXI_S.H w%d, w%d, %d", wd, ws, wt);
13078                      t1 = newTemp(Ity_V128);
13079                      t2 = newTemp(Ity_V128);
13080                      t3 = newTemp(Ity_V128);
13081                      short stemp = ((int)tmp << 27) >> 27;
13082                      tmp = (UShort)stemp;
13083                      tmp |= (tmp << 48) | (tmp << 32) | (tmp << 16);
13084                      assign(t1, getWReg(ws));
13085                      assign(t2, binop(Iop_64HLtoV128, mkU64(tmp), mkU64(tmp)));
13086                      assign(t3, binop(Iop_Max16Sx8, mkexpr(t1), mkexpr(t2)));
13087                      putWReg(wd, mkexpr(t3));
13088                      break;
13089                   }
13090 
13091                case 0x02: { /* MAXI_S.W */
13092                      DIP("MAXI_S.W w%d, w%d, %d", wd, ws, wt);
13093                      t1 = newTemp(Ity_V128);
13094                      t2 = newTemp(Ity_V128);
13095                      t3 = newTemp(Ity_V128);
13096                      int stemp = ((int)tmp << 27) >> 27;
13097                      tmp = (UInt)stemp;
13098                      tmp |= (tmp << 32);
13099                      assign(t1, getWReg(ws));
13100                      assign(t2, binop(Iop_64HLtoV128, mkU64(tmp), mkU64(tmp)));
13101                      assign(t3, binop(Iop_Max32Sx4, mkexpr(t1), mkexpr(t2)));
13102                      putWReg(wd, mkexpr(t3));
13103                      break;
13104                   }
13105 
13106                case 0x03: { /* MAXI_S.D */
13107                      DIP("MAXI_S.D w%d, w%d, %d", wd, ws, wt);
13108                      t1 = newTemp(Ity_V128);
13109                      t2 = newTemp(Ity_V128);
13110                      t3 = newTemp(Ity_V128);
13111                      Long stemp = ((Long)tmp << 59) >> 59;
13112                      tmp = stemp;
13113                      assign(t1, getWReg(ws));
13114                      assign(t2, binop(Iop_64HLtoV128, mkU64(tmp), mkU64(tmp)));
13115                      assign(t3, binop(Iop_Max64Sx2, mkexpr(t1), mkexpr(t2)));
13116                      putWReg(wd, mkexpr(t3));
13117                      break;
13118                   }
13119             }
13120 
13121             break;
13122          }
13123 
13124       case 0x03: { /* MAXI_U */
13125             ULong tmp = wt;
13126 
13127             switch (df) {
13128                case 0x00: { /* MAXI_U.B */
13129                      DIP("MAXI_U.B w%d, w%d, %d", wd, ws, wt);
13130                      t1 = newTemp(Ity_V128);
13131                      t2 = newTemp(Ity_V128);
13132                      t3 = newTemp(Ity_V128);
13133                      tmp |= (tmp << 56) | (tmp << 48) | (tmp << 40) |
13134                             (tmp << 32) | (tmp << 24) | (tmp << 16) |
13135                             (tmp << 8);
13136                      assign(t1, getWReg(ws));
13137                      assign(t2, binop(Iop_64HLtoV128, mkU64(tmp), mkU64(tmp)));
13138                      assign(t3, binop(Iop_Max8Ux16, mkexpr(t1), mkexpr(t2)));
13139                      putWReg(wd, mkexpr(t3));
13140                      break;
13141                   }
13142 
13143                case 0x01: { /* MAXI_U.H */
13144                      DIP("MAXI_U.H w%d, w%d, %d", wd, ws, wt);
13145                      t1 = newTemp(Ity_V128);
13146                      t2 = newTemp(Ity_V128);
13147                      t3 = newTemp(Ity_V128);
13148                      tmp |= (tmp << 48) | (tmp << 32) | (tmp << 16);
13149                      assign(t1, getWReg(ws));
13150                      assign(t2, binop(Iop_64HLtoV128, mkU64(tmp), mkU64(tmp)));
13151                      assign(t3, binop(Iop_Max16Ux8, mkexpr(t1), mkexpr(t2)));
13152                      putWReg(wd, mkexpr(t3));
13153                      break;
13154                   }
13155 
13156                case 0x02: { /* MAXI_U.W */
13157                      DIP("MAXI_U.W w%d, w%d, %d", wd, ws, wt);
13158                      t1 = newTemp(Ity_V128);
13159                      t2 = newTemp(Ity_V128);
13160                      t3 = newTemp(Ity_V128);
13161                      tmp |= (tmp << 32);
13162                      assign(t1, getWReg(ws));
13163                      assign(t2, binop(Iop_64HLtoV128, mkU64(tmp), mkU64(tmp)));
13164                      assign(t3, binop(Iop_Max32Ux4, mkexpr(t1), mkexpr(t2)));
13165                      putWReg(wd, mkexpr(t3));
13166                      break;
13167                   }
13168 
13169                case 0x03: { /* MAXI_U.D */
13170                      DIP("MAXI_U.D w%d, w%d, %d", wd, ws, wt);
13171                      t1 = newTemp(Ity_V128);
13172                      t2 = newTemp(Ity_V128);
13173                      t3 = newTemp(Ity_V128);
13174                      assign(t1, getWReg(ws));
13175                      assign(t2, binop(Iop_64HLtoV128, mkU64(tmp), mkU64(tmp)));
13176                      assign(t3, binop(Iop_Max64Ux2, mkexpr(t1), mkexpr(t2)));
13177                      putWReg(wd, mkexpr(t3));
13178                      break;
13179                   }
13180             }
13181 
13182             break;
13183          }
13184 
13185       case 0x04: { /* MINI_S */
13186             ULong tmp = wt;
13187 
13188             switch (df) {
13189                case 0x00: { /* MINI_S.B */
13190                      DIP("MINI_S.B w%d, w%d, %d", wd, ws, wt);
13191                      t1 = newTemp(Ity_V128);
13192                      t2 = newTemp(Ity_V128);
13193                      t3 = newTemp(Ity_V128);
13194                      char stemp = ((int)tmp << 27) >> 27;
13195                      tmp = (UChar)stemp;
13196                      tmp |= (tmp << 56) | (tmp << 48) | (tmp << 40) |
13197                             (tmp << 32) | (tmp << 24) | (tmp << 16) |
13198                             (tmp << 8);
13199                      assign(t1, getWReg(ws));
13200                      assign(t2, binop(Iop_64HLtoV128, mkU64(tmp), mkU64(tmp)));
13201                      assign(t3, binop(Iop_Min8Sx16, mkexpr(t1), mkexpr(t2)));
13202                      putWReg(wd, mkexpr(t3));
13203                      break;
13204                   }
13205 
13206                case 0x01: { /* MINI_S.H */
13207                      DIP("MINI_S.H w%d, w%d, %d", wd, ws, wt);
13208                      t1 = newTemp(Ity_V128);
13209                      t2 = newTemp(Ity_V128);
13210                      t3 = newTemp(Ity_V128);
13211                      short stemp = ((int)tmp << 27) >> 27;
13212                      tmp = (UShort)stemp;
13213                      tmp |= (tmp << 48) | (tmp << 32) | (tmp << 16);
13214                      assign(t1, getWReg(ws));
13215                      assign(t2, binop(Iop_64HLtoV128, mkU64(tmp), mkU64(tmp)));
13216                      assign(t3, binop(Iop_Min16Sx8, mkexpr(t1), mkexpr(t2)));
13217                      putWReg(wd, mkexpr(t3));
13218                      break;
13219                   }
13220 
13221                case 0x02: { /* MINI_S.W */
13222                      DIP("MINI_S.W w%d, w%d, %d", wd, ws, wt);
13223                      t1 = newTemp(Ity_V128);
13224                      t2 = newTemp(Ity_V128);
13225                      t3 = newTemp(Ity_V128);
13226                      int stemp = ((int)tmp << 27) >> 27;
13227                      tmp = (UInt)stemp;
13228                      tmp |= (tmp << 32);
13229                      assign(t1, getWReg(ws));
13230                      assign(t2, binop(Iop_64HLtoV128, mkU64(tmp), mkU64(tmp)));
13231                      assign(t3, binop(Iop_Min32Sx4, mkexpr(t1), mkexpr(t2)));
13232                      putWReg(wd, mkexpr(t3));
13233                      break;
13234                   }
13235 
13236                case 0x03: { /* MINI_S.D */
13237                      DIP("MINI_S.D w%d, w%d, %d", wd, ws, wt);
13238                      t1 = newTemp(Ity_V128);
13239                      t2 = newTemp(Ity_V128);
13240                      t3 = newTemp(Ity_V128);
13241                      Long stemp = ((Long)tmp << 59) >> 59;
13242                      tmp = stemp;
13243                      assign(t1, getWReg(ws));
13244                      assign(t2, binop(Iop_64HLtoV128, mkU64(tmp), mkU64(tmp)));
13245                      assign(t3, binop(Iop_Min64Sx2, mkexpr(t1), mkexpr(t2)));
13246                      putWReg(wd, mkexpr(t3));
13247                      break;
13248                   }
13249             }
13250 
13251             break;
13252          }
13253 
13254       case 0x05: { /* MINI_U */
13255             ULong tmp = wt;
13256 
13257             switch (df) {
13258                case 0x00: { /* MINI_U.B */
13259                      DIP("MINI_U.B w%d, w%d, %d", wd, ws, wt);
13260                      t1 = newTemp(Ity_V128);
13261                      t2 = newTemp(Ity_V128);
13262                      t3 = newTemp(Ity_V128);
13263                      tmp |= (tmp << 56) | (tmp << 48) | (tmp << 40) |
13264                             (tmp << 32) | (tmp << 24) | (tmp << 16) |
13265                             (tmp << 8);
13266                      assign(t1, getWReg(ws));
13267                      assign(t2, binop(Iop_64HLtoV128, mkU64(tmp), mkU64(tmp)));
13268                      assign(t3, binop(Iop_Min8Ux16, mkexpr(t1), mkexpr(t2)));
13269                      putWReg(wd, mkexpr(t3));
13270                      break;
13271                   }
13272 
13273                case 0x01: { /* MINI_U.H */
13274                      DIP("MINI_U.H w%d, w%d, %d", wd, ws, wt);
13275                      t1 = newTemp(Ity_V128);
13276                      t2 = newTemp(Ity_V128);
13277                      t3 = newTemp(Ity_V128);
13278                      tmp |= (tmp << 48) | (tmp << 32) | (tmp << 16);
13279                      assign(t1, getWReg(ws));
13280                      assign(t2, binop(Iop_64HLtoV128, mkU64(tmp), mkU64(tmp)));
13281                      assign(t3, binop(Iop_Min16Ux8, mkexpr(t1), mkexpr(t2)));
13282                      putWReg(wd, mkexpr(t3));
13283                      break;
13284                   }
13285 
13286                case 0x02: { /* MINI_U.W */
13287                      DIP("MINI_U.W w%d, w%d, %d", wd, ws, wt);
13288                      t1 = newTemp(Ity_V128);
13289                      t2 = newTemp(Ity_V128);
13290                      t3 = newTemp(Ity_V128);
13291                      tmp |= (tmp << 32);
13292                      assign(t1, getWReg(ws));
13293                      assign(t2, binop(Iop_64HLtoV128, mkU64(tmp), mkU64(tmp)));
13294                      assign(t3, binop(Iop_Min32Ux4, mkexpr(t1), mkexpr(t2)));
13295                      putWReg(wd, mkexpr(t3));
13296                      break;
13297                   }
13298 
13299                case 0x03: { /* MINI_U.D */
13300                      DIP("MINI_U.D w%d, w%d, %d", wd, ws, wt);
13301                      t1 = newTemp(Ity_V128);
13302                      t2 = newTemp(Ity_V128);
13303                      t3 = newTemp(Ity_V128);
13304                      assign(t1, getWReg(ws));
13305                      assign(t2, binop(Iop_64HLtoV128, mkU64(tmp), mkU64(tmp)));
13306                      assign(t3, binop(Iop_Min64Ux2, mkexpr(t1), mkexpr(t2)));
13307                      putWReg(wd, mkexpr(t3));
13308                      break;
13309                   }
13310             }
13311 
13312             break;
13313          }
13314 
13315       default: {
13316             return -1;
13317          }
13318    }
13319 
13320    return 0;
13321 }
13322 
msa_I5_07(UInt cins,UChar wd,UChar ws)13323 static Int msa_I5_07(UInt cins, UChar wd, UChar ws) { /* I5 (0x07) / I10 */
13324    IRTemp t1, t2, t3;
13325    UShort operation;
13326    UChar df, i5;
13327 
13328    operation = (cins & 0x03800000) >> 23;
13329    df = (cins & 0x00600000) >> 21;
13330    i5 = (cins & 0x001F0000) >> 16;
13331 
13332    switch (operation) {
13333       case 0x00: {
13334             ULong tmp = i5;
13335 
13336             switch (df) {
13337                case 0x00: { /* CEQI.B */
13338                      DIP("CEQI.B w%d, w%d, %d", wd, ws, i5);
13339                      t1 = newTemp(Ity_V128);
13340                      t2 = newTemp(Ity_V128);
13341                      t3 = newTemp(Ity_V128);
13342                      char stemp = ((int)tmp << 27) >> 27;
13343                      tmp = (UChar)stemp;
13344                      tmp |= (tmp << 56) | (tmp << 48) | (tmp << 40) |
13345                             (tmp << 32) | (tmp << 24) | (tmp << 16) |
13346                             (tmp << 8);
13347                      assign(t1, getWReg(ws));
13348                      assign(t2, binop(Iop_64HLtoV128, mkU64(tmp), mkU64(tmp)));
13349                      assign(t3, binop(Iop_CmpEQ8x16, mkexpr(t1), mkexpr(t2)));
13350                      putWReg(wd, mkexpr(t3));
13351                      break;
13352                   }
13353 
13354                case 0x01: { /* CEQI.H */
13355                      DIP("CEQI.H w%d, w%d, %d", wd, ws, i5);
13356                      t1 = newTemp(Ity_V128);
13357                      t2 = newTemp(Ity_V128);
13358                      t3 = newTemp(Ity_V128);
13359                      short stemp = ((int)tmp << 27) >> 27;
13360                      tmp = (UShort)stemp;
13361                      tmp |= (tmp << 48) | (tmp << 32) | (tmp << 16);
13362                      assign(t1, getWReg(ws));
13363                      assign(t2, binop(Iop_64HLtoV128, mkU64(tmp), mkU64(tmp)));
13364                      assign(t3, binop(Iop_CmpEQ16x8, mkexpr(t1), mkexpr(t2)));
13365                      putWReg(wd, mkexpr(t3));
13366                      break;
13367                   }
13368 
13369                case 0x02: { /* CEQI.W */
13370                      DIP("CEQI.W w%d, w%d, %d", wd, ws, i5);
13371                      t1 = newTemp(Ity_V128);
13372                      t2 = newTemp(Ity_V128);
13373                      t3 = newTemp(Ity_V128);
13374                      int stemp = ((int)tmp << 27) >> 27;
13375                      tmp = (UInt)stemp;
13376                      tmp |= (tmp << 32);
13377                      assign(t1, getWReg(ws));
13378                      assign(t2, binop(Iop_64HLtoV128, mkU64(tmp), mkU64(tmp)));
13379                      assign(t3, binop(Iop_CmpEQ32x4, mkexpr(t1), mkexpr(t2)));
13380                      putWReg(wd, mkexpr(t3));
13381                      break;
13382                   }
13383 
13384                case 0x03: { /* CEQI.D */
13385                      DIP("CEQI.D w%d, w%d, %d", wd, ws, i5);
13386                      t1 = newTemp(Ity_V128);
13387                      t2 = newTemp(Ity_V128);
13388                      t3 = newTemp(Ity_V128);
13389                      Long stemp = ((Long)tmp << 59) >> 59;
13390                      tmp = stemp;
13391                      assign(t1, getWReg(ws));
13392                      assign(t2, binop(Iop_64HLtoV128, mkU64(tmp), mkU64(tmp)));
13393                      assign(t3, binop(Iop_CmpEQ64x2, mkexpr(t1), mkexpr(t2)));
13394                      putWReg(wd, mkexpr(t3));
13395                      break;
13396                   }
13397             }
13398 
13399             break;
13400          }
13401 
13402       case 0x02: { /* CLTI_S.df */
13403             ULong tmp = i5;
13404 
13405             switch (df) {
13406                case 0x00: { /* CLTI_S.B */
13407                      DIP("CLTI_S.B w%d, w%d, %d", wd, ws, i5);
13408                      t1 = newTemp(Ity_V128);
13409                      t2 = newTemp(Ity_V128);
13410                      t3 = newTemp(Ity_V128);
13411                      char stemp = ((int)tmp << 27) >> 27;
13412                      tmp = (UChar)stemp;
13413                      tmp |= (tmp << 56) | (tmp << 48) | (tmp << 40) |
13414                             (tmp << 32) | (tmp << 24) | (tmp << 16) |
13415                             (tmp << 8);
13416                      assign(t1, getWReg(ws));
13417                      assign(t2, binop(Iop_64HLtoV128, mkU64(tmp), mkU64(tmp)));
13418                      assign(t3, binop(Iop_CmpGT8Sx16, mkexpr(t2), mkexpr(t1)));
13419                      putWReg(wd, mkexpr(t3));
13420                      break;
13421                   }
13422 
13423                case 0x01: { /* CLTI_S.H */
13424                      DIP("CLTI_S.H w%d, w%d, %d", wd, ws, i5);
13425                      t1 = newTemp(Ity_V128);
13426                      t2 = newTemp(Ity_V128);
13427                      t3 = newTemp(Ity_V128);
13428                      short stemp = ((int)tmp << 27) >> 27;
13429                      tmp = (UShort)stemp;
13430                      tmp |= (tmp << 48) | (tmp << 32) | (tmp << 16);
13431                      assign(t1, getWReg(ws));
13432                      assign(t2, binop(Iop_64HLtoV128, mkU64(tmp), mkU64(tmp)));
13433                      assign(t3, binop(Iop_CmpGT16Sx8, mkexpr(t2), mkexpr(t1)));
13434                      putWReg(wd, mkexpr(t3));
13435                      break;
13436                   }
13437 
13438                case 0x02: { /* CLTI_S.W */
13439                      DIP("CLTI_S.W w%d, w%d, %d", wd, ws, i5);
13440                      t1 = newTemp(Ity_V128);
13441                      t2 = newTemp(Ity_V128);
13442                      t3 = newTemp(Ity_V128);
13443                      int stemp = ((int)tmp << 27) >> 27;
13444                      tmp = (UInt)stemp;
13445                      tmp |= (tmp << 32);
13446                      assign(t1, getWReg(ws));
13447                      assign(t2, binop(Iop_64HLtoV128, mkU64(tmp), mkU64(tmp)));
13448                      assign(t3, binop(Iop_CmpGT32Sx4, mkexpr(t2), mkexpr(t1)));
13449                      putWReg(wd, mkexpr(t3));
13450                      break;
13451                   }
13452 
13453                case 0x03: { /* CLTI_S.D */
13454                      DIP("CLTI_S.D w%d, w%d, %d", wd, ws, i5);
13455                      t1 = newTemp(Ity_V128);
13456                      t2 = newTemp(Ity_V128);
13457                      t3 = newTemp(Ity_V128);
13458                      Long stemp = ((Long)tmp << 59) >> 59;
13459                      tmp = stemp;
13460                      assign(t1, getWReg(ws));
13461                      assign(t2, binop(Iop_64HLtoV128, mkU64(tmp), mkU64(tmp)));
13462                      assign(t3, binop(Iop_CmpGT64Sx2, mkexpr(t2), mkexpr(t1)));
13463                      putWReg(wd, mkexpr(t3));
13464                      break;
13465                   }
13466 
13467                default:
13468                   return -1;
13469             }
13470 
13471             break;
13472          }
13473 
13474       case 0x03: { /* CLTI_U.df */
13475             ULong tmp = i5;
13476 
13477             switch (df) {
13478                case 0x00: { /* CLTI_U.B */
13479                      DIP("CLTI_U.B w%d, w%d, %d", wd, ws, i5);
13480                      t1 = newTemp(Ity_V128);
13481                      t2 = newTemp(Ity_V128);
13482                      t3 = newTemp(Ity_V128);
13483                      tmp |= (tmp << 56) | (tmp << 48) | (tmp << 40) |
13484                             (tmp << 32) | (tmp << 24) | (tmp << 16) |
13485                             (tmp << 8);
13486                      assign(t1, getWReg(ws));
13487                      assign(t2, binop(Iop_64HLtoV128, mkU64(tmp), mkU64(tmp)));
13488                      assign(t3, binop(Iop_CmpGT8Ux16, mkexpr(t2), mkexpr(t1)));
13489                      putWReg(wd, mkexpr(t3));
13490                      break;
13491                   }
13492 
13493                case 0x01: { /* CLTI_U.H */
13494                      DIP("CLTI_U.H w%d, w%d, %d", wd, ws, i5);
13495                      t1 = newTemp(Ity_V128);
13496                      t2 = newTemp(Ity_V128);
13497                      t3 = newTemp(Ity_V128);
13498                      tmp |= (tmp << 48) | (tmp << 32) | (tmp << 16);
13499                      assign(t1, getWReg(ws));
13500                      assign(t2, binop(Iop_64HLtoV128, mkU64(tmp), mkU64(tmp)));
13501                      assign(t3, binop(Iop_CmpGT16Ux8, mkexpr(t2), mkexpr(t1)));
13502                      putWReg(wd, mkexpr(t3));
13503                      break;
13504                   }
13505 
13506                case 0x02: { /* CLTI_U.W */
13507                      DIP("CLTI_U.W w%d, w%d, %d", wd, ws, i5);
13508                      t1 = newTemp(Ity_V128);
13509                      t2 = newTemp(Ity_V128);
13510                      t3 = newTemp(Ity_V128);
13511                      tmp |= (tmp << 32);
13512                      assign(t1, getWReg(ws));
13513                      assign(t2, binop(Iop_64HLtoV128, mkU64(tmp), mkU64(tmp)));
13514                      assign(t3, binop(Iop_CmpGT32Ux4, mkexpr(t2), mkexpr(t1)));
13515                      putWReg(wd, mkexpr(t3));
13516                      break;
13517                   }
13518 
13519                case 0x03: { /* CLTI_U.D */
13520                      DIP("CLTI_U.D w%d, w%d, %d", wd, ws, i5);
13521                      t1 = newTemp(Ity_V128);
13522                      t2 = newTemp(Ity_V128);
13523                      t3 = newTemp(Ity_V128);
13524                      assign(t1, getWReg(ws));
13525                      assign(t2, binop(Iop_64HLtoV128, mkU64(tmp), mkU64(tmp)));
13526                      assign(t3, binop(Iop_CmpGT64Ux2, mkexpr(t2), mkexpr(t1)));
13527                      putWReg(wd, mkexpr(t3));
13528                      break;
13529                   }
13530             }
13531 
13532             break;
13533          }
13534 
13535       case 0x04: { /* CLEI_S.df */
13536             ULong tmp = i5;
13537 
13538             switch (df) {
13539                case 0x00: { /* CLEI_S.B */
13540                      DIP("CLEI_S.B w%d, w%d, %d", wd, ws, i5);
13541                      t1 = newTemp(Ity_V128);
13542                      t2 = newTemp(Ity_V128);
13543                      t3 = newTemp(Ity_V128);
13544                      char stemp = ((int)tmp << 27) >> 27;
13545                      tmp = (UChar)stemp;
13546                      tmp |= (tmp << 56) | (tmp << 48) | (tmp << 40) |
13547                             (tmp << 32) | (tmp << 24) | (tmp << 16) |
13548                             (tmp << 8);
13549                      assign(t1, getWReg(ws));
13550                      assign(t2, binop(Iop_64HLtoV128, mkU64(tmp), mkU64(tmp)));
13551                      assign(t3, binop(Iop_OrV128, binop(Iop_CmpGT8Sx16,
13552                                                       mkexpr(t2), mkexpr(t1)),
13553                                                   binop(Iop_CmpEQ8x16,
13554                                                       mkexpr(t1), mkexpr(t2))));
13555                      putWReg(wd, mkexpr(t3));
13556                      break;
13557                   }
13558 
13559                case 0x01: { /* CLEI_S.H */
13560                      DIP("CLEI_S.H w%d, w%d, %d", wd, ws, i5);
13561                      t1 = newTemp(Ity_V128);
13562                      t2 = newTemp(Ity_V128);
13563                      t3 = newTemp(Ity_V128);
13564                      short stemp = ((int)tmp << 27) >> 27;
13565                      tmp = (UShort)stemp;
13566                      tmp |= (tmp << 48) | (tmp << 32) | (tmp << 16);
13567                      assign(t1, getWReg(ws));
13568                      assign(t2, binop(Iop_64HLtoV128, mkU64(tmp), mkU64(tmp)));
13569                      assign(t3, binop(Iop_OrV128, binop(Iop_CmpGT16Sx8,
13570                                                       mkexpr(t2), mkexpr(t1)),
13571                                                   binop(Iop_CmpEQ16x8,
13572                                                       mkexpr(t1), mkexpr(t2))));
13573                      putWReg(wd, mkexpr(t3));
13574                      break;
13575                   }
13576 
13577                case 0x02: { /* CLEI_S.W */
13578                      DIP("CLEI_S.W w%d, w%d, %d", wd, ws, i5);
13579                      t1 = newTemp(Ity_V128);
13580                      t2 = newTemp(Ity_V128);
13581                      t3 = newTemp(Ity_V128);
13582                      int stemp = ((int)tmp << 27) >> 27;
13583                      tmp = (UInt)stemp;
13584                      tmp |= (tmp << 32);
13585                      assign(t1, getWReg(ws));
13586                      assign(t2, binop(Iop_64HLtoV128, mkU64(tmp), mkU64(tmp)));
13587                      assign(t3, binop(Iop_OrV128,
13588                                       binop(Iop_CmpGT32Sx4,
13589                                             mkexpr(t2), mkexpr(t1)),
13590                                       binop(Iop_CmpEQ32x4,
13591                                             mkexpr(t1), mkexpr(t2))));
13592                      putWReg(wd, mkexpr(t3));
13593                      break;
13594                   }
13595 
13596                case 0x03: { /* CLEI_S.D */
13597                      DIP("CLEI_S.D w%d, w%d, %d", wd, ws, i5);
13598                      t1 = newTemp(Ity_V128);
13599                      t2 = newTemp(Ity_V128);
13600                      t3 = newTemp(Ity_V128);
13601                      Long stemp = ((Long)tmp << 59) >> 59;
13602                      tmp = stemp;
13603                      assign(t1, getWReg(ws));
13604                      assign(t2, binop(Iop_64HLtoV128, mkU64(tmp), mkU64(tmp)));
13605                      assign(t3, binop(Iop_OrV128,
13606                                       binop(Iop_CmpGT64Sx2,
13607                                             mkexpr(t2), mkexpr(t1)),
13608                                       binop(Iop_CmpEQ64x2,
13609                                             mkexpr(t1), mkexpr(t2))));
13610                      putWReg(wd, mkexpr(t3));
13611                      break;
13612                   }
13613 
13614                default:
13615                   return -1;
13616             }
13617 
13618             break;
13619          }
13620 
13621       case 0x05: { /* CLEI_U.df */
13622             ULong tmp = i5;
13623 
13624             switch (df) {
13625                case 0x00: { /* CLEI_U.B */
13626                      DIP("CLEI_U.B w%d, w%d, %d", wd, ws, i5);
13627                      t1 = newTemp(Ity_V128);
13628                      t2 = newTemp(Ity_V128);
13629                      t3 = newTemp(Ity_V128);
13630                      tmp |= (tmp << 56) | (tmp << 48) | (tmp << 40) |
13631                             (tmp << 32) | (tmp << 24) | (tmp << 16) |
13632                             (tmp << 8);
13633                      assign(t1, getWReg(ws));
13634                      assign(t2, binop(Iop_64HLtoV128, mkU64(tmp), mkU64(tmp)));
13635                      assign(t3, binop(Iop_OrV128,
13636                                       binop(Iop_CmpGT8Ux16,
13637                                             mkexpr(t2), mkexpr(t1)),
13638                                       binop(Iop_CmpEQ8x16,
13639                                             mkexpr(t1), mkexpr(t2))));
13640                      putWReg(wd, mkexpr(t3));
13641                      break;
13642                   }
13643 
13644                case 0x01: { /* CLEI_U.H */
13645                      DIP("CLEI_U.H w%d, w%d, %d", wd, ws, i5);
13646                      t1 = newTemp(Ity_V128);
13647                      t2 = newTemp(Ity_V128);
13648                      t3 = newTemp(Ity_V128);
13649                      tmp |= (tmp << 48) | (tmp << 32) | (tmp << 16);
13650                      assign(t1, getWReg(ws));
13651                      assign(t2, binop(Iop_64HLtoV128, mkU64(tmp), mkU64(tmp)));
13652                      assign(t3, binop(Iop_OrV128,
13653                                       binop(Iop_CmpGT16Ux8,
13654                                             mkexpr(t2), mkexpr(t1)),
13655                                       binop(Iop_CmpEQ16x8,
13656                                             mkexpr(t1), mkexpr(t2))));
13657                      putWReg(wd, mkexpr(t3));
13658                      break;
13659                   }
13660 
13661                case 0x02: { /* CLEI_U.W */
13662                      DIP("CLEI_U.W w%d, w%d, %d", wd, ws, i5);
13663                      t1 = newTemp(Ity_V128);
13664                      t2 = newTemp(Ity_V128);
13665                      t3 = newTemp(Ity_V128);
13666                      tmp |= (tmp << 32);
13667                      assign(t1, getWReg(ws));
13668                      assign(t2, binop(Iop_64HLtoV128, mkU64(tmp), mkU64(tmp)));
13669                      assign(t3, binop(Iop_OrV128,
13670                                       binop(Iop_CmpGT32Ux4,
13671                                             mkexpr(t2), mkexpr(t1)),
13672                                       binop(Iop_CmpEQ32x4,
13673                                             mkexpr(t1), mkexpr(t2))));
13674                      putWReg(wd, mkexpr(t3));
13675                      break;
13676                   }
13677 
13678                case 0x03: { /* CLEI_U.D */
13679                      DIP("CLEI_U.D w%d, w%d, %d", wd, ws, i5);
13680                      t1 = newTemp(Ity_V128);
13681                      t2 = newTemp(Ity_V128);
13682                      t3 = newTemp(Ity_V128);
13683                      assign(t1, getWReg(ws));
13684                      assign(t2, binop(Iop_64HLtoV128, mkU64(tmp), mkU64(tmp)));
13685                      assign(t3, binop(Iop_OrV128,
13686                                       binop(Iop_CmpGT64Ux2,
13687                                             mkexpr(t2), mkexpr(t1)),
13688                                       binop(Iop_CmpEQ64x2,
13689                                             mkexpr(t1), mkexpr(t2))));
13690                      putWReg(wd, mkexpr(t3));
13691                      break;
13692                   }
13693             }
13694 
13695             break;
13696          }
13697 
13698       case 0x06: { /* LDI.df */
13699             ULong tmp;
13700             UShort s10;
13701             s10 = (cins & 0x001FF800) >> 11;
13702             switch (df) {
13703                case 0x00: /* LDI.B */
13704                   DIP("LDI.B w%d, %d", wd, s10);
13705                   tmp = s10 & 0xFFl;
13706                   tmp = tmp | (tmp << 8) | (tmp << 16) | (tmp << 24)
13707                         | (tmp << 32) | (tmp << 40) | (tmp << 48) |
13708                         (tmp << 56);
13709                   break;
13710 
13711                case 0x01: /* LDI.H */
13712                   DIP("LDI.H w%d, %d", wd, s10);
13713                   tmp = extend_s_10to16(s10);
13714                   tmp = tmp | (tmp << 16) | (tmp << 32) | (tmp << 48);
13715                   break;
13716 
13717                case 0x02: /* LDI.W */
13718                   DIP("LDI.W w%d, %d", wd, s10);
13719                   tmp = extend_s_10to32(s10);
13720                   tmp = tmp | (tmp << 32);
13721                   break;
13722 
13723                case 0x03: /* LDI.D */
13724                   DIP("LDI.D w%d, %d", wd, s10);
13725                   tmp = extend_s_10to64(s10);
13726                   break;
13727 
13728                default:
13729                   return -1;
13730             }
13731 
13732             putWReg(wd, binop(Iop_64HLtoV128, mkU64(tmp), mkU64(tmp)));
13733             break;
13734          }
13735 
13736       default:
13737          return -1;
13738    }
13739 
13740    return 0;
13741 }
13742 
msa_BIT_09(UInt cins,UChar wd,UChar ws)13743 static Int msa_BIT_09(UInt cins, UChar wd, UChar ws) { /* BIT (0x09) */
13744    IRTemp t1, t2, t3;
13745    UShort operation;
13746    UChar df, m;
13747 
13748    operation = (cins & 0x03800000) >> 23;
13749    df = (cins & 0x007F0000) >> 16;
13750 
13751    if ((df & 0x70) == 0x70) {        // 111mmmm; b
13752       m = df & 0x07;
13753       df = 0;
13754    } else if ((df & 0x60) == 0x60) { // 110mmmm; h
13755       m = df & 0x0F;
13756       df = 1;
13757    } else if ((df & 0x40) == 0x40) { // 10mmmmm; w
13758       m = df & 0x1F;
13759       df = 2;
13760    } else if ((df & 0x00) == 0x00) { // 0mmmmmm; d
13761       m = df & 0x3F;
13762       df = 3;
13763    }
13764 
13765    switch (operation) {
13766       case 0x00: { /* SLLI.df */
13767             switch (df) {
13768                case 0x00: { /* SLLI.B */
13769                      DIP("SLLI.B w%d, w%d, %d", wd, ws, m);
13770                      putWReg(wd, binop(Iop_ShlN8x16, getWReg(ws), mkU8(m)));
13771                      break;
13772                   }
13773 
13774                case 0x01: { /* SLLI.H */
13775                      DIP("SLLI.H w%d, w%d, %d", wd, ws, m);
13776                      putWReg(wd, binop(Iop_ShlN16x8, getWReg(ws), mkU8(m)));
13777                      break;
13778                   }
13779 
13780                case 0x02: { /* SLLI.W */
13781                      DIP("SLLI.W w%d, w%d, %d", wd, ws, m);
13782                      putWReg(wd, binop(Iop_ShlN32x4, getWReg(ws), mkU8(m)));
13783                      break;
13784                   }
13785 
13786                case 0x03: { /* SLLI.D */
13787                      DIP("SLLI.D w%d, w%d, %d", wd, ws, m);
13788                      putWReg(wd, binop(Iop_ShlN64x2, getWReg(ws), mkU8(m)));
13789                      break;
13790                   }
13791             }
13792 
13793             break;
13794          }
13795 
13796       case 0x01: { /* SRAI.df */
13797             switch (df) {
13798                case 0x00: { /* SRAI.B */
13799                      DIP("SRAI.B w%d, w%d, %d", wd, ws, m);
13800                      putWReg(wd, binop(Iop_SarN8x16, getWReg(ws), mkU8(m)));
13801                      break;
13802                   }
13803 
13804                case 0x01: { /* SRAI.H */
13805                      DIP("SRAI.H w%d, w%d, %d", wd, ws, m);
13806                      putWReg(wd, binop(Iop_SarN16x8, getWReg(ws), mkU8(m)));
13807                      break;
13808                   }
13809 
13810                case 0x02: { /* SRAI.W */
13811                      DIP("SRAI.W w%d, w%d, %d", wd, ws, m);
13812                      putWReg(wd, binop(Iop_SarN32x4, getWReg(ws), mkU8(m)));
13813                      break;
13814                   }
13815 
13816                case 0x03: { /* SRAI.D */
13817                      DIP("SRAI.D w%d, w%d, %d", wd, ws, m);
13818                      putWReg(wd, binop(Iop_SarN64x2, getWReg(ws), mkU8(m)));
13819                      break;
13820                   }
13821             }
13822 
13823             break;
13824          }
13825 
13826       case 0x02: { /* SRLI.df */
13827             switch (df) {
13828                case 0x00: { /* SRLI.B */
13829                      DIP("SRLI.B w%d, w%d, %d", wd, ws, m);
13830                      putWReg(wd, binop(Iop_ShrN8x16, getWReg(ws), mkU8(m)));
13831                      break;
13832                   }
13833 
13834                case 0x01: { /* SRLI.H */
13835                      DIP("SRLI.H w%d, w%d, %d", wd, ws, m);
13836                      putWReg(wd, binop(Iop_ShrN16x8, getWReg(ws), mkU8(m)));
13837                      break;
13838                   }
13839 
13840                case 0x02: { /* SRLI.W */
13841                      DIP("SRLI.W w%d, w%d, %d", wd, ws, m);
13842                      putWReg(wd, binop(Iop_ShrN32x4, getWReg(ws), mkU8(m)));
13843                      break;
13844                   }
13845 
13846                case 0x03: { /* SRLI.D */
13847                      DIP("SRLI.D w%d, w%d, %d", wd, ws, m);
13848                      putWReg(wd, binop(Iop_ShrN64x2, getWReg(ws), mkU8(m)));
13849                      break;
13850                   }
13851             }
13852 
13853             break;
13854          }
13855 
13856       case 0x03: { /* BCLRI.df */
13857             t1 = newTemp(Ity_V128);
13858             t2 = newTemp(Ity_V128);
13859             t3 = newTemp(Ity_V128);
13860             ULong tmp = 1;
13861             assign(t1, getWReg(ws));
13862 
13863             switch (df) {
13864                case 0x00: { /* BCLRI.B */
13865                      DIP("BCLRI.B w%d, w%d, %d", wd, ws, m);
13866                      tmp |= (tmp << 56) | (tmp << 48) | (tmp << 40) |
13867                             (tmp << 32) | (tmp << 24) | (tmp << 16) |
13868                             (tmp << 8);
13869                      assign(t2, binop(Iop_ShlN8x16,
13870                                       binop(Iop_64HLtoV128,
13871                                             mkU64(tmp), mkU64(tmp)),mkU8(m)));
13872                      break;
13873                   }
13874 
13875                case 0x01: { /* BCLRI.H */
13876                      DIP("BCLRI.H w%d, w%d, %d", wd, ws, m);
13877                      tmp |= (tmp << 48) | (tmp << 32) | (tmp << 16);
13878                      assign(t2, binop(Iop_ShlN16x8,
13879                                       binop(Iop_64HLtoV128,
13880                                             mkU64(tmp), mkU64(tmp)), mkU8(m)));
13881                      break;
13882                   }
13883 
13884                case 0x02: { /* BCLRI.W */
13885                      DIP("BCLRI.W w%d, w%d, %d", wd, ws, m);
13886                      tmp |= (tmp << 32);
13887                      assign(t2, binop(Iop_ShlN32x4,
13888                                       binop(Iop_64HLtoV128,
13889                                             mkU64(tmp), mkU64(tmp)), mkU8(m)));
13890                      break;
13891                   }
13892 
13893                case 0x03: { /* BCLRI.D */
13894                      DIP("BCLRI.D w%d, w%d, %d", wd, ws, m);
13895                      assign(t2, binop(Iop_ShlN64x2,
13896                                       binop(Iop_64HLtoV128,
13897                                             mkU64(tmp), mkU64(tmp)), mkU8(m)));
13898                      break;
13899                   }
13900             }
13901 
13902             assign(t3, binop(Iop_AndV128,
13903                              mkexpr(t1), unop(Iop_NotV128, mkexpr(t2))));
13904             putWReg(wd, mkexpr(t3));
13905             break;
13906          }
13907 
13908       case 0x04: { /* BSETI */
13909             t1 = newTemp(Ity_V128);
13910             t2 = newTemp(Ity_V128);
13911             t3 = newTemp(Ity_V128);
13912             ULong tmp = 1;
13913             assign(t1, getWReg(ws));
13914 
13915             switch (df) {
13916                case 0x00: { /* BSETI.B */
13917                      DIP("BSETI.B w%d, w%d, %d", wd, ws, m);
13918                      tmp |= (tmp << 56) | (tmp << 48) | (tmp << 40) |
13919                             (tmp << 32) | (tmp << 24) | (tmp << 16) |
13920                             (tmp << 8);
13921                      assign(t2, binop(Iop_ShlN8x16,
13922                                       binop(Iop_64HLtoV128,
13923                                             mkU64(tmp), mkU64(tmp)), mkU8(m)));
13924                      break;
13925                   }
13926 
13927                case 0x01: { /* BSETI.H */
13928                      DIP("BSETI.H w%d, w%d, %d", wd, ws, m);
13929                      tmp |= (tmp << 48) | (tmp << 32) | (tmp << 16);
13930                      assign(t2, binop(Iop_ShlN16x8,
13931                                       binop(Iop_64HLtoV128,
13932                                             mkU64(tmp), mkU64(tmp)), mkU8(m)));
13933                      break;
13934                   }
13935 
13936                case 0x02: { /* BSETI.W */
13937                      DIP("BSETI.W w%d, w%d, %d", wd, ws, m);
13938                      tmp |= (tmp << 32);
13939                      assign(t2, binop(Iop_ShlN32x4,
13940                                       binop(Iop_64HLtoV128,
13941                                             mkU64(tmp), mkU64(tmp)), mkU8(m)));
13942                      break;
13943                   }
13944 
13945                case 0x03: { /* BSETI.D */
13946                      DIP("BSETI.D w%d, w%d, %d", wd, ws, m);
13947                      assign(t2, binop(Iop_ShlN64x2,
13948                                       binop(Iop_64HLtoV128,
13949                                             mkU64(tmp), mkU64(tmp)), mkU8(m)));
13950                      break;
13951                   }
13952             }
13953 
13954             assign(t3, binop(Iop_OrV128, mkexpr(t1), mkexpr(t2)));
13955             putWReg(wd, mkexpr(t3));
13956             break;
13957          }
13958 
13959       case 0x05: { /* BNEGI.df */
13960             t1 = newTemp(Ity_V128);
13961             t2 = newTemp(Ity_V128);
13962             t3 = newTemp(Ity_V128);
13963             ULong tmp = 1;
13964             assign(t1, getWReg(ws));
13965 
13966             switch (df) {
13967                case 0x00: { /* BNEGI.B */
13968                      DIP("BNEGI.B w%d, w%d, %d", wd, ws, m);
13969                      tmp |= (tmp << 56) | (tmp << 48) | (tmp << 40) |
13970                             (tmp << 32) | (tmp << 24) | (tmp << 16) |
13971                             (tmp << 8);
13972                      assign(t2, binop(Iop_ShlN8x16,
13973                                       binop(Iop_64HLtoV128,
13974                                             mkU64(tmp), mkU64(tmp)), mkU8(m)));
13975                      break;
13976                   }
13977 
13978                case 0x01: { /* BNEGI.H */
13979                      DIP("BNEGI.H w%d, w%d, %d", wd, ws, m);
13980                      tmp |= (tmp << 48) | (tmp << 32) | (tmp << 16);
13981                      assign(t2, binop(Iop_ShlN16x8,
13982                                       binop(Iop_64HLtoV128,
13983                                             mkU64(tmp), mkU64(tmp)), mkU8(m)));
13984                      break;
13985                   }
13986 
13987                case 0x02: { /* BNEGI.W */
13988                      DIP("BNEGI.W w%d, w%d, %d", wd, ws, m);
13989                      tmp |= (tmp << 32);
13990                      assign(t2, binop(Iop_ShlN32x4,
13991                                       binop(Iop_64HLtoV128,
13992                                             mkU64(tmp), mkU64(tmp)), mkU8(m)));
13993                      break;
13994                   }
13995 
13996                case 0x03: { /* BNEGI.D */
13997                      DIP("BNEGI.D w%d, w%d, %d", wd, ws, m);
13998                      assign(t2, binop(Iop_ShlN64x2,
13999                                       binop(Iop_64HLtoV128,
14000                                             mkU64(tmp), mkU64(tmp)), mkU8(m)));
14001                      break;
14002                   }
14003             }
14004 
14005             assign(t3, binop(Iop_XorV128, mkexpr(t1), mkexpr(t2)));
14006             putWReg(wd, mkexpr(t3));
14007             break;
14008          }
14009 
14010       case 0x06: { /* BINSLI.df */
14011             switch (df) {
14012                case 0x00: { /* BINSLI.B */
14013                      DIP("BINSLI.B w%d, w%d, w%d", wd, ws, m);
14014                      t1 = newTemp(Ity_V128);
14015                      t2 = newTemp(Ity_V128);
14016                      t3 = newTemp(Ity_V128);
14017                      ULong tmp = 0x8080808080808080ULL;
14018                      assign(t1, binop(Iop_SarN8x16,
14019                                   binop(Iop_64HLtoV128,
14020                                         mkU64(tmp), mkU64(tmp)), mkU8(m)));
14021                      assign(t2,
14022                             binop(Iop_AndV128,
14023                                   unop(Iop_NotV128, mkexpr(t1)), getWReg(wd)));
14024                      assign(t3,
14025                             binop(Iop_AndV128,
14026                                   mkexpr(t1), getWReg(ws)));
14027                      putWReg(wd,
14028                              binop(Iop_OrV128,
14029                                    mkexpr(t2), mkexpr(t3)));
14030                      break;
14031                   }
14032 
14033                case 0x01: { /* BINSLI.H */
14034                      DIP("BINSLI.H w%d, w%d, w%d", wd, ws, m);
14035                      t1 = newTemp(Ity_V128);
14036                      t2 = newTemp(Ity_V128);
14037                      t3 = newTemp(Ity_V128);
14038                      ULong tmp = 0x8000800080008000ULL;
14039                      assign(t1,
14040                             binop(Iop_SarN16x8,
14041                                   binop(Iop_64HLtoV128,
14042                                         mkU64(tmp), mkU64(tmp)), mkU8(m)));
14043                      assign(t2,
14044                             binop(Iop_AndV128,
14045                                   unop(Iop_NotV128, mkexpr(t1)), getWReg(wd)));
14046                      assign(t3,
14047                             binop(Iop_AndV128,
14048                                   mkexpr(t1), getWReg(ws)));
14049                      putWReg(wd,
14050                              binop(Iop_OrV128,
14051                                    mkexpr(t2), mkexpr(t3)));
14052                      break;
14053                   }
14054 
14055                case 0x02: { /* BINSLI.W */
14056                      DIP("BINSLI.W w%d, w%d, w%d", wd, ws, m);
14057                      t1 = newTemp(Ity_V128);
14058                      t2 = newTemp(Ity_V128);
14059                      t3 = newTemp(Ity_V128);
14060                      ULong tmp = 0x8000000080000000ULL;
14061                      assign(t1,
14062                             binop(Iop_SarN32x4,
14063                                   binop(Iop_64HLtoV128,
14064                                         mkU64(tmp), mkU64(tmp)), mkU8(m)));
14065                      assign(t2,
14066                             binop(Iop_AndV128,
14067                                   unop(Iop_NotV128, mkexpr(t1)), getWReg(wd)));
14068                      assign(t3,
14069                             binop(Iop_AndV128,
14070                                   mkexpr(t1), getWReg(ws)));
14071                      putWReg(wd,
14072                              binop(Iop_OrV128,
14073                                    mkexpr(t2), mkexpr(t3)));
14074                      break;
14075                   }
14076 
14077                case 0x03: { /* BINSLI.D */
14078                      DIP("BINSLI.D w%d, w%d, w%d", wd, ws, m);
14079                      t1 = newTemp(Ity_V128);
14080                      t2 = newTemp(Ity_V128);
14081                      t3 = newTemp(Ity_V128);
14082                      ULong tmp = 0x8000000000000000ULL;
14083                      assign(t1,
14084                             binop(Iop_SarN64x2,
14085                                   binop(Iop_64HLtoV128,
14086                                         mkU64(tmp), mkU64(tmp)), mkU8(m)));
14087                      assign(t2,
14088                             binop(Iop_AndV128,
14089                                   unop(Iop_NotV128, mkexpr(t1)), getWReg(wd)));
14090                      assign(t3,
14091                             binop(Iop_AndV128,
14092                                   mkexpr(t1), getWReg(ws)));
14093                      putWReg(wd,
14094                              binop(Iop_OrV128,
14095                                    mkexpr(t2), mkexpr(t3)));
14096                      break;
14097                   }
14098 
14099                default:
14100                   return -1;
14101             }
14102 
14103             break;
14104          }
14105 
14106       case 0x07: {
14107             switch (df) {
14108                case 0x00: { /* BINSRI.B */
14109                      DIP("BINSRI.B w%d, w%d, w%d", wd, ws, m);
14110                      t1 = newTemp(Ity_V128);
14111                      t2 = newTemp(Ity_V128);
14112                      t3 = newTemp(Ity_V128);
14113                      ULong tmp = 0xFEFEFEFEFEFEFEFEULL;
14114                      assign(t1,
14115                             binop(Iop_ShlN8x16,
14116                                   binop(Iop_64HLtoV128,
14117                                         mkU64(tmp), mkU64(tmp)), mkU8(m)));
14118                      assign(t2,
14119                             binop(Iop_AndV128,
14120                                   unop(Iop_NotV128, mkexpr(t1)), getWReg(ws)));
14121                      assign(t3,
14122                             binop(Iop_AndV128,
14123                                   mkexpr(t1), getWReg(wd)));
14124                      putWReg(wd,
14125                              binop(Iop_OrV128,
14126                                    mkexpr(t2), mkexpr(t3)));
14127                      break;
14128                   }
14129 
14130                case 0x01: { /* BINSRI.H */
14131                      DIP("BINSRI.H w%d, w%d, w%d", wd, ws, m);
14132                      t1 = newTemp(Ity_V128);
14133                      t2 = newTemp(Ity_V128);
14134                      t3 = newTemp(Ity_V128);
14135                      ULong tmp = 0xFFFEFFFEFFFEFFFEULL;
14136                      assign(t1,
14137                             binop(Iop_ShlN16x8,
14138                                   binop(Iop_64HLtoV128,
14139                                         mkU64(tmp), mkU64(tmp)),
14140                                   mkU8(m)));
14141                      assign(t2,
14142                             binop(Iop_AndV128,
14143                                   unop(Iop_NotV128, mkexpr(t1)),
14144                                   getWReg(ws)));
14145                      assign(t3,
14146                             binop(Iop_AndV128,
14147                                   mkexpr(t1), getWReg(wd)));
14148                      putWReg(wd,
14149                              binop(Iop_OrV128,
14150                                    mkexpr(t2), mkexpr(t3)));
14151                      break;
14152                   }
14153 
14154                case 0x02: { /* BINSRI.W */
14155                      DIP("BINSRI.W w%d, w%d, w%d", wd, ws, m);
14156                      t1 = newTemp(Ity_V128);
14157                      t2 = newTemp(Ity_V128);
14158                      t3 = newTemp(Ity_V128);
14159                      ULong tmp = 0xFFFFFFFEFFFFFFFEULL;
14160                      assign(t1,
14161                             binop(Iop_ShlN32x4,
14162                                   binop(Iop_64HLtoV128,
14163                                         mkU64(tmp), mkU64(tmp)),
14164                                   mkU8(m)));
14165                      assign(t2,
14166                             binop(Iop_AndV128,
14167                                   unop(Iop_NotV128, mkexpr(t1)),
14168                                   getWReg(ws)));
14169                      assign(t3,
14170                             binop(Iop_AndV128,
14171                                   mkexpr(t1), getWReg(wd)));
14172                      putWReg(wd,
14173                              binop(Iop_OrV128,
14174                                    mkexpr(t2), mkexpr(t3)));
14175                      break;
14176                   }
14177 
14178                case 0x03: { /* BINSRI.D */
14179                      DIP("BINSRI.D w%d, w%d, w%d", wd, ws, m);
14180                      t1 = newTemp(Ity_V128);
14181                      t2 = newTemp(Ity_V128);
14182                      t3 = newTemp(Ity_V128);
14183                      ULong tmp = -2;
14184                      assign(t1,
14185                             binop(Iop_ShlN64x2,
14186                                   binop(Iop_64HLtoV128,
14187                                         mkU64(tmp), mkU64(tmp)),
14188                                   mkU8(m)));
14189                      assign(t2,
14190                             binop(Iop_AndV128,
14191                                   unop(Iop_NotV128, mkexpr(t1)),
14192                                   getWReg(ws)));
14193                      assign(t3,
14194                             binop(Iop_AndV128,
14195                                   mkexpr(t1), getWReg(wd)));
14196                      putWReg(wd,
14197                              binop(Iop_OrV128,
14198                                    mkexpr(t2), mkexpr(t3)));
14199                      break;
14200                   }
14201 
14202                default:
14203                   return -1;
14204             }
14205 
14206             break;
14207          }
14208 
14209       default:
14210          return -1;
14211    }
14212 
14213    return 0;
14214 }
14215 
msa_BIT_0A(UInt cins,UChar wd,UChar ws)14216 static Int msa_BIT_0A(UInt cins, UChar wd, UChar ws) { /* BIT (0x0A) */
14217    IRTemp t1, t2;
14218    UShort operation;
14219    UChar df, m;
14220 
14221    operation = (cins & 0x03800000) >> 23;
14222    df = (cins & 0x007F0000) >> 16;
14223 
14224    if ((df & 0x70) == 0x70) {        // 111mmmm; b
14225       m = df & 0x07;
14226       df = 0;
14227    } else if ((df & 0x60) == 0x60) { // 110mmmm; h
14228       m = df & 0x0F;
14229       df = 1;
14230    } else if ((df & 0x40) == 0x40) { // 10mmmmm; w
14231       m = df & 0x1F;
14232       df = 2;
14233    } else if ((df & 0x00) == 0x00) { // 0mmmmmm; d
14234       m = df & 0x3F;
14235       df = 3;
14236    }
14237 
14238    switch (operation) {
14239       case 0x00: { /* SAT_S.df */
14240             switch (df) {
14241                case 0x00: { /* SAT_S.B */
14242                      DIP("SAT_S.B w%d, w%d, %d", wd, ws, m);
14243                      t1 = newTemp(Ity_V128);
14244                      assign(t1, binop(Iop_SarN8x16, getWReg(ws), mkU8(7)));
14245 
14246                      if (m == 0) {
14247                         putWReg(wd, mkexpr(t1));
14248                      } else {
14249                         t2 = newTemp(Ity_V128);
14250                         assign(t2,
14251                                binop(Iop_SarN8x16, getWReg(ws), mkU8(m)));
14252                         putWReg(wd,
14253                                 binop(Iop_OrV128,
14254                                       binop(Iop_OrV128,
14255                                             binop(Iop_AndV128,
14256                                                   binop(Iop_CmpEQ8x16,
14257                                                         mkexpr(t1),
14258                                                         mkexpr(t2)),
14259                                                   getWReg(ws)),
14260                                             binop(Iop_ShlN8x16,
14261                                                   binop(Iop_CmpGT8Sx16,
14262                                                         mkexpr(t1),
14263                                                         mkexpr(t2)),
14264                                                   mkU8(m))),
14265                                       binop(Iop_ShrN8x16,
14266                                             binop(Iop_CmpGT8Sx16,
14267                                                   mkexpr(t2),
14268                                                   mkexpr(t1)),
14269                                             mkU8(8 - m))));
14270                      }
14271 
14272                      break;
14273                   }
14274 
14275                case 0x01: { /* SAT_S.H */
14276                      DIP("SAT_S.H w%d, w%d, %d", wd, ws, m);
14277                      t1 = newTemp(Ity_V128);
14278                      assign(t1, binop(Iop_SarN16x8, getWReg(ws), mkU8(15)));
14279 
14280                      if (m == 0) {
14281                         putWReg(wd, mkexpr(t1));
14282                      } else {
14283                         t2 = newTemp(Ity_V128);
14284                         assign(t2,
14285                                binop(Iop_SarN16x8,
14286                                      getWReg(ws),
14287                                      mkU8(m)));
14288                         putWReg(wd,
14289                                 binop(Iop_OrV128,
14290                                       binop(Iop_OrV128,
14291                                             binop(Iop_AndV128,
14292                                                   binop(Iop_CmpEQ16x8,
14293                                                         mkexpr(t1),
14294                                                         mkexpr(t2)),
14295                                                   getWReg(ws)),
14296                                             binop(Iop_ShlN16x8,
14297                                                   binop(Iop_CmpGT16Sx8,
14298                                                         mkexpr(t1),
14299                                                         mkexpr(t2)),
14300                                                   mkU8(m))),
14301                                       binop(Iop_ShrN16x8,
14302                                             binop(Iop_CmpGT16Sx8,
14303                                                   mkexpr(t2),
14304                                                   mkexpr(t1)),
14305                                             mkU8(16 - m))));
14306                      }
14307 
14308                      break;
14309                   }
14310 
14311                case 0x02: { /* SAT_S.W */
14312                      DIP("SAT_S.W w%d, w%d, %d", wd, ws, m);
14313                      t1 = newTemp(Ity_V128);
14314                      assign(t1, binop(Iop_SarN32x4, getWReg(ws), mkU8(31)));
14315 
14316                      if (m == 0) {
14317                         putWReg(wd, mkexpr(t1));
14318                      } else {
14319                         t2 = newTemp(Ity_V128);
14320                         assign(t2,
14321                                binop(Iop_SarN32x4,
14322                                      getWReg(ws),
14323                                      mkU8(m)));
14324                         putWReg(wd,
14325                                 binop(Iop_OrV128,
14326                                       binop(Iop_OrV128,
14327                                             binop(Iop_AndV128,
14328                                                   binop(Iop_CmpEQ32x4,
14329                                                         mkexpr(t1),
14330                                                         mkexpr(t2)),
14331                                                   getWReg(ws)),
14332                                             binop(Iop_ShlN32x4,
14333                                                   binop(Iop_CmpGT32Sx4,
14334                                                         mkexpr(t1),
14335                                                         mkexpr(t2)),
14336                                                   mkU8(m))),
14337                                       binop(Iop_ShrN32x4,
14338                                             binop(Iop_CmpGT32Sx4,
14339                                                   mkexpr(t2),
14340                                                   mkexpr(t1)),
14341                                             mkU8(32 - m))));
14342                      }
14343 
14344                      break;
14345                   }
14346 
14347                case 0x03: { /* SAT_S.D */
14348                      DIP("SAT_S.D w%d, w%d, %d", wd, ws, m);
14349                      t1 = newTemp(Ity_V128);
14350                      assign(t1, binop(Iop_SarN64x2, getWReg(ws), mkU8(63)));
14351 
14352                      if (m == 0) {
14353                         putWReg(wd, mkexpr(t1));
14354                      } else {
14355                         t2 = newTemp(Ity_V128);
14356                         assign(t2,
14357                                binop(Iop_SarN64x2,
14358                                      getWReg(ws),
14359                                      mkU8(m)));
14360                         putWReg(wd,
14361                                 binop(Iop_OrV128,
14362                                       binop(Iop_OrV128,
14363                                             binop(Iop_AndV128,
14364                                                   binop(Iop_CmpEQ64x2,
14365                                                         mkexpr(t1),
14366                                                         mkexpr(t2)),
14367                                                   getWReg(ws)),
14368                                             binop(Iop_ShlN64x2,
14369                                                   binop(Iop_CmpGT64Sx2,
14370                                                         mkexpr(t1),
14371                                                         mkexpr(t2)),
14372                                                   mkU8(m))),
14373                                       binop(Iop_ShrN64x2,
14374                                             binop(Iop_CmpGT64Sx2,
14375                                                   mkexpr(t2),
14376                                                   mkexpr(t1)),
14377                                             mkU8(64 - m))));
14378                      }
14379 
14380                      break;
14381                   }
14382             }
14383 
14384             break;
14385          }
14386 
14387       case 0x01: { /* SAT_U.df */
14388             switch (df) {
14389                case 0x00: { /* SAT_U.B */
14390                      DIP("SAT_U.B w%d, w%d, %d", wd, ws, m);
14391 
14392                      if (m == 7) {
14393                         putWReg(wd, getWReg(ws));
14394                      } else {
14395                         t1 = newTemp(Ity_V128);
14396                         assign(t1,
14397                                binop(Iop_CmpEQ8x16,
14398                                      binop(Iop_ShrN8x16,
14399                                            getWReg(ws),
14400                                            mkU8(m + 1)),
14401                                      binop(Iop_64HLtoV128,
14402                                            mkU64(0), mkU64(0))));
14403                         putWReg(wd,
14404                                 binop(Iop_OrV128,
14405                                       binop(Iop_AndV128,
14406                                             mkexpr(t1),
14407                                             getWReg(ws)),
14408                                       binop(Iop_ShrN8x16,
14409                                             unop(Iop_NotV128,
14410                                                  mkexpr(t1)),
14411                                             mkU8(7 - m))));
14412                      }
14413 
14414                      break;
14415                   }
14416 
14417                case 0x01: { /* SAT_U.H */
14418                      DIP("SAT_U.H w%d, w%d, %d", wd, ws, m);
14419 
14420                      if (m == 15) {
14421                         putWReg(wd, getWReg(ws));
14422                      } else {
14423                         t1 = newTemp(Ity_V128);
14424                         assign(t1,
14425                                binop(Iop_CmpEQ16x8,
14426                                      binop(Iop_ShrN16x8,
14427                                            getWReg(ws),
14428                                            mkU8(m + 1)),
14429                                      binop(Iop_64HLtoV128,
14430                                            mkU64(0), mkU64(0))));
14431                         putWReg(wd,
14432                                 binop(Iop_OrV128,
14433                                       binop(Iop_AndV128,
14434                                             mkexpr(t1),
14435                                             getWReg(ws)),
14436                                       binop(Iop_ShrN16x8,
14437                                             unop(Iop_NotV128,
14438                                                  mkexpr(t1)),
14439                                             mkU8(15 - m))));
14440                      }
14441 
14442                      break;
14443                   }
14444 
14445                case 0x02: { /* SAT_U.W */
14446                      DIP("SAT_U.W w%d, w%d, %d", wd, ws, m);
14447 
14448                      if (m == 31) {
14449                         putWReg(wd, getWReg(ws));
14450                      } else {
14451                         t1 = newTemp(Ity_V128);
14452                         assign(t1,
14453                                binop(Iop_CmpEQ32x4,
14454                                      binop(Iop_ShrN32x4,
14455                                            getWReg(ws),
14456                                            mkU8(m + 1)),
14457                                      binop(Iop_64HLtoV128,
14458                                            mkU64(0), mkU64(0))));
14459                         putWReg(wd,
14460                                 binop(Iop_OrV128,
14461                                       binop(Iop_AndV128,
14462                                             mkexpr(t1), \
14463                                             getWReg(ws)),
14464                                       binop(Iop_ShrN32x4,
14465                                             unop(Iop_NotV128,
14466                                                  mkexpr(t1)),
14467                                             mkU8(31 - m))));
14468                      }
14469 
14470                      break;
14471                   }
14472 
14473                case 0x03: { /* SAT_U.D */
14474                      DIP("SAT_U.D w%d, w%d, %d", wd, ws, m);
14475 
14476                      if (m == 63) {
14477                         putWReg(wd, getWReg(ws));
14478                      } else {
14479                         t1 = newTemp(Ity_V128);
14480                         assign(t1,
14481                                binop(Iop_CmpEQ64x2,
14482                                      binop(Iop_ShrN64x2,
14483                                            getWReg(ws),
14484                                            mkU8(m + 1)),
14485                                      binop(Iop_64HLtoV128,
14486                                            mkU64(0), mkU64(0))));
14487                         putWReg(wd,
14488                                 binop(Iop_OrV128,
14489                                       binop(Iop_AndV128,
14490                                             mkexpr(t1),
14491                                             getWReg(ws)),
14492                                       binop(Iop_ShrN64x2,
14493                                             unop(Iop_NotV128,
14494                                                  mkexpr(t1)),
14495                                             mkU8(63 - m))));
14496                      }
14497 
14498                      break;
14499                   }
14500             }
14501 
14502             break;
14503          }
14504 
14505       case 0x02: { /* SRARI.df */
14506             switch (df) {
14507                case 0x00: { /* SRARI.B */
14508                      DIP("SRARI.B w%d, w%d, %d", wd, ws, m);
14509                      t1 = newTemp(Ity_V128);
14510                      t2 = newTemp(Ity_V128);
14511                      assign(t1,
14512                             binop(Iop_SarN8x16,
14513                                   getWReg(ws),
14514                                   mkU8(m)));
14515                      assign(t2,
14516                             binop(Iop_ShrN8x16,
14517                                   binop(Iop_ShlN8x16,
14518                                         getWReg(ws),
14519                                         mkU8(8 - m)),
14520                                   mkU8(7)));
14521 
14522                      if (m) putWReg(wd, binop(Iop_Add8x16,
14523                                               mkexpr(t1),
14524                                               mkexpr(t2)));
14525                      else putWReg(wd, mkexpr(t1));
14526 
14527                      break;
14528                   }
14529 
14530                case 0x01: { /* SRARI.H */
14531                      DIP("SRARI.H w%d, w%d, %d", wd, ws, m);
14532                      t1 = newTemp(Ity_V128);
14533                      t2 = newTemp(Ity_V128);
14534                      assign(t1,
14535                             binop(Iop_SarN16x8,
14536                                   getWReg(ws),
14537                                   mkU8(m)));
14538                      assign(t2,
14539                             binop(Iop_ShrN16x8,
14540                                   binop(Iop_ShlN16x8,
14541                                         getWReg(ws),
14542                                         mkU8(16 - m)),
14543                                   mkU8(15)));
14544 
14545                      if (m)
14546                         putWReg(wd,
14547                                 binop(Iop_Add16x8,
14548                                       mkexpr(t1), mkexpr(t2)));
14549                      else putWReg(wd, mkexpr(t1));
14550 
14551                      break;
14552                   }
14553 
14554                case 0x02: { /* SRARI.W */
14555                      DIP("SRARI.W w%d, w%d, %d", wd, ws, m);
14556                      t1 = newTemp(Ity_V128);
14557                      t2 = newTemp(Ity_V128);
14558                      assign(t1,
14559                             binop(Iop_SarN32x4,
14560                                   getWReg(ws),
14561                                   mkU8(m)));
14562                      assign(t2,
14563                             binop(Iop_ShrN32x4,
14564                                   binop(Iop_ShlN32x4,
14565                                         getWReg(ws),
14566                                         mkU8(32 - m)),
14567                                   mkU8(31)));
14568 
14569                      if (m)
14570                         putWReg(wd,
14571                                 binop(Iop_Add32x4,
14572                                       mkexpr(t1), mkexpr(t2)));
14573                      else putWReg(wd, mkexpr(t1));
14574 
14575                      break;
14576                   }
14577 
14578                case 0x03: { /* SRARI.D */
14579                      DIP("SRARI.D w%d, w%d, %d", wd, ws, m);
14580                      t1 = newTemp(Ity_V128);
14581                      t2 = newTemp(Ity_V128);
14582                      assign(t1,
14583                             binop(Iop_SarN64x2,
14584                                   getWReg(ws),
14585                                   mkU8(m)));
14586                      assign(t2,
14587                             binop(Iop_ShrN64x2,
14588                                   binop(Iop_ShlN64x2,
14589                                         getWReg(ws),
14590                                         mkU8(64 - m)),
14591                                   mkU8(63)));
14592 
14593                      if (m)
14594                         putWReg(wd,
14595                                 binop(Iop_Add64x2,
14596                                       mkexpr(t1), mkexpr(t2)));
14597                      else putWReg(wd, mkexpr(t1));
14598 
14599                      break;
14600                   }
14601             }
14602 
14603             break;
14604          }
14605 
14606       case 0x03: { /* SRLRI.df */
14607             switch (df) {
14608                case 0x00: { /* SRLRI.B */
14609                      DIP("SRLRI.B w%d, w%d, %d", wd, ws, m);
14610                      t1 = newTemp(Ity_V128);
14611                      t2 = newTemp(Ity_V128);
14612                      assign(t1,
14613                             binop(Iop_ShrN8x16,
14614                                   getWReg(ws),
14615                                   mkU8(m)));
14616                      assign(t2,
14617                             binop(Iop_ShrN8x16,
14618                                   binop(Iop_ShlN8x16,
14619                                         getWReg(ws),
14620                                         mkU8(8 - m)),
14621                                   mkU8(7)));
14622 
14623                      if (m)
14624                         putWReg(wd,
14625                                 binop(Iop_Add8x16,
14626                                       mkexpr(t1), mkexpr(t2)));
14627                      else putWReg(wd, mkexpr(t1));
14628 
14629                      break;
14630                   }
14631 
14632                case 0x01: { /* SRLRI.H */
14633                      DIP("SRLRI.H w%d, w%d, %d", wd, ws, m);
14634                      t1 = newTemp(Ity_V128);
14635                      t2 = newTemp(Ity_V128);
14636                      assign(t1,
14637                             binop(Iop_ShrN16x8,
14638                                   getWReg(ws),
14639                                   mkU8(m)));
14640                      assign(t2,
14641                             binop(Iop_ShrN16x8,
14642                                   binop(Iop_ShlN16x8,
14643                                         getWReg(ws),
14644                                         mkU8(16 - m)),
14645                                   mkU8(15)));
14646 
14647                      if (m)
14648                         putWReg(wd,
14649                                 binop(Iop_Add16x8,
14650                                       mkexpr(t1), mkexpr(t2)));
14651                      else putWReg(wd, mkexpr(t1));
14652 
14653                      break;
14654                   }
14655 
14656                case 0x02: { /* SRLRI.W */
14657                      DIP("SRLRI.W w%d, w%d, %d", wd, ws, m);
14658                      t1 = newTemp(Ity_V128);
14659                      t2 = newTemp(Ity_V128);
14660                      assign(t1,
14661                             binop(Iop_ShrN32x4,
14662                                   getWReg(ws),
14663                                   mkU8(m)));
14664                      assign(t2,
14665                             binop(Iop_ShrN32x4,
14666                                   binop(Iop_ShlN32x4,
14667                                         getWReg(ws),
14668                                         mkU8(32 - m)),
14669                                   mkU8(31)));
14670 
14671                      if (m)
14672                         putWReg(wd,
14673                                 binop(Iop_Add32x4,
14674                                       mkexpr(t1), mkexpr(t2)));
14675                      else putWReg(wd, mkexpr(t1));
14676 
14677                      break;
14678                   }
14679 
14680                case 0x03: { /* SRLRI.D */
14681                      DIP("SRLRI.D w%d, w%d, %d", wd, ws, m);
14682                      t1 = newTemp(Ity_V128);
14683                      t2 = newTemp(Ity_V128);
14684                      assign(t1,
14685                             binop(Iop_ShrN64x2,
14686                                   getWReg(ws),
14687                                   mkU8(m)));
14688                      assign(t2,
14689                             binop(Iop_ShrN64x2,
14690                                   binop(Iop_ShlN64x2,
14691                                         getWReg(ws),
14692                                         mkU8(64 - m)),
14693                                   mkU8(63)));
14694 
14695                      if (m)
14696                         putWReg(wd,
14697                                 binop(Iop_Add64x2,
14698                                       mkexpr(t1), mkexpr(t2)));
14699                      else putWReg(wd, mkexpr(t1));
14700 
14701                      break;
14702                   }
14703             }
14704 
14705             break;
14706          }
14707 
14708       default:
14709          return -1;
14710    }
14711 
14712    return 0;
14713 }
14714 
msa_3R_0D(UInt cins,UChar wd,UChar ws)14715 static Int msa_3R_0D(UInt cins, UChar wd, UChar ws) { /* 3R (0x0D) */
14716    IRTemp t1, t2, t3;
14717    UShort operation;
14718    UChar df, wt;
14719 
14720    operation = (cins & 0x03800000) >> 23;
14721    df = (cins & 0x00600000) >> 21;
14722    wt = (cins & 0x001F0000) >> 16;
14723 
14724    switch (operation) {
14725       case 0x00: { /* SLL.df */
14726             switch (df) {
14727                case 0x00: { /* SLL.B */
14728                      DIP("SLL.B w%d, w%d, w%d", wd, ws, wt);
14729                      t1 = newTemp(Ity_V128);
14730                      t2 = newTemp(Ity_V128);
14731                      t3 = newTemp(Ity_V128);
14732                      assign(t1, getWReg(ws));
14733                      assign(t2, getWReg(wt));
14734                      assign(t3, binop(Iop_Shl8x16, mkexpr(t1), mkexpr(t2)));
14735                      putWReg(wd, mkexpr(t3));
14736                      break;
14737                   }
14738 
14739                case 0x01: { /* SLL.H */
14740                      DIP("SLL.H w%d, w%d, w%d", wd, ws, wt);
14741                      t1 = newTemp(Ity_V128);
14742                      t2 = newTemp(Ity_V128);
14743                      t3 = newTemp(Ity_V128);
14744                      assign(t1, getWReg(ws));
14745                      assign(t2, getWReg(wt));
14746                      assign(t3, binop(Iop_Shl16x8, mkexpr(t1), mkexpr(t2)));
14747                      putWReg(wd, mkexpr(t3));
14748                      break;
14749                   }
14750 
14751                case 0x02: { /* SLL.W */
14752                      DIP("SLL.W w%d, w%d, w%d", wd, ws, wt);
14753                      t1 = newTemp(Ity_V128);
14754                      t2 = newTemp(Ity_V128);
14755                      t3 = newTemp(Ity_V128);
14756                      assign(t1, getWReg(ws));
14757                      assign(t2, getWReg(wt));
14758                      assign(t3, binop(Iop_Shl32x4, mkexpr(t1), mkexpr(t2)));
14759                      putWReg(wd, mkexpr(t3));
14760                      break;
14761                   }
14762 
14763                case 0x03: { /* SLL.D */
14764                      DIP("SLL.D w%d, w%d, w%d", wd, ws, wt);
14765                      t1 = newTemp(Ity_V128);
14766                      t2 = newTemp(Ity_V128);
14767                      t3 = newTemp(Ity_V128);
14768                      assign(t1, getWReg(ws));
14769                      assign(t2, getWReg(wt));
14770                      assign(t3, binop(Iop_Shl64x2, mkexpr(t1), mkexpr(t2)));
14771                      putWReg(wd, mkexpr(t3));
14772                      break;
14773                   }
14774 
14775                default:
14776                   return -1;
14777             }
14778 
14779             break;
14780          }
14781 
14782       case 0x01: { /* SRA.df */
14783             switch (df) {
14784                case 0x00: { /* SRA.B */
14785                      DIP("SRA.B w%d, w%d, w%d", wd, ws, wt);
14786                      t1 = newTemp(Ity_V128);
14787                      t2 = newTemp(Ity_V128);
14788                      t3 = newTemp(Ity_V128);
14789                      assign(t1, getWReg(ws));
14790                      assign(t2, getWReg(wt));
14791                      assign(t3, binop(Iop_Sar8x16, mkexpr(t1), mkexpr(t2)));
14792                      putWReg(wd, mkexpr(t3));
14793                      break;
14794                   }
14795 
14796                case 0x01: { /* SRA.H */
14797                      DIP("SRA.H w%d, w%d, w%d", wd, ws, wt);
14798                      t1 = newTemp(Ity_V128);
14799                      t2 = newTemp(Ity_V128);
14800                      t3 = newTemp(Ity_V128);
14801                      assign(t1, getWReg(ws));
14802                      assign(t2, getWReg(wt));
14803                      assign(t3, binop(Iop_Sar16x8, mkexpr(t1), mkexpr(t2)));
14804                      putWReg(wd, mkexpr(t3));
14805                      break;
14806                   }
14807 
14808                case 0x02: { /* SRA.W */
14809                      DIP("SRA.W w%d, w%d, w%d", wd, ws, wt);
14810                      t1 = newTemp(Ity_V128);
14811                      t2 = newTemp(Ity_V128);
14812                      t3 = newTemp(Ity_V128);
14813                      assign(t1, getWReg(ws));
14814                      assign(t2, getWReg(wt));
14815                      assign(t3, binop(Iop_Sar32x4, mkexpr(t1), mkexpr(t2)));
14816                      putWReg(wd, mkexpr(t3));
14817                      break;
14818                   }
14819 
14820                case 0x03: { /* SRA.D */
14821                      DIP("SRA.D w%d, w%d, w%d", wd, ws, wt);
14822                      t1 = newTemp(Ity_V128);
14823                      t2 = newTemp(Ity_V128);
14824                      t3 = newTemp(Ity_V128);
14825                      assign(t1, getWReg(ws));
14826                      assign(t2, getWReg(wt));
14827                      assign(t3, binop(Iop_Sar64x2, mkexpr(t1), mkexpr(t2)));
14828                      putWReg(wd, mkexpr(t3));
14829                      break;
14830                   }
14831 
14832                default:
14833                   return -1;
14834             }
14835 
14836             break;
14837          }
14838 
14839       case 0x02: { /* SRL.df */
14840             switch (df) {
14841                case 0x00: { /* SRL.B */
14842                      DIP("SRL.B w%d, w%d, w%d", wd, ws, wt);
14843                      t1 = newTemp(Ity_V128);
14844                      t2 = newTemp(Ity_V128);
14845                      t3 = newTemp(Ity_V128);
14846                      assign(t1, getWReg(ws));
14847                      assign(t2, getWReg(wt));
14848                      assign(t3, binop(Iop_Shr8x16, mkexpr(t1), mkexpr(t2)));
14849                      putWReg(wd, mkexpr(t3));
14850                      break;
14851                   }
14852 
14853                case 0x01: { /* SRL.H */
14854                      DIP("SRL.H w%d, w%d, w%d", wd, ws, wt);
14855                      t1 = newTemp(Ity_V128);
14856                      t2 = newTemp(Ity_V128);
14857                      t3 = newTemp(Ity_V128);
14858                      assign(t1, getWReg(ws));
14859                      assign(t2, getWReg(wt));
14860                      assign(t3, binop(Iop_Shr16x8, mkexpr(t1), mkexpr(t2)));
14861                      putWReg(wd, mkexpr(t3));
14862                      break;
14863                   }
14864 
14865                case 0x02: { /* SRL.W */
14866                      DIP("SRL.W w%d, w%d, w%d", wd, ws, wt);
14867                      t1 = newTemp(Ity_V128);
14868                      t2 = newTemp(Ity_V128);
14869                      t3 = newTemp(Ity_V128);
14870                      assign(t1, getWReg(ws));
14871                      assign(t2, getWReg(wt));
14872                      assign(t3, binop(Iop_Shr32x4, mkexpr(t1), mkexpr(t2)));
14873                      putWReg(wd, mkexpr(t3));
14874                      break;
14875                   }
14876 
14877                case 0x03: { /* SRL.D */
14878                      DIP("SRL.D w%d, w%d, w%d", wd, ws, wt);
14879                      t1 = newTemp(Ity_V128);
14880                      t2 = newTemp(Ity_V128);
14881                      t3 = newTemp(Ity_V128);
14882                      assign(t1, getWReg(ws));
14883                      assign(t2, getWReg(wt));
14884                      assign(t3, binop(Iop_Shr64x2, mkexpr(t1), mkexpr(t2)));
14885                      putWReg(wd, mkexpr(t3));
14886                      break;
14887                   }
14888 
14889                default:
14890                   return -1;
14891             }
14892 
14893             break;
14894          }
14895 
14896       case 0x03: { /* BCLR.df */
14897             t1 = newTemp(Ity_V128);
14898             t2 = newTemp(Ity_V128);
14899             t3 = newTemp(Ity_V128);
14900             ULong tmp = 1;
14901             assign(t1, getWReg(ws));
14902 
14903             switch (df) {
14904                case 0x00: { /* BCLR.B */
14905                      DIP("BCLR.B w%d, w%d, w%d", wd, ws, wt);
14906                      tmp |= (tmp << 56) | (tmp << 48) | (tmp << 40) |
14907                             (tmp << 32) | (tmp << 24) | (tmp << 16) |
14908                             (tmp << 8);
14909                      assign(t2, binop(Iop_Shl8x16,
14910                                       binop(Iop_64HLtoV128,
14911                                             mkU64(tmp), mkU64(tmp)),
14912                                       getWReg(wt)));
14913                      break;
14914                   }
14915 
14916                case 0x01: { /* BCLR.H */
14917                      DIP("BCLR.H w%d, w%d, w%d", wd, ws, wt);
14918                      tmp |= (tmp << 48) | (tmp << 32) | (tmp << 16);
14919                      assign(t2,
14920                             binop(Iop_Shl16x8,
14921                                   binop(Iop_64HLtoV128,
14922                                         mkU64(tmp), mkU64(tmp)),
14923                                   getWReg(wt)));
14924                      break;
14925                   }
14926 
14927                case 0x02: { /* BCLR.W */
14928                      DIP("BCLR.W w%d, w%d, w%d", wd, ws, wt);
14929                      tmp |= (tmp << 32);
14930                      assign(t2,
14931                             binop(Iop_Shl32x4,
14932                                   binop(Iop_64HLtoV128,
14933                                         mkU64(tmp), mkU64(tmp)),
14934                                   getWReg(wt)));
14935                      break;
14936                   }
14937 
14938                case 0x03: { /* BCLR.D */
14939                      DIP("BCLR.D w%d, w%d, w%d", wd, ws, wt);
14940                      assign(t2,
14941                             binop(Iop_Shl64x2,
14942                                   binop(Iop_64HLtoV128,
14943                                         mkU64(tmp), mkU64(tmp)),
14944                                   getWReg(wt)));
14945                      break;
14946                   }
14947             }
14948 
14949             assign(t3,
14950                    binop(Iop_AndV128,
14951                          mkexpr(t1), unop(Iop_NotV128, mkexpr(t2))));
14952             putWReg(wd, mkexpr(t3));
14953             break;
14954          }
14955 
14956       case 0x04: { /* BSET.df */
14957             t1 = newTemp(Ity_V128);
14958             t2 = newTemp(Ity_V128);
14959             t3 = newTemp(Ity_V128);
14960             ULong tmp = 1;
14961             assign(t1, getWReg(ws));
14962 
14963             switch (df) {
14964                case 0x00: { /* BSET.B */
14965                      DIP("BSET.B w%d, w%d, w%d", wd, ws, wt);
14966                      tmp |= (tmp << 56) | (tmp << 48) | (tmp << 40) |
14967                             (tmp << 32) | (tmp << 24) | (tmp << 16) |
14968                             (tmp << 8);
14969                      assign(t2,
14970                             binop(Iop_Shl8x16,
14971                                   binop(Iop_64HLtoV128,
14972                                         mkU64(tmp), mkU64(tmp)),
14973                                   getWReg(wt)));
14974                      break;
14975                   }
14976 
14977                case 0x01: { /* BSET.H */
14978                      DIP("BSET.H w%d, w%d, w%d", wd, ws, wt);
14979                      tmp |= (tmp << 48) | (tmp << 32) | (tmp << 16);
14980                      assign(t2,
14981                             binop(Iop_Shl16x8,
14982                                   binop(Iop_64HLtoV128,
14983                                         mkU64(tmp), mkU64(tmp)),
14984                                   getWReg(wt)));
14985                      break;
14986                   }
14987 
14988                case 0x02: { /* BSET.W */
14989                      DIP("BSET.W w%d, w%d, w%d", wd, ws, wt);
14990                      tmp |= (tmp << 32);
14991                      assign(t2,
14992                             binop(Iop_Shl32x4,
14993                                   binop(Iop_64HLtoV128,
14994                                         mkU64(tmp), mkU64(tmp)),
14995                                   getWReg(wt)));
14996                      break;
14997                   }
14998 
14999                case 0x03: { /* BSET.D */
15000                      DIP("BSET.D w%d, w%d, w%d", wd, ws, wt);
15001                      assign(t2,
15002                             binop(Iop_Shl64x2,
15003                                   binop(Iop_64HLtoV128,
15004                                         mkU64(tmp), mkU64(tmp)),
15005                                   getWReg(wt)));
15006                      break;
15007                   }
15008             }
15009 
15010             assign(t3, binop(Iop_OrV128, mkexpr(t1), mkexpr(t2)));
15011             putWReg(wd, mkexpr(t3));
15012             break;
15013          }
15014 
15015       case 0x05: { /* BNEG.df */
15016             t1 = newTemp(Ity_V128);
15017             t2 = newTemp(Ity_V128);
15018             t3 = newTemp(Ity_V128);
15019             ULong tmp = 1;
15020             assign(t1, getWReg(ws));
15021 
15022             switch (df) {
15023                case 0x00: { /* BNEG.B */
15024                      DIP("BNEG.B w%d, w%d, w%d", wd, ws, wt);
15025                      tmp |= (tmp << 56) | (tmp << 48) | (tmp << 40) |
15026                             (tmp << 32) | (tmp << 24) | (tmp << 16) |
15027                             (tmp << 8);
15028                      assign(t2,
15029                             binop(Iop_Shl8x16,
15030                                   binop(Iop_64HLtoV128,
15031                                         mkU64(tmp), mkU64(tmp)),
15032                                   getWReg(wt)));
15033                      break;
15034                   }
15035 
15036                case 0x01: { /* BNEG.H */
15037                      DIP("BNEG.H w%d, w%d, w%d", wd, ws, wt);
15038                      tmp |= (tmp << 48) | (tmp << 32) | (tmp << 16);
15039                      assign(t2,
15040                             binop(Iop_Shl16x8,
15041                                   binop(Iop_64HLtoV128,
15042                                         mkU64(tmp), mkU64(tmp)),
15043                                   getWReg(wt)));
15044                      break;
15045                   }
15046 
15047                case 0x02: { /* BNEG.W */
15048                      DIP("BNEG.W w%d, w%d, w%d", wd, ws, wt);
15049                      tmp |= (tmp << 32);
15050                      assign(t2,
15051                             binop(Iop_Shl32x4,
15052                                   binop(Iop_64HLtoV128,
15053                                         mkU64(tmp), mkU64(tmp)),
15054                                   getWReg(wt)));
15055                      break;
15056                   }
15057 
15058                case 0x03: { /* BNEG.D */
15059                      DIP("BNEG.D w%d, w%d, w%d", wd, ws, wt);
15060                      assign(t2,
15061                             binop(Iop_Shl64x2,
15062                                   binop(Iop_64HLtoV128,
15063                                         mkU64(tmp), mkU64(tmp)),
15064                                   getWReg(wt)));
15065                      break;
15066                   }
15067             }
15068 
15069             assign(t3, binop(Iop_XorV128, mkexpr(t1), mkexpr(t2)));
15070             putWReg(wd, mkexpr(t3));
15071             break;
15072          }
15073 
15074       case 0x06: { /* BINSL.df */
15075             switch (df) {
15076                case 0x00: { /* BINSL.B */
15077                      DIP("BINSL.B w%d, w%d, w%d", wd, ws, wt);
15078                      t1 = newTemp(Ity_V128);
15079                      t2 = newTemp(Ity_V128);
15080                      t3 = newTemp(Ity_V128);
15081                      ULong tmp = 0x8080808080808080ULL;
15082                      assign(t1,
15083                             binop(Iop_Sar8x16,
15084                                   binop(Iop_64HLtoV128,
15085                                         mkU64(tmp), mkU64(tmp)),
15086                                   getWReg(wt)));
15087                      assign(t2,
15088                             binop(Iop_AndV128,
15089                                   unop(Iop_NotV128, mkexpr(t1)),
15090                                   getWReg(wd)));
15091                      assign(t3,
15092                             binop(Iop_AndV128,
15093                                   mkexpr(t1), getWReg(ws)));
15094                      putWReg(wd,
15095                              binop(Iop_OrV128,
15096                                    mkexpr(t2), mkexpr(t3)));
15097                      break;
15098                   }
15099 
15100                case 0x01: { /* BINSL.H */
15101                      DIP("BINSL.H w%d, w%d, w%d", wd, ws, wt);
15102                      t1 = newTemp(Ity_V128);
15103                      t2 = newTemp(Ity_V128);
15104                      t3 = newTemp(Ity_V128);
15105                      ULong tmp = 0x8000800080008000ULL;
15106                      assign(t1,
15107                             binop(Iop_Sar16x8,
15108                                   binop(Iop_64HLtoV128,
15109                                         mkU64(tmp), mkU64(tmp)),
15110                                   getWReg(wt)));
15111                      assign(t2,
15112                             binop(Iop_AndV128,
15113                                   unop(Iop_NotV128, mkexpr(t1)),
15114                                   getWReg(wd)));
15115                      assign(t3,
15116                             binop(Iop_AndV128,
15117                                   mkexpr(t1), getWReg(ws)));
15118                      putWReg(wd,
15119                              binop(Iop_OrV128,
15120                                    mkexpr(t2), mkexpr(t3)));
15121                      break;
15122                   }
15123 
15124                case 0x02: { /* BINSL.W */
15125                      DIP("BINSL.W w%d, w%d, w%d", wd, ws, wt);
15126                      t1 = newTemp(Ity_V128);
15127                      t2 = newTemp(Ity_V128);
15128                      t3 = newTemp(Ity_V128);
15129                      ULong tmp = 0x8000000080000000ULL;
15130                      assign(t1,
15131                             binop(Iop_Sar32x4,
15132                                   binop(Iop_64HLtoV128,
15133                                         mkU64(tmp), mkU64(tmp)),
15134                                   getWReg(wt)));
15135                      assign(t2,
15136                             binop(Iop_AndV128,
15137                                   unop(Iop_NotV128, mkexpr(t1)),
15138                                   getWReg(wd)));
15139                      assign(t3,
15140                             binop(Iop_AndV128,
15141                                   mkexpr(t1), getWReg(ws)));
15142                      putWReg(wd,
15143                              binop(Iop_OrV128,
15144                                    mkexpr(t2), mkexpr(t3)));
15145                      break;
15146                   }
15147 
15148                case 0x03: { /* BINSL.D */
15149                      DIP("BINSL.D w%d, w%d, w%d", wd, ws, wt);
15150                      t1 = newTemp(Ity_V128);
15151                      t2 = newTemp(Ity_V128);
15152                      t3 = newTemp(Ity_V128);
15153                      ULong tmp = 0x8000000000000000ULL;
15154                      assign(t1,
15155                             binop(Iop_Sar64x2,
15156                                   binop(Iop_64HLtoV128,
15157                                         mkU64(tmp), mkU64(tmp)),
15158                                   getWReg(wt)));
15159                      assign(t2,
15160                             binop(Iop_AndV128,
15161                                   unop(Iop_NotV128, mkexpr(t1)),
15162                                   getWReg(wd)));
15163                      assign(t3,
15164                             binop(Iop_AndV128,
15165                                   mkexpr(t1), getWReg(ws)));
15166                      putWReg(wd,
15167                              binop(Iop_OrV128,
15168                                    mkexpr(t2), mkexpr(t3)));
15169                      break;
15170                   }
15171 
15172                default:
15173                   return -1;
15174             }
15175 
15176             break;
15177          }
15178 
15179       case 0x07: { /* BINSR.df */
15180             switch (df) {
15181                case 0x00: { /* BINSR.B */
15182                      DIP("BINSR.B w%d, w%d, w%d", wd, ws, wt);
15183                      t1 = newTemp(Ity_V128);
15184                      t2 = newTemp(Ity_V128);
15185                      t3 = newTemp(Ity_V128);
15186                      ULong tmp = 0xFEFEFEFEFEFEFEFEULL;
15187                      assign(t1,
15188                             binop(Iop_Shl8x16,
15189                                   binop(Iop_64HLtoV128,
15190                                         mkU64(tmp), mkU64(tmp)),
15191                                   getWReg(wt)));
15192                      assign(t2,
15193                             binop(Iop_AndV128,
15194                                   unop(Iop_NotV128, mkexpr(t1)),
15195                                   getWReg(ws)));
15196                      assign(t3,
15197                             binop(Iop_AndV128,
15198                                   mkexpr(t1), getWReg(wd)));
15199                      putWReg(wd,
15200                              binop(Iop_OrV128,
15201                                    mkexpr(t2), mkexpr(t3)));
15202                      break;
15203                   }
15204 
15205                case 0x01: { /* BINSR.H */
15206                      DIP("BINSR.H w%d, w%d, w%d", wd, ws, wt);
15207                      t1 = newTemp(Ity_V128);
15208                      t2 = newTemp(Ity_V128);
15209                      t3 = newTemp(Ity_V128);
15210                      ULong tmp = 0xFFFEFFFEFFFEFFFEULL;
15211                      assign(t1,
15212                             binop(Iop_Shl16x8,
15213                                   binop(Iop_64HLtoV128,
15214                                         mkU64(tmp), mkU64(tmp)),
15215                                   getWReg(wt)));
15216                      assign(t2,
15217                             binop(Iop_AndV128,
15218                                   unop(Iop_NotV128, mkexpr(t1)),
15219                                   getWReg(ws)));
15220                      assign(t3,
15221                             binop(Iop_AndV128,
15222                                   mkexpr(t1), getWReg(wd)));
15223                      putWReg(wd,
15224                              binop(Iop_OrV128,
15225                                    mkexpr(t2), mkexpr(t3)));
15226                      break;
15227                   }
15228 
15229                case 0x02: { /* BINSR.W */
15230                      DIP("BINSR.W w%d, w%d, w%d", wd, ws, wt);
15231                      t1 = newTemp(Ity_V128);
15232                      t2 = newTemp(Ity_V128);
15233                      t3 = newTemp(Ity_V128);
15234                      ULong tmp = 0xFFFFFFFEFFFFFFFEULL;
15235                      assign(t1,
15236                             binop(Iop_Shl32x4,
15237                                   binop(Iop_64HLtoV128,
15238                                         mkU64(tmp), mkU64(tmp)),
15239                                   getWReg(wt)));
15240                      assign(t2,
15241                             binop(Iop_AndV128,
15242                                   unop(Iop_NotV128, mkexpr(t1)),
15243                                   getWReg(ws)));
15244                      assign(t3,
15245                             binop(Iop_AndV128,
15246                                   mkexpr(t1), getWReg(wd)));
15247                      putWReg(wd,
15248                              binop(Iop_OrV128,
15249                                    mkexpr(t2), mkexpr(t3)));
15250                      break;
15251                   }
15252 
15253                case 0x03: { /* BINSR.D */
15254                      DIP("BINSR.D w%d, w%d, w%d", wd, ws, wt);
15255                      t1 = newTemp(Ity_V128);
15256                      t2 = newTemp(Ity_V128);
15257                      t3 = newTemp(Ity_V128);
15258                      ULong tmp = -2;
15259                      assign(t1,
15260                             binop(Iop_Shl64x2,
15261                                   binop(Iop_64HLtoV128,
15262                                         mkU64(tmp), mkU64(tmp)),
15263                                   getWReg(wt)));
15264                      assign(t2,
15265                             binop(Iop_AndV128,
15266                                   unop(Iop_NotV128, mkexpr(t1)),
15267                                   getWReg(ws)));
15268                      assign(t3,
15269                             binop(Iop_AndV128,
15270                                   mkexpr(t1), getWReg(wd)));
15271                      putWReg(wd,
15272                              binop(Iop_OrV128,
15273                                    mkexpr(t2), mkexpr(t3)));
15274                      break;
15275                   }
15276 
15277                default:
15278                   return -1;
15279             }
15280 
15281             break;
15282          }
15283 
15284       default:
15285          return -1;
15286    }
15287 
15288    return 0;
15289 }
15290 
msa_3R_0E(UInt cins,UChar wd,UChar ws)15291 static Int msa_3R_0E(UInt cins, UChar wd, UChar ws) { /* 3R (0x0E) */
15292    IRTemp t1, t2, t3, t4;
15293    UShort operation;
15294    UChar df, wt;
15295 
15296    operation = (cins & 0x03800000) >> 23;
15297    df = (cins & 0x00600000) >> 21;
15298    wt = (cins & 0x001F0000) >> 16;
15299 
15300    switch (operation) {
15301       case 0x00: { /* ADDV.df */
15302             switch (df) {
15303                case 0x00: { /* ADDV.B */
15304                      DIP("ADDV.B w%d, w%d, w%d", wd, ws, wt);
15305                      t1 = newTemp(Ity_V128);
15306                      t2 = newTemp(Ity_V128);
15307                      t3 = newTemp(Ity_V128);
15308                      assign(t1, getWReg(ws));
15309                      assign(t2, getWReg(wt));
15310                      assign(t3, binop(Iop_Add8x16, mkexpr(t1), mkexpr(t2)));
15311                      putWReg(wd, mkexpr(t3));
15312                      break;
15313                   }
15314 
15315                case 0x01: { /* ADDV.H */
15316                      DIP("ADDV.H w%d, w%d, w%d", wd, ws, wt);
15317                      t1 = newTemp(Ity_V128);
15318                      t2 = newTemp(Ity_V128);
15319                      t3 = newTemp(Ity_V128);
15320                      assign(t1, getWReg(ws));
15321                      assign(t2, getWReg(wt));
15322                      assign(t3, binop(Iop_Add16x8, mkexpr(t1), mkexpr(t2)));
15323                      putWReg(wd, mkexpr(t3));
15324                      break;
15325                   }
15326 
15327                case 0x02: { /* ADDV.W */
15328                      DIP("ADDV.W w%d, w%d, w%d", wd, ws, wt);
15329                      t1 = newTemp(Ity_V128);
15330                      t2 = newTemp(Ity_V128);
15331                      t3 = newTemp(Ity_V128);
15332                      assign(t1, getWReg(ws));
15333                      assign(t2, getWReg(wt));
15334                      assign(t3, binop(Iop_Add32x4, mkexpr(t1), mkexpr(t2)));
15335                      putWReg(wd, mkexpr(t3));
15336                      break;
15337                   }
15338 
15339                case 0x03: { /* ADDV.D */
15340                      DIP("ADDV.D w%d, w%d, w%d", wd, ws, wt);
15341                      t1 = newTemp(Ity_V128);
15342                      t2 = newTemp(Ity_V128);
15343                      t3 = newTemp(Ity_V128);
15344                      assign(t1, getWReg(ws));
15345                      assign(t2, getWReg(wt));
15346                      assign(t3, binop(Iop_Add64x2, mkexpr(t1), mkexpr(t2)));
15347                      putWReg(wd, mkexpr(t3));
15348                      break;
15349                   }
15350 
15351                default:
15352                   return -1;
15353             }
15354 
15355             break;
15356          }
15357 
15358       case 0x01: { /* SUBV.df */
15359             switch (df) {
15360                case 0x00: { /* SUBV.B */
15361                      DIP("SUBV.B w%d, w%d, w%d", wd, ws, wt);
15362                      t1 = newTemp(Ity_V128);
15363                      t2 = newTemp(Ity_V128);
15364                      t3 = newTemp(Ity_V128);
15365                      assign(t1, getWReg(ws));
15366                      assign(t2, getWReg(wt));
15367                      assign(t3, binop(Iop_Sub8x16, mkexpr(t1), mkexpr(t2)));
15368                      putWReg(wd, mkexpr(t3));
15369                      break;
15370                   }
15371 
15372                case 0x01: { /* SUBV.H */
15373                      DIP("SUBV.H w%d, w%d, w%d", wd, ws, wt);
15374                      t1 = newTemp(Ity_V128);
15375                      t2 = newTemp(Ity_V128);
15376                      t3 = newTemp(Ity_V128);
15377                      assign(t1, getWReg(ws));
15378                      assign(t2, getWReg(wt));
15379                      assign(t3, binop(Iop_Sub16x8, mkexpr(t1), mkexpr(t2)));
15380                      putWReg(wd, mkexpr(t3));
15381                      break;
15382                   }
15383 
15384                case 0x02: { /* SUBV.W */
15385                      DIP("SUBV.W w%d, w%d, w%d", wd, ws, wt);
15386                      t1 = newTemp(Ity_V128);
15387                      t2 = newTemp(Ity_V128);
15388                      t3 = newTemp(Ity_V128);
15389                      assign(t1, getWReg(ws));
15390                      assign(t2, getWReg(wt));
15391                      assign(t3, binop(Iop_Sub32x4, mkexpr(t1), mkexpr(t2)));
15392                      putWReg(wd, mkexpr(t3));
15393                      break;
15394                   }
15395 
15396                case 0x03: { /* SUBV.D */
15397                      DIP("SUBV.D w%d, w%d, w%d", wd, ws, wt);
15398                      t1 = newTemp(Ity_V128);
15399                      t2 = newTemp(Ity_V128);
15400                      t3 = newTemp(Ity_V128);
15401                      assign(t1, getWReg(ws));
15402                      assign(t2, getWReg(wt));
15403                      assign(t3, binop(Iop_Sub64x2, mkexpr(t1), mkexpr(t2)));
15404                      putWReg(wd, mkexpr(t3));
15405                      break;
15406                   }
15407 
15408                default:
15409                   return -1;
15410             }
15411 
15412             break;
15413          }
15414 
15415       case 0x02: { /* MAX_S.df */
15416             switch (df) {
15417                case 0x00: { /* MAX_S.B */
15418                      DIP("MAX_S.B w%d, w%d, w%d", wd, ws, wt);
15419                      t1 = newTemp(Ity_V128);
15420                      t2 = newTemp(Ity_V128);
15421                      t3 = newTemp(Ity_V128);
15422                      assign(t1, getWReg(ws));
15423                      assign(t2, getWReg(wt));
15424                      assign(t3, binop(Iop_Max8Sx16, mkexpr(t1), mkexpr(t2)));
15425                      putWReg(wd, mkexpr(t3));
15426                      break;
15427                   }
15428 
15429                case 0x01: { /* MAX_S.H */
15430                      DIP("MAX_S.H w%d, w%d, w%d", wd, ws, wt);
15431                      t1 = newTemp(Ity_V128);
15432                      t2 = newTemp(Ity_V128);
15433                      t3 = newTemp(Ity_V128);
15434                      assign(t1, getWReg(ws));
15435                      assign(t2, getWReg(wt));
15436                      assign(t3, binop(Iop_Max16Sx8, mkexpr(t1), mkexpr(t2)));
15437                      putWReg(wd, mkexpr(t3));
15438                      break;
15439                   }
15440 
15441                case 0x02: { /* MAX_S.W */
15442                      DIP("MAX_S.W w%d, w%d, w%d", wd, ws, wt);
15443                      t1 = newTemp(Ity_V128);
15444                      t2 = newTemp(Ity_V128);
15445                      t3 = newTemp(Ity_V128);
15446                      assign(t1, getWReg(ws));
15447                      assign(t2, getWReg(wt));
15448                      assign(t3, binop(Iop_Max32Sx4, mkexpr(t1), mkexpr(t2)));
15449                      putWReg(wd, mkexpr(t3));
15450                      break;
15451                   }
15452 
15453                case 0x03: { /* MAX_S.D */
15454                      DIP("MAX_S.D w%d, w%d, w%d", wd, ws, wt);
15455                      t1 = newTemp(Ity_V128);
15456                      t2 = newTemp(Ity_V128);
15457                      t3 = newTemp(Ity_V128);
15458                      assign(t1, getWReg(ws));
15459                      assign(t2, getWReg(wt));
15460                      assign(t3, binop(Iop_Max64Sx2, mkexpr(t1), mkexpr(t2)));
15461                      putWReg(wd, mkexpr(t3));
15462                      break;
15463                   }
15464 
15465                default:
15466                   return -1;
15467             }
15468 
15469             break;
15470          }
15471 
15472       case 0x03: { /* MAX_U.df */
15473             switch (df) {
15474                case 0x00: { /* MAX_U.B */
15475                      DIP("MAX_U.B w%d, w%d, w%d", wd, ws, wt);
15476                      t1 = newTemp(Ity_V128);
15477                      t2 = newTemp(Ity_V128);
15478                      t3 = newTemp(Ity_V128);
15479                      assign(t1, getWReg(ws));
15480                      assign(t2, getWReg(wt));
15481                      assign(t3, binop(Iop_Max8Ux16, mkexpr(t1), mkexpr(t2)));
15482                      putWReg(wd, mkexpr(t3));
15483                      break;
15484                   }
15485 
15486                case 0x01: { /* MAX_U.H */
15487                      DIP("MAX_U.H w%d, w%d, w%d", wd, ws, wt);
15488                      t1 = newTemp(Ity_V128);
15489                      t2 = newTemp(Ity_V128);
15490                      t3 = newTemp(Ity_V128);
15491                      assign(t1, getWReg(ws));
15492                      assign(t2, getWReg(wt));
15493                      assign(t3, binop(Iop_Max16Ux8, mkexpr(t1), mkexpr(t2)));
15494                      putWReg(wd, mkexpr(t3));
15495                      break;
15496                   }
15497 
15498                case 0x02: { /* MAX_U.W */
15499                      DIP("MAX_U.W w%d, w%d, w%d", wd, ws, wt);
15500                      t1 = newTemp(Ity_V128);
15501                      t2 = newTemp(Ity_V128);
15502                      t3 = newTemp(Ity_V128);
15503                      assign(t1, getWReg(ws));
15504                      assign(t2, getWReg(wt));
15505                      assign(t3, binop(Iop_Max32Ux4, mkexpr(t1), mkexpr(t2)));
15506                      putWReg(wd, mkexpr(t3));
15507                      break;
15508                   }
15509 
15510                case 0x03: { /* MAX_U.D */
15511                      DIP("MAX_U.D w%d, w%d, w%d", wd, ws, wt);
15512                      t1 = newTemp(Ity_V128);
15513                      t2 = newTemp(Ity_V128);
15514                      t3 = newTemp(Ity_V128);
15515                      assign(t1, getWReg(ws));
15516                      assign(t2, getWReg(wt));
15517                      assign(t3, binop(Iop_Max64Ux2, mkexpr(t1), mkexpr(t2)));
15518                      putWReg(wd, mkexpr(t3));
15519                      break;
15520                   }
15521 
15522                default:
15523                   return -1;
15524             }
15525 
15526             break;
15527          }
15528 
15529       case 0x04: { /* MIN_S.df */
15530             switch (df) {
15531                case 0x00: { /* MIN_S.B */
15532                      DIP("MIN_S.B w%d, w%d, w%d", wd, ws, wt);
15533                      t1 = newTemp(Ity_V128);
15534                      t2 = newTemp(Ity_V128);
15535                      t3 = newTemp(Ity_V128);
15536                      assign(t1, getWReg(ws));
15537                      assign(t2, getWReg(wt));
15538                      assign(t3, binop(Iop_Min8Sx16, mkexpr(t1), mkexpr(t2)));
15539                      putWReg(wd, mkexpr(t3));
15540                      break;
15541                   }
15542 
15543                case 0x01: { /* MIN_S.H */
15544                      DIP("MIN_S.H w%d, w%d, w%d", wd, ws, wt);
15545                      t1 = newTemp(Ity_V128);
15546                      t2 = newTemp(Ity_V128);
15547                      t3 = newTemp(Ity_V128);
15548                      assign(t1, getWReg(ws));
15549                      assign(t2, getWReg(wt));
15550                      assign(t3, binop(Iop_Min16Sx8, mkexpr(t1), mkexpr(t2)));
15551                      putWReg(wd, mkexpr(t3));
15552                      break;
15553                   }
15554 
15555                case 0x02: { /* MIN_S.W */
15556                      DIP("MIN_S.W w%d, w%d, w%d", wd, ws, wt);
15557                      t1 = newTemp(Ity_V128);
15558                      t2 = newTemp(Ity_V128);
15559                      t3 = newTemp(Ity_V128);
15560                      assign(t1, getWReg(ws));
15561                      assign(t2, getWReg(wt));
15562                      assign(t3, binop(Iop_Min32Sx4, mkexpr(t1), mkexpr(t2)));
15563                      putWReg(wd, mkexpr(t3));
15564                      break;
15565                   }
15566 
15567                case 0x03: { /* MIN_S.D */
15568                      DIP("MIN_S.D w%d, w%d, w%d", wd, ws, wt);
15569                      t1 = newTemp(Ity_V128);
15570                      t2 = newTemp(Ity_V128);
15571                      t3 = newTemp(Ity_V128);
15572                      assign(t1, getWReg(ws));
15573                      assign(t2, getWReg(wt));
15574                      assign(t3, binop(Iop_Min64Sx2, mkexpr(t1), mkexpr(t2)));
15575                      putWReg(wd, mkexpr(t3));
15576                      break;
15577                   }
15578 
15579                default:
15580                   return -1;
15581             }
15582 
15583             break;
15584          }
15585 
15586       case 0x05: { /* MIN_U.df */
15587             switch (df) {
15588                case 0x00: { /* MIN_U.B */
15589                      DIP("MIN_U.B w%d, w%d, w%d", wd, ws, wt);
15590                      t1 = newTemp(Ity_V128);
15591                      t2 = newTemp(Ity_V128);
15592                      t3 = newTemp(Ity_V128);
15593                      assign(t1, getWReg(ws));
15594                      assign(t2, getWReg(wt));
15595                      assign(t3, binop(Iop_Min8Ux16, mkexpr(t1), mkexpr(t2)));
15596                      putWReg(wd, mkexpr(t3));
15597                      break;
15598                   }
15599 
15600                case 0x01: { /* MIN_U.H */
15601                      DIP("MIN_U.H w%d, w%d, w%d", wd, ws, wt);
15602                      t1 = newTemp(Ity_V128);
15603                      t2 = newTemp(Ity_V128);
15604                      t3 = newTemp(Ity_V128);
15605                      assign(t1, getWReg(ws));
15606                      assign(t2, getWReg(wt));
15607                      assign(t3, binop(Iop_Min16Ux8, mkexpr(t1), mkexpr(t2)));
15608                      putWReg(wd, mkexpr(t3));
15609                      break;
15610                   }
15611 
15612                case 0x02: { /* MIN_U.W */
15613                      DIP("MIN_U.W w%d, w%d, w%d", wd, ws, wt);
15614                      t1 = newTemp(Ity_V128);
15615                      t2 = newTemp(Ity_V128);
15616                      t3 = newTemp(Ity_V128);
15617                      assign(t1, getWReg(ws));
15618                      assign(t2, getWReg(wt));
15619                      assign(t3, binop(Iop_Min32Ux4, mkexpr(t1), mkexpr(t2)));
15620                      putWReg(wd, mkexpr(t3));
15621                      break;
15622                   }
15623 
15624                case 0x03: { /* MIN_U.D */
15625                      DIP("MIN_U.D w%d, w%d, w%d", wd, ws, wt);
15626                      t1 = newTemp(Ity_V128);
15627                      t2 = newTemp(Ity_V128);
15628                      t3 = newTemp(Ity_V128);
15629                      assign(t1, getWReg(ws));
15630                      assign(t2, getWReg(wt));
15631                      assign(t3, binop(Iop_Min64Ux2, mkexpr(t1), mkexpr(t2)));
15632                      putWReg(wd, mkexpr(t3));
15633                      break;
15634                   }
15635 
15636                default:
15637                   return -1;
15638             }
15639 
15640             break;
15641          }
15642 
15643       case 0x06: { /* MAX_A.df */
15644             switch (df) {
15645                case 0x00: { /* MAX_A.B */
15646                      DIP("MAX_A.B w%d, w%d, w%d", wd, ws, wt);
15647                      t1 = newTemp(Ity_V128);
15648                      t2 = newTemp(Ity_V128);
15649                      t3 = newTemp(Ity_V128);
15650                      t4 = newTemp(Ity_V128);
15651                      assign(t1, unop(Iop_Abs8x16, getWReg(ws)));
15652                      assign(t2, unop(Iop_Abs8x16, getWReg(wt)));
15653                      assign(t4, binop(Iop_CmpGT8Ux16, mkexpr(t1), mkexpr(t2)));
15654                      assign(t3, binop(Iop_OrV128,
15655                                       binop(Iop_AndV128,
15656                                             mkexpr(t4),
15657                                             getWReg(ws)),
15658                                       binop(Iop_AndV128,
15659                                             unop(Iop_NotV128, mkexpr(t4)),
15660                                             getWReg(wt))));
15661                      putWReg(wd, mkexpr(t3));
15662                      break;
15663                   }
15664 
15665                case 0x01: { /* MAX_A.H */
15666                      DIP("MAX_A.H w%d, w%d, w%d", wd, ws, wt);
15667                      t1 = newTemp(Ity_V128);
15668                      t2 = newTemp(Ity_V128);
15669                      t3 = newTemp(Ity_V128);
15670                      t4 = newTemp(Ity_V128);
15671                      assign(t1, unop(Iop_Abs16x8, getWReg(ws)));
15672                      assign(t2, unop(Iop_Abs16x8, getWReg(wt)));
15673                      assign(t4, binop(Iop_CmpGT16Ux8, mkexpr(t1), mkexpr(t2)));
15674                      assign(t3, binop(Iop_OrV128,
15675                                       binop(Iop_AndV128,
15676                                             mkexpr(t4),
15677                                             getWReg(ws)),
15678                                       binop(Iop_AndV128,
15679                                             unop(Iop_NotV128, mkexpr(t4)),
15680                                             getWReg(wt))));
15681                      putWReg(wd, mkexpr(t3));
15682                      break;
15683                   }
15684 
15685                case 0x02: { /* MAX_A.W */
15686                      DIP("MAX_A.W w%d, w%d, w%d", wd, ws, wt);
15687                      t1 = newTemp(Ity_V128);
15688                      t2 = newTemp(Ity_V128);
15689                      t3 = newTemp(Ity_V128);
15690                      t4 = newTemp(Ity_V128);
15691                      assign(t1, unop(Iop_Abs32x4, getWReg(ws)));
15692                      assign(t2, unop(Iop_Abs32x4, getWReg(wt)));
15693                      assign(t4, binop(Iop_CmpGT32Ux4, mkexpr(t1), mkexpr(t2)));
15694                      assign(t3, binop(Iop_OrV128,
15695                                       binop(Iop_AndV128,
15696                                             mkexpr(t4),
15697                                             getWReg(ws)),
15698                                       binop(Iop_AndV128,
15699                                             unop(Iop_NotV128, mkexpr(t4)),
15700                                             getWReg(wt))));
15701                      putWReg(wd, mkexpr(t3));
15702                      break;
15703                   }
15704 
15705                case 0x03: { /* MAX_A.D */
15706                      DIP("MAX_A.D w%d, w%d, w%d", wd, ws, wt);
15707                      t1 = newTemp(Ity_V128);
15708                      t2 = newTemp(Ity_V128);
15709                      t3 = newTemp(Ity_V128);
15710                      t4 = newTemp(Ity_V128);
15711                      assign(t1, unop(Iop_Abs64x2, getWReg(ws)));
15712                      assign(t2, unop(Iop_Abs64x2, getWReg(wt)));
15713                      assign(t4, binop(Iop_CmpGT64Ux2, mkexpr(t1), mkexpr(t2)));
15714                      assign(t3, binop(Iop_OrV128,
15715                                       binop(Iop_AndV128,
15716                                             mkexpr(t4),
15717                                             getWReg(ws)),
15718                                       binop(Iop_AndV128,
15719                                             unop(Iop_NotV128, mkexpr(t4)),
15720                                             getWReg(wt))));
15721                      putWReg(wd, mkexpr(t3));
15722                      break;
15723                   }
15724 
15725                default:
15726                   return -1;
15727             }
15728 
15729             break;
15730          }
15731 
15732       case 0x07: { /* MIN_A.df */
15733             switch (df) {
15734                case 0x00: { /* MIN_A.B */
15735                      DIP("MIN_A.B w%d, w%d, w%d", wd, ws, wt);
15736                      t1 = newTemp(Ity_V128);
15737                      t2 = newTemp(Ity_V128);
15738                      t3 = newTemp(Ity_V128);
15739                      t4 = newTemp(Ity_V128);
15740                      assign(t1, unop(Iop_Abs8x16, getWReg(ws)));
15741                      assign(t2, unop(Iop_Abs8x16, getWReg(wt)));
15742                      assign(t4, binop(Iop_OrV128,
15743                                       binop(Iop_CmpGT8Ux16,
15744                                             mkexpr(t1), mkexpr(t2)),
15745                                       binop(Iop_CmpEQ8x16,
15746                                             mkexpr(t1), mkexpr(t2))));
15747                      assign(t3, binop(Iop_OrV128,
15748                                       binop(Iop_AndV128,
15749                                             mkexpr(t4),
15750                                             getWReg(wt)),
15751                                       binop(Iop_AndV128,
15752                                             unop(Iop_NotV128, mkexpr(t4)),
15753                                             getWReg(ws))));
15754                      putWReg(wd, mkexpr(t3));
15755                      break;
15756                   }
15757 
15758                case 0x01: { /* MIN_A.H */
15759                      DIP("MIN_A.H w%d, w%d, w%d", wd, ws, wt);
15760                      t1 = newTemp(Ity_V128);
15761                      t2 = newTemp(Ity_V128);
15762                      t3 = newTemp(Ity_V128);
15763                      t4 = newTemp(Ity_V128);
15764                      assign(t1, unop(Iop_Abs16x8, getWReg(ws)));
15765                      assign(t2, unop(Iop_Abs16x8, getWReg(wt)));
15766                      assign(t4, binop(Iop_OrV128,
15767                                       binop(Iop_CmpGT16Ux8,
15768                                             mkexpr(t1), mkexpr(t2)),
15769                                       binop(Iop_CmpEQ16x8,
15770                                             mkexpr(t1), mkexpr(t2))));
15771                      assign(t3, binop(Iop_OrV128,
15772                                       binop(Iop_AndV128,
15773                                             mkexpr(t4),
15774                                             getWReg(wt)),
15775                                       binop(Iop_AndV128,
15776                                             unop(Iop_NotV128, mkexpr(t4)),
15777                                             getWReg(ws))));
15778                      putWReg(wd, mkexpr(t3));
15779                      break;
15780                   }
15781 
15782                case 0x02: { /* MIN_A.W */
15783                      DIP("MIN_A.W w%d, w%d, w%d", wd, ws, wt);
15784                      t1 = newTemp(Ity_V128);
15785                      t2 = newTemp(Ity_V128);
15786                      t3 = newTemp(Ity_V128);
15787                      t4 = newTemp(Ity_V128);
15788                      assign(t1, unop(Iop_Abs32x4, getWReg(ws)));
15789                      assign(t2, unop(Iop_Abs32x4, getWReg(wt)));
15790                      assign(t4, binop(Iop_OrV128,
15791                                       binop(Iop_CmpGT32Ux4,
15792                                             mkexpr(t1), mkexpr(t2)),
15793                                       binop(Iop_CmpEQ32x4,
15794                                             mkexpr(t1), mkexpr(t2))));
15795                      assign(t3, binop(Iop_OrV128,
15796                                       binop(Iop_AndV128,
15797                                             mkexpr(t4),
15798                                             getWReg(wt)),
15799                                       binop(Iop_AndV128,
15800                                             unop(Iop_NotV128, mkexpr(t4)),
15801                                             getWReg(ws))));
15802                      putWReg(wd, mkexpr(t3));
15803                      break;
15804                   }
15805 
15806                case 0x03: { /* MIN_A.D */
15807                      DIP("MIN_A.D w%d, w%d, w%d", wd, ws, wt);
15808                      t1 = newTemp(Ity_V128);
15809                      t2 = newTemp(Ity_V128);
15810                      t3 = newTemp(Ity_V128);
15811                      t4 = newTemp(Ity_V128);
15812                      assign(t1, unop(Iop_Abs64x2, getWReg(ws)));
15813                      assign(t2, unop(Iop_Abs64x2, getWReg(wt)));
15814                      assign(t4, binop(Iop_OrV128,
15815                                       binop(Iop_CmpGT64Ux2,
15816                                             mkexpr(t1), mkexpr(t2)),
15817                                       binop(Iop_CmpEQ64x2,
15818                                             mkexpr(t1), mkexpr(t2))));
15819                      assign(t3, binop(Iop_OrV128,
15820                                       binop(Iop_AndV128,
15821                                             mkexpr(t4),
15822                                             getWReg(wt)),
15823                                       binop(Iop_AndV128,
15824                                             unop(Iop_NotV128, mkexpr(t4)),
15825                                             getWReg(ws))));
15826                      putWReg(wd, mkexpr(t3));
15827                      break;
15828                   }
15829 
15830                default:
15831                   return -1;
15832             }
15833 
15834             break;
15835          }
15836 
15837       default:
15838          return -1;
15839    }
15840 
15841    return 0;
15842 }
15843 
msa_3R_0F(UInt cins,UChar wd,UChar ws)15844 static Int msa_3R_0F(UInt cins, UChar wd, UChar ws) { /* 3R (0x0F) */
15845    IRTemp t1, t2, t3;
15846    UShort operation;
15847    UChar df, wt;
15848 
15849    operation = (cins & 0x03800000) >> 23;
15850    df = (cins & 0x00600000) >> 21;
15851    wt = (cins & 0x001F0000) >> 16;
15852 
15853    switch (operation) {
15854       case 0x00: { /* CEQ.df */
15855             switch (df) {
15856                case 0x00: { /* CEQ.B */
15857                      DIP("CEQ.B w%d, w%d, w%d", wd, ws, wt);
15858                      t1 = newTemp(Ity_V128);
15859                      t2 = newTemp(Ity_V128);
15860                      t3 = newTemp(Ity_V128);
15861                      assign(t1, getWReg(ws));
15862                      assign(t2, getWReg(wt));
15863                      assign(t3, binop(Iop_CmpEQ8x16, mkexpr(t1), mkexpr(t2)));
15864                      putWReg(wd, mkexpr(t3));
15865                      break;
15866                   }
15867 
15868                case 0x01: { /* CEQ.H */
15869                      DIP("CEQ.H w%d, w%d, w%d", wd, ws, wt);
15870                      t1 = newTemp(Ity_V128);
15871                      t2 = newTemp(Ity_V128);
15872                      t3 = newTemp(Ity_V128);
15873                      assign(t1, getWReg(ws));
15874                      assign(t2, getWReg(wt));
15875                      assign(t3, binop(Iop_CmpEQ16x8, mkexpr(t1), mkexpr(t2)));
15876                      putWReg(wd, mkexpr(t3));
15877                      break;
15878                   }
15879 
15880                case 0x02: { /* CEQ.W */
15881                      DIP("CEQ.W w%d, w%d, w%d", wd, ws, wt);
15882                      t1 = newTemp(Ity_V128);
15883                      t2 = newTemp(Ity_V128);
15884                      t3 = newTemp(Ity_V128);
15885                      assign(t1, getWReg(ws));
15886                      assign(t2, getWReg(wt));
15887                      assign(t3, binop(Iop_CmpEQ32x4, mkexpr(t1), mkexpr(t2)));
15888                      putWReg(wd, mkexpr(t3));
15889                      break;
15890                   }
15891 
15892                case 0x03: { /* CEQ.D */
15893                      DIP("CEQ.D w%d, w%d, w%d", wd, ws, wt);
15894                      t1 = newTemp(Ity_V128);
15895                      t2 = newTemp(Ity_V128);
15896                      t3 = newTemp(Ity_V128);
15897                      assign(t1, getWReg(ws));
15898                      assign(t2, getWReg(wt));
15899                      assign(t3, binop(Iop_CmpEQ64x2, mkexpr(t1), mkexpr(t2)));
15900                      putWReg(wd, mkexpr(t3));
15901                      break;
15902                   }
15903 
15904                default:
15905                   return -1;
15906             }
15907 
15908             break;
15909          }
15910 
15911       case 0x02: { /* CLT_S.df */
15912             switch (df) {
15913                case 0x00: { /* CLT_S.B */
15914                      DIP("CLT_S.B w%d, w%d, w%d", wd, ws, wt);
15915                      t1 = newTemp(Ity_V128);
15916                      t2 = newTemp(Ity_V128);
15917                      t3 = newTemp(Ity_V128);
15918                      assign(t1, getWReg(ws));
15919                      assign(t2, getWReg(wt));
15920                      assign(t3, binop(Iop_CmpGT8Sx16, mkexpr(t2), mkexpr(t1)));
15921                      putWReg(wd, mkexpr(t3));
15922                      break;
15923                   }
15924 
15925                case 0x01: { /* CLT_S.H */
15926                      DIP("CLT_S.H w%d, w%d, w%d", wd, ws, wt);
15927                      t1 = newTemp(Ity_V128);
15928                      t2 = newTemp(Ity_V128);
15929                      t3 = newTemp(Ity_V128);
15930                      assign(t1, getWReg(ws));
15931                      assign(t2, getWReg(wt));
15932                      assign(t3, binop(Iop_CmpGT16Sx8, mkexpr(t2), mkexpr(t1)));
15933                      putWReg(wd, mkexpr(t3));
15934                      break;
15935                   }
15936 
15937                case 0x02: { /* CLT_S.W */
15938                      DIP("CLT_S.W w%d, w%d, w%d", wd, ws, wt);
15939                      t1 = newTemp(Ity_V128);
15940                      t2 = newTemp(Ity_V128);
15941                      t3 = newTemp(Ity_V128);
15942                      assign(t1, getWReg(ws));
15943                      assign(t2, getWReg(wt));
15944                      assign(t3, binop(Iop_CmpGT32Sx4, mkexpr(t2), mkexpr(t1)));
15945                      putWReg(wd, mkexpr(t3));
15946                      break;
15947                   }
15948 
15949                case 0x03: { /* CLT_S.D */
15950                      DIP("CLT_S.D w%d, w%d, w%d", wd, ws, wt);
15951                      t1 = newTemp(Ity_V128);
15952                      t2 = newTemp(Ity_V128);
15953                      t3 = newTemp(Ity_V128);
15954                      assign(t1, getWReg(ws));
15955                      assign(t2, getWReg(wt));
15956                      assign(t3, binop(Iop_CmpGT64Sx2, mkexpr(t2), mkexpr(t1)));
15957                      putWReg(wd, mkexpr(t3));
15958                      break;
15959                   }
15960 
15961                default:
15962                   return -1;
15963             }
15964 
15965             break;
15966          }
15967 
15968       case 0x03: { /* CLT_U.df */
15969             switch (df) {
15970                case 0x00: { /* CLT_U.B */
15971                      DIP("CLT_U.B w%d, w%d, w%d", wd, ws, wt);
15972                      t1 = newTemp(Ity_V128);
15973                      t2 = newTemp(Ity_V128);
15974                      t3 = newTemp(Ity_V128);
15975                      assign(t1, getWReg(ws));
15976                      assign(t2, getWReg(wt));
15977                      assign(t3, binop(Iop_CmpGT8Ux16, mkexpr(t2), mkexpr(t1)));
15978                      putWReg(wd, mkexpr(t3));
15979                      break;
15980                   }
15981 
15982                case 0x01: { /* CLT_U.H */
15983                      DIP("CLT_U.H w%d, w%d, w%d", wd, ws, wt);
15984                      t1 = newTemp(Ity_V128);
15985                      t2 = newTemp(Ity_V128);
15986                      t3 = newTemp(Ity_V128);
15987                      assign(t1, getWReg(ws));
15988                      assign(t2, getWReg(wt));
15989                      assign(t3, binop(Iop_CmpGT16Ux8, mkexpr(t2), mkexpr(t1)));
15990                      putWReg(wd, mkexpr(t3));
15991                      break;
15992                   }
15993 
15994                case 0x02: { /* CLT_U.W */
15995                      DIP("CLT_U.W w%d, w%d, w%d", wd, ws, wt);
15996                      t1 = newTemp(Ity_V128);
15997                      t2 = newTemp(Ity_V128);
15998                      t3 = newTemp(Ity_V128);
15999                      assign(t1, getWReg(ws));
16000                      assign(t2, getWReg(wt));
16001                      assign(t3, binop(Iop_CmpGT32Ux4, mkexpr(t2), mkexpr(t1)));
16002                      putWReg(wd, mkexpr(t3));
16003                      break;
16004                   }
16005 
16006                case 0x03: { /* CLT_U.D */
16007                      DIP("CLT_U.D w%d, w%d, w%d", wd, ws, wt);
16008                      t1 = newTemp(Ity_V128);
16009                      t2 = newTemp(Ity_V128);
16010                      t3 = newTemp(Ity_V128);
16011                      assign(t1, getWReg(ws));
16012                      assign(t2, getWReg(wt));
16013                      assign(t3, binop(Iop_CmpGT64Ux2, mkexpr(t2), mkexpr(t1)));
16014                      putWReg(wd, mkexpr(t3));
16015                      break;
16016                   }
16017 
16018                default:
16019                   return -1;
16020             }
16021 
16022             break;
16023          }
16024 
16025       case 0x04: { /* CLE_S.df */
16026             switch (df) {
16027                case 0x00: { /* CLE_S.B */
16028                      DIP("CLE_S.B w%d, w%d, w%d", wd, ws, wt);
16029                      t1 = newTemp(Ity_V128);
16030                      t2 = newTemp(Ity_V128);
16031                      t3 = newTemp(Ity_V128);
16032                      assign(t1, getWReg(ws));
16033                      assign(t2, getWReg(wt));
16034                      assign(t3, binop(Iop_OrV128,
16035                                       binop(Iop_CmpGT8Sx16,
16036                                             mkexpr(t2), mkexpr(t1)),
16037                                       binop(Iop_CmpEQ8x16,
16038                                             mkexpr(t1), mkexpr(t2))));
16039                      putWReg(wd, mkexpr(t3));
16040                      break;
16041                   }
16042 
16043                case 0x01: { /* CLE_S.H */
16044                      DIP("CLE_S.H w%d, w%d, w%d", wd, ws, wt);
16045                      t1 = newTemp(Ity_V128);
16046                      t2 = newTemp(Ity_V128);
16047                      t3 = newTemp(Ity_V128);
16048                      assign(t1, getWReg(ws));
16049                      assign(t2, getWReg(wt));
16050                      assign(t3, binop(Iop_OrV128,
16051                                       binop(Iop_CmpGT16Sx8,
16052                                             mkexpr(t2), mkexpr(t1)),
16053                                       binop(Iop_CmpEQ16x8,
16054                                             mkexpr(t1), mkexpr(t2))));
16055                      putWReg(wd, mkexpr(t3));
16056                      break;
16057                   }
16058 
16059                case 0x02: { /* CLE_S.W */
16060                      DIP("CLE_S.W w%d, w%d, w%d", wd, ws, wt);
16061                      t1 = newTemp(Ity_V128);
16062                      t2 = newTemp(Ity_V128);
16063                      t3 = newTemp(Ity_V128);
16064                      assign(t1, getWReg(ws));
16065                      assign(t2, getWReg(wt));
16066                      assign(t3, binop(Iop_OrV128,
16067                                       binop(Iop_CmpGT32Sx4,
16068                                             mkexpr(t2), mkexpr(t1)),
16069                                       binop(Iop_CmpEQ32x4,
16070                                             mkexpr(t1), mkexpr(t2))));
16071                      putWReg(wd, mkexpr(t3));
16072                      break;
16073                   }
16074 
16075                case 0x03: { /* CLE_S.D */
16076                      DIP("CLE_S.D w%d, w%d, w%d", wd, ws, wt);
16077                      t1 = newTemp(Ity_V128);
16078                      t2 = newTemp(Ity_V128);
16079                      t3 = newTemp(Ity_V128);
16080                      assign(t1, getWReg(ws));
16081                      assign(t2, getWReg(wt));
16082                      assign(t3, binop(Iop_OrV128,
16083                                       binop(Iop_CmpGT64Sx2,
16084                                             mkexpr(t2), mkexpr(t1)),
16085                                       binop(Iop_CmpEQ64x2,
16086                                             mkexpr(t1), mkexpr(t2))));
16087                      putWReg(wd, mkexpr(t3));
16088                      break;
16089                   }
16090 
16091                default:
16092                   return -1;
16093             }
16094 
16095             break;
16096          }
16097 
16098       case 0x05: { /* CLE_U.df */
16099             switch (df) {
16100                case 0x00: { /* CLE_U.B */
16101                      DIP("CLE_U.B w%d, w%d, w%d", wd, ws, wt);
16102                      t1 = newTemp(Ity_V128);
16103                      t2 = newTemp(Ity_V128);
16104                      t3 = newTemp(Ity_V128);
16105                      assign(t1, getWReg(ws));
16106                      assign(t2, getWReg(wt));
16107                      assign(t3, binop(Iop_OrV128,
16108                                       binop(Iop_CmpGT8Ux16,
16109                                             mkexpr(t2), mkexpr(t1)),
16110                                       binop(Iop_CmpEQ8x16,
16111                                             mkexpr(t1), mkexpr(t2))));
16112                      putWReg(wd, mkexpr(t3));
16113                      break;
16114                   }
16115 
16116                case 0x01: { /* CLE_U.H */
16117                      DIP("CLE_U.H w%d, w%d, w%d", wd, ws, wt);
16118                      t1 = newTemp(Ity_V128);
16119                      t2 = newTemp(Ity_V128);
16120                      t3 = newTemp(Ity_V128);
16121                      assign(t1, getWReg(ws));
16122                      assign(t2, getWReg(wt));
16123                      assign(t3, binop(Iop_OrV128,
16124                                       binop(Iop_CmpGT16Ux8,
16125                                             mkexpr(t2), mkexpr(t1)),
16126                                       binop(Iop_CmpEQ16x8,
16127                                             mkexpr(t1), mkexpr(t2))));
16128                      putWReg(wd, mkexpr(t3));
16129                      break;
16130                   }
16131 
16132                case 0x02: { /* CLE_U.W */
16133                      DIP("CLE_U.W w%d, w%d, w%d", wd, ws, wt);
16134                      t1 = newTemp(Ity_V128);
16135                      t2 = newTemp(Ity_V128);
16136                      t3 = newTemp(Ity_V128);
16137                      assign(t1, getWReg(ws));
16138                      assign(t2, getWReg(wt));
16139                      assign(t3, binop(Iop_OrV128,
16140                                       binop(Iop_CmpGT32Ux4,
16141                                             mkexpr(t2), mkexpr(t1)),
16142                                       binop(Iop_CmpEQ32x4,
16143                                             mkexpr(t1), mkexpr(t2))));
16144                      putWReg(wd, mkexpr(t3));
16145                      break;
16146                   }
16147 
16148                case 0x03: { /* CLE_U.D */
16149                      DIP("CLE_U.D w%d, w%d, w%d", wd, ws, wt);
16150                      t1 = newTemp(Ity_V128);
16151                      t2 = newTemp(Ity_V128);
16152                      t3 = newTemp(Ity_V128);
16153                      assign(t1, getWReg(ws));
16154                      assign(t2, getWReg(wt));
16155                      assign(t3,
16156                             binop(Iop_OrV128,
16157                                   binop(Iop_CmpGT64Ux2,
16158                                         mkexpr(t2), mkexpr(t1)),
16159                                   binop(Iop_CmpEQ64x2,
16160                                         mkexpr(t1), mkexpr(t2))));
16161                      putWReg(wd, mkexpr(t3));
16162                      break;
16163                   }
16164 
16165                default:
16166                   return -1;
16167             }
16168 
16169             break;
16170          }
16171 
16172       default:
16173          return -1;
16174    }
16175 
16176    return 0;
16177 }
16178 
msa_3R_10(UInt cins,UChar wd,UChar ws)16179 static Int msa_3R_10(UInt cins, UChar wd, UChar ws) { /* 3R (0x10) */
16180    IRTemp t1, t2, t3, t4;
16181    UShort operation;
16182    UChar df, wt;
16183 
16184    operation = (cins & 0x03800000) >> 23;
16185    df = (cins & 0x00600000) >> 21;
16186    wt = (cins & 0x001F0000) >> 16;
16187 
16188    switch (operation) {
16189       case 0x00: { /* ADD_A.df */
16190             switch (df) {
16191                case 0x00: { /* ADD_A.B */
16192                      DIP("ADD_A.B w%d, w%d, w%d", wd, ws, wt);
16193                      t1 = newTemp(Ity_V128);
16194                      t2 = newTemp(Ity_V128);
16195                      t3 = newTemp(Ity_V128);
16196                      assign(t1, unop(Iop_Abs8x16, getWReg(ws)));
16197                      assign(t2, unop(Iop_Abs8x16, getWReg(wt)));
16198                      assign(t3, binop(Iop_Add8x16, mkexpr(t1), mkexpr(t2)));
16199                      putWReg(wd, mkexpr(t3));
16200                      break;
16201                   }
16202 
16203                case 0x01: { /* ADD_A.H */
16204                      DIP("ADD_A.H w%d, w%d, w%d", wd, ws, wt);
16205                      t1 = newTemp(Ity_V128);
16206                      t2 = newTemp(Ity_V128);
16207                      t3 = newTemp(Ity_V128);
16208                      assign(t1, unop(Iop_Abs16x8, getWReg(ws)));
16209                      assign(t2, unop(Iop_Abs16x8, getWReg(wt)));
16210                      assign(t3, binop(Iop_Add16x8, mkexpr(t1), mkexpr(t2)));
16211                      putWReg(wd, mkexpr(t3));
16212                      break;
16213                   }
16214 
16215                case 0x02: { /* ADD_A.W */
16216                      DIP("ADD_A.W w%d, w%d, w%d", wd, ws, wt);
16217                      t1 = newTemp(Ity_V128);
16218                      t2 = newTemp(Ity_V128);
16219                      t3 = newTemp(Ity_V128);
16220                      assign(t1, unop(Iop_Abs32x4, getWReg(ws)));
16221                      assign(t2, unop(Iop_Abs32x4, getWReg(wt)));
16222                      assign(t3, binop(Iop_Add32x4, mkexpr(t1), mkexpr(t2)));
16223                      putWReg(wd, mkexpr(t3));
16224                      break;
16225                   }
16226 
16227                case 0x03: { /* ADD_A.D */
16228                      DIP("ADD_A.D w%d, w%d, w%d", wd, ws, wt);
16229                      t1 = newTemp(Ity_V128);
16230                      t2 = newTemp(Ity_V128);
16231                      t3 = newTemp(Ity_V128);
16232                      assign(t1, unop(Iop_Abs64x2, getWReg(ws)));
16233                      assign(t2, unop(Iop_Abs64x2, getWReg(wt)));
16234                      assign(t3, binop(Iop_Add64x2, mkexpr(t1), mkexpr(t2)));
16235                      putWReg(wd, mkexpr(t3));
16236                      break;
16237                   }
16238 
16239                default:
16240                   return -1;
16241             }
16242 
16243             break;
16244          }
16245 
16246       case 0x01: { /* ADDS_A.df */
16247             switch (df) {
16248                case 0x00: { /* ADDS_A.B */
16249                      DIP("ADDS_A.B w%d, w%d, w%d", wd, ws, wt);
16250                      t1 = newTemp(Ity_V128);
16251                      t2 = newTemp(Ity_V128);
16252                      t3 = newTemp(Ity_V128);
16253                      t4 = newTemp(Ity_V128);
16254                      assign(t1, unop(Iop_Abs8x16, getWReg(ws)));
16255                      assign(t2, unop(Iop_Abs8x16, getWReg(wt)));
16256                      assign(t3, binop(Iop_SarN8x16,
16257                                       binop(Iop_AndV128,
16258                                             mkexpr(t1),
16259                                             getWReg(ws)),
16260                                       mkU8(7)));
16261                      assign(t4, binop(Iop_SarN8x16,
16262                                       binop(Iop_AndV128,
16263                                             mkexpr(t2),
16264                                             getWReg(wt)),
16265                                       mkU8(7)));
16266                      putWReg(wd, binop(Iop_QAdd8Sx16,
16267                                        binop(Iop_OrV128,
16268                                              binop(Iop_AndV128,
16269                                                    unop(Iop_NotV128,
16270                                                         mkexpr(t3)),
16271                                                    mkexpr(t1)),
16272                                              binop(Iop_AndV128,
16273                                                    unop(Iop_NotV128,
16274                                                         mkexpr(t1)),
16275                                                    mkexpr(t3))),
16276                                        binop(Iop_OrV128,
16277                                              binop(Iop_AndV128,
16278                                                    unop(Iop_NotV128,
16279                                                         mkexpr(t4)),
16280                                                    mkexpr(t2)),
16281                                              binop(Iop_AndV128,
16282                                                    unop(Iop_NotV128,
16283                                                         mkexpr(t2)),
16284                                                    mkexpr(t4)))));
16285                      break;
16286                   }
16287 
16288                case 0x01: { /* ADDS_A.H */
16289                      DIP("ADDS_A.H w%d, w%d, w%d", wd, ws, wt);
16290                      t1 = newTemp(Ity_V128);
16291                      t2 = newTemp(Ity_V128);
16292                      t3 = newTemp(Ity_V128);
16293                      t4 = newTemp(Ity_V128);
16294                      assign(t1, unop(Iop_Abs16x8, getWReg(ws)));
16295                      assign(t2, unop(Iop_Abs16x8, getWReg(wt)));
16296                      assign(t3, binop(Iop_SarN16x8,
16297                                       binop(Iop_AndV128,
16298                                             mkexpr(t1),
16299                                             getWReg(ws)),
16300                                       mkU8(15)));
16301                      assign(t4, binop(Iop_SarN16x8,
16302                                    binop(Iop_AndV128,
16303                                          mkexpr(t2),
16304                                          getWReg(wt)),
16305                                    mkU8(15)));
16306                      putWReg(wd, binop(Iop_QAdd16Sx8,
16307                                        binop(Iop_OrV128,
16308                                              binop(Iop_AndV128,
16309                                                    unop(Iop_NotV128,
16310                                                         mkexpr(t3)),
16311                                                    mkexpr(t1)),
16312                                              binop(Iop_AndV128,
16313                                                    unop(Iop_NotV128,
16314                                                         mkexpr(t1)),
16315                                                    mkexpr(t3))),
16316                                        binop(Iop_OrV128,
16317                                              binop(Iop_AndV128,
16318                                                    unop(Iop_NotV128,
16319                                                         mkexpr(t4)),
16320                                                    mkexpr(t2)),
16321                                              binop(Iop_AndV128,
16322                                                    unop(Iop_NotV128,
16323                                                         mkexpr(t2)),
16324                                                    mkexpr(t4)))));
16325                      break;
16326                   }
16327 
16328                case 0x02: { /* ADDS_A.W */
16329                      DIP("ADDS_A.W w%d, w%d, w%d", wd, ws, wt);
16330                      t1 = newTemp(Ity_V128);
16331                      t2 = newTemp(Ity_V128);
16332                      t3 = newTemp(Ity_V128);
16333                      t4 = newTemp(Ity_V128);
16334                      assign(t1, unop(Iop_Abs32x4, getWReg(ws)));
16335                      assign(t2, unop(Iop_Abs32x4, getWReg(wt)));
16336                      assign(t3, binop(Iop_SarN32x4,
16337                                       binop(Iop_AndV128,
16338                                             mkexpr(t1),
16339                                             getWReg(ws)),
16340                                       mkU8(31)));
16341                      assign(t4, binop(Iop_SarN32x4,
16342                                       binop(Iop_AndV128,
16343                                             mkexpr(t2),
16344                                             getWReg(wt)),
16345                                       mkU8(31)));
16346                      putWReg(wd, binop(Iop_QAdd32Sx4,
16347                                        binop(Iop_OrV128,
16348                                              binop(Iop_AndV128,
16349                                                    unop(Iop_NotV128,
16350                                                         mkexpr(t3)),
16351                                                    mkexpr(t1)),
16352                                              binop(Iop_AndV128,
16353                                                    unop(Iop_NotV128,
16354                                                         mkexpr(t1)),
16355                                                    mkexpr(t3))),
16356                                        binop(Iop_OrV128,
16357                                              binop(Iop_AndV128,
16358                                                    unop(Iop_NotV128,
16359                                                         mkexpr(t4)),
16360                                                    mkexpr(t2)),
16361                                              binop(Iop_AndV128,
16362                                                    unop(Iop_NotV128,
16363                                                         mkexpr(t2)),
16364                                                    mkexpr(t4)))));
16365                      break;
16366                   }
16367 
16368                case 0x03: { /* ADDS_A.D */
16369                      DIP("ADDS_A.D w%d, w%d, w%d", wd, ws, wt);
16370                      t1 = newTemp(Ity_V128);
16371                      t2 = newTemp(Ity_V128);
16372                      t3 = newTemp(Ity_V128);
16373                      t4 = newTemp(Ity_V128);
16374                      assign(t1, unop(Iop_Abs64x2, getWReg(ws)));
16375                      assign(t2, unop(Iop_Abs64x2, getWReg(wt)));
16376                      assign(t3, binop(Iop_SarN64x2,
16377                                       binop(Iop_AndV128,
16378                                             mkexpr(t1),
16379                                             getWReg(ws)),
16380                                       mkU8(63)));
16381                      assign(t4, binop(Iop_SarN64x2,
16382                                       binop(Iop_AndV128,
16383                                             mkexpr(t2),
16384                                             getWReg(wt)),
16385                                       mkU8(63)));
16386                      putWReg(wd,
16387                              binop(Iop_QAdd64Sx2,
16388                                    binop(Iop_OrV128,
16389                                          binop(Iop_AndV128,
16390                                                unop(Iop_NotV128,
16391                                                     mkexpr(t3)),
16392                                                mkexpr(t1)),
16393                                          binop(Iop_AndV128,
16394                                                unop(Iop_NotV128,
16395                                                     mkexpr(t1)),
16396                                                mkexpr(t3))),
16397                                    binop(Iop_OrV128,
16398                                          binop(Iop_AndV128,
16399                                                unop(Iop_NotV128,
16400                                                     mkexpr(t4)),
16401                                                mkexpr(t2)),
16402                                          binop(Iop_AndV128,
16403                                                unop(Iop_NotV128,
16404                                                     mkexpr(t2)),
16405                                                mkexpr(t4)))));
16406                      break;
16407                   }
16408 
16409                default:
16410                   return -1;
16411             }
16412 
16413             break;
16414          }
16415 
16416       case 0x02: { /* ADDS_S.df */
16417             switch (df) {
16418                case 0x00: { /* ADDS_S.B */
16419                      DIP("ADDS_S.B w%d, w%d, w%d", wd, ws, wt);
16420                      t1 = newTemp(Ity_V128);
16421                      t2 = newTemp(Ity_V128);
16422                      t3 = newTemp(Ity_V128);
16423                      assign(t1, getWReg(ws));
16424                      assign(t2, getWReg(wt));
16425                      assign(t3, binop(Iop_QAdd8Sx16, mkexpr(t1), mkexpr(t2)));
16426                      putWReg(wd, mkexpr(t3));
16427                      break;
16428                   }
16429 
16430                case 0x01: { /* ADDS_S.H */
16431                      DIP("ADDS_S.H w%d, w%d, w%d", wd, ws, wt);
16432                      t1 = newTemp(Ity_V128);
16433                      t2 = newTemp(Ity_V128);
16434                      t3 = newTemp(Ity_V128);
16435                      assign(t1, getWReg(ws));
16436                      assign(t2, getWReg(wt));
16437                      assign(t3, binop(Iop_QAdd16Sx8, mkexpr(t1), mkexpr(t2)));
16438                      putWReg(wd, mkexpr(t3));
16439                      break;
16440                   }
16441 
16442                case 0x02: { /* ADDS_S.W */
16443                      DIP("ADDS_S.W w%d, w%d, w%d", wd, ws, wt);
16444                      t1 = newTemp(Ity_V128);
16445                      t2 = newTemp(Ity_V128);
16446                      t3 = newTemp(Ity_V128);
16447                      assign(t1, getWReg(ws));
16448                      assign(t2, getWReg(wt));
16449                      assign(t3, binop(Iop_QAdd32Sx4, mkexpr(t1), mkexpr(t2)));
16450                      putWReg(wd, mkexpr(t3));
16451                      break;
16452                   }
16453 
16454                case 0x03: { /* ADDS_S.D */
16455                      DIP("ADDS_S.D w%d, w%d, w%d", wd, ws, wt);
16456                      t1 = newTemp(Ity_V128);
16457                      t2 = newTemp(Ity_V128);
16458                      t3 = newTemp(Ity_V128);
16459                      assign(t1, getWReg(ws));
16460                      assign(t2, getWReg(wt));
16461                      assign(t3, binop(Iop_QAdd64Sx2, mkexpr(t1), mkexpr(t2)));
16462                      putWReg(wd, mkexpr(t3));
16463                      break;
16464                   }
16465 
16466                default:
16467                   return -1;
16468             }
16469 
16470             break;
16471          }
16472 
16473       case 0x03: { /* ADDS_U.df */
16474             switch (df) {
16475                case 0x00: { /* ADDS_U.B */
16476                      DIP("ADDS_U.B w%d, w%d, w%d", wd, ws, wt);
16477                      t1 = newTemp(Ity_V128);
16478                      t2 = newTemp(Ity_V128);
16479                      t3 = newTemp(Ity_V128);
16480                      assign(t1, getWReg(ws));
16481                      assign(t2, getWReg(wt));
16482                      assign(t3, binop(Iop_QAdd8Ux16, mkexpr(t1), mkexpr(t2)));
16483                      putWReg(wd, mkexpr(t3));
16484                      break;
16485                   }
16486 
16487                case 0x01: { /* ADDS_U.H */
16488                      DIP("ADDS_U.H w%d, w%d, w%d", wd, ws, wt);
16489                      t1 = newTemp(Ity_V128);
16490                      t2 = newTemp(Ity_V128);
16491                      t3 = newTemp(Ity_V128);
16492                      assign(t1, getWReg(ws));
16493                      assign(t2, getWReg(wt));
16494                      assign(t3, binop(Iop_QAdd16Ux8, mkexpr(t1), mkexpr(t2)));
16495                      putWReg(wd, mkexpr(t3));
16496                      break;
16497                   }
16498 
16499                case 0x02: { /* ADDS_U.W */
16500                      DIP("ADDS_U.W w%d, w%d, w%d", wd, ws, wt);
16501                      t1 = newTemp(Ity_V128);
16502                      t2 = newTemp(Ity_V128);
16503                      t3 = newTemp(Ity_V128);
16504                      assign(t1, getWReg(ws));
16505                      assign(t2, getWReg(wt));
16506                      assign(t3, binop(Iop_QAdd32Ux4, mkexpr(t1), mkexpr(t2)));
16507                      putWReg(wd, mkexpr(t3));
16508                      break;
16509                   }
16510 
16511                case 0x03: { /* ADDS_U.D */
16512                      DIP("ADDS_U.D w%d, w%d, w%d", wd, ws, wt);
16513                      t1 = newTemp(Ity_V128);
16514                      t2 = newTemp(Ity_V128);
16515                      t3 = newTemp(Ity_V128);
16516                      assign(t1, getWReg(ws));
16517                      assign(t2, getWReg(wt));
16518                      assign(t3, binop(Iop_QAdd64Ux2, mkexpr(t1), mkexpr(t2)));
16519                      putWReg(wd, mkexpr(t3));
16520                      break;
16521                   }
16522 
16523                default:
16524                   return -1;
16525             }
16526 
16527             break;
16528          }
16529 
16530       case 0x04: { /* AVE_S.df */
16531             switch (df) {
16532                case 0x00: { /* AVE_S.B */
16533                      DIP("AVE_S.B w%d, w%d, w%d", wd, ws, wt);
16534                      t1 = newTemp(Ity_V128);
16535                      t2 = newTemp(Ity_V128);
16536                      t3 = newTemp(Ity_V128);
16537                      assign(t1, getWReg(ws));
16538                      assign(t2, getWReg(wt));
16539                      assign(t3, binop(Iop_Add8x16,
16540                                       binop(Iop_Add8x16,
16541                                             binop(Iop_SarN8x16,
16542                                                   mkexpr(t1), mkU8(1)),
16543                                             binop(Iop_SarN8x16,
16544                                                   mkexpr(t2), mkU8(1))),
16545                                       binop(Iop_ShrN8x16,
16546                                             binop(Iop_ShlN8x16,
16547                                                   binop(Iop_AndV128,
16548                                                         mkexpr(t1),
16549                                                         mkexpr(t2)),
16550                                                   mkU8(7)),
16551                                             mkU8(7))));
16552                      putWReg(wd, mkexpr(t3));
16553                      break;
16554                   }
16555 
16556                case 0x01: { /* AVE_S.H */
16557                      DIP("AVE_S.H w%d, w%d, w%d", wd, ws, wt);
16558                      t1 = newTemp(Ity_V128);
16559                      t2 = newTemp(Ity_V128);
16560                      t3 = newTemp(Ity_V128);
16561                      assign(t1, getWReg(ws));
16562                      assign(t2, getWReg(wt));
16563                      assign(t3,
16564                             binop(Iop_Add16x8,
16565                                   binop(Iop_Add16x8,
16566                                         binop(Iop_SarN16x8,
16567                                               mkexpr(t1), mkU8(1)),
16568                                         binop(Iop_SarN16x8,
16569                                               mkexpr(t2), mkU8(1))),
16570                                   binop(Iop_ShrN16x8,
16571                                         binop(Iop_ShlN16x8,
16572                                               binop(Iop_AndV128,
16573                                                     mkexpr(t1),
16574                                                     mkexpr(t2)),
16575                                               mkU8(15)),
16576                                         mkU8(15))));
16577                      putWReg(wd, mkexpr(t3));
16578                      break;
16579                   }
16580 
16581                case 0x02: { /* AVE_S.W */
16582                      DIP("AVE_S.W w%d, w%d, w%d", wd, ws, wt);
16583                      t1 = newTemp(Ity_V128);
16584                      t2 = newTemp(Ity_V128);
16585                      t3 = newTemp(Ity_V128);
16586                      assign(t1, getWReg(ws));
16587                      assign(t2, getWReg(wt));
16588                      assign(t3, binop(Iop_Add32x4,
16589                                       binop(Iop_Add32x4,
16590                                             binop(Iop_SarN32x4,
16591                                                   mkexpr(t1), mkU8(1)),
16592                                             binop(Iop_SarN32x4,
16593                                                   mkexpr(t2), mkU8(1))),
16594                                       binop(Iop_ShrN32x4,
16595                                             binop(Iop_ShlN32x4,
16596                                                   binop(Iop_AndV128,
16597                                                         mkexpr(t1),
16598                                                         mkexpr(t2)),
16599                                                   mkU8(31)),
16600                                             mkU8(31))));
16601                      putWReg(wd, mkexpr(t3));
16602                      break;
16603                   }
16604 
16605                case 0x03: { /* AVE_S.D */
16606                      DIP("AVE_S.D w%d, w%d, w%d", wd, ws, wt);
16607                      t1 = newTemp(Ity_V128);
16608                      t2 = newTemp(Ity_V128);
16609                      t3 = newTemp(Ity_V128);
16610                      assign(t1, getWReg(ws));
16611                      assign(t2, getWReg(wt));
16612                      assign(t3, binop(Iop_Add64x2,
16613                                       binop(Iop_Add64x2,
16614                                             binop(Iop_SarN64x2,
16615                                                   mkexpr(t1), mkU8(1)),
16616                                             binop(Iop_SarN64x2,
16617                                                   mkexpr(t2), mkU8(1))),
16618                                       binop(Iop_ShrN64x2,
16619                                             binop(Iop_ShlN64x2,
16620                                                   binop(Iop_AndV128,
16621                                                         mkexpr(t1),
16622                                                         mkexpr(t2)),
16623                                                   mkU8(63)),
16624                                             mkU8(63))));
16625                      putWReg(wd, mkexpr(t3));
16626                      break;
16627                   }
16628 
16629                default:
16630                   return -1;
16631             }
16632 
16633             break;
16634          }
16635 
16636       case 0x05: { /* AVE_U.df */
16637             switch (df) {
16638                case 0x00: { /* AVE_U.B */
16639                      DIP("AVE_U.B w%d, w%d, w%d", wd, ws, wt);
16640                      t1 = newTemp(Ity_V128);
16641                      t2 = newTemp(Ity_V128);
16642                      t3 = newTemp(Ity_V128);
16643                      assign(t1, getWReg(ws));
16644                      assign(t2, getWReg(wt));
16645                      assign(t3, binop(Iop_Add16x8,
16646                                       binop(Iop_Add8x16,
16647                                             binop(Iop_ShrN8x16,
16648                                                   mkexpr(t1), mkU8(1)),
16649                                             binop(Iop_ShrN8x16,
16650                                                   mkexpr(t2), mkU8(1))),
16651                                       binop(Iop_ShrN8x16,
16652                                             binop(Iop_ShlN8x16,
16653                                                   binop(Iop_AndV128,
16654                                                         mkexpr(t1),
16655                                                         mkexpr(t2)),
16656                                                   mkU8(7)),
16657                                             mkU8(7))));
16658                      putWReg(wd, mkexpr(t3));
16659                      break;
16660                   }
16661 
16662                case 0x01: { /* AVE_U.H */
16663                      DIP("AVE_U.H w%d, w%d, w%d", wd, ws, wt);
16664                      t1 = newTemp(Ity_V128);
16665                      t2 = newTemp(Ity_V128);
16666                      t3 = newTemp(Ity_V128);
16667                      assign(t1, getWReg(ws));
16668                      assign(t2, getWReg(wt));
16669                      assign(t3, binop(Iop_Add16x8,
16670                                       binop(Iop_Add16x8,
16671                                             binop(Iop_ShrN16x8,
16672                                                   mkexpr(t1), mkU8(1)),
16673                                             binop(Iop_ShrN16x8,
16674                                                   mkexpr(t2), mkU8(1))),
16675                                       binop(Iop_ShrN16x8,
16676                                             binop(Iop_ShlN16x8,
16677                                                   binop(Iop_AndV128,
16678                                                         mkexpr(t1),
16679                                                         mkexpr(t2)),
16680                                                   mkU8(15)),
16681                                             mkU8(15))));
16682                      putWReg(wd, mkexpr(t3));
16683                      break;
16684                   }
16685 
16686                case 0x02: { /* AVE_U.W */
16687                      DIP("AVE_U.W w%d, w%d, w%d", wd, ws, wt);
16688                      t1 = newTemp(Ity_V128);
16689                      t2 = newTemp(Ity_V128);
16690                      t3 = newTemp(Ity_V128);
16691                      assign(t1, getWReg(ws));
16692                      assign(t2, getWReg(wt));
16693                      assign(t3, binop(Iop_Add32x4,
16694                                       binop(Iop_Add32x4,
16695                                             binop(Iop_ShrN32x4,
16696                                                   mkexpr(t1), mkU8(1)),
16697                                             binop(Iop_ShrN32x4,
16698                                                   mkexpr(t2), mkU8(1))),
16699                                       binop(Iop_ShrN32x4,
16700                                             binop(Iop_ShlN32x4,
16701                                                   binop(Iop_AndV128,
16702                                                         mkexpr(t1),
16703                                                         mkexpr(t2)),
16704                                                   mkU8(31)),
16705                                             mkU8(31))));
16706                      putWReg(wd, mkexpr(t3));
16707                      break;
16708                   }
16709 
16710                case 0x03: { /* AVE_U.D */
16711                      DIP("AVE_U.D w%d, w%d, w%d", wd, ws, wt);
16712                      t1 = newTemp(Ity_V128);
16713                      t2 = newTemp(Ity_V128);
16714                      t3 = newTemp(Ity_V128);
16715                      assign(t1, getWReg(ws));
16716                      assign(t2, getWReg(wt));
16717                      assign(t3, binop(Iop_Add64x2,
16718                                       binop(Iop_Add64x2,
16719                                             binop(Iop_ShrN64x2,
16720                                                   mkexpr(t1), mkU8(1)),
16721                                             binop(Iop_ShrN64x2,
16722                                                   mkexpr(t2), mkU8(1))),
16723                                       binop(Iop_ShrN64x2,
16724                                             binop(Iop_ShlN64x2,
16725                                                   binop(Iop_AndV128,
16726                                                         mkexpr(t1),
16727                                                         mkexpr(t2)),
16728                                                   mkU8(63)),
16729                                             mkU8(63))));
16730                      putWReg(wd, mkexpr(t3));
16731                      break;
16732                   }
16733 
16734                default:
16735                   return -1;
16736             }
16737 
16738             break;
16739          }
16740 
16741       case 0x06: { /* AVER_S.df */
16742             switch (df) {
16743                case 0x00: { /* AVER_S.B */
16744                      DIP("AVER_S.B w%d, w%d, w%d", wd, ws, wt);
16745                      t1 = newTemp(Ity_V128);
16746                      t2 = newTemp(Ity_V128);
16747                      t3 = newTemp(Ity_V128);
16748                      assign(t1, getWReg(ws));
16749                      assign(t2, getWReg(wt));
16750                      assign(t3, binop(Iop_Avg8Sx16, mkexpr(t1), mkexpr(t2)));
16751                      putWReg(wd, mkexpr(t3));
16752                      break;
16753                   }
16754 
16755                case 0x01: { /* AVER_S.H */
16756                      DIP("AVER_S.H w%d, w%d, w%d", wd, ws, wt);
16757                      t1 = newTemp(Ity_V128);
16758                      t2 = newTemp(Ity_V128);
16759                      t3 = newTemp(Ity_V128);
16760                      assign(t1, getWReg(ws));
16761                      assign(t2, getWReg(wt));
16762                      assign(t3, binop(Iop_Avg16Sx8, mkexpr(t1), mkexpr(t2)));
16763                      putWReg(wd, mkexpr(t3));
16764                      break;
16765                   }
16766 
16767                case 0x02: { /* AVER_S.W */
16768                      DIP("AVER_S.W w%d, w%d, w%d", wd, ws, wt);
16769                      t1 = newTemp(Ity_V128);
16770                      t2 = newTemp(Ity_V128);
16771                      t3 = newTemp(Ity_V128);
16772                      assign(t1, getWReg(ws));
16773                      assign(t2, getWReg(wt));
16774                      assign(t3, binop(Iop_Avg32Sx4, mkexpr(t1), mkexpr(t2)));
16775                      putWReg(wd, mkexpr(t3));
16776                      break;
16777                   }
16778 
16779                case 0x03: { /* AVER_S.D */
16780                      DIP("AVER_S.D w%d, w%d, w%d", wd, ws, wt);
16781                      t1 = newTemp(Ity_V128);
16782                      t2 = newTemp(Ity_V128);
16783                      t3 = newTemp(Ity_V128);
16784                      assign(t1, getWReg(ws));
16785                      assign(t2, getWReg(wt));
16786                      assign(t3, binop(Iop_Add64x2,
16787                                       binop(Iop_Add64x2,
16788                                             binop(Iop_SarN64x2,
16789                                                   mkexpr(t1), mkU8(1)),
16790                                             binop(Iop_SarN64x2,
16791                                                   mkexpr(t2), mkU8(1))),
16792                                       binop(Iop_ShrN64x2,
16793                                             binop(Iop_ShlN64x2,
16794                                                   binop(Iop_OrV128,
16795                                                         mkexpr(t1),
16796                                                         mkexpr(t2)),
16797                                                   mkU8(63)),
16798                                             mkU8(63))));
16799                      putWReg(wd, mkexpr(t3));
16800                      break;
16801                   }
16802 
16803                default:
16804                   return -1;
16805             }
16806 
16807             break;
16808          }
16809 
16810       case 0x07: { /* AVER_U.df */
16811             switch (df) {
16812                case 0x00: { /* AVER_U.B */
16813                      DIP("AVER_U.B w%d, w%d, w%d", wd, ws, wt);
16814                      t1 = newTemp(Ity_V128);
16815                      t2 = newTemp(Ity_V128);
16816                      t3 = newTemp(Ity_V128);
16817                      assign(t1, getWReg(ws));
16818                      assign(t2, getWReg(wt));
16819                      assign(t3, binop(Iop_Avg8Ux16, mkexpr(t1), mkexpr(t2)));
16820                      putWReg(wd, mkexpr(t3));
16821                      break;
16822                   }
16823 
16824                case 0x01: { /* AVER_U.H */
16825                      DIP("AVER_U.H w%d, w%d, w%d", wd, ws, wt);
16826                      t1 = newTemp(Ity_V128);
16827                      t2 = newTemp(Ity_V128);
16828                      t3 = newTemp(Ity_V128);
16829                      assign(t1, getWReg(ws));
16830                      assign(t2, getWReg(wt));
16831                      assign(t3, binop(Iop_Avg16Ux8, mkexpr(t1), mkexpr(t2)));
16832                      putWReg(wd, mkexpr(t3));
16833                      break;
16834                   }
16835 
16836                case 0x02: { /* AVER_U.W */
16837                      DIP("AVER_U.W w%d, w%d, w%d", wd, ws, wt);
16838                      t1 = newTemp(Ity_V128);
16839                      t2 = newTemp(Ity_V128);
16840                      t3 = newTemp(Ity_V128);
16841                      assign(t1, getWReg(ws));
16842                      assign(t2, getWReg(wt));
16843                      assign(t3, binop(Iop_Avg32Ux4, mkexpr(t1), mkexpr(t2)));
16844                      putWReg(wd, mkexpr(t3));
16845                      break;
16846                   }
16847 
16848                case 0x03: { /* AVER_U.D */
16849                      DIP("AVER_U.D w%d, w%d, w%d", wd, ws, wt);
16850                      t1 = newTemp(Ity_V128);
16851                      t2 = newTemp(Ity_V128);
16852                      t3 = newTemp(Ity_V128);
16853                      assign(t1, getWReg(ws));
16854                      assign(t2, getWReg(wt));
16855                      assign(t3, binop(Iop_Add64x2,
16856                                       binop(Iop_Add64x2,
16857                                             binop(Iop_ShrN64x2,
16858                                                   mkexpr(t1), mkU8(1)),
16859                                             binop(Iop_ShrN64x2,
16860                                                   mkexpr(t2), mkU8(1))),
16861                                       binop(Iop_ShrN64x2,
16862                                             binop(Iop_ShlN64x2,
16863                                                   binop(Iop_OrV128,
16864                                                         mkexpr(t1),
16865                                                         mkexpr(t2)),
16866                                                   mkU8(63)),
16867                                             mkU8(63))));
16868                      putWReg(wd, mkexpr(t3));
16869                      break;
16870                   }
16871 
16872                default:
16873                   return -1;
16874             }
16875 
16876             break;
16877          }
16878 
16879       default:
16880          return -1;
16881    }
16882 
16883    return 0;
16884 }
16885 
msa_3R_11(UInt cins,UChar wd,UChar ws)16886 static Int msa_3R_11(UInt cins, UChar wd, UChar ws) { /* 3R (0x11) */
16887    IRTemp t1, t2, t3;
16888    UShort operation;
16889    UChar df, wt;
16890 
16891    operation = (cins & 0x03800000) >> 23;
16892    df = (cins & 0x00600000) >> 21;
16893    wt = (cins & 0x001F0000) >> 16;
16894 
16895    switch (operation) {
16896       case 0x00: { /* SUBS_S.df */
16897             switch (df) {
16898                case 0x00: { /* SUBS_S.B */
16899                      DIP("SUBS_S.B w%d, w%d, w%d", wd, ws, wt);
16900                      t1 = newTemp(Ity_V128);
16901                      t2 = newTemp(Ity_V128);
16902                      t3 = newTemp(Ity_V128);
16903                      assign(t1, getWReg(ws));
16904                      assign(t2, getWReg(wt));
16905                      assign(t3, binop(Iop_QSub8Sx16, mkexpr(t1), mkexpr(t2)));
16906                      putWReg(wd, mkexpr(t3));
16907                      break;
16908                   }
16909 
16910                case 0x01: { /* SUBS_S.H */
16911                      DIP("SUBS_S.H w%d, w%d, w%d", wd, ws, wt);
16912                      t1 = newTemp(Ity_V128);
16913                      t2 = newTemp(Ity_V128);
16914                      t3 = newTemp(Ity_V128);
16915                      assign(t1, getWReg(ws));
16916                      assign(t2, getWReg(wt));
16917                      assign(t3, binop(Iop_QSub16Sx8, mkexpr(t1), mkexpr(t2)));
16918                      putWReg(wd, mkexpr(t3));
16919                      break;
16920                   }
16921 
16922                case 0x02: { /* SUBS_S.W */
16923                      DIP("SUBS_S.W w%d, w%d, w%d", wd, ws, wt);
16924                      t1 = newTemp(Ity_V128);
16925                      t2 = newTemp(Ity_V128);
16926                      t3 = newTemp(Ity_V128);
16927                      assign(t1, getWReg(ws));
16928                      assign(t2, getWReg(wt));
16929                      assign(t3, binop(Iop_QSub32Sx4, mkexpr(t1), mkexpr(t2)));
16930                      putWReg(wd, mkexpr(t3));
16931                      break;
16932                   }
16933 
16934                case 0x03: { /* SUBS_S.D */
16935                      DIP("SUBS_S.D w%d, w%d, w%d", wd, ws, wt);
16936                      t1 = newTemp(Ity_V128);
16937                      t2 = newTemp(Ity_V128);
16938                      t3 = newTemp(Ity_V128);
16939                      assign(t1, getWReg(ws));
16940                      assign(t2, getWReg(wt));
16941                      assign(t3, binop(Iop_QSub64Sx2, mkexpr(t1), mkexpr(t2)));
16942                      putWReg(wd, mkexpr(t3));
16943                      break;
16944                   }
16945 
16946                default:
16947                   return -1;
16948             }
16949 
16950             break;
16951          }
16952 
16953       case 0x01: { /* SUBS_U.df */
16954             switch (df) {
16955                case 0x00: { /* SUBS_U.B */
16956                      DIP("SUBS_U.B w%d, w%d, w%d", wd, ws, wt);
16957                      t1 = newTemp(Ity_V128);
16958                      t2 = newTemp(Ity_V128);
16959                      t3 = newTemp(Ity_V128);
16960                      assign(t1, getWReg(ws));
16961                      assign(t2, getWReg(wt));
16962                      assign(t3, binop(Iop_QSub8Ux16, mkexpr(t1), mkexpr(t2)));
16963                      putWReg(wd, mkexpr(t3));
16964                      break;
16965                   }
16966 
16967                case 0x01: { /* SUBS_U.H */
16968                      DIP("SUBS_U.H w%d, w%d, w%d", wd, ws, wt);
16969                      t1 = newTemp(Ity_V128);
16970                      t2 = newTemp(Ity_V128);
16971                      t3 = newTemp(Ity_V128);
16972                      assign(t1, getWReg(ws));
16973                      assign(t2, getWReg(wt));
16974                      assign(t3, binop(Iop_QSub16Ux8, mkexpr(t1), mkexpr(t2)));
16975                      putWReg(wd, mkexpr(t3));
16976                      break;
16977                   }
16978 
16979                case 0x02: { /* SUBS_U.W */
16980                      DIP("SUBS_U.W w%d, w%d, w%d", wd, ws, wt);
16981                      t1 = newTemp(Ity_V128);
16982                      t2 = newTemp(Ity_V128);
16983                      t3 = newTemp(Ity_V128);
16984                      assign(t1, getWReg(ws));
16985                      assign(t2, getWReg(wt));
16986                      assign(t3, binop(Iop_QSub32Ux4, mkexpr(t1), mkexpr(t2)));
16987                      putWReg(wd, mkexpr(t3));
16988                      break;
16989                   }
16990 
16991                case 0x03: { /* SUBS_U.D */
16992                      DIP("SUBS_U.D w%d, w%d, w%d", wd, ws, wt);
16993                      t1 = newTemp(Ity_V128);
16994                      t2 = newTemp(Ity_V128);
16995                      t3 = newTemp(Ity_V128);
16996                      assign(t1, getWReg(ws));
16997                      assign(t2, getWReg(wt));
16998                      assign(t3, binop(Iop_QSub64Ux2, mkexpr(t1), mkexpr(t2)));
16999                      putWReg(wd, mkexpr(t3));
17000                      break;
17001                   }
17002 
17003                default:
17004                   return -1;
17005             }
17006 
17007             break;
17008          }
17009 
17010       case 0x02: { /* SUBSUS_U.df */
17011             switch (df) {
17012                case 0x00: { /* SUBSUS_U.B */
17013                      DIP("SUBSUS_U.B w%d, w%d, w%d", wd, ws, wt);
17014                      t1 = newTemp(Ity_V128);
17015                      t2 = newTemp(Ity_V128);
17016                      t3 = newTemp(Ity_V128);
17017                      assign(t1, binop(Iop_Sub8x16, getWReg(ws), getWReg(wt)));
17018                      assign(t2, binop(Iop_SarN8x16, getWReg(wt), mkU8(7)));
17019                      assign(t3, binop(Iop_OrV128,
17020                                       binop(Iop_CmpGT8Ux16,
17021                                             getWReg(ws),
17022                                             getWReg(wt)),
17023                                       binop(Iop_CmpEQ8x16,
17024                                             getWReg(ws),
17025                                             getWReg(wt))));
17026                      putWReg(wd,
17027                              binop(Iop_OrV128,
17028                                    binop(Iop_AndV128,
17029                                          mkexpr(t3), mkexpr(t2)),
17030                                    binop(Iop_AndV128,
17031                                          mkexpr(t1),
17032                                          binop(Iop_XorV128,
17033                                                mkexpr(t3),
17034                                                mkexpr(t2)))));
17035                      break;
17036                   }
17037 
17038                case 0x01: { /* SUBSUS_U.H */
17039                      DIP("SUBSUS_U.H w%d, w%d, w%d", wd, ws, wt);
17040                      t1 = newTemp(Ity_V128);
17041                      t2 = newTemp(Ity_V128);
17042                      t3 = newTemp(Ity_V128);
17043                      assign(t1, binop(Iop_Sub16x8, getWReg(ws), getWReg(wt)));
17044                      assign(t2, binop(Iop_SarN16x8, getWReg(wt), mkU8(15)));
17045                      assign(t3,
17046                             binop(Iop_OrV128,
17047                                   binop(Iop_CmpGT16Ux8,
17048                                         getWReg(ws),
17049                                         getWReg(wt)),
17050                                   binop(Iop_CmpEQ16x8,
17051                                         getWReg(ws),
17052                                         getWReg(wt))));
17053                      putWReg(wd,
17054                              binop(Iop_OrV128,
17055                                    binop(Iop_AndV128,
17056                                          mkexpr(t3), mkexpr(t2)),
17057                                    binop(Iop_AndV128,
17058                                          mkexpr(t1),
17059                                          binop(Iop_XorV128,
17060                                                mkexpr(t3),
17061                                                mkexpr(t2)))));
17062                      break;
17063                   }
17064 
17065                case 0x02: { /* SUBSUS_U.W */
17066                      DIP("SUBSUS_U.W w%d, w%d, w%d", wd, ws, wt);
17067                      t1 = newTemp(Ity_V128);
17068                      t2 = newTemp(Ity_V128);
17069                      t3 = newTemp(Ity_V128);
17070                      assign(t1, binop(Iop_Sub32x4, getWReg(ws), getWReg(wt)));
17071                      assign(t2, binop(Iop_SarN32x4, getWReg(wt), mkU8(31)));
17072                      assign(t3,
17073                             binop(Iop_OrV128,
17074                                   binop(Iop_CmpGT32Ux4,
17075                                         getWReg(ws),
17076                                         getWReg(wt)),
17077                                   binop(Iop_CmpEQ32x4,
17078                                         getWReg(ws),
17079                                         getWReg(wt))));
17080                      putWReg(wd,
17081                              binop(Iop_OrV128,
17082                                    binop(Iop_AndV128,
17083                                          mkexpr(t3), mkexpr(t2)),
17084                                    binop(Iop_AndV128,
17085                                          mkexpr(t1),
17086                                          binop(Iop_XorV128,
17087                                                mkexpr(t3),
17088                                                mkexpr(t2)))));
17089                      break;
17090                   }
17091 
17092                case 0x03: { /* SUBSUS_U.D */
17093                      DIP("SUBSUS_U.D w%d, w%d, w%d", wd, ws, wt);
17094                      t1 = newTemp(Ity_V128);
17095                      t2 = newTemp(Ity_V128);
17096                      t3 = newTemp(Ity_V128);
17097                      assign(t1, binop(Iop_Sub64x2, getWReg(ws), getWReg(wt)));
17098                      assign(t2, binop(Iop_SarN64x2, getWReg(wt), mkU8(63)));
17099                      assign(t3,
17100                             binop(Iop_OrV128,
17101                                   binop(Iop_CmpGT64Ux2,
17102                                         getWReg(ws),
17103                                         getWReg(wt)),
17104                                   binop(Iop_CmpEQ64x2,
17105                                         getWReg(ws),
17106                                         getWReg(wt))));
17107                      putWReg(wd,
17108                              binop(Iop_OrV128,
17109                                    binop(Iop_AndV128,
17110                                          mkexpr(t3), mkexpr(t2)),
17111                                    binop(Iop_AndV128,
17112                                          mkexpr(t1),
17113                                          binop(Iop_XorV128,
17114                                                mkexpr(t3),
17115                                                mkexpr(t2)))));
17116                      break;
17117                   }
17118 
17119                default:
17120                   return -1;
17121             }
17122 
17123             break;
17124          }
17125 
17126       case 0x03: { /* SUBSUU_S.df */
17127             switch (df) {
17128                case 0x00: { /* SUBSUU_S.B */
17129                      DIP("SUBSUU_S.B w%d, w%d, w%d", wd, ws, wt);
17130                      t1 = newTemp(Ity_V128);
17131                      t2 = newTemp(Ity_V128);
17132                      t3 = newTemp(Ity_V128);
17133                      assign(t1, binop(Iop_Sub8x16, getWReg(ws), getWReg(wt)));
17134                      assign(t2,
17135                             binop(Iop_SarN8x16,
17136                                   binop (Iop_AndV128,
17137                                          binop(Iop_XorV128,
17138                                                getWReg(ws),
17139                                                getWReg(wt)),
17140                                          binop(Iop_XorV128,
17141                                                mkexpr(t1),
17142                                                getWReg(wt))),
17143                                   mkU8(7)));
17144                      assign(t3,
17145                             binop(Iop_AndV128,
17146                                   binop(Iop_SarN8x16,
17147                                         getWReg(ws), mkU8(7)),
17148                                   mkexpr(t2)));
17149                      putWReg(wd,
17150                              binop(Iop_OrV128,
17151                                    binop(Iop_AndV128,
17152                                          mkexpr(t1),
17153                                          unop(Iop_NotV128,
17154                                               mkexpr(t2))),
17155                                    binop(Iop_XorV128,
17156                                          binop(Iop_ShlN8x16,
17157                                                mkexpr(t2), mkU8(7)),
17158                                          mkexpr(t3))));
17159                      break;
17160                   }
17161 
17162                case 0x01: { /* SUBSUU_S.H */
17163                      DIP("SUBSUU_S.H w%d, w%d, w%d", wd, ws, wt);
17164                      t1 = newTemp(Ity_V128);
17165                      t2 = newTemp(Ity_V128);
17166                      t3 = newTemp(Ity_V128);
17167                      assign(t1, binop(Iop_Sub16x8, getWReg(ws), getWReg(wt)));
17168                      assign(t2,
17169                             binop(Iop_SarN16x8,
17170                                   binop (Iop_AndV128,
17171                                          binop(Iop_XorV128,
17172                                                getWReg(ws),
17173                                                getWReg(wt)),
17174                                          binop(Iop_XorV128,
17175                                                mkexpr(t1),
17176                                                getWReg(wt))),
17177                                   mkU8(15)));
17178                      assign(t3,
17179                             binop(Iop_AndV128,
17180                                   binop(Iop_SarN16x8,
17181                                         getWReg(ws),
17182                                         mkU8(15)),
17183                                   mkexpr(t2)));
17184                      putWReg(wd,
17185                              binop(Iop_OrV128,
17186                                    binop(Iop_AndV128,
17187                                          mkexpr(t1),
17188                                          unop(Iop_NotV128,
17189                                               mkexpr(t2))),
17190                                    binop(Iop_XorV128,
17191                                          binop(Iop_ShlN16x8,
17192                                                mkexpr(t2), mkU8(15)),
17193                                          mkexpr(t3))));
17194                      break;
17195                   }
17196 
17197                case 0x02: { /* SUBSUU_S.W */
17198                      DIP("SUBSUU_S.W w%d, w%d, w%d", wd, ws, wt);
17199                      t1 = newTemp(Ity_V128);
17200                      t2 = newTemp(Ity_V128);
17201                      t3 = newTemp(Ity_V128);
17202                      assign(t1, binop(Iop_Sub32x4, getWReg(ws), getWReg(wt)));
17203                      assign(t2,
17204                             binop(Iop_SarN32x4,
17205                                   binop (Iop_AndV128,
17206                                          binop(Iop_XorV128,
17207                                                getWReg(ws),
17208                                                getWReg(wt)),
17209                                          binop(Iop_XorV128,
17210                                                mkexpr(t1),
17211                                                getWReg(wt))),
17212                                   mkU8(31)));
17213                      assign(t3,
17214                             binop(Iop_AndV128,
17215                                   binop(Iop_SarN32x4,
17216                                         getWReg(ws),
17217                                         mkU8(31)),
17218                                   mkexpr(t2)));
17219                      putWReg(wd,
17220                              binop(Iop_OrV128,
17221                                    binop(Iop_AndV128,
17222                                          mkexpr(t1),
17223                                          unop(Iop_NotV128,
17224                                               mkexpr(t2))),
17225                                    binop(Iop_XorV128,
17226                                          binop(Iop_ShlN32x4,
17227                                                mkexpr(t2),
17228                                                mkU8(31)),
17229                                          mkexpr(t3))));
17230                      break;
17231                   }
17232 
17233                case 0x03: { /* SUBSUU_S.D */
17234                      DIP("SUBSUU_S.D w%d, w%d, w%d", wd, ws, wt);
17235                      t1 = newTemp(Ity_V128);
17236                      t2 = newTemp(Ity_V128);
17237                      t3 = newTemp(Ity_V128);
17238                      assign(t1, binop(Iop_Sub64x2, getWReg(ws), getWReg(wt)));
17239                      assign(t2,
17240                             binop(Iop_SarN64x2,
17241                                   binop (Iop_AndV128,
17242                                          binop(Iop_XorV128,
17243                                                getWReg(ws),
17244                                                getWReg(wt)),
17245                                          binop(Iop_XorV128,
17246                                                mkexpr(t1),
17247                                                getWReg(wt))),
17248                                   mkU8(63)));
17249                      assign(t3,
17250                             binop(Iop_AndV128,
17251                                   binop(Iop_SarN64x2,
17252                                         getWReg(ws),
17253                                         mkU8(63)),
17254                                   mkexpr(t2)));
17255                      putWReg(wd,
17256                              binop(Iop_OrV128,
17257                                    binop(Iop_AndV128,
17258                                          mkexpr(t1),
17259                                          unop(Iop_NotV128,
17260                                               mkexpr(t2))),
17261                                    binop(Iop_XorV128,
17262                                          binop(Iop_ShlN64x2,
17263                                                mkexpr(t2), mkU8(63)),
17264                                          mkexpr(t3))));
17265                      break;
17266                   }
17267 
17268                default:
17269                   return -1;
17270             }
17271 
17272             break;
17273          }
17274 
17275       case 0x04: { /* ASUB_S.df */
17276             switch (df) {
17277                case 0x00: { /* ASUB_S.B */
17278                      DIP("ASUB_S.B w%d, w%d, w%d", wd, ws, wt);
17279                      t1 = newTemp(Ity_V128);
17280                      t2 = newTemp(Ity_V128);
17281                      t3 = newTemp(Ity_V128);
17282                      assign(t1, binop(Iop_SarN8x16, getWReg(ws), mkU8(7)));
17283                      assign(t2, binop(Iop_SarN8x16, getWReg(wt), mkU8(7)));
17284                      assign(t3, binop(Iop_Sub8x16, getWReg(ws), getWReg(wt)));
17285                      putWReg(wd,
17286                              binop(Iop_OrV128,
17287                                    binop(Iop_OrV128,
17288                                          binop(Iop_AndV128,
17289                                                binop(Iop_AndV128,
17290                                                      unop(Iop_NotV128,
17291                                                           mkexpr(t1)),
17292                                                      mkexpr(t2)),
17293                                                mkexpr(t3)),
17294                                          binop(Iop_AndV128,
17295                                                unop(Iop_NotV128,
17296                                                     binop(Iop_XorV128,
17297                                                           mkexpr(t1),
17298                                                           mkexpr(t2))),
17299                                                unop(Iop_Abs8x16,
17300                                                     mkexpr(t3)))),
17301                                    binop(Iop_AndV128,
17302                                          binop(Iop_AndV128,
17303                                                mkexpr(t1),
17304                                                unop(Iop_NotV128,
17305                                                     mkexpr(t2))),
17306                                          binop(Iop_Sub8x16,
17307                                                getWReg(wt),
17308                                                getWReg(ws)))));
17309                      break;
17310                   }
17311 
17312                case 0x01: { /* ASUB_S.H */
17313                      DIP("ASUB_S.H w%d, w%d, w%d", wd, ws, wt);
17314                      t1 = newTemp(Ity_V128);
17315                      t2 = newTemp(Ity_V128);
17316                      t3 = newTemp(Ity_V128);
17317                      assign(t1, binop(Iop_SarN16x8, getWReg(ws), mkU8(15)));
17318                      assign(t2, binop(Iop_SarN16x8, getWReg(wt), mkU8(15)));
17319                      assign(t3, binop(Iop_Sub16x8, getWReg(ws), getWReg(wt)));
17320                      putWReg(wd,
17321                              binop(Iop_OrV128,
17322                                    binop(Iop_OrV128,
17323                                          binop(Iop_AndV128,
17324                                                binop(Iop_AndV128,
17325                                                      unop(Iop_NotV128,
17326                                                           mkexpr(t1)),
17327                                                      mkexpr(t2)),
17328                                                mkexpr(t3)),
17329                                          binop(Iop_AndV128,
17330                                                unop(Iop_NotV128,
17331                                                     binop(Iop_XorV128,
17332                                                           mkexpr(t1),
17333                                                           mkexpr(t2))),
17334                                                unop(Iop_Abs16x8,
17335                                                     mkexpr(t3)))),
17336                                    binop(Iop_AndV128,
17337                                          binop(Iop_AndV128,
17338                                                mkexpr(t1),
17339                                                unop(Iop_NotV128,
17340                                                     mkexpr(t2))),
17341                                          binop(Iop_Sub16x8,
17342                                                getWReg(wt),
17343                                                getWReg(ws)))));
17344                      break;
17345                   }
17346 
17347                case 0x02: { /* ASUB_S.W */
17348                      DIP("ASUB_S.W w%d, w%d, w%d", wd, ws, wt);
17349                      t1 = newTemp(Ity_V128);
17350                      t2 = newTemp(Ity_V128);
17351                      t3 = newTemp(Ity_V128);
17352                      assign(t1, binop(Iop_SarN32x4, getWReg(ws), mkU8(31)));
17353                      assign(t2, binop(Iop_SarN32x4, getWReg(wt), mkU8(31)));
17354                      assign(t3, binop(Iop_Sub32x4, getWReg(ws), getWReg(wt)));
17355                      putWReg(wd,
17356                              binop(Iop_OrV128,
17357                                    binop(Iop_OrV128,
17358                                          binop(Iop_AndV128,
17359                                                binop(Iop_AndV128,
17360                                                      unop(Iop_NotV128,
17361                                                           mkexpr(t1)),
17362                                                      mkexpr(t2)),
17363                                                mkexpr(t3)),
17364                                          binop(Iop_AndV128,
17365                                                unop(Iop_NotV128,
17366                                                     binop(Iop_XorV128,
17367                                                           mkexpr(t1),
17368                                                           mkexpr(t2))),
17369                                                unop(Iop_Abs32x4,
17370                                                     mkexpr(t3)))),
17371                                    binop(Iop_AndV128,
17372                                          binop(Iop_AndV128,
17373                                                mkexpr(t1),
17374                                                unop(Iop_NotV128,
17375                                                     mkexpr(t2))),
17376                                          binop(Iop_Sub32x4,
17377                                                getWReg(wt),
17378                                                getWReg(ws)))));
17379                      break;
17380                   }
17381 
17382                case 0x03: { /* ASUB_S.D */
17383                      DIP("ASUB_S.D w%d, w%d, w%d", wd, ws, wt);
17384                      t1 = newTemp(Ity_V128);
17385                      t2 = newTemp(Ity_V128);
17386                      t3 = newTemp(Ity_V128);
17387                      assign(t1, binop(Iop_SarN64x2, getWReg(ws), mkU8(63)));
17388                      assign(t2, binop(Iop_SarN64x2, getWReg(wt), mkU8(63)));
17389                      assign(t3, binop(Iop_Sub64x2, getWReg(ws), getWReg(wt)));
17390                      putWReg(wd,
17391                              binop(Iop_OrV128,
17392                                    binop(Iop_OrV128,
17393                                          binop(Iop_AndV128,
17394                                                binop(Iop_AndV128,
17395                                                      unop(Iop_NotV128,
17396                                                           mkexpr(t1)),
17397                                                      mkexpr(t2)),
17398                                                mkexpr(t3)),
17399                                          binop(Iop_AndV128,
17400                                                unop(Iop_NotV128,
17401                                                     binop(Iop_XorV128,
17402                                                           mkexpr(t1),
17403                                                           mkexpr(t2))),
17404                                                unop(Iop_Abs64x2,
17405                                                     mkexpr(t3)))),
17406                                    binop(Iop_AndV128,
17407                                          binop(Iop_AndV128,
17408                                                mkexpr(t1),
17409                                                unop(Iop_NotV128,
17410                                                     mkexpr(t2))),
17411                                          binop(Iop_Sub64x2,
17412                                                getWReg(wt),
17413                                                getWReg(ws)))));
17414                      break;
17415                   }
17416 
17417                default:
17418                   return -1;
17419             }
17420 
17421             break;
17422          }
17423 
17424       case 0x05: { /* ASUB_U.df */
17425             switch (df) {
17426                case 0x00: { /* ASUB_U.B */
17427                      DIP("ASUB_U.B w%d, w%d, w%d", wd, ws, wt);
17428                      t1 = newTemp(Ity_V128);
17429                      t2 = newTemp(Ity_V128);
17430                      t3 = newTemp(Ity_V128);
17431                      assign(t1, getWReg(ws));
17432                      assign(t2, getWReg(wt));
17433                      assign(t3,
17434                             binop(Iop_SarN8x16,
17435                                   binop(Iop_XorV128,
17436                                         mkexpr(t1), mkexpr(t2)),
17437                                   mkU8(7)));
17438                      putWReg(wd,
17439                              binop(Iop_OrV128,
17440                                    binop(Iop_AndV128,
17441                                          unop(Iop_NotV128, mkexpr(t3)),
17442                                          unop(Iop_Abs8x16,
17443                                               binop(Iop_Sub8x16,
17444                                                     mkexpr(t1),
17445                                                     mkexpr(t2)))),
17446                                    binop(Iop_AndV128, mkexpr(t3),
17447                                          binop(Iop_Sub8x16,
17448                                                binop(Iop_Max8Ux16,
17449                                                      mkexpr(t1),
17450                                                      mkexpr(t2)),
17451                                                binop(Iop_Min8Ux16,
17452                                                      mkexpr(t1),
17453                                                      mkexpr(t2))))));
17454                      break;
17455                   }
17456 
17457                case 0x01: { /* ASUB_U.H */
17458                      DIP("ASUB_U.H w%d, w%d, w%d", wd, ws, wt);
17459                      t1 = newTemp(Ity_V128);
17460                      t2 = newTemp(Ity_V128);
17461                      t3 = newTemp(Ity_V128);
17462                      assign(t1, getWReg(ws));
17463                      assign(t2, getWReg(wt));
17464                      assign(t3,
17465                             binop(Iop_SarN16x8,
17466                                   binop(Iop_XorV128,
17467                                         mkexpr(t1), mkexpr(t2)),
17468                                   mkU8(15)));
17469                      putWReg(wd,
17470                              binop(Iop_OrV128,
17471                                    binop(Iop_AndV128,
17472                                          unop(Iop_NotV128,
17473                                               mkexpr(t3)),
17474                                          unop(Iop_Abs16x8,
17475                                               binop(Iop_Sub16x8,
17476                                                     mkexpr(t1),
17477                                                     mkexpr(t2)))),
17478                                    binop(Iop_AndV128,
17479                                          mkexpr(t3),
17480                                          binop(Iop_Sub16x8,
17481                                                binop(Iop_Max16Ux8,
17482                                                      mkexpr(t1),
17483                                                      mkexpr(t2)),
17484                                                binop(Iop_Min16Ux8,
17485                                                      mkexpr(t1),
17486                                                      mkexpr(t2))))));
17487                      break;
17488                   }
17489 
17490                case 0x02: { /* ASUB_U.W */
17491                      DIP("ASUB_U.W w%d, w%d, w%d", wd, ws, wt);
17492                      t1 = newTemp(Ity_V128);
17493                      t2 = newTemp(Ity_V128);
17494                      t3 = newTemp(Ity_V128);
17495                      assign(t1, getWReg(ws));
17496                      assign(t2, getWReg(wt));
17497                      assign(t3,
17498                             binop(Iop_SarN32x4,
17499                                   binop(Iop_XorV128,
17500                                         mkexpr(t1), mkexpr(t2)),
17501                                   mkU8(31)));
17502                      putWReg(wd,
17503                              binop(Iop_OrV128,
17504                                    binop(Iop_AndV128,
17505                                          unop(Iop_NotV128, mkexpr(t3)),
17506                                          unop(Iop_Abs32x4,
17507                                               binop(Iop_Sub32x4,
17508                                                     mkexpr(t1),
17509                                                     mkexpr(t2)))),
17510                                    binop(Iop_AndV128,
17511                                          mkexpr(t3),
17512                                          binop(Iop_Sub32x4,
17513                                                binop(Iop_Max32Ux4,
17514                                                      mkexpr(t1),
17515                                                      mkexpr(t2)),
17516                                                binop(Iop_Min32Ux4,
17517                                                      mkexpr(t1),
17518                                                      mkexpr(t2))))));
17519                      break;
17520                   }
17521 
17522                case 0x03: { /* ASUB_U.D */
17523                      DIP("ASUB_U.D w%d, w%d, w%d", wd, ws, wt);
17524                      t1 = newTemp(Ity_V128);
17525                      t2 = newTemp(Ity_V128);
17526                      t3 = newTemp(Ity_V128);
17527                      assign(t1, getWReg(ws));
17528                      assign(t2, getWReg(wt));
17529                      assign(t3,
17530                             binop(Iop_SarN64x2,
17531                                   binop(Iop_XorV128,
17532                                         mkexpr(t1), mkexpr(t2)),
17533                                   mkU8(63)));
17534                      putWReg(wd,
17535                              binop(Iop_OrV128,
17536                                    binop(Iop_AndV128,
17537                                          unop(Iop_NotV128, mkexpr(t3)),
17538                                          unop(Iop_Abs64x2,
17539                                               binop(Iop_Sub64x2,
17540                                                     mkexpr(t1),
17541                                                     mkexpr(t2)))),
17542                                    binop(Iop_AndV128,
17543                                          mkexpr(t3),
17544                                          binop(Iop_Sub64x2,
17545                                                binop(Iop_Max64Ux2,
17546                                                      mkexpr(t1),
17547                                                      mkexpr(t2)),
17548                                                binop(Iop_Min64Ux2,
17549                                                      mkexpr(t1),
17550                                                      mkexpr(t2))))));
17551                      break;
17552                   }
17553 
17554                default:
17555                   return -1;
17556             }
17557 
17558             break;
17559          }
17560 
17561       default:
17562          return -1;
17563    }
17564 
17565    return 0;
17566 }
17567 
msa_3R_12(UInt cins,UChar wd,UChar ws)17568 static Int msa_3R_12(UInt cins, UChar wd, UChar ws) { /* 3R (0x12) */
17569    IRTemp t1, t2, t3, t4, t5, t6;
17570    UShort operation;
17571    UChar df, wt;
17572 
17573    operation = (cins & 0x03800000) >> 23;
17574    df = (cins & 0x00600000) >> 21;
17575    wt = (cins & 0x001F0000) >> 16;
17576 
17577    switch (operation) {
17578       case 0x00: { /* MULV.df */
17579             switch (df) {
17580                case 0x00: { /* MULV.B */
17581                      DIP("MULV.B w%d, w%d, w%d", wd, ws, wt);
17582                      putWReg(wd, binop(Iop_Mul8x16, getWReg(ws), getWReg(wt)));
17583                      break;
17584                   }
17585 
17586                case 0x01: { /* MULV.H */
17587                      DIP("MULV.H w%d, w%d, w%d", wd, ws, wt);
17588                      putWReg(wd, binop(Iop_Mul16x8, getWReg(ws), getWReg(wt)));
17589                      break;
17590                   }
17591 
17592                case 0x02: { /* MULV.W */
17593                      DIP("MULV.W w%d, w%d, w%d", wd, ws, wt);
17594                      putWReg(wd, binop(Iop_Mul32x4, getWReg(ws), getWReg(wt)));
17595                      break;
17596                   }
17597 
17598                case 0x03: { /* MULV.D */
17599                      DIP("MULV.D w%d, w%d, w%d", wd, ws, wt);
17600                      t1 = newTemp(Ity_V128);
17601                      t2 = newTemp(Ity_V128);
17602                      assign(t1, getWReg(ws));
17603                      assign(t2, getWReg(wt));
17604                      putWReg(wd,
17605                              binop(Iop_64HLtoV128,
17606                                    binop(Iop_Mul64,
17607                                          unop(Iop_V128HIto64,
17608                                               mkexpr(t1)),
17609                                          unop(Iop_V128HIto64,
17610                                               mkexpr(t2))),
17611                                    binop(Iop_Mul64,
17612                                          unop(Iop_V128to64,
17613                                               mkexpr(t1)),
17614                                          unop(Iop_V128to64,
17615                                               mkexpr(t2)))));
17616                      break;
17617                   }
17618 
17619                default:
17620                   return -1;
17621             }
17622 
17623             break;
17624          }
17625 
17626       case 0x01: { /* MADDV.df */
17627             switch (df) {
17628                case 0x00: { /* MADDV.B */
17629                      DIP("MADDV.B w%d, w%d, w%d", wd, ws, wt);
17630                      putWReg(wd,
17631                              binop(Iop_Add8x16,
17632                                    getWReg(wd),
17633                                    binop(Iop_Mul8x16,
17634                                          getWReg(ws),
17635                                          getWReg(wt))));
17636                      break;
17637                   }
17638 
17639                case 0x01: { /* MADDV.H */
17640                      DIP("MADDV.H w%d, w%d, w%d", wd, ws, wt);
17641                      putWReg(wd,
17642                              binop(Iop_Add16x8,
17643                                    getWReg(wd),
17644                                    binop(Iop_Mul16x8,
17645                                          getWReg(ws),
17646                                          getWReg(wt))));
17647                      break;
17648                   }
17649 
17650                case 0x02: { /* MADDV.W */
17651                      DIP("MADDV.W w%d, w%d, w%d", wd, ws, wt);
17652                      putWReg(wd,
17653                              binop(Iop_Add32x4,
17654                                    getWReg(wd),
17655                                    binop(Iop_Mul32x4,
17656                                          getWReg(ws),
17657                                          getWReg(wt))));
17658                      break;
17659                   }
17660 
17661                case 0x03: { /* MADDV.D */
17662                      DIP("MADDV.D w%d, w%d, w%d", wd, ws, wt);
17663                      t1 = newTemp(Ity_V128);
17664                      t2 = newTemp(Ity_V128);
17665                      assign(t1, getWReg(ws));
17666                      assign(t2, getWReg(wt));
17667                      putWReg(wd,
17668                              binop(Iop_Add64x2,
17669                                    getWReg(wd),
17670                                    binop(Iop_64HLtoV128,
17671                                          binop(Iop_Mul64,
17672                                                unop(Iop_V128HIto64,
17673                                                     mkexpr(t1)),
17674                                                unop(Iop_V128HIto64,
17675                                                     mkexpr(t2))),
17676                                          binop(Iop_Mul64,
17677                                                unop(Iop_V128to64,
17678                                                     mkexpr(t1)),
17679                                                unop(Iop_V128to64,
17680                                                     mkexpr(t2))))));
17681                      break;
17682                   }
17683 
17684                default:
17685                   return -1;
17686             }
17687 
17688             break;
17689          }
17690 
17691       case 0x02: { /* MSUBV.df */
17692             switch (df) {
17693                case 0x00: { /* MSUBV.B */
17694                      DIP("MSUBV.B w%d, w%d, w%d", wd, ws, wt);
17695                      putWReg(wd,
17696                              binop(Iop_Sub8x16,
17697                                    getWReg(wd),
17698                                    binop(Iop_Mul8x16,
17699                                          getWReg(ws),
17700                                          getWReg(wt))));
17701                      break;
17702                   }
17703 
17704                case 0x01: { /* MSUBV.H */
17705                      DIP("MSUBV.H w%d, w%d, w%d", wd, ws, wt);
17706                      putWReg(wd,
17707                              binop(Iop_Sub16x8,
17708                                    getWReg(wd),
17709                                    binop(Iop_Mul16x8,
17710                                          getWReg(ws),
17711                                          getWReg(wt))));
17712                      break;
17713                   }
17714 
17715                case 0x02: { /* MSUBV.W */
17716                      DIP("MSUBV.W w%d, w%d, w%d", wd, ws, wt);
17717                      putWReg(wd,
17718                              binop(Iop_Sub32x4,
17719                                    getWReg(wd),
17720                                    binop(Iop_Mul32x4,
17721                                          getWReg(ws),
17722                                          getWReg(wt))));
17723                      break;
17724                   }
17725 
17726                case 0x03: { /* MSUBV.D */
17727                      DIP("MSUBV.D w%d, w%d, w%d", wd, ws, wt);
17728                      t1 = newTemp(Ity_V128);
17729                      t2 = newTemp(Ity_V128);
17730                      assign(t1, getWReg(ws));
17731                      assign(t2, getWReg(wt));
17732                      putWReg(wd,
17733                              binop(Iop_Sub64x2,
17734                                    getWReg(wd),
17735                                    binop(Iop_64HLtoV128,
17736                                          binop(Iop_Mul64,
17737                                                unop(Iop_V128HIto64,
17738                                                     mkexpr(t1)),
17739                                                unop(Iop_V128HIto64,
17740                                                     mkexpr(t2))),
17741                                          binop(Iop_Mul64,
17742                                                unop(Iop_V128to64,
17743                                                     mkexpr(t1)),
17744                                                unop(Iop_V128to64,
17745                                                     mkexpr(t2))))));
17746                      break;
17747                   }
17748 
17749                default:
17750                   return -1;
17751             }
17752 
17753             break;
17754          }
17755 
17756       case 0x04: { /* DIV_S.df */
17757             t1 = newTemp(Ity_V128);
17758             t2 = newTemp(Ity_V128);
17759             assign(t1, getWReg(ws));
17760             assign(t2, getWReg(wt));
17761 
17762             switch (df) {
17763                case 0x00: { /* DIV_S.B */
17764                      DIP("DIV_S.B w%d, w%d, w%d", wd, ws, wt);
17765                      IRTemp tmp[16];
17766                      Int i;
17767 
17768                      for (i = 0; i < 16; i++) {
17769                         tmp[i] = newTemp(Ity_I32);
17770                         assign(tmp[i],
17771                            binop(Iop_Shl32,
17772                                  binop(Iop_And32,
17773                                        mkU32(0xFF),
17774                                        binop(Iop_DivS32,
17775                                              unop(Iop_8Sto32,
17776                                                   binop(Iop_GetElem8x16,
17777                                                         mkexpr(t1),
17778                                                         mkU8(i))),
17779                                              unop(Iop_8Sto32,
17780                                                   binop(Iop_GetElem8x16,
17781                                                         mkexpr(t2),
17782                                                         mkU8(i))))),
17783                                  mkU8((i & 3) << 3)));
17784                      }
17785 
17786                      putWReg(wd,
17787                           binop(Iop_64HLtoV128,
17788                              binop(Iop_32HLto64,
17789                                    binop(Iop_Or32,
17790                                          mkexpr(tmp[15]),
17791                                          binop(Iop_Or32,
17792                                                mkexpr(tmp[14]),
17793                                                binop(Iop_Or32,
17794                                                      mkexpr(tmp[13]),
17795                                                      mkexpr(tmp[12])))),
17796                                    binop(Iop_Or32,
17797                                          mkexpr(tmp[11]),
17798                                          binop(Iop_Or32,
17799                                                mkexpr(tmp[10]),
17800                                                binop(Iop_Or32,
17801                                                      mkexpr(tmp[9]),
17802                                                      mkexpr(tmp[8]))))),
17803                              binop(Iop_32HLto64,
17804                                    binop(Iop_Or32,
17805                                          mkexpr(tmp[7]),
17806                                          binop(Iop_Or32,
17807                                                mkexpr(tmp[6]),
17808                                                binop(Iop_Or32,
17809                                                      mkexpr(tmp[5]),
17810                                                      mkexpr(tmp[4])))),
17811                                    binop(Iop_Or32,
17812                                          mkexpr(tmp[3]),
17813                                          binop(Iop_Or32,
17814                                                mkexpr(tmp[2]),
17815                                                binop(Iop_Or32,
17816                                                      mkexpr(tmp[1]),
17817                                                      mkexpr(tmp[0]))))))
17818                      );
17819                      break;
17820                   }
17821 
17822                case 0x01: { /* DIV_S.H */
17823                      DIP("DIV_S.H w%d, w%d, w%d", wd, ws, wt);
17824                      IRTemp tmp[8];
17825                      Int i;
17826 
17827                      for (i = 0; i < 8; i++) {
17828                         tmp[i] = newTemp(Ity_I32);
17829                         assign(tmp[i],
17830                             binop(Iop_Shl32,
17831                                   binop(Iop_And32,
17832                                      mkU32(0xFFFF),
17833                                      binop(Iop_DivS32,
17834                                            unop(Iop_16Sto32,
17835                                                 binop(Iop_GetElem16x8,
17836                                                       mkexpr(t1),
17837                                                       mkU8(i))),
17838                                            unop(Iop_16Sto32,
17839                                                 binop(Iop_GetElem16x8,
17840                                                       mkexpr(t2),
17841                                                       mkU8(i))))),
17842                                   mkU8((i & 1) << 4)));
17843                      }
17844 
17845                      putWReg(wd,
17846                              binop(Iop_64HLtoV128,
17847                                    binop(Iop_32HLto64,
17848                                          binop(Iop_Or32,
17849                                                mkexpr(tmp[7]),
17850                                                mkexpr(tmp[6])),
17851                                          binop(Iop_Or32,
17852                                                mkexpr(tmp[5]),
17853                                                mkexpr(tmp[4]))),
17854                                    binop(Iop_32HLto64,
17855                                          binop(Iop_Or32,
17856                                                mkexpr(tmp[3]),
17857                                                mkexpr(tmp[2])),
17858                                          binop(Iop_Or32,
17859                                                mkexpr(tmp[1]),
17860                                                mkexpr(tmp[0])))));
17861                      break;
17862                   }
17863 
17864                case 0x02: { /* DIV_S.W */
17865                      DIP("DIV_S.W w%d, w%d, w%d", wd, ws, wt);
17866                      IRTemp tmp[4];
17867                      Int i;
17868 
17869                      for (i = 0; i < 4; i++) {
17870                         tmp[i] = newTemp(Ity_I32);
17871                         assign(tmp[i],
17872                                binop(Iop_DivS32,
17873                                      binop(Iop_GetElem32x4,
17874                                            mkexpr(t1), mkU8(i)),
17875                                      binop(Iop_GetElem32x4,
17876                                            mkexpr(t2), mkU8(i))));
17877                      }
17878 
17879                      putWReg(wd,
17880                              binop(Iop_64HLtoV128, \
17881                                    binop(Iop_32HLto64,
17882                                          mkexpr(tmp[3]),
17883                                          mkexpr(tmp[2])),
17884                                    binop(Iop_32HLto64,
17885                                          mkexpr(tmp[1]),
17886                                          mkexpr(tmp[0]))));
17887                      break;
17888                   }
17889 
17890                case 0x03: { /* DIV_S.D */
17891                      DIP("DIV_S.D w%d, w%d, w%d", wd, ws, wt);
17892                      putWReg(wd,
17893                              binop(Iop_64HLtoV128,
17894                                    binop(Iop_DivS64,
17895                                          unop(Iop_V128HIto64,
17896                                               mkexpr(t1)),
17897                                          unop(Iop_V128HIto64,
17898                                               mkexpr(t2))),
17899                                    binop(Iop_DivS64,
17900                                          unop(Iop_V128to64,
17901                                               mkexpr(t1)),
17902                                          unop(Iop_V128to64,
17903                                               mkexpr(t2)))));
17904                      break;
17905                   }
17906 
17907                default:
17908                   return -1;
17909             }
17910 
17911             break;
17912          }
17913 
17914       case 0x05: { /* DIV_U.df */
17915             t1 = newTemp(Ity_V128);
17916             t2 = newTemp(Ity_V128);
17917             assign(t1, getWReg(ws));
17918             assign(t2, getWReg(wt));
17919 
17920             switch (df) {
17921                case 0x00: { /* DIV_U.B */
17922                      DIP("DIV_U.B w%d, w%d, w%d", wd, ws, wt);
17923                      IRTemp tmp[16];
17924                      Int i;
17925 
17926                      for (i = 0; i < 16; i++) {
17927                         tmp[i] = newTemp(Ity_I32);
17928                         assign(tmp[i],
17929                             binop(Iop_Shl32,
17930                                binop(Iop_And32,
17931                                      mkU32(0xFF),
17932                                      binop(Iop_DivU32,
17933                                            unop(Iop_8Uto32,
17934                                                 binop(Iop_GetElem8x16,
17935                                                       mkexpr(t1),
17936                                                       mkU8(i))),
17937                                            unop(Iop_8Uto32,
17938                                                 binop(Iop_GetElem8x16,
17939                                                       mkexpr(t2),
17940                                                       mkU8(i))))),
17941                                mkU8((i & 3) << 3)));
17942                      }
17943 
17944                      putWReg(wd,
17945                         binop(Iop_64HLtoV128,
17946                              binop(Iop_32HLto64,
17947                                    binop(Iop_Or32,
17948                                          mkexpr(tmp[15]),
17949                                          binop(Iop_Or32,
17950                                                mkexpr(tmp[14]),
17951                                                binop(Iop_Or32,
17952                                                      mkexpr(tmp[13]),
17953                                                      mkexpr(tmp[12])))),
17954                                    binop(Iop_Or32,
17955                                          mkexpr(tmp[11]),
17956                                          binop(Iop_Or32,
17957                                                mkexpr(tmp[10]),
17958                                                binop(Iop_Or32,
17959                                                      mkexpr(tmp[9]),
17960                                                      mkexpr(tmp[8]))))),
17961                              binop(Iop_32HLto64,
17962                                    binop(Iop_Or32,
17963                                          mkexpr(tmp[7]),
17964                                          binop(Iop_Or32,
17965                                                mkexpr(tmp[6]),
17966                                                binop(Iop_Or32,
17967                                                      mkexpr(tmp[5]),
17968                                                      mkexpr(tmp[4])))),
17969                                    binop(Iop_Or32,
17970                                          mkexpr(tmp[3]),
17971                                          binop(Iop_Or32,
17972                                                mkexpr(tmp[2]),
17973                                                binop(Iop_Or32,
17974                                                      mkexpr(tmp[1]),
17975                                                      mkexpr(tmp[0]))))))
17976                      );
17977                      break;
17978                   }
17979 
17980                case 0x01: { /* DIV_U.H */
17981                      DIP("DIV_U.H w%d, w%d, w%d", wd, ws, wt);
17982                      IRTemp tmp[8];
17983                      Int i;
17984 
17985                      for (i = 0; i < 8; i++) {
17986                         tmp[i] = newTemp(Ity_I32);
17987                         assign(tmp[i],
17988                            binop(Iop_Shl32,
17989                                binop(Iop_And32,
17990                                      mkU32(0xFFFF),
17991                                      binop(Iop_DivU32,
17992                                            unop(Iop_16Uto32,
17993                                                 binop(Iop_GetElem16x8,
17994                                                       mkexpr(t1),
17995                                                       mkU8(i))),
17996                                            unop(Iop_16Uto32,
17997                                                 binop(Iop_GetElem16x8,
17998                                                       mkexpr(t2),
17999                                                       mkU8(i))))),
18000                                mkU8((i & 1) << 4)));
18001                      }
18002 
18003                      putWReg(wd,
18004                              binop(Iop_64HLtoV128,
18005                                    binop(Iop_32HLto64,
18006                                          binop(Iop_Or32,
18007                                                mkexpr(tmp[7]),
18008                                                mkexpr(tmp[6])),
18009                                          binop(Iop_Or32,
18010                                                mkexpr(tmp[5]),
18011                                                mkexpr(tmp[4]))),
18012                                    binop(Iop_32HLto64,
18013                                          binop(Iop_Or32,
18014                                                mkexpr(tmp[3]),
18015                                                mkexpr(tmp[2])),
18016                                          binop(Iop_Or32,
18017                                                mkexpr(tmp[1]),
18018                                                mkexpr(tmp[0])))));
18019                      break;
18020                   }
18021 
18022                case 0x02: { /* DIV_U.W */
18023                      DIP("DIV_U.W w%d, w%d, w%d", wd, ws, wt);
18024                      IRTemp tmp[4];
18025                      Int i;
18026 
18027                      for (i = 0; i < 4; i++) {
18028                         tmp[i] = newTemp(Ity_I32);
18029                         assign(tmp[i],
18030                                binop(Iop_DivU32,
18031                                      binop(Iop_GetElem32x4,
18032                                            mkexpr(t1), mkU8(i)),
18033                                      binop(Iop_GetElem32x4,
18034                                            mkexpr(t2), mkU8(i))));
18035                      }
18036 
18037                      putWReg(wd,
18038                              binop(Iop_64HLtoV128,
18039                                    binop(Iop_32HLto64,
18040                                          mkexpr(tmp[3]),
18041                                          mkexpr(tmp[2])),
18042                                    binop(Iop_32HLto64,
18043                                          mkexpr(tmp[1]),
18044                                          mkexpr(tmp[0]))));
18045                      break;
18046                   }
18047 
18048                case 0x03: { /* DIV_U.D */
18049                      DIP("DIV_U.D w%d, w%d, w%d", wd, ws, wt);
18050                      putWReg(wd,
18051                              binop(Iop_64HLtoV128,
18052                                    binop(Iop_DivU64,
18053                                          unop(Iop_V128HIto64,
18054                                               mkexpr(t1)),
18055                                          unop(Iop_V128HIto64,
18056                                               mkexpr(t2))),
18057                                    binop(Iop_DivU64,
18058                                          unop(Iop_V128to64,
18059                                               mkexpr(t1)),
18060                                          unop(Iop_V128to64,
18061                                               mkexpr(t2)))));
18062                      break;
18063                   }
18064 
18065                default:
18066                   return -1;
18067             }
18068 
18069             break;
18070          }
18071 
18072       case 0x06: { /* MOD_S.df */
18073             t1 = newTemp(Ity_V128);
18074             t2 = newTemp(Ity_V128);
18075             assign(t1, getWReg(ws));
18076             assign(t2, getWReg(wt));
18077 
18078             switch (df) {
18079                case 0x00: { /* MOD_S.B */
18080                      DIP("MOD_S.B w%d, w%d, w%d", wd, ws, wt);
18081                      IRTemp tmp[16];
18082                      Int i;
18083 
18084                      for (i = 0; i < 16; i++) {
18085                         tmp[i] = newTemp(Ity_I32);
18086                         assign(tmp[i],
18087                            binop(Iop_Shl32,
18088                               binop(Iop_And32,
18089                                   mkU32(0xFF),
18090                                   unop(Iop_64HIto32,
18091                                        binop(Iop_DivModS32to32,
18092                                              unop(Iop_8Sto32,
18093                                                   binop(Iop_GetElem8x16,
18094                                                         mkexpr(t1),
18095                                                         mkU8(i))),
18096                                              unop(Iop_8Sto32,
18097                                                   binop(Iop_GetElem8x16,
18098                                                         mkexpr(t2),
18099                                                         mkU8(i)))))),
18100                               mkU8((i & 3) << 3)));
18101                      }
18102 
18103                      putWReg(wd,
18104                         binop(Iop_64HLtoV128,
18105                            binop(Iop_32HLto64,
18106                                 binop(Iop_Or32,
18107                                       mkexpr(tmp[15]),
18108                                       binop(Iop_Or32,
18109                                             mkexpr(tmp[14]),
18110                                             binop(Iop_Or32,
18111                                                   mkexpr(tmp[13]),
18112                                                   mkexpr(tmp[12])))),
18113                                 binop(Iop_Or32,
18114                                       mkexpr(tmp[11]),
18115                                       binop(Iop_Or32,
18116                                             mkexpr(tmp[10]),
18117                                             binop(Iop_Or32,
18118                                                   mkexpr(tmp[9]),
18119                                                   mkexpr(tmp[8]))))),
18120                            binop(Iop_32HLto64,
18121                                 binop(Iop_Or32,
18122                                       mkexpr(tmp[7]),
18123                                       binop(Iop_Or32,
18124                                             mkexpr(tmp[6]),
18125                                             binop(Iop_Or32,
18126                                                   mkexpr(tmp[5]),
18127                                                   mkexpr(tmp[4])))),
18128                                 binop(Iop_Or32,
18129                                       mkexpr(tmp[3]),
18130                                       binop(Iop_Or32,
18131                                             mkexpr(tmp[2]),
18132                                             binop(Iop_Or32,
18133                                                   mkexpr(tmp[1]),
18134                                                   mkexpr(tmp[0])))))));
18135                      break;
18136                   }
18137 
18138                case 0x01: { /* MOD_S.H */
18139                      DIP("MOD_S.H w%d, w%d, w%d", wd, ws, wt);
18140                      IRTemp tmp[8];
18141                      Int i;
18142 
18143                      for (i = 0; i < 8; i++) {
18144                         tmp[i] = newTemp(Ity_I32);
18145                         assign(tmp[i],
18146                            binop(Iop_Shl32,
18147                               binop(Iop_And32,
18148                                   mkU32(0xFFFF),
18149                                   unop(Iop_64HIto32,
18150                                        binop(Iop_DivModS32to32,
18151                                              unop(Iop_16Sto32,
18152                                                   binop(Iop_GetElem16x8,
18153                                                         mkexpr(t1),
18154                                                         mkU8(i))),
18155                                              unop(Iop_16Sto32,
18156                                                   binop(Iop_GetElem16x8,
18157                                                         mkexpr(t2),
18158                                                         mkU8(i)))))),
18159                               mkU8((i & 1) << 4)));
18160                      }
18161 
18162                      putWReg(wd,
18163                              binop(Iop_64HLtoV128,
18164                                    binop(Iop_32HLto64,
18165                                          binop(Iop_Or32,
18166                                                mkexpr(tmp[7]),
18167                                                mkexpr(tmp[6])),
18168                                          binop(Iop_Or32,
18169                                                mkexpr(tmp[5]),
18170                                                mkexpr(tmp[4]))),
18171                                    binop(Iop_32HLto64,
18172                                          binop(Iop_Or32,
18173                                                mkexpr(tmp[3]),
18174                                                mkexpr(tmp[2])),
18175                                          binop(Iop_Or32,
18176                                                mkexpr(tmp[1]),
18177                                                mkexpr(tmp[0])))));
18178                      break;
18179                   }
18180 
18181                case 0x02: { /* MOD_S.W */
18182                      DIP("MOD_S.W w%d, w%d, w%d", wd, ws, wt);
18183                      IRTemp tmp[4];
18184                      Int i;
18185 
18186                      for (i = 0; i < 4; i++) {
18187                         tmp[i] = newTemp(Ity_I32);
18188                         assign(tmp[i],
18189                                unop(Iop_64HIto32,
18190                                     binop(Iop_DivModS32to32,
18191                                             binop(Iop_GetElem32x4,
18192                                                   mkexpr(t1),
18193                                                   mkU8(i)),
18194                                           binop(Iop_GetElem32x4,
18195                                                 mkexpr(t2),
18196                                                 mkU8(i)))));
18197                      }
18198 
18199                      putWReg(wd,
18200                              binop(Iop_64HLtoV128,
18201                                    binop(Iop_32HLto64,
18202                                          mkexpr(tmp[3]),
18203                                          mkexpr(tmp[2])),
18204                                    binop(Iop_32HLto64,
18205                                          mkexpr(tmp[1]),
18206                                          mkexpr(tmp[0]))));
18207                      break;
18208                   }
18209 
18210                case 0x03: { /* MOD_S.D */
18211                      DIP("MOD_S.D w%d, w%d, w%d", wd, ws, wt);
18212                      t3 = newTemp(Ity_I64);
18213                      t4 = newTemp(Ity_I64);
18214                      t5 = newTemp(Ity_I64);
18215                      t6 = newTemp(Ity_I64);
18216                      assign(t3, unop(Iop_V128HIto64, mkexpr(t1)));
18217                      assign(t4, unop(Iop_V128HIto64, mkexpr(t2)));
18218                      assign(t5, unop(Iop_V128to64, mkexpr(t1)));
18219                      assign(t6, unop(Iop_V128to64, mkexpr(t2)));
18220                      putWReg(wd,
18221                              binop(Iop_64HLtoV128,
18222                                    binop(Iop_Sub64,
18223                                          mkexpr(t3),
18224                                          binop(Iop_Mul64,
18225                                                mkexpr(t4),
18226                                                binop(Iop_DivS64,
18227                                                      mkexpr(t3),
18228                                                      mkexpr(t4)))),
18229                                    binop(Iop_Sub64,
18230                                          mkexpr(t5),
18231                                          binop(Iop_Mul64,
18232                                                mkexpr(t6),
18233                                                binop(Iop_DivS64,
18234                                                      mkexpr(t5),
18235                                                      mkexpr(t6))))));
18236                      break;
18237                   }
18238 
18239                default:
18240                   return -1;
18241             }
18242 
18243             break;
18244          }
18245 
18246       case 0x07: { /* MOD_U.df */
18247             t1 = newTemp(Ity_V128);
18248             t2 = newTemp(Ity_V128);
18249             assign(t1, getWReg(ws));
18250             assign(t2, getWReg(wt));
18251 
18252             switch (df) {
18253                case 0x00: { /* MOD_U.B */
18254                      DIP("MOD_U.B w%d, w%d, w%d", wd, ws, wt);
18255                      IRTemp tmp[16];
18256                      Int i;
18257 
18258                      for (i = 0; i < 16; i++) {
18259                         tmp[i] = newTemp(Ity_I32);
18260                         assign(tmp[i],
18261                            binop(Iop_Shl32,
18262                               binop(Iop_And32,
18263                                   mkU32(0xFF),
18264                                   unop(Iop_64HIto32,
18265                                        binop(Iop_DivModU32to32,
18266                                              unop(Iop_8Uto32,
18267                                                   binop(Iop_GetElem8x16,
18268                                                         mkexpr(t1),
18269                                                         mkU8(i))),
18270                                              unop(Iop_8Uto32,
18271                                                   binop(Iop_GetElem8x16,
18272                                                         mkexpr(t2),
18273                                                         mkU8(i)))))),
18274                               mkU8((i & 3) << 3)));
18275                      }
18276 
18277                      putWReg(wd,
18278                         binop(Iop_64HLtoV128,
18279                           binop(Iop_32HLto64,
18280                                 binop(Iop_Or32,
18281                                       mkexpr(tmp[15]),
18282                                       binop(Iop_Or32,
18283                                             mkexpr(tmp[14]),
18284                                             binop(Iop_Or32,
18285                                                   mkexpr(tmp[13]),
18286                                                   mkexpr(tmp[12])))),
18287                                 binop(Iop_Or32,
18288                                       mkexpr(tmp[11]),
18289                                       binop(Iop_Or32,
18290                                             mkexpr(tmp[10]),
18291                                             binop(Iop_Or32,
18292                                                   mkexpr(tmp[9]),
18293                                                   mkexpr(tmp[8]))))),
18294                           binop(Iop_32HLto64,
18295                                 binop(Iop_Or32,
18296                                       mkexpr(tmp[7]),
18297                                       binop(Iop_Or32,
18298                                             mkexpr(tmp[6]),
18299                                             binop(Iop_Or32,
18300                                                   mkexpr(tmp[5]),
18301                                                   mkexpr(tmp[4])))),
18302                                 binop(Iop_Or32,
18303                                       mkexpr(tmp[3]),
18304                                       binop(Iop_Or32,
18305                                             mkexpr(tmp[2]),
18306                                             binop(Iop_Or32,
18307                                                   mkexpr(tmp[1]),
18308                                                   mkexpr(tmp[0])))))));
18309                      break;
18310                   }
18311 
18312                case 0x01: { /* MOD_U.H */
18313                      DIP("MOD_U.H w%d, w%d, w%d", wd, ws, wt);
18314                      IRTemp tmp[8];
18315                      Int i;
18316 
18317                      for (i = 0; i < 8; i++) {
18318                         tmp[i] = newTemp(Ity_I32);
18319                         assign(tmp[i],
18320                            binop(Iop_Shl32,
18321                               binop(Iop_And32,
18322                                   mkU32(0xFFFF),
18323                                   unop(Iop_64HIto32,
18324                                        binop(Iop_DivModU32to32,
18325                                              unop(Iop_16Uto32,
18326                                                   binop(Iop_GetElem16x8,
18327                                                         mkexpr(t1),
18328                                                         mkU8(i))),
18329                                              unop(Iop_16Uto32,
18330                                                   binop(Iop_GetElem16x8,
18331                                                         mkexpr(t2),
18332                                                         mkU8(i)))))),
18333                               mkU8((i & 1) << 4)));
18334                      }
18335 
18336                      putWReg(wd,
18337                              binop(Iop_64HLtoV128,
18338                                    binop(Iop_32HLto64,
18339                                          binop(Iop_Or32,
18340                                                mkexpr(tmp[7]),
18341                                                mkexpr(tmp[6])),
18342                                          binop(Iop_Or32,
18343                                                mkexpr(tmp[5]),
18344                                                mkexpr(tmp[4]))),
18345                                    binop(Iop_32HLto64,
18346                                          binop(Iop_Or32,
18347                                                mkexpr(tmp[3]),
18348                                                mkexpr(tmp[2])),
18349                                          binop(Iop_Or32,
18350                                                mkexpr(tmp[1]),
18351                                                mkexpr(tmp[0])))));
18352                      break;
18353                   }
18354 
18355                case 0x02: { /* MOD_U.W */
18356                      DIP("MOD_U.W w%d, w%d, w%d", wd, ws, wt);
18357                      IRTemp tmp[4];
18358                      Int i;
18359 
18360                      for (i = 0; i < 4; i++) {
18361                         tmp[i] = newTemp(Ity_I32);
18362                         assign(tmp[i],
18363                                unop(Iop_64HIto32,
18364                                     binop(Iop_DivModU32to32,
18365                                           binop(Iop_GetElem32x4,
18366                                                 mkexpr(t1),
18367                                                 mkU8(i)),
18368                                           binop(Iop_GetElem32x4,
18369                                                 mkexpr(t2),
18370                                                 mkU8(i)))));
18371                      }
18372 
18373                      putWReg(wd,
18374                              binop(Iop_64HLtoV128,
18375                                    binop(Iop_32HLto64,
18376                                          mkexpr(tmp[3]),
18377                                          mkexpr(tmp[2])),
18378                                    binop(Iop_32HLto64,
18379                                          mkexpr(tmp[1]),
18380                                          mkexpr(tmp[0]))));
18381                      break;
18382                   }
18383 
18384                case 0x03: { /* MOD_U.D */
18385                      DIP("MOD_U.D w%d, w%d, w%d", wd, ws, wt);
18386                      t3 = newTemp(Ity_I64);
18387                      t4 = newTemp(Ity_I64);
18388                      t5 = newTemp(Ity_I64);
18389                      t6 = newTemp(Ity_I64);
18390                      assign(t3, unop(Iop_V128HIto64, mkexpr(t1)));
18391                      assign(t4, unop(Iop_V128HIto64, mkexpr(t2)));
18392                      assign(t5, unop(Iop_V128to64, mkexpr(t1)));
18393                      assign(t6, unop(Iop_V128to64, mkexpr(t2)));
18394                      putWReg(wd,
18395                              binop(Iop_64HLtoV128,
18396                                    binop(Iop_Sub64,
18397                                          mkexpr(t3),
18398                                          binop(Iop_Mul64,
18399                                                mkexpr(t4),
18400                                                binop(Iop_DivU64,
18401                                                      mkexpr(t3),
18402                                                      mkexpr(t4)))),
18403                                    binop(Iop_Sub64,
18404                                          mkexpr(t5),
18405                                          binop(Iop_Mul64,
18406                                                mkexpr(t6),
18407                                                binop(Iop_DivU64,
18408                                                      mkexpr(t5),
18409                                                      mkexpr(t6))))));
18410                      break;
18411                   }
18412 
18413                default:
18414                   return -1;
18415             }
18416 
18417             break;
18418          }
18419 
18420       default:
18421          return -1;
18422    }
18423 
18424    return 0;
18425 }
18426 
msa_3R_13(UInt cins,UChar wd,UChar ws)18427 static Int msa_3R_13(UInt cins, UChar wd, UChar ws) { /* 3R (0x13) */
18428    IRTemp t1, t2;
18429    UShort operation;
18430    UChar df, wt;
18431 
18432    operation = (cins & 0x03800000) >> 23;
18433    df = (cins & 0x00600000) >> 21;
18434    wt = (cins & 0x001F0000) >> 16;
18435 
18436    switch (operation) {
18437       case 0x00: { /* DOTP_S.df */
18438             t1 = newTemp(Ity_V128);
18439             t2 = newTemp(Ity_V128);
18440             assign(t1, getWReg(ws));
18441             assign(t2, getWReg(wt));
18442 
18443             switch (df) {
18444                case 0x01: { /* DOTP_S.H */
18445                      DIP("DOTP_S.H w%d, w%d, w%d", wd, ws, wt);
18446                      IRTemp tmp[8];
18447                      Int i;
18448 
18449                      for (i = 0; i < 8; i++) {
18450                         tmp[i] = newTemp(Ity_I16);
18451                         assign(tmp[i],
18452                                binop(Iop_Add16,
18453                                      binop(Iop_MullS8,
18454                                            binop(Iop_GetElem8x16,
18455                                                  mkexpr(t1),
18456                                                  mkU8(2 * i)),
18457                                            binop(Iop_GetElem8x16,
18458                                                  mkexpr(t2),
18459                                                  mkU8(2 * i))),
18460                                      binop(Iop_MullS8,
18461                                            binop(Iop_GetElem8x16,
18462                                                  mkexpr(t1),
18463                                                  mkU8(2 * i + 1)),
18464                                            binop(Iop_GetElem8x16,
18465                                                  mkexpr(t2),
18466                                                  mkU8(2 * i + 1)))));
18467                      }
18468 
18469                      putWReg(wd,
18470                              binop(Iop_64HLtoV128,
18471                                    binop(Iop_32HLto64,
18472                                          binop(Iop_16HLto32,
18473                                                mkexpr(tmp[7]),
18474                                                mkexpr(tmp[6])),
18475                                          binop(Iop_16HLto32,
18476                                                mkexpr(tmp[5]),
18477                                                mkexpr(tmp[4]))),
18478                                    binop(Iop_32HLto64,
18479                                          binop(Iop_16HLto32,
18480                                                mkexpr(tmp[3]),
18481                                                mkexpr(tmp[2])),
18482                                          binop(Iop_16HLto32,
18483                                                mkexpr(tmp[1]),
18484                                                mkexpr(tmp[0])))));
18485                      break;
18486                   }
18487 
18488                case 0x02: { /* DOTP_S.W */
18489                      DIP("DOTP_S.W w%d, w%d, w%d", wd, ws, wt);
18490                      IRTemp tmp[4];
18491                      Int i;
18492 
18493                      for (i = 0; i < 4; i++) {
18494                         tmp[i] = newTemp(Ity_I32);
18495                         assign(tmp[i],
18496                                binop(Iop_Add32,
18497                                      binop(Iop_MullS16,
18498                                            binop(Iop_GetElem16x8,
18499                                                  mkexpr(t1),
18500                                                  mkU8(2 * i)),
18501                                            binop(Iop_GetElem16x8,
18502                                                  mkexpr(t2),
18503                                                  mkU8(2 * i))),
18504                                      binop(Iop_MullS16,
18505                                            binop(Iop_GetElem16x8,
18506                                                  mkexpr(t1),
18507                                                  mkU8(2 * i + 1)),
18508                                            binop(Iop_GetElem16x8,
18509                                                  mkexpr(t2),
18510                                                  mkU8(2 * i + 1)))));
18511                      }
18512 
18513                      putWReg(wd,
18514                              binop(Iop_64HLtoV128,
18515                                    binop(Iop_32HLto64,
18516                                          mkexpr(tmp[3]),
18517                                          mkexpr(tmp[2])),
18518                                    binop(Iop_32HLto64,
18519                                          mkexpr(tmp[1]),
18520                                          mkexpr(tmp[0]))));
18521                      break;
18522                   }
18523 
18524                case 0x03: { /* DOTP_S.D */
18525                      DIP("DOTP_S.D w%d, w%d, w%d", wd, ws, wt);
18526                      IRTemp tmp[2];
18527                      Int i;
18528 
18529                      for (i = 0; i < 2; i++) {
18530                         tmp[i] = newTemp(Ity_I64);
18531                         assign(tmp[i],
18532                                binop(Iop_Add64,
18533                                      binop(Iop_MullS32,
18534                                            binop(Iop_GetElem32x4,
18535                                                  mkexpr(t1),
18536                                                  mkU8(2 * i)),
18537                                            binop(Iop_GetElem32x4,
18538                                                  mkexpr(t2),
18539                                                  mkU8(2 * i))),
18540                                      binop(Iop_MullS32,
18541                                            binop(Iop_GetElem32x4,
18542                                                  mkexpr(t1),
18543                                                  mkU8(2 * i + 1)),
18544                                            binop(Iop_GetElem32x4,
18545                                                  mkexpr(t2),
18546                                                  mkU8(2 * i + 1)))));
18547                      }
18548 
18549                      putWReg(wd,
18550                              binop(Iop_64HLtoV128,
18551                                    mkexpr(tmp[1]), mkexpr(tmp[0])));
18552                      break;
18553                   }
18554 
18555                default:
18556                   return -1;
18557             }
18558 
18559             break;
18560          }
18561 
18562       case 0x01: { /* DOTP_U.df */
18563             t1 = newTemp(Ity_V128);
18564             t2 = newTemp(Ity_V128);
18565             assign(t1, getWReg(ws));
18566             assign(t2, getWReg(wt));
18567 
18568             switch (df) {
18569                case 0x01: { /* DOTP_U.H */
18570                      DIP("DOTP_U.H w%d, w%d, w%d", wd, ws, wt);
18571                      IRTemp tmp[8];
18572                      Int i;
18573 
18574                      for (i = 0; i < 8; i++) {
18575                         tmp[i] = newTemp(Ity_I16);
18576                         assign(tmp[i],
18577                                binop(Iop_Add16,
18578                                      binop(Iop_MullU8,
18579                                            binop(Iop_GetElem8x16,
18580                                                  mkexpr(t1),
18581                                                  mkU8(2 * i)),
18582                                            binop(Iop_GetElem8x16,
18583                                                  mkexpr(t2),
18584                                                  mkU8(2 * i))),
18585                                      binop(Iop_MullU8,
18586                                            binop(Iop_GetElem8x16,
18587                                                  mkexpr(t1),
18588                                                  mkU8(2 * i + 1)),
18589                                            binop(Iop_GetElem8x16,
18590                                                  mkexpr(t2),
18591                                                  mkU8(2 * i + 1)))));
18592                      }
18593 
18594                      putWReg(wd,
18595                              binop(Iop_64HLtoV128,
18596                                    binop(Iop_32HLto64,
18597                                          binop(Iop_16HLto32,
18598                                                mkexpr(tmp[7]),
18599                                                mkexpr(tmp[6])),
18600                                          binop(Iop_16HLto32,
18601                                                mkexpr(tmp[5]),
18602                                                mkexpr(tmp[4]))),
18603                                    binop(Iop_32HLto64,
18604                                          binop(Iop_16HLto32,
18605                                                mkexpr(tmp[3]),
18606                                                mkexpr(tmp[2])),
18607                                          binop(Iop_16HLto32,
18608                                                mkexpr(tmp[1]),
18609                                                mkexpr(tmp[0])))));
18610                      break;
18611                   }
18612 
18613                case 0x02: { /* DOTP_U.W */
18614                      DIP("DOTP_U.W w%d, w%d, w%d", wd, ws, wt);
18615                      IRTemp tmp[4];
18616                      Int i;
18617 
18618                      for (i = 0; i < 4; i++) {
18619                         tmp[i] = newTemp(Ity_I32);
18620                         assign(tmp[i],
18621                                binop(Iop_Add32,
18622                                      binop(Iop_MullU16,
18623                                            binop(Iop_GetElem16x8,
18624                                                  mkexpr(t1),
18625                                                  mkU8(2 * i)),
18626                                            binop(Iop_GetElem16x8,
18627                                                  mkexpr(t2),
18628                                                  mkU8(2 * i))),
18629                                      binop(Iop_MullU16,
18630                                            binop(Iop_GetElem16x8,
18631                                                  mkexpr(t1),
18632                                                  mkU8(2 * i + 1)),
18633                                            binop(Iop_GetElem16x8,
18634                                                  mkexpr(t2),
18635                                                  mkU8(2 * i + 1)))));
18636                      }
18637 
18638                      putWReg(wd,
18639                              binop(Iop_64HLtoV128,
18640                                    binop(Iop_32HLto64,
18641                                          mkexpr(tmp[3]),
18642                                          mkexpr(tmp[2])),
18643                                    binop(Iop_32HLto64,
18644                                          mkexpr(tmp[1]),
18645                                          mkexpr(tmp[0]))));
18646                      break;
18647                   }
18648 
18649                case 0x03: { /* DOTP_U.D */
18650                      DIP("DOTP_U.D w%d, w%d, w%d", wd, ws, wt);
18651                      IRTemp tmp[2];
18652                      Int i;
18653 
18654                      for (i = 0; i < 2; i++) {
18655                         tmp[i] = newTemp(Ity_I64);
18656                         assign(tmp[i],
18657                                binop(Iop_Add64,
18658                                      binop(Iop_MullU32,
18659                                            binop(Iop_GetElem32x4,
18660                                                  mkexpr(t1),
18661                                                  mkU8(2 * i)),
18662                                            binop(Iop_GetElem32x4,
18663                                                  mkexpr(t2),
18664                                                  mkU8(2 * i))),
18665                                      binop(Iop_MullU32,
18666                                            binop(Iop_GetElem32x4,
18667                                                  mkexpr(t1),
18668                                                  mkU8(2 * i + 1)),
18669                                            binop(Iop_GetElem32x4,
18670                                                  mkexpr(t2),
18671                                                  mkU8(2 * i + 1)))));
18672                      }
18673 
18674                      putWReg(wd,
18675                              binop(Iop_64HLtoV128,
18676                                    mkexpr(tmp[1]), mkexpr(tmp[0])));
18677                      break;
18678                   }
18679 
18680                default:
18681                   return -1;
18682             }
18683 
18684             break;
18685          }
18686 
18687       case 0x02: { /* DPADD_S.df */
18688             t1 = newTemp(Ity_V128);
18689             t2 = newTemp(Ity_V128);
18690             assign(t1, getWReg(ws));
18691             assign(t2, getWReg(wt));
18692 
18693             switch (df) {
18694                case 0x01: { /* DPADD_S.H */
18695                      DIP("DPADD_S.H w%d, w%d, w%d", wd, ws, wt);
18696                      IRTemp tmp[8];
18697                      Int i;
18698 
18699                      for (i = 0; i < 8; i++) {
18700                         tmp[i] = newTemp(Ity_I16);
18701                         assign(tmp[i],
18702                                binop(Iop_Add16,
18703                                      binop(Iop_MullS8,
18704                                            binop(Iop_GetElem8x16,
18705                                                  mkexpr(t1),
18706                                                  mkU8(2 * i)),
18707                                            binop(Iop_GetElem8x16,
18708                                                  mkexpr(t2),
18709                                                  mkU8(2 * i))),
18710                                      binop(Iop_MullS8,
18711                                            binop(Iop_GetElem8x16,
18712                                                  mkexpr(t1),
18713                                                  mkU8(2 * i + 1)),
18714                                            binop(Iop_GetElem8x16,
18715                                                  mkexpr(t2),
18716                                                  mkU8(2 * i + 1)))));
18717                      }
18718 
18719                      putWReg(wd,
18720                              binop(Iop_Add16x8,
18721                                 getWReg(wd),
18722                                 binop(Iop_64HLtoV128,
18723                                       binop(Iop_32HLto64,
18724                                             binop(Iop_16HLto32,
18725                                                   mkexpr(tmp[7]),
18726                                                   mkexpr(tmp[6])),
18727                                             binop(Iop_16HLto32,
18728                                                   mkexpr(tmp[5]),
18729                                                   mkexpr(tmp[4]))),
18730                                       binop(Iop_32HLto64,
18731                                             binop(Iop_16HLto32,
18732                                                   mkexpr(tmp[3]),
18733                                                   mkexpr(tmp[2])),
18734                                             binop(Iop_16HLto32,
18735                                                   mkexpr(tmp[1]),
18736                                                   mkexpr(tmp[0]))))));
18737                      break;
18738                   }
18739 
18740                case 0x02: { /* DPADD_S.W */
18741                      DIP("DPADD_S.W w%d, w%d, w%d", wd, ws, wt);
18742                      IRTemp tmp[4];
18743                      Int i;
18744 
18745                      for (i = 0; i < 4; i++) {
18746                         tmp[i] = newTemp(Ity_I32);
18747                         assign(tmp[i],
18748                                binop(Iop_Add32,
18749                                      binop(Iop_MullS16,
18750                                            binop(Iop_GetElem16x8,
18751                                                  mkexpr(t1),
18752                                                  mkU8(2 * i)),
18753                                            binop(Iop_GetElem16x8,
18754                                                  mkexpr(t2),
18755                                                  mkU8(2 * i))),
18756                                      binop(Iop_MullS16,
18757                                            binop(Iop_GetElem16x8,
18758                                                  mkexpr(t1),
18759                                                  mkU8(2 * i + 1)),
18760                                            binop(Iop_GetElem16x8,
18761                                                  mkexpr(t2),
18762                                                  mkU8(2 * i + 1)))));
18763                      }
18764 
18765                      putWReg(wd,
18766                              binop(Iop_Add32x4,
18767                                    getWReg(wd),
18768                                    binop(Iop_64HLtoV128,
18769                                          binop(Iop_32HLto64,
18770                                                mkexpr(tmp[3]),
18771                                                mkexpr(tmp[2])),
18772                                          binop(Iop_32HLto64,
18773                                                mkexpr(tmp[1]),
18774                                                mkexpr(tmp[0])))));
18775                      break;
18776                   }
18777 
18778                case 0x03: { /* DPADD_S.D */
18779                      DIP("DPADD_S.D w%d, w%d, w%d", wd, ws, wt);
18780                      IRTemp tmp[2];
18781                      Int i;
18782 
18783                      for (i = 0; i < 2; i++) {
18784                         tmp[i] = newTemp(Ity_I64);
18785                         assign(tmp[i],
18786                                binop(Iop_Add64,
18787                                      binop(Iop_MullS32,
18788                                            binop(Iop_GetElem32x4,
18789                                                  mkexpr(t1),
18790                                                  mkU8(2 * i)),
18791                                            binop(Iop_GetElem32x4,
18792                                                  mkexpr(t2),
18793                                                  mkU8(2 * i))),
18794                                      binop(Iop_MullS32,
18795                                            binop(Iop_GetElem32x4,
18796                                                  mkexpr(t1),
18797                                                  mkU8(2 * i + 1)),
18798                                            binop(Iop_GetElem32x4,
18799                                                  mkexpr(t2),
18800                                                  mkU8(2 * i + 1)))));
18801                      }
18802 
18803                      putWReg(wd,
18804                              binop(Iop_Add64x2,
18805                                    getWReg(wd),
18806                                    binop(Iop_64HLtoV128,
18807                                          mkexpr(tmp[1]),
18808                                          mkexpr(tmp[0]))));
18809                      break;
18810                   }
18811 
18812                default:
18813                   return -1;
18814             }
18815 
18816             break;
18817          }
18818 
18819       case 0x03: { /* DPADD_U.df */
18820             t1 = newTemp(Ity_V128);
18821             t2 = newTemp(Ity_V128);
18822             assign(t1, getWReg(ws));
18823             assign(t2, getWReg(wt));
18824 
18825             switch (df) {
18826                case 0x01: { /* DPADD_U.H */
18827                      DIP("DPADD_U.H w%d, w%d, w%d", wd, ws, wt);
18828                      IRTemp tmp[8];
18829                      Int i;
18830 
18831                      for (i = 0; i < 8; i++) {
18832                         tmp[i] = newTemp(Ity_I16);
18833                         assign(tmp[i],
18834                                binop(Iop_Add16,
18835                                      binop(Iop_MullU8,
18836                                            binop(Iop_GetElem8x16,
18837                                                  mkexpr(t1),
18838                                                  mkU8(2 * i)),
18839                                            binop(Iop_GetElem8x16,
18840                                                  mkexpr(t2),
18841                                                  mkU8(2 * i))),
18842                                      binop(Iop_MullU8,
18843                                            binop(Iop_GetElem8x16,
18844                                                  mkexpr(t1),
18845                                                  mkU8(2 * i + 1)),
18846                                            binop(Iop_GetElem8x16,
18847                                                  mkexpr(t2),
18848                                                  mkU8(2 * i + 1)))));
18849                      }
18850 
18851                      putWReg(wd,
18852                           binop(Iop_Add16x8,
18853                                 getWReg(wd),
18854                                 binop(Iop_64HLtoV128,
18855                                       binop(Iop_32HLto64,
18856                                             binop(Iop_16HLto32,
18857                                                   mkexpr(tmp[7]),
18858                                                   mkexpr(tmp[6])),
18859                                             binop(Iop_16HLto32,
18860                                                   mkexpr(tmp[5]),
18861                                                   mkexpr(tmp[4]))),
18862                                       binop(Iop_32HLto64,
18863                                             binop(Iop_16HLto32,
18864                                                   mkexpr(tmp[3]),
18865                                                   mkexpr(tmp[2])),
18866                                             binop(Iop_16HLto32,
18867                                                   mkexpr(tmp[1]),
18868                                                   mkexpr(tmp[0]))))));
18869                      break;
18870                   }
18871 
18872                case 0x02: { /* DPADD_U.W */
18873                      DIP("DPADD_U.W w%d, w%d, w%d", wd, ws, wt);
18874                      IRTemp tmp[4];
18875                      Int i;
18876 
18877                      for (i = 0; i < 4; i++) {
18878                         tmp[i] = newTemp(Ity_I32);
18879                         assign(tmp[i],
18880                                binop(Iop_Add32,
18881                                      binop(Iop_MullU16,
18882                                            binop(Iop_GetElem16x8,
18883                                                  mkexpr(t1),
18884                                                  mkU8(2 * i)),
18885                                            binop(Iop_GetElem16x8,
18886                                                  mkexpr(t2),
18887                                                  mkU8(2 * i))),
18888                                      binop(Iop_MullU16,
18889                                            binop(Iop_GetElem16x8,
18890                                                  mkexpr(t1),
18891                                                  mkU8(2 * i + 1)),
18892                                            binop(Iop_GetElem16x8,
18893                                                  mkexpr(t2),
18894                                                  mkU8(2 * i + 1)))));
18895                      }
18896 
18897                      putWReg(wd,
18898                              binop(Iop_Add32x4,
18899                                    getWReg(wd),
18900                                    binop(Iop_64HLtoV128,
18901                                          binop(Iop_32HLto64,
18902                                                mkexpr(tmp[3]),
18903                                                mkexpr(tmp[2])),
18904                                          binop(Iop_32HLto64,
18905                                                mkexpr(tmp[1]),
18906                                                mkexpr(tmp[0])))));
18907                      break;
18908                   }
18909 
18910                case 0x03: { /* DPADD_U.D */
18911                      DIP("DPADD_U.D w%d, w%d, w%d", wd, ws, wt);
18912                      IRTemp tmp[2];
18913                      Int i;
18914 
18915                      for (i = 0; i < 2; i++) {
18916                         tmp[i] = newTemp(Ity_I64);
18917                         assign(tmp[i],
18918                                binop(Iop_Add64,
18919                                      binop(Iop_MullU32,
18920                                            binop(Iop_GetElem32x4,
18921                                                  mkexpr(t1),
18922                                                  mkU8(2 * i)),
18923                                            binop(Iop_GetElem32x4,
18924                                                  mkexpr(t2),
18925                                                  mkU8(2 * i))),
18926                                      binop(Iop_MullU32,
18927                                            binop(Iop_GetElem32x4,
18928                                                  mkexpr(t1),
18929                                                  mkU8(2 * i + 1)),
18930                                            binop(Iop_GetElem32x4,
18931                                                  mkexpr(t2),
18932                                                  mkU8(2 * i + 1)))));
18933                      }
18934 
18935                      putWReg(wd,
18936                              binop(Iop_Add64x2,
18937                                    getWReg(wd),
18938                                    binop(Iop_64HLtoV128,
18939                                          mkexpr(tmp[1]),
18940                                          mkexpr(tmp[0]))));
18941                      break;
18942                   }
18943 
18944                default:
18945                   return -1;
18946             }
18947 
18948             break;
18949          }
18950 
18951       case 0x04: { /* DPSUB_S.df */
18952             t1 = newTemp(Ity_V128);
18953             t2 = newTemp(Ity_V128);
18954             assign(t1, getWReg(ws));
18955             assign(t2, getWReg(wt));
18956 
18957             switch (df) {
18958                case 0x01: { /* DPSUB_S.H */
18959                      DIP("DPSUB_S.H w%d, w%d, w%d", wd, ws, wt);
18960                      IRTemp tmp[8];
18961                      Int i;
18962 
18963                      for (i = 0; i < 8; i++) {
18964                         tmp[i] = newTemp(Ity_I16);
18965                         assign(tmp[i],
18966                                binop(Iop_Add16,
18967                                      binop(Iop_MullS8,
18968                                            binop(Iop_GetElem8x16,
18969                                                  mkexpr(t1),
18970                                                  mkU8(2 * i)),
18971                                            binop(Iop_GetElem8x16,
18972                                                  mkexpr(t2),
18973                                                  mkU8(2 * i))),
18974                                      binop(Iop_MullS8,
18975                                            binop(Iop_GetElem8x16,
18976                                                  mkexpr(t1),
18977                                                  mkU8(2 * i + 1)),
18978                                            binop(Iop_GetElem8x16,
18979                                                  mkexpr(t2),
18980                                                  mkU8(2 * i + 1)))));
18981                      }
18982 
18983                      putWReg(wd,
18984                           binop(Iop_Sub16x8,
18985                                 getWReg(wd),
18986                                 binop(Iop_64HLtoV128,
18987                                       binop(Iop_32HLto64,
18988                                             binop(Iop_16HLto32,
18989                                                   mkexpr(tmp[7]),
18990                                                   mkexpr(tmp[6])),
18991                                             binop(Iop_16HLto32,
18992                                                   mkexpr(tmp[5]),
18993                                                   mkexpr(tmp[4]))),
18994                                       binop(Iop_32HLto64,
18995                                             binop(Iop_16HLto32,
18996                                                   mkexpr(tmp[3]),
18997                                                   mkexpr(tmp[2])),
18998                                             binop(Iop_16HLto32,
18999                                                   mkexpr(tmp[1]),
19000                                                   mkexpr(tmp[0]))))));
19001                      break;
19002                   }
19003 
19004                case 0x02: { /* DPSUB_S.W */
19005                      DIP("DPSUB_S.W w%d, w%d, w%d", wd, ws, wt);
19006                      IRTemp tmp[4];
19007                      Int i;
19008 
19009                      for (i = 0; i < 4; i++) {
19010                         tmp[i] = newTemp(Ity_I32);
19011                         assign(tmp[i],
19012                                binop(Iop_Add32,
19013                                      binop(Iop_MullS16,
19014                                            binop(Iop_GetElem16x8,
19015                                                  mkexpr(t1),
19016                                                  mkU8(2 * i)),
19017                                            binop(Iop_GetElem16x8,
19018                                                  mkexpr(t2),
19019                                                  mkU8(2 * i))),
19020                                      binop(Iop_MullS16,
19021                                            binop(Iop_GetElem16x8,
19022                                                  mkexpr(t1),
19023                                                  mkU8(2 * i + 1)),
19024                                            binop(Iop_GetElem16x8,
19025                                                  mkexpr(t2),
19026                                                  mkU8(2 * i + 1)))));
19027                      }
19028 
19029                      putWReg(wd,
19030                              binop(Iop_Sub32x4,
19031                                    getWReg(wd),
19032                                    binop(Iop_64HLtoV128,
19033                                          binop(Iop_32HLto64,
19034                                                mkexpr(tmp[3]),
19035                                                mkexpr(tmp[2])),
19036                                          binop(Iop_32HLto64,
19037                                                mkexpr(tmp[1]),
19038                                                mkexpr(tmp[0])))));
19039                      break;
19040                   }
19041 
19042                case 0x03: { /* DPSUB_S.D */
19043                      DIP("DPSUB_S.D w%d, w%d, w%d", wd, ws, wt);
19044                      IRTemp tmp[2];
19045                      Int i;
19046 
19047                      for (i = 0; i < 2; i++) {
19048                         tmp[i] = newTemp(Ity_I64);
19049                         assign(tmp[i],
19050                                binop(Iop_Add64,
19051                                      binop(Iop_MullS32,
19052                                            binop(Iop_GetElem32x4,
19053                                                  mkexpr(t1),
19054                                                  mkU8(2 * i)),
19055                                            binop(Iop_GetElem32x4,
19056                                                  mkexpr(t2),
19057                                                  mkU8(2 * i))),
19058                                      binop(Iop_MullS32,
19059                                            binop(Iop_GetElem32x4,
19060                                                  mkexpr(t1),
19061                                                  mkU8(2 * i + 1)),
19062                                            binop(Iop_GetElem32x4,
19063                                                  mkexpr(t2),
19064                                                  mkU8(2 * i + 1)))));
19065                      }
19066 
19067                      putWReg(wd,
19068                              binop(Iop_Sub64x2,
19069                                    getWReg(wd),
19070                                    binop(Iop_64HLtoV128,
19071                                          mkexpr(tmp[1]),
19072                                          mkexpr(tmp[0]))));
19073                      break;
19074                   }
19075 
19076                default:
19077                   return -1;
19078             }
19079 
19080             break;
19081          }
19082 
19083       case 0x05: { /* DPSUB_U.df */
19084             t1 = newTemp(Ity_V128);
19085             t2 = newTemp(Ity_V128);
19086             assign(t1, getWReg(ws));
19087             assign(t2, getWReg(wt));
19088 
19089             switch (df) {
19090                case 0x01: { /* DPSUB_U.H */
19091                      DIP("DPSUB_U.H w%d, w%d, w%d", wd, ws, wt);
19092                      IRTemp tmp[8];
19093                      Int i;
19094 
19095                      for (i = 0; i < 8; i++) {
19096                         tmp[i] = newTemp(Ity_I16);
19097                         assign(tmp[i],
19098                                binop(Iop_Add16,
19099                                      binop(Iop_MullU8,
19100                                            binop(Iop_GetElem8x16,
19101                                                  mkexpr(t1),
19102                                                  mkU8(2 * i)),
19103                                            binop(Iop_GetElem8x16,
19104                                                  mkexpr(t2),
19105                                                  mkU8(2 * i))),
19106                                      binop(Iop_MullU8,
19107                                            binop(Iop_GetElem8x16,
19108                                                  mkexpr(t1),
19109                                                  mkU8(2 * i + 1)),
19110                                            binop(Iop_GetElem8x16,
19111                                                  mkexpr(t2),
19112                                                  mkU8(2 * i + 1)))));
19113                      }
19114 
19115                      putWReg(wd,
19116                           binop(Iop_Sub16x8,
19117                                 getWReg(wd),
19118                                 binop(Iop_64HLtoV128,
19119                                       binop(Iop_32HLto64,
19120                                             binop(Iop_16HLto32,
19121                                                   mkexpr(tmp[7]),
19122                                                   mkexpr(tmp[6])),
19123                                             binop(Iop_16HLto32,
19124                                                   mkexpr(tmp[5]),
19125                                                   mkexpr(tmp[4]))),
19126                                       binop(Iop_32HLto64,
19127                                             binop(Iop_16HLto32,
19128                                                   mkexpr(tmp[3]),
19129                                                   mkexpr(tmp[2])),
19130                                             binop(Iop_16HLto32,
19131                                                   mkexpr(tmp[1]),
19132                                                   mkexpr(tmp[0]))))));
19133                      break;
19134                   }
19135 
19136                case 0x02: { /* DPSUB_U.W */
19137                      DIP("DPSUB_U.W w%d, w%d, w%d", wd, ws, wt);
19138                      IRTemp tmp[4];
19139                      Int i;
19140 
19141                      for (i = 0; i < 4; i++) {
19142                         tmp[i] = newTemp(Ity_I32);
19143                         assign(tmp[i],
19144                                binop(Iop_Add32,
19145                                      binop(Iop_MullU16,
19146                                            binop(Iop_GetElem16x8,
19147                                                  mkexpr(t1),
19148                                                  mkU8(2 * i)),
19149                                            binop(Iop_GetElem16x8,
19150                                                  mkexpr(t2),
19151                                                  mkU8(2 * i))),
19152                                      binop(Iop_MullU16,
19153                                            binop(Iop_GetElem16x8,
19154                                                  mkexpr(t1),
19155                                                  mkU8(2 * i + 1)),
19156                                            binop(Iop_GetElem16x8,
19157                                                  mkexpr(t2),
19158                                                  mkU8(2 * i + 1)))));
19159                      }
19160 
19161                      putWReg(wd,
19162                              binop(Iop_Sub32x4,
19163                                    getWReg(wd),
19164                                    binop(Iop_64HLtoV128,
19165                                          binop(Iop_32HLto64,
19166                                                mkexpr(tmp[3]),
19167                                                mkexpr(tmp[2])),
19168                                          binop(Iop_32HLto64,
19169                                                mkexpr(tmp[1]),
19170                                                mkexpr(tmp[0])))));
19171                      break;
19172                   }
19173 
19174                case 0x03: { /* DPSUB_U.D */
19175                      DIP("DPSUB_U.D w%d, w%d, w%d", wd, ws, wt);
19176                      IRTemp tmp[2];
19177                      Int i;
19178 
19179                      for (i = 0; i < 2; i++) {
19180                         tmp[i] = newTemp(Ity_I64);
19181                         assign(tmp[i],
19182                                binop(Iop_Add64,
19183                                      binop(Iop_MullU32,
19184                                            binop(Iop_GetElem32x4,
19185                                                  mkexpr(t1),
19186                                                  mkU8(2 * i)),
19187                                            binop(Iop_GetElem32x4,
19188                                                  mkexpr(t2),
19189                                                  mkU8(2 * i))),
19190                                      binop(Iop_MullU32,
19191                                            binop(Iop_GetElem32x4,
19192                                                  mkexpr(t1),
19193                                                  mkU8(2 * i + 1)),
19194                                            binop(Iop_GetElem32x4,
19195                                                  mkexpr(t2),
19196                                                  mkU8(2 * i + 1)))));
19197                      }
19198 
19199                      putWReg(wd,
19200                              binop(Iop_Sub64x2,
19201                                    getWReg(wd),
19202                                    binop(Iop_64HLtoV128,
19203                                          mkexpr(tmp[1]),
19204                                          mkexpr(tmp[0]))));
19205                      break;
19206                   }
19207 
19208                default:
19209                   return -1;
19210             }
19211 
19212             break;
19213          }
19214 
19215       default:
19216          return -1;
19217    }
19218 
19219    return 0;
19220 }
19221 
msa_3R_14(UInt cins,UChar wd,UChar ws)19222 static Int msa_3R_14(UInt cins, UChar wd, UChar ws) { /* 3R (0x14) */
19223    IRTemp t1, t2, t3, t4;
19224    IRType ty;
19225    UShort operation;
19226    UChar df, wt;
19227 
19228    operation = (cins & 0x03800000) >> 23;
19229    df = (cins & 0x00600000) >> 21;
19230    wt = (cins & 0x001F0000) >> 16;
19231    ty = mode64 ? Ity_I64 : Ity_I32;
19232 
19233    switch (operation) {
19234       case 0x00: { /* SLD.df */
19235             switch (df) {
19236                case 0x00: {
19237                      DIP("SLD.B w%d, w%d[%d]", wd, ws, wt);
19238                      t1 = newTemp(Ity_I32);
19239                      t2 = newTemp(Ity_V128);
19240                      t3 = newTemp(Ity_V128);
19241                      assign(t1,
19242                             binop(Iop_Shl32,
19243                                   binop(Iop_And32,
19244                                         mkNarrowTo32(ty,
19245                                                      getIReg(wt)),
19246                                         mkU32(15)),
19247                                   mkU8(3)));
19248                      assign(t2,
19249                             binop(Iop_ShrV128,
19250                                   getWReg(ws),
19251                                   unop(Iop_32to8, mkexpr(t1))));
19252                      assign(t3,
19253                             binop(Iop_ShlV128,
19254                                   getWReg(wd),
19255                                   unop(Iop_32to8,
19256                                        binop(Iop_Sub32,
19257                                              mkU32(128),
19258                                              mkexpr(t1)))));
19259                      putWReg(wd,
19260                              binop(Iop_OrV128,
19261                                    mkexpr(t2), mkexpr(t3)));
19262                      break;
19263                   }
19264 
19265                case 0x01: {/* SLD.H */
19266                      DIP("SLD.H w%d, w%d[%d]", wd, ws, wt);
19267                      t1 = newTemp(Ity_I32);
19268                      t2 = newTemp(Ity_I64);
19269                      t3 = newTemp(Ity_V128);
19270                      t4 = newTemp(Ity_V128);
19271                      assign(t1,
19272                             binop(Iop_Shl32,
19273                                   binop(Iop_And32,
19274                                         mkNarrowTo32(ty,
19275                                                      getIReg(wt)),
19276                                         mkU32(7)),
19277                                   mkU8(3)));
19278                      assign(t2,
19279                             binop(Iop_32HLto64, mkU32(0), mkexpr(t1)));
19280                      assign(t3,
19281                             binop(Iop_Shr64x2,
19282                                   getWReg(ws),
19283                                   binop(Iop_64HLtoV128,
19284                                         mkexpr(t2), mkexpr(t2))));
19285                      assign(t4,
19286                             binop(Iop_Shl64x2,
19287                                   getWReg(wd),
19288                                   binop(Iop_Sub64x2,
19289                                         binop(Iop_64HLtoV128,
19290                                               mkU64(0x40ul),
19291                                               mkU64(0x40ul)),
19292                                         binop(Iop_64HLtoV128,
19293                                               mkexpr(t2),
19294                                               mkexpr(t2)))));
19295                      putWReg(wd,
19296                              binop(Iop_OrV128,
19297                                    mkexpr(t3),
19298                                    IRExpr_ITE(
19299                                       binop(Iop_CmpNE32,
19300                                             mkexpr(t1), mkU32(0)),
19301                                       mkexpr(t4),
19302                                       binop(Iop_64HLtoV128,
19303                                             mkU64(0), mkU64(0)))));
19304                      break;
19305                   }
19306 
19307                case 0x02: {/* SLD.W */
19308                      DIP("SLD.W w%d, w%d[%d]", wd, ws, wt);
19309                      t1 = newTemp(Ity_I32);
19310                      t2 = newTemp(Ity_I64);
19311                      t3 = newTemp(Ity_V128);
19312                      t4 = newTemp(Ity_V128);
19313                      assign(t1,
19314                             binop(Iop_Shl32,
19315                                   binop(Iop_And32,
19316                                         mkNarrowTo32(ty,
19317                                                      getIReg(wt)),
19318                                         mkU32(3)),
19319                                   mkU8(3)));
19320                      assign(t2,
19321                             binop(Iop_32HLto64,
19322                                   mkexpr(t1), mkexpr(t1)));
19323                      assign(t3,
19324                             binop(Iop_Shr32x4,
19325                                   getWReg(ws),
19326                                   binop(Iop_64HLtoV128,
19327                                         mkexpr(t2), mkexpr(t2))));
19328                      assign(t4,
19329                             binop(Iop_Shl32x4,
19330                                   getWReg(wd),
19331                                   binop(Iop_Sub32x4,
19332                                         binop(Iop_64HLtoV128,
19333                                               mkU64(0x2000000020ul),
19334                                               mkU64(0x2000000020ul)),
19335                                         binop(Iop_64HLtoV128,
19336                                               mkexpr(t2),
19337                                               mkexpr(t2)))));
19338                      putWReg(wd,
19339                              binop(Iop_OrV128,
19340                                    mkexpr(t3),
19341                                    IRExpr_ITE(
19342                                       binop(Iop_CmpNE32,
19343                                             mkexpr(t1), mkU32(0)),
19344                                       mkexpr(t4),
19345                                       binop(Iop_64HLtoV128,
19346                                             mkU64(0), mkU64(0)))));
19347                      break;
19348                   }
19349 
19350                case 0x03: { /* SLD.D */
19351                      DIP("SLD.D w%d, w%d[%d]", wd, ws, wt);
19352                      t1 = newTemp(Ity_I32);
19353                      t2 = newTemp(Ity_I64);
19354                      t3 = newTemp(Ity_V128);
19355                      t4 = newTemp(Ity_V128);
19356                      assign(t1,
19357                             binop(Iop_Shl32,
19358                                   binop(Iop_And32,
19359                                         mkNarrowTo32(ty,
19360                                                      getIReg(wt)),
19361                                         mkU32(1)),
19362                                   mkU8(3)));
19363                      assign(t2,
19364                             binop(Iop_32HLto64,
19365                                   binop(Iop_Or32,
19366                                         mkexpr(t1),
19367                                         binop(Iop_Shl32,
19368                                               mkexpr(t1), mkU8(16))),
19369                                   binop(Iop_Or32,
19370                                         mkexpr(t1),
19371                                         binop(Iop_Shl32,
19372                                               mkexpr(t1), mkU8(16)))));
19373                      assign(t3,
19374                             binop(Iop_Shr16x8,
19375                                   getWReg(ws),
19376                                   binop(Iop_64HLtoV128,
19377                                         mkexpr(t2), mkexpr(t2))));
19378                      assign(t4,
19379                             binop(Iop_Shl16x8,
19380                                getWReg(wd),
19381                                binop(Iop_Sub16x8,
19382                                      binop(Iop_64HLtoV128,
19383                                            mkU64(0x10001000100010ul),
19384                                            mkU64(0x10001000100010ul)),
19385                                      binop(Iop_64HLtoV128,
19386                                            mkexpr(t2),
19387                                            mkexpr(t2)))));
19388                      putWReg(wd,
19389                              binop(Iop_OrV128,
19390                                    mkexpr(t3),
19391                                    IRExpr_ITE(
19392                                       binop(Iop_CmpNE32,
19393                                             mkexpr(t1), mkU32(0)),
19394                                       mkexpr(t4),
19395                                       binop(Iop_64HLtoV128,
19396                                             mkU64(0), mkU64(0)))));
19397                      break;
19398                   }
19399             }
19400 
19401             break;
19402          }
19403 
19404       case 0x01: { /* SPLAT.df */
19405             switch (df) {
19406                   Int i;
19407 
19408                case 0x00: { /* SPLAT.B */
19409                      DIP("SPLAT.B w%d, w%d, w%d", wd, ws, wt);
19410                      t1 = newTemp(Ity_V128);
19411                      t2 = newTemp(Ity_I32);
19412                      assign(t1, getWReg(ws));
19413                      assign(t2,
19414                             mkNarrowTo32(ty, getIReg(wt)));
19415                      IRTemp tmp[16];
19416 
19417                      for (i = 0; i < 16; i++) {
19418                         tmp[i] = newTemp(Ity_I8);
19419                         assign(tmp[i],
19420                                binop(Iop_GetElem8x16,
19421                                      mkexpr(t1),
19422                                      unop(Iop_32to8, mkexpr(t2))));
19423                      }
19424 
19425                      putWReg(wd,
19426                           binop(Iop_64HLtoV128,
19427                                 binop(Iop_32HLto64,
19428                                       binop(Iop_16HLto32,
19429                                             binop(Iop_8HLto16,
19430                                                   mkexpr(tmp[15]),
19431                                                   mkexpr(tmp[14])),
19432                                             binop(Iop_8HLto16,
19433                                                   mkexpr(tmp[13]),
19434                                                   mkexpr(tmp[12]))),
19435                                       binop(Iop_16HLto32,
19436                                             binop(Iop_8HLto16,
19437                                                   mkexpr(tmp[11]),
19438                                                   mkexpr(tmp[10])),
19439                                             binop(Iop_8HLto16,
19440                                                   mkexpr(tmp[9]),
19441                                                   mkexpr(tmp[8])))),
19442                                 binop(Iop_32HLto64,
19443                                       binop(Iop_16HLto32,
19444                                             binop(Iop_8HLto16,
19445                                                   mkexpr(tmp[7]),
19446                                                   mkexpr(tmp[6])),
19447                                             binop(Iop_8HLto16,
19448                                                   mkexpr(tmp[5]),
19449                                                   mkexpr(tmp[4]))),
19450                                       binop(Iop_16HLto32,
19451                                             binop(Iop_8HLto16,
19452                                                   mkexpr(tmp[3]),
19453                                                   mkexpr(tmp[2])),
19454                                             binop(Iop_8HLto16,
19455                                                   mkexpr(tmp[1]),
19456                                                   mkexpr(tmp[0]))))));
19457                      break;
19458                   }
19459 
19460                case 0x01: { /* SPLAT.H */
19461                      DIP("SPLAT.H w%d, w%d, w%d", wd, ws, wt);
19462                      t1 = newTemp(Ity_V128);
19463                      t2 = newTemp(Ity_I32);
19464                      assign(t1, getWReg(ws));
19465                      assign(t2,
19466                             mkNarrowTo32(ty, getIReg(wt)));
19467                      IRTemp tmp[8];
19468 
19469                      for (i = 0; i < 8; i++) {
19470                         tmp[i] = newTemp(Ity_I16);
19471                         assign(tmp[i],
19472                                binop(Iop_GetElem16x8,
19473                                      mkexpr(t1),
19474                                      unop(Iop_32to8, mkexpr(t2))));
19475                      }
19476 
19477                      putWReg(wd,
19478                              binop(Iop_64HLtoV128,
19479                                    binop(Iop_32HLto64,
19480                                          binop(Iop_16HLto32,
19481                                                mkexpr(tmp[7]),
19482                                                mkexpr(tmp[6])),
19483                                          binop(Iop_16HLto32,
19484                                                mkexpr(tmp[5]),
19485                                                mkexpr(tmp[4]))),
19486                                    binop(Iop_32HLto64,
19487                                          binop(Iop_16HLto32,
19488                                                mkexpr(tmp[3]),
19489                                                mkexpr(tmp[2])),
19490                                          binop(Iop_16HLto32,
19491                                                mkexpr(tmp[1]),
19492                                                mkexpr(tmp[0])))));
19493                      break;
19494                   }
19495 
19496                case 0x02: { /* SPLAT.W */
19497                      DIP("SPLAT.W w%d, w%d, w%d", wd, ws, wt);
19498                      t1 = newTemp(Ity_V128);
19499                      t2 = newTemp(Ity_I32);
19500                      assign(t1, getWReg(ws));
19501                      assign(t2,
19502                             mkNarrowTo32(ty, getIReg(wt)));
19503                      IRTemp tmp[4];
19504 
19505                      for (i = 0; i < 4; i++) {
19506                         tmp[i] = newTemp(Ity_I32);
19507                         assign(tmp[i],
19508                                binop(Iop_GetElem32x4,
19509                                      mkexpr(t1),
19510                                      unop(Iop_32to8, mkexpr(t2))));
19511                      }
19512 
19513                      putWReg(wd,
19514                              binop(Iop_64HLtoV128,
19515                                    binop(Iop_32HLto64,
19516                                          mkexpr(tmp[3]),
19517                                          mkexpr(tmp[2])),
19518                                    binop(Iop_32HLto64,
19519                                          mkexpr(tmp[1]),
19520                                          mkexpr(tmp[0]))));
19521                      break;
19522                   }
19523 
19524                case 0x03: { /* SPLAT.D */
19525                      DIP("SPLAT.D w%d, w%d, w%d", wd, ws, wt);
19526                      t1 = newTemp(Ity_V128);
19527                      t2 = newTemp(Ity_I32);
19528                      assign(t1, getWReg(ws));
19529                      assign(t2,
19530                             mkNarrowTo32(ty, getIReg(wt)));
19531                      IRTemp tmp[2];
19532 
19533                      for (i = 0; i < 2; i++) {
19534                         tmp[i] = newTemp(Ity_I64);
19535                         assign(tmp[i],
19536                                binop(Iop_GetElem64x2,
19537                                      mkexpr(t1),
19538                                      unop(Iop_32to8, mkexpr(t2))));
19539                      }
19540 
19541                      putWReg(wd,
19542                              binop(Iop_64HLtoV128,
19543                                    mkexpr(tmp[1]), mkexpr(tmp[0])));
19544                      break;
19545                   }
19546             }
19547 
19548             break;
19549          }
19550 
19551       case 0x02: { /* PCKEV.df */
19552             switch (df) {
19553                case 0x00: { /* PCKEV.B */
19554                      DIP("PCKEV.B w%d, w%d, w%d", wd, ws, wt);
19555                      t1 = newTemp(Ity_V128);
19556                      t2 = newTemp(Ity_V128);
19557                      t3 = newTemp(Ity_V128);
19558                      assign(t1, getWReg(ws));
19559                      assign(t2, getWReg(wt));
19560                      assign(t3,
19561                             binop(Iop_PackEvenLanes8x16,
19562                                   mkexpr(t1), mkexpr(t2)));
19563                      putWReg(wd, mkexpr(t3));
19564                      break;
19565                   }
19566 
19567                case 0x01: { /* PCKEV.H */
19568                      DIP("PCKEV.H w%d, w%d, w%d", wd, ws, wt);
19569                      t1 = newTemp(Ity_V128);
19570                      t2 = newTemp(Ity_V128);
19571                      t3 = newTemp(Ity_V128);
19572                      assign(t1, getWReg(ws));
19573                      assign(t2, getWReg(wt));
19574                      assign(t3,
19575                             binop(Iop_PackEvenLanes16x8,
19576                                   mkexpr(t1), mkexpr(t2)));
19577                      putWReg(wd, mkexpr(t3));
19578                      break;
19579                   }
19580 
19581                case 0x02: { /* PCKEV.W */
19582                      DIP("PCKEV.W w%d, w%d, w%d", wd, ws, wt);
19583                      t1 = newTemp(Ity_V128);
19584                      t2 = newTemp(Ity_V128);
19585                      t3 = newTemp(Ity_V128);
19586                      assign(t1, getWReg(ws));
19587                      assign(t2, getWReg(wt));
19588                      assign(t3,
19589                             binop(Iop_PackEvenLanes32x4,
19590                                   mkexpr(t1), mkexpr(t2)));
19591                      putWReg(wd, mkexpr(t3));
19592                      break;
19593                   }
19594 
19595                case 0x03: { /* PCKEV.D */
19596                      DIP("PCKEV.D w%d, w%d, w%d", wd, ws, wt);
19597                      t1 = newTemp(Ity_V128);
19598                      t2 = newTemp(Ity_V128);
19599                      t3 = newTemp(Ity_V128);
19600                      assign(t1, getWReg(ws));
19601                      assign(t2, getWReg(wt));
19602                      assign(t3,
19603                             binop(Iop_InterleaveLO64x2,
19604                                   mkexpr(t1), mkexpr(t2)));
19605                      putWReg(wd, mkexpr(t3));
19606                      break;
19607                   }
19608 
19609                default:
19610                   return -1;
19611             }
19612 
19613             break;
19614          }
19615 
19616       case 0x03: { /* PCKOD.df */
19617             switch (df) {
19618                case 0x00: { /* PCKOD.B */
19619                      DIP("PCKOD.B w%d, w%d, w%d", wd, ws, wt);
19620                      t1 = newTemp(Ity_V128);
19621                      t2 = newTemp(Ity_V128);
19622                      t3 = newTemp(Ity_V128);
19623                      assign(t1, getWReg(ws));
19624                      assign(t2, getWReg(wt));
19625                      assign(t3,
19626                             binop(Iop_PackOddLanes8x16,
19627                                   mkexpr(t1), mkexpr(t2)));
19628                      putWReg(wd, mkexpr(t3));
19629                      break;
19630                   }
19631 
19632                case 0x01: { /* PCKOD.H */
19633                      DIP("PCKOD.H w%d, w%d, w%d", wd, ws, wt);
19634                      t1 = newTemp(Ity_V128);
19635                      t2 = newTemp(Ity_V128);
19636                      t3 = newTemp(Ity_V128);
19637                      assign(t1, getWReg(ws));
19638                      assign(t2, getWReg(wt));
19639                      assign(t3,
19640                             binop(Iop_PackOddLanes16x8,
19641                                   mkexpr(t1), mkexpr(t2)));
19642                      putWReg(wd, mkexpr(t3));
19643                      break;
19644                   }
19645 
19646                case 0x02: { /* PCKOD.W */
19647                      DIP("PCKOD.W w%d, w%d, w%d", wd, ws, wt);
19648                      t1 = newTemp(Ity_V128);
19649                      t2 = newTemp(Ity_V128);
19650                      t3 = newTemp(Ity_V128);
19651                      assign(t1, getWReg(ws));
19652                      assign(t2, getWReg(wt));
19653                      assign(t3,
19654                             binop(Iop_PackOddLanes32x4,
19655                                   mkexpr(t1), mkexpr(t2)));
19656                      putWReg(wd, mkexpr(t3));
19657                      break;
19658                   }
19659 
19660                case 0x03: { /* PCKOD.D */
19661                      DIP("PCKOD.D w%d, w%d, w%d", wd, ws, wt);
19662                      t1 = newTemp(Ity_V128);
19663                      t2 = newTemp(Ity_V128);
19664                      t3 = newTemp(Ity_V128);
19665                      assign(t1, getWReg(ws));
19666                      assign(t2, getWReg(wt));
19667                      assign(t3,
19668                             binop(Iop_InterleaveHI64x2,
19669                                   mkexpr(t1), mkexpr(t2)));
19670                      putWReg(wd, mkexpr(t3));
19671                      break;
19672                   }
19673 
19674                default:
19675                   return -1;
19676             }
19677 
19678             break;
19679          }
19680 
19681       case 0x04: { /* ILVL.df */
19682             switch (df) {
19683                case 0x00: { /* ILVL.B */
19684                      DIP("ILVL.B w%d, w%d, w%d", wd, ws, wt);
19685                      t1 = newTemp(Ity_V128);
19686                      t2 = newTemp(Ity_V128);
19687                      t3 = newTemp(Ity_V128);
19688                      assign(t1, getWReg(ws));
19689                      assign(t2, getWReg(wt));
19690                      assign(t3,
19691                             binop(Iop_InterleaveHI8x16,
19692                                   mkexpr(t1), mkexpr(t2)));
19693                      putWReg(wd, mkexpr(t3));
19694                      break;
19695                   }
19696 
19697                case 0x01: { /* ILVL.H */
19698                      DIP("ILVL.H w%d, w%d, w%d", wd, ws, wt);
19699                      t1 = newTemp(Ity_V128);
19700                      t2 = newTemp(Ity_V128);
19701                      t3 = newTemp(Ity_V128);
19702                      assign(t1, getWReg(ws));
19703                      assign(t2, getWReg(wt));
19704                      assign(t3,
19705                             binop(Iop_InterleaveHI16x8,
19706                                   mkexpr(t1), mkexpr(t2)));
19707                      putWReg(wd, mkexpr(t3));
19708                      break;
19709                   }
19710 
19711                case 0x02: { /* ILVL.W */
19712                      DIP("ILVL.W w%d, w%d, w%d", wd, ws, wt);
19713                      t1 = newTemp(Ity_V128);
19714                      t2 = newTemp(Ity_V128);
19715                      t3 = newTemp(Ity_V128);
19716                      assign(t1, getWReg(ws));
19717                      assign(t2, getWReg(wt));
19718                      assign(t3,
19719                             binop(Iop_InterleaveHI32x4,
19720                                   mkexpr(t1), mkexpr(t2)));
19721                      putWReg(wd, mkexpr(t3));
19722                      break;
19723                   }
19724 
19725                case 0x03: { /* ILVL.D */
19726                      DIP("ILVL.D w%d, w%d, w%d", wd, ws, wt);
19727                      t1 = newTemp(Ity_V128);
19728                      t2 = newTemp(Ity_V128);
19729                      t3 = newTemp(Ity_V128);
19730                      assign(t1, getWReg(ws));
19731                      assign(t2, getWReg(wt));
19732                      assign(t3,
19733                             binop(Iop_InterleaveHI64x2,
19734                                   mkexpr(t1), mkexpr(t2)));
19735                      putWReg(wd, mkexpr(t3));
19736                      break;
19737                   }
19738 
19739                default:
19740                   return -1;
19741             }
19742 
19743             break;
19744          }
19745 
19746       case 0x05: { /* ILVR.df */
19747             switch (df) {
19748                case 0x00: { /* ILVL.B */
19749                      DIP("ILVL.B w%d, w%d, w%d", wd, ws, wt);
19750                      t1 = newTemp(Ity_V128);
19751                      t2 = newTemp(Ity_V128);
19752                      t3 = newTemp(Ity_V128);
19753                      assign(t1, getWReg(ws));
19754                      assign(t2, getWReg(wt));
19755                      assign(t3,
19756                             binop(Iop_InterleaveLO8x16,
19757                                   mkexpr(t1), mkexpr(t2)));
19758                      putWReg(wd, mkexpr(t3));
19759                      break;
19760                   }
19761 
19762                case 0x01: { /* ILVL.H */
19763                      DIP("ILVL.H w%d, w%d, w%d", wd, ws, wt);
19764                      t1 = newTemp(Ity_V128);
19765                      t2 = newTemp(Ity_V128);
19766                      t3 = newTemp(Ity_V128);
19767                      assign(t1, getWReg(ws));
19768                      assign(t2, getWReg(wt));
19769                      assign(t3,
19770                             binop(Iop_InterleaveLO16x8,
19771                                   mkexpr(t1), mkexpr(t2)));
19772                      putWReg(wd, mkexpr(t3));
19773                      break;
19774                   }
19775 
19776                case 0x02: { /* ILVL.W */
19777                      DIP("ILVL.W w%d, w%d, w%d", wd, ws, wt);
19778                      t1 = newTemp(Ity_V128);
19779                      t2 = newTemp(Ity_V128);
19780                      t3 = newTemp(Ity_V128);
19781                      assign(t1, getWReg(ws));
19782                      assign(t2, getWReg(wt));
19783                      assign(t3,
19784                             binop(Iop_InterleaveLO32x4,
19785                                   mkexpr(t1), mkexpr(t2)));
19786                      putWReg(wd, mkexpr(t3));
19787                      break;
19788                   }
19789 
19790                case 0x03: { /* ILVL.D */
19791                      DIP("ILVL.D w%d, w%d, w%d", wd, ws, wt);
19792                      t1 = newTemp(Ity_V128);
19793                      t2 = newTemp(Ity_V128);
19794                      t3 = newTemp(Ity_V128);
19795                      assign(t1, getWReg(ws));
19796                      assign(t2, getWReg(wt));
19797                      assign(t3,
19798                             binop(Iop_InterleaveLO64x2,
19799                                   mkexpr(t1), mkexpr(t2)));
19800                      putWReg(wd, mkexpr(t3));
19801                      break;
19802                   }
19803             }
19804 
19805             break;
19806          }
19807 
19808       case 0x06: { /* ILVEV.df */
19809             switch (df) {
19810                case 0x00: { /* ILVEV.B */
19811                      DIP("ILVEV.B w%d, w%d, w%d", wd, ws, wt);
19812                      t1 = newTemp(Ity_V128);
19813                      t2 = newTemp(Ity_V128);
19814                      t3 = newTemp(Ity_V128);
19815                      assign(t1, getWReg(ws));
19816                      assign(t2, getWReg(wt));
19817                      assign(t3,
19818                             binop(Iop_InterleaveEvenLanes8x16,
19819                                   mkexpr(t1), mkexpr(t2)));
19820                      putWReg(wd, mkexpr(t3));
19821                      break;
19822                   }
19823 
19824                case 0x01: { /* ILVEV.H */
19825                      DIP("ILVEV.H w%d, w%d, w%d", wd, ws, wt);
19826                      t1 = newTemp(Ity_V128);
19827                      t2 = newTemp(Ity_V128);
19828                      t3 = newTemp(Ity_V128);
19829                      assign(t1, getWReg(ws));
19830                      assign(t2, getWReg(wt));
19831                      assign(t3,
19832                             binop(Iop_InterleaveEvenLanes16x8,
19833                                   mkexpr(t1), mkexpr(t2)));
19834                      putWReg(wd, mkexpr(t3));
19835                      break;
19836                   }
19837 
19838                case 0x02: { /* ILVEV.W */
19839                      DIP("ILVEV.W w%d, w%d, w%d", wd, ws, wt);
19840                      t1 = newTemp(Ity_V128);
19841                      t2 = newTemp(Ity_V128);
19842                      t3 = newTemp(Ity_V128);
19843                      assign(t1, getWReg(ws));
19844                      assign(t2, getWReg(wt));
19845                      assign(t3,
19846                             binop(Iop_InterleaveEvenLanes32x4,
19847                                   mkexpr(t1), mkexpr(t2)));
19848                      putWReg(wd, mkexpr(t3));
19849                      break;
19850                   }
19851 
19852                case 0x03: { /* ILVEV.D */
19853                      DIP("ILVEV.D w%d, w%d, w%d", wd, ws, wt);
19854                      t1 = newTemp(Ity_V128);
19855                      t2 = newTemp(Ity_V128);
19856                      t3 = newTemp(Ity_V128);
19857                      assign(t1, getWReg(ws));
19858                      assign(t2, getWReg(wt));
19859                      assign(t3,
19860                             binop(Iop_InterleaveLO64x2,
19861                                   mkexpr(t1), mkexpr(t2)));
19862                      putWReg(wd, mkexpr(t3));
19863                      break;
19864                   }
19865 
19866                default:
19867                   return -1;
19868             }
19869 
19870             break;
19871          }
19872 
19873       case 0x07: { /* ILVOD.df */
19874             switch (df) {
19875                case 0x00: { /* ILVOD.B */
19876                      DIP("ILVOD.B w%d, w%d, w%d", wd, ws, wt);
19877                      t1 = newTemp(Ity_V128);
19878                      t2 = newTemp(Ity_V128);
19879                      t3 = newTemp(Ity_V128);
19880                      assign(t1, getWReg(ws));
19881                      assign(t2, getWReg(wt));
19882                      assign(t3,
19883                             binop(Iop_InterleaveOddLanes8x16,
19884                                   mkexpr(t1), mkexpr(t2)));
19885                      putWReg(wd, mkexpr(t3));
19886                      break;
19887                   }
19888 
19889                case 0x01: { /* ILVOD.H */
19890                      DIP("ILVOD.H w%d, w%d, w%d", wd, ws, wt);
19891                      t1 = newTemp(Ity_V128);
19892                      t2 = newTemp(Ity_V128);
19893                      t3 = newTemp(Ity_V128);
19894                      assign(t1, getWReg(ws));
19895                      assign(t2, getWReg(wt));
19896                      assign(t3,
19897                             binop(Iop_InterleaveOddLanes16x8,
19898                                   mkexpr(t1), mkexpr(t2)));
19899                      putWReg(wd, mkexpr(t3));
19900                      break;
19901                   }
19902 
19903                case 0x02: { /* ILVOD.W */
19904                      DIP("ILVOD.W w%d, w%d, w%d", wd, ws, wt);
19905                      t1 = newTemp(Ity_V128);
19906                      t2 = newTemp(Ity_V128);
19907                      t3 = newTemp(Ity_V128);
19908                      assign(t1, getWReg(ws));
19909                      assign(t2, getWReg(wt));
19910                      assign(t3,
19911                             binop(Iop_InterleaveOddLanes32x4,
19912                                   mkexpr(t1), mkexpr(t2)));
19913                      putWReg(wd, mkexpr(t3));
19914                      break;
19915                   }
19916 
19917                case 0x03: { /* ILVOD.D */
19918                      DIP("ILVOD.D w%d, w%d, w%d", wd, ws, wt);
19919                      t1 = newTemp(Ity_V128);
19920                      t2 = newTemp(Ity_V128);
19921                      t3 = newTemp(Ity_V128);
19922                      assign(t1, getWReg(ws));
19923                      assign(t2, getWReg(wt));
19924                      assign(t3,
19925                             binop(Iop_InterleaveHI64x2,
19926                                   mkexpr(t1), mkexpr(t2)));
19927                      putWReg(wd, mkexpr(t3));
19928                      break;
19929                   }
19930 
19931                default:
19932                   return -1;
19933             }
19934 
19935             break;
19936          }
19937 
19938       default:
19939          return -1;
19940    }
19941 
19942    return 0;
19943 }
19944 
msa_3R_15(UInt cins,UChar wd,UChar ws)19945 static Int msa_3R_15(UInt cins, UChar wd, UChar ws) { /* 3R (0x15) */
19946    IRTemp t1, t2, t3, t4;
19947    UShort operation;
19948    UChar df, wt;
19949 
19950    operation = (cins & 0x03800000) >> 23;
19951    df = (cins & 0x00600000) >> 21;
19952    wt = (cins & 0x001F0000) >> 16;
19953 
19954    switch (operation) {
19955       case 0x00: { /* VSHF.df */
19956             t1 = newTemp(Ity_V128);
19957             t2 = newTemp(Ity_V128);
19958             t3 = newTemp(Ity_V128);
19959             assign(t1, getWReg(wd));
19960             assign(t2, getWReg(ws));
19961             assign(t3, getWReg(wt));
19962 
19963             switch (df) {
19964                case 0x00: { /* VSHF.B */
19965                      DIP("VSHF.B w%d, w%d, w%d", wd, ws, wt);
19966                      IRTemp tmp[16];
19967                      Int i;
19968 
19969                      for (i = 0; i < 16; i++) {
19970                         tmp[i] = newTemp(Ity_I8);
19971                         assign(tmp[i],
19972                                IRExpr_ITE(
19973                                   binop(Iop_CmpEQ8,
19974                                         binop(Iop_And8,
19975                                               binop(Iop_GetElem8x16,
19976                                                     mkexpr(t1),
19977                                                     mkU8(i)),
19978                                               mkU8(0xC0)),
19979                                         mkU8(0x0)),
19980                                   IRExpr_ITE(
19981                                      binop(Iop_CmpEQ8,
19982                                            binop(Iop_And8,
19983                                                  binop(Iop_GetElem8x16,
19984                                                        mkexpr(t1),
19985                                                        mkU8(i)),
19986                                                  mkU8(0x10)),
19987                                            mkU8(0x0)),
19988                                      binop(Iop_GetElem8x16,
19989                                            mkexpr(t3),
19990                                            binop(Iop_GetElem8x16,
19991                                                  mkexpr(t1),
19992                                                  mkU8(i))),
19993                                      binop(Iop_GetElem8x16,
19994                                            mkexpr(t2),
19995                                            binop(Iop_GetElem8x16,
19996                                                  mkexpr(t1),
19997                                                  mkU8(i)))),
19998                                   mkU8(0x0)));
19999                      }
20000 
20001                      putWReg(wd,
20002                           binop(Iop_64HLtoV128,
20003                                 binop(Iop_32HLto64,
20004                                       binop(Iop_16HLto32,
20005                                             binop(Iop_8HLto16,
20006                                                   mkexpr(tmp[15]),
20007                                                   mkexpr(tmp[14])),
20008                                             binop(Iop_8HLto16,
20009                                                   mkexpr(tmp[13]),
20010                                                   mkexpr(tmp[12]))),
20011                                       binop(Iop_16HLto32,
20012                                             binop(Iop_8HLto16,
20013                                                   mkexpr(tmp[11]),
20014                                                   mkexpr(tmp[10])),
20015                                             binop(Iop_8HLto16,
20016                                                   mkexpr(tmp[9]),
20017                                                   mkexpr(tmp[8])))),
20018                                 binop(Iop_32HLto64,
20019                                       binop(Iop_16HLto32,
20020                                             binop(Iop_8HLto16,
20021                                                   mkexpr(tmp[7]),
20022                                                   mkexpr(tmp[6])),
20023                                             binop(Iop_8HLto16,
20024                                                   mkexpr(tmp[5]),
20025                                                   mkexpr(tmp[4]))),
20026                                       binop(Iop_16HLto32,
20027                                             binop(Iop_8HLto16,
20028                                                   mkexpr(tmp[3]),
20029                                                   mkexpr(tmp[2])),
20030                                             binop(Iop_8HLto16,
20031                                                   mkexpr(tmp[1]),
20032                                                   mkexpr(tmp[0]))))));
20033                      break;
20034                   }
20035 
20036                case 0x01: { /* VSHF.H */
20037                      DIP("VSHF.H w%d, w%d, w%d", wd, ws, wt);
20038                      IRTemp tmp[8];
20039                      Int i;
20040 
20041                      for (i = 0; i < 8; i++) {
20042                         tmp[i] = newTemp(Ity_I16);
20043                         assign(tmp[i],
20044                                IRExpr_ITE(
20045                                   binop(Iop_CmpEQ16,
20046                                         binop(Iop_And16,
20047                                               binop(Iop_GetElem16x8,
20048                                                     mkexpr(t1),
20049                                                     mkU8(i)),
20050                                               mkU16(0xC0)),
20051                                         mkU16(0x0)),
20052                                   IRExpr_ITE(
20053                                      binop(Iop_CmpEQ16,
20054                                            binop(Iop_And16,
20055                                                  binop(Iop_GetElem16x8,
20056                                                        mkexpr(t1),
20057                                                        mkU8(i)),
20058                                                  mkU16(0x08)),
20059                                            mkU16(0x0)),
20060                                      binop(Iop_GetElem16x8,
20061                                            mkexpr(t3),
20062                                            unop(Iop_16to8,
20063                                                 binop(Iop_GetElem16x8,
20064                                                       mkexpr(t1),
20065                                                       mkU8(i)))),
20066                                      binop(Iop_GetElem16x8,
20067                                            mkexpr(t2),
20068                                            unop(Iop_16to8,
20069                                                 binop(Iop_GetElem16x8,
20070                                                       mkexpr(t1),
20071                                                       mkU8(i))))),
20072                                   mkU16(0x0)));
20073                      }
20074 
20075                      putWReg(wd,
20076                              binop(Iop_64HLtoV128,
20077                                    binop(Iop_32HLto64,
20078                                          binop(Iop_16HLto32,
20079                                                mkexpr(tmp[7]),
20080                                                mkexpr(tmp[6])),
20081                                          binop(Iop_16HLto32,
20082                                                mkexpr(tmp[5]),
20083                                                mkexpr(tmp[4]))),
20084                                    binop(Iop_32HLto64,
20085                                          binop(Iop_16HLto32,
20086                                                mkexpr(tmp[3]),
20087                                                mkexpr(tmp[2])),
20088                                          binop(Iop_16HLto32,
20089                                                mkexpr(tmp[1]),
20090                                                mkexpr(tmp[0])))));
20091                      break;
20092                   }
20093 
20094                case 0x02: { /* VSHF.W */
20095                      DIP("VSHF.W w%d, w%d, w%d", wd, ws, wt);
20096                      IRTemp tmp[4];
20097                      Int i;
20098 
20099                      for (i = 0; i < 4; i++) {
20100                         tmp[i] = newTemp(Ity_I32);
20101                         assign(tmp[i],
20102                                IRExpr_ITE(
20103                                   binop(Iop_CmpEQ32,
20104                                         binop(Iop_And32,
20105                                               binop(Iop_GetElem32x4,
20106                                                     mkexpr(t1),
20107                                                     mkU8(i)),
20108                                               mkU32(0xC0)),
20109                                         mkU32(0x0)),
20110                                   IRExpr_ITE(
20111                                      binop(Iop_CmpEQ32,
20112                                            binop(Iop_And32,
20113                                                  binop(Iop_GetElem32x4,
20114                                                        mkexpr(t1),
20115                                                        mkU8(i)),
20116                                                  mkU32(0x04)),
20117                                            mkU32(0x0)),
20118                                      binop(Iop_GetElem32x4,
20119                                            mkexpr(t3),
20120                                            unop(Iop_32to8,
20121                                                 binop(Iop_GetElem32x4,
20122                                                       mkexpr(t1),
20123                                                       mkU8(i)))),
20124                                      binop(Iop_GetElem32x4,
20125                                            mkexpr(t2),
20126                                            unop(Iop_32to8,
20127                                                 binop(Iop_GetElem32x4,
20128                                                       mkexpr(t1),
20129                                                       mkU8(i))))),
20130                                   mkU32(0x0)));
20131                      }
20132 
20133                      putWReg(wd,
20134                              binop(Iop_64HLtoV128,
20135                                    binop(Iop_32HLto64,
20136                                          mkexpr(tmp[3]),
20137                                          mkexpr(tmp[2])),
20138                                    binop(Iop_32HLto64,
20139                                          mkexpr(tmp[1]),
20140                                          mkexpr(tmp[0]))));
20141                      break;
20142                   }
20143 
20144                case 0x03: { /* VSHF.D */
20145                      DIP("VSHF.D w%d, w%d, w%d", wd, ws, wt);
20146                      IRTemp tmp[2];
20147                      Int i;
20148 
20149                      for (i = 0; i < 2; i++) {
20150                         tmp[i] = newTemp(Ity_I64);
20151                         assign(tmp[i],
20152                                IRExpr_ITE(
20153                                   binop(Iop_CmpEQ64,
20154                                         binop(Iop_And64,
20155                                               binop(Iop_GetElem64x2,
20156                                                     mkexpr(t1),
20157                                                     mkU8(i)),
20158                                               mkU64(0xC0)),
20159                                         mkU64(0x0)),
20160                                   IRExpr_ITE(
20161                                      binop(Iop_CmpEQ64,
20162                                            binop(Iop_And64,
20163                                                  binop(Iop_GetElem64x2,
20164                                                        mkexpr(t1),
20165                                                        mkU8(i)),
20166                                                  mkU64(0x02)),
20167                                            mkU64(0x0)),
20168                                      binop(Iop_GetElem64x2,
20169                                            mkexpr(t3),
20170                                            unop(Iop_64to8,
20171                                                 binop(Iop_GetElem64x2,
20172                                                       mkexpr(t1),
20173                                                       mkU8(i)))),
20174                                      binop(Iop_GetElem64x2,
20175                                            mkexpr(t2),
20176                                            unop(Iop_64to8,
20177                                                 binop(Iop_GetElem64x2,
20178                                                       mkexpr(t1),
20179                                                       mkU8(i))))),
20180                                   mkU64(0x0)));
20181                      }
20182 
20183                      putWReg(wd,
20184                              binop(Iop_64HLtoV128,
20185                                    mkexpr(tmp[1]), mkexpr(tmp[0])));
20186                      break;
20187                   }
20188 
20189                default:
20190                   return -1;
20191             }
20192 
20193             break;
20194          }
20195 
20196       case 0x01: { /* SRAR.df */
20197             switch (df) {
20198                case 0x00: { /* SRAR.B */
20199                      DIP("SRAR.B w%d, w%d, w%d", wd, ws, wt);
20200                      t1 = newTemp(Ity_V128);
20201                      t2 = newTemp(Ity_V128);
20202                      t3 = newTemp(Ity_V128);
20203                      t4 = newTemp(Ity_V128);
20204                      assign(t1,
20205                             binop(Iop_Sar8x16,
20206                                   getWReg(ws),
20207                                   getWReg(wt)));
20208                      assign(t2,
20209                             binop(Iop_Sub8x16,
20210                                   binop(Iop_64HLtoV128,
20211                                         mkU64(0x808080808080808ull),
20212                                         mkU64(0x808080808080808ull)),
20213                                   getWReg(wt)));
20214                      assign(t4,
20215                             unop(Iop_NotV128,
20216                                  binop(Iop_CmpEQ8x16,
20217                                        binop(Iop_ShlN8x16,
20218                                              getWReg(wt),
20219                                              mkU8(5)),
20220                                        binop(Iop_64HLtoV128,
20221                                              mkU64(0), mkU64(0)))));
20222                      assign(t3,
20223                             binop(Iop_ShrN8x16,
20224                                   binop(Iop_AndV128,
20225                                         binop(Iop_Shl8x16,
20226                                               getWReg(ws),
20227                                               mkexpr(t2)),
20228                                         mkexpr(t4)),
20229                                   mkU8(7)));
20230                      putWReg(wd,
20231                              binop(Iop_Add8x16,
20232                                    mkexpr(t1), mkexpr(t3)));
20233                      break;
20234                   }
20235 
20236                case 0x01: { /* SRAR.H */
20237                      DIP("SRAR.H w%d, w%d, w%d", wd, ws, wt);
20238                      t1 = newTemp(Ity_V128);
20239                      t2 = newTemp(Ity_V128);
20240                      t3 = newTemp(Ity_V128);
20241                      t4 = newTemp(Ity_V128);
20242                      assign(t1,
20243                             binop(Iop_Sar16x8,
20244                                   getWReg(ws),
20245                                   getWReg(wt)));
20246                      assign(t2,
20247                             binop(Iop_Sub16x8,
20248                                   binop(Iop_64HLtoV128,
20249                                         mkU64(0x10001000100010ul),
20250                                         mkU64(0x10001000100010ul)),
20251                                   getWReg(wt)));
20252                      assign(t4,
20253                             unop(Iop_NotV128,
20254                                  binop(Iop_CmpEQ16x8,
20255                                        binop(Iop_ShlN16x8,
20256                                              getWReg(wt),
20257                                              mkU8(12)),
20258                                        binop(Iop_64HLtoV128,
20259                                              mkU64(0), mkU64(0)))));
20260                      assign(t3,
20261                             binop(Iop_ShrN16x8,
20262                                   binop(Iop_AndV128,
20263                                         binop(Iop_Shl16x8,
20264                                               getWReg(ws),
20265                                               mkexpr(t2)),
20266                                         mkexpr(t4)),
20267                                   mkU8(15)));
20268                      putWReg(wd,
20269                              binop(Iop_Add16x8,
20270                                    mkexpr(t1), mkexpr(t3)));
20271                      break;
20272                   }
20273 
20274                case 0x02: { /* SRAR.W */
20275                      DIP("SRAR.W w%d, w%d, w%d", wd, ws, wt);
20276                      t1 = newTemp(Ity_V128); // shifted
20277                      t2 = newTemp(Ity_V128); // 32 - wt
20278                      t3 = newTemp(Ity_V128); // rv
20279                      t4 = newTemp(Ity_V128); // wt % 32 == 0
20280                      assign(t1,
20281                             binop(Iop_Sar32x4,
20282                                   getWReg(ws),
20283                                   getWReg(wt)));
20284                      assign(t2,
20285                             binop(Iop_Sub32x4,
20286                                   binop(Iop_64HLtoV128,
20287                                         mkU64(0x2000000020ul),
20288                                         mkU64(0x2000000020ul)),
20289                                   getWReg(wt)));
20290                      assign(t4,
20291                             unop(Iop_NotV128,
20292                                  binop(Iop_CmpEQ32x4,
20293                                        binop(Iop_ShlN32x4,
20294                                              getWReg(wt),
20295                                              mkU8(27)),
20296                                        binop(Iop_64HLtoV128,
20297                                              mkU64(0), mkU64(0)))));
20298                      assign(t3,
20299                             binop(Iop_ShrN32x4,
20300                                   binop(Iop_AndV128,
20301                                         binop(Iop_Shl32x4,
20302                                               getWReg(ws),
20303                                               mkexpr(t2)),
20304                                         mkexpr(t4)),
20305                                   mkU8(31)));
20306                      putWReg(wd,
20307                              binop(Iop_Add32x4,
20308                                    mkexpr(t1), mkexpr(t3)));
20309                      break;
20310                   }
20311 
20312                case 0x03: { /* SRAR.D */
20313                      DIP("SRAR.D w%d, w%d, w%d", wd, ws, wt);
20314                      t1 = newTemp(Ity_V128);
20315                      t2 = newTemp(Ity_V128);
20316                      t3 = newTemp(Ity_V128);
20317                      t4 = newTemp(Ity_V128);
20318                      assign(t1,
20319                             binop(Iop_Sar64x2,
20320                                   getWReg(ws),
20321                                   getWReg(wt)));
20322                      assign(t2,
20323                             binop(Iop_Sub64x2,
20324                                   binop(Iop_64HLtoV128,
20325                                         mkU64(64ul), mkU64(64ul)),
20326                                   getWReg(wt)));
20327                      assign(t4,
20328                             unop(Iop_NotV128,
20329                                  binop(Iop_CmpEQ64x2,
20330                                        binop(Iop_ShlN64x2,
20331                                              getWReg(wt),
20332                                              mkU8(58)),
20333                                        binop(Iop_64HLtoV128,
20334                                              mkU64(0), mkU64(0)))));
20335                      assign(t3,
20336                             binop(Iop_ShrN64x2,
20337                                   binop(Iop_AndV128,
20338                                         binop(Iop_Shl64x2,
20339                                               getWReg(ws),
20340                                               mkexpr(t2)),
20341                                         mkexpr(t4)),
20342                                   mkU8(63)));
20343                      putWReg(wd,
20344                              binop(Iop_Add64x2,
20345                                    mkexpr(t1), mkexpr(t3)));
20346                      break;
20347                   }
20348 
20349                default:
20350                   return -1;
20351             }
20352 
20353             break;
20354          }
20355 
20356       case 0x02: { /* SRLR.df */
20357             switch (df) {
20358                case 0x00: { /* SRLR.B */
20359                      DIP("SRLR.B w%d, w%d, w%d", wd, ws, wt);
20360                      t1 = newTemp(Ity_V128);
20361                      t2 = newTemp(Ity_V128);
20362                      t3 = newTemp(Ity_V128);
20363                      t4 = newTemp(Ity_V128);
20364                      assign(t1,
20365                             binop(Iop_Shr8x16,
20366                                   getWReg(ws),
20367                                   getWReg(wt)));
20368                      assign(t2,
20369                             binop(Iop_Sub8x16,
20370                                   binop(Iop_64HLtoV128,
20371                                         mkU64(0x808080808080808ull),
20372                                         mkU64(0x808080808080808ull)),
20373                                   getWReg(wt)));
20374                      assign(t4,
20375                             unop(Iop_NotV128,
20376                                  binop(Iop_CmpEQ8x16,
20377                                        binop(Iop_ShlN8x16,
20378                                              getWReg(wt),
20379                                              mkU8(5)),
20380                                        binop(Iop_64HLtoV128,
20381                                              mkU64(0), mkU64(0)))));
20382                      assign(t3,
20383                             binop(Iop_ShrN8x16,
20384                                   binop(Iop_AndV128,
20385                                         binop(Iop_Shl8x16,
20386                                               getWReg(ws),
20387                                               mkexpr(t2)),
20388                                         mkexpr(t4)),
20389                                   mkU8(7)));
20390                      putWReg(wd,
20391                              binop(Iop_Add8x16,
20392                                    mkexpr(t1), mkexpr(t3)));
20393                      break;
20394                   }
20395 
20396                case 0x01: { /* SRLR.H */
20397                      DIP("SRLR.H w%d, w%d, w%d", wd, ws, wt);
20398                      t1 = newTemp(Ity_V128);
20399                      t2 = newTemp(Ity_V128);
20400                      t3 = newTemp(Ity_V128);
20401                      t4 = newTemp(Ity_V128);
20402                      assign(t1,
20403                             binop(Iop_Shr16x8,
20404                                   getWReg(ws),
20405                                   getWReg(wt)));
20406                      assign(t2,
20407                             binop(Iop_Sub16x8,
20408                                   binop(Iop_64HLtoV128,
20409                                         mkU64(0x10001000100010ul),
20410                                         mkU64(0x10001000100010ul)),
20411                                   getWReg(wt)));
20412                      assign(t4,
20413                             unop(Iop_NotV128,
20414                                  binop(Iop_CmpEQ16x8,
20415                                        binop(Iop_ShlN16x8,
20416                                              getWReg(wt),
20417                                              mkU8(12)),
20418                                        binop(Iop_64HLtoV128,
20419                                              mkU64(0), mkU64(0)))));
20420                      assign(t3,
20421                             binop(Iop_ShrN16x8,
20422                                   binop(Iop_AndV128,
20423                                         binop(Iop_Shl16x8,
20424                                               getWReg(ws),
20425                                               mkexpr(t2)),
20426                                         mkexpr(t4)),
20427                                   mkU8(15)));
20428                      putWReg(wd,
20429                              binop(Iop_Add16x8,
20430                                    mkexpr(t1), mkexpr(t3)));
20431                      break;
20432                   }
20433 
20434                case 0x02: { /* SRLR.W */
20435                      DIP("SRLR.W w%d, w%d, w%d", wd, ws, wt);
20436                      t1 = newTemp(Ity_V128);
20437                      t2 = newTemp(Ity_V128);
20438                      t3 = newTemp(Ity_V128);
20439                      t4 = newTemp(Ity_V128);
20440                      assign(t1,
20441                             binop(Iop_Shr32x4,
20442                                   getWReg(ws),
20443                                   getWReg(wt)));
20444                      assign(t2,
20445                             binop(Iop_Sub32x4,
20446                                   binop(Iop_64HLtoV128,
20447                                         mkU64(0x2000000020ul),
20448                                         mkU64(0x2000000020ul)),
20449                                   getWReg(wt)));
20450                      assign(t4,
20451                             unop(Iop_NotV128,
20452                                  binop(Iop_CmpEQ32x4,
20453                                        binop(Iop_ShlN32x4,
20454                                              getWReg(wt),
20455                                              mkU8(27)),
20456                                        binop(Iop_64HLtoV128,
20457                                              mkU64(0), mkU64(0)))));
20458                      assign(t3,
20459                             binop(Iop_ShrN32x4,
20460                                   binop(Iop_AndV128,
20461                                         binop(Iop_Shl32x4,
20462                                               getWReg(ws),
20463                                               mkexpr(t2)),
20464                                         mkexpr(t4)),
20465                                   mkU8(31)));
20466                      putWReg(wd,
20467                              binop(Iop_Add32x4,
20468                                    mkexpr(t1), mkexpr(t3)));
20469                      break;
20470                   }
20471 
20472                case 0x03: { /* SRLR.D */
20473                      DIP("SRLR.D w%d, w%d, w%d", wd, ws, wt);
20474                      t1 = newTemp(Ity_V128);
20475                      t2 = newTemp(Ity_V128);
20476                      t3 = newTemp(Ity_V128);
20477                      t4 = newTemp(Ity_V128);
20478                      assign(t1,
20479                             binop(Iop_Shr64x2,
20480                                   getWReg(ws),
20481                                   getWReg(wt)));
20482                      assign(t2,
20483                             binop(Iop_Sub64x2,
20484                                   binop(Iop_64HLtoV128,
20485                                         mkU64(64ul), mkU64(64ul)),
20486                                   getWReg(wt)));
20487                      assign(t4,
20488                             unop(Iop_NotV128,
20489                                  binop(Iop_CmpEQ64x2,
20490                                        binop(Iop_ShlN64x2,
20491                                              getWReg(wt),
20492                                              mkU8(58)),
20493                                        binop(Iop_64HLtoV128,
20494                                              mkU64(0), mkU64(0)))));
20495                      assign(t3,
20496                             binop(Iop_ShrN64x2,
20497                                   binop(Iop_AndV128,
20498                                         binop(Iop_Shl64x2,
20499                                               getWReg(ws),
20500                                               mkexpr(t2)),
20501                                         mkexpr(t4)),
20502                                   mkU8(63)));
20503                      putWReg(wd,
20504                              binop(Iop_Add64x2,
20505                                    mkexpr(t1), mkexpr(t3)));
20506                      break;
20507                   }
20508 
20509                default:
20510                   return -1;
20511             }
20512 
20513             break;
20514          }
20515 
20516       case 0x04: { /* HADD_S.df */
20517             switch (df) {
20518                case 0x01: { /* HADD_S.H */
20519                      DIP("HADD_S.H w%d, w%d, w%d", wd, ws, wt);
20520                      t1 = newTemp(Ity_V128);
20521                      t2 = newTemp(Ity_V128);
20522                      t3 = newTemp(Ity_V128);
20523                      assign(t1, getWReg(ws));
20524                      assign(t2, getWReg(wt));
20525                      assign(t3,
20526                             binop(Iop_Add16x8,
20527                                   binop(Iop_SarN16x8,
20528                                         mkexpr(t1), mkU8(8)),
20529                                   binop(Iop_SarN16x8,
20530                                         binop(Iop_ShlN16x8,
20531                                               mkexpr(t2), mkU8(8)),
20532                                         mkU8(8))));
20533                      putWReg(wd, mkexpr(t3));
20534                      break;
20535                   }
20536 
20537                case 0x02: { /* HADD_S.W */
20538                      DIP("HADD_S.W w%d, w%d, w%d", wd, ws, wt);
20539                      t1 = newTemp(Ity_V128);
20540                      t2 = newTemp(Ity_V128);
20541                      t3 = newTemp(Ity_V128);
20542                      assign(t1, getWReg(ws));
20543                      assign(t2, getWReg(wt));
20544                      assign(t3,
20545                             binop(Iop_Add32x4,
20546                                   binop(Iop_SarN32x4,
20547                                         mkexpr(t1), mkU8(16)),
20548                                   binop(Iop_SarN32x4,
20549                                         binop(Iop_ShlN32x4,
20550                                               mkexpr(t2), mkU8(16)),
20551                                         mkU8(16))));
20552                      putWReg(wd, mkexpr(t3));
20553                      break;
20554                   }
20555 
20556                case 0x03: { /* HADD_S.D */
20557                      DIP("HADD_S.D w%d, w%d, w%d", wd, ws, wt);
20558                      t1 = newTemp(Ity_V128);
20559                      t2 = newTemp(Ity_V128);
20560                      t3 = newTemp(Ity_V128);
20561                      assign(t1, getWReg(ws));
20562                      assign(t2, getWReg(wt));
20563                      assign(t3,
20564                             binop(Iop_Add64x2,
20565                                   binop(Iop_SarN64x2,
20566                                         mkexpr(t1), mkU8(32)),
20567                                   binop(Iop_SarN64x2,
20568                                         binop(Iop_ShlN64x2,
20569                                               mkexpr(t2), mkU8(32)),
20570                                         mkU8(32))));
20571                      putWReg(wd, mkexpr(t3));
20572                      break;
20573                   }
20574 
20575                default:
20576                   return -1;
20577             }
20578 
20579             break;
20580          }
20581 
20582       case 0x05: { /* HADD_U.df */
20583             switch (df) {
20584                case 0x01: { /* HADD_U.H */
20585                      DIP("HADD_U.H w%d, w%d, w%d", wd, ws, wt);
20586                      t1 = newTemp(Ity_V128);
20587                      t2 = newTemp(Ity_V128);
20588                      t3 = newTemp(Ity_V128);
20589                      assign(t1, getWReg(ws));
20590                      assign(t2, getWReg(wt));
20591                      assign(t3,
20592                             binop(Iop_Add16x8,
20593                                   binop(Iop_ShrN16x8,
20594                                         mkexpr(t1), mkU8(8)),
20595                                   binop(Iop_ShrN16x8,
20596                                         binop(Iop_ShlN16x8,
20597                                               mkexpr(t2), mkU8(8)),
20598                                         mkU8(8))));
20599                      putWReg(wd, mkexpr(t3));
20600                      break;
20601                   }
20602 
20603                case 0x02: { /* HADD_U.W */
20604                      DIP("HADD_U.W w%d, w%d, w%d", wd, ws, wt);
20605                      t1 = newTemp(Ity_V128);
20606                      t2 = newTemp(Ity_V128);
20607                      t3 = newTemp(Ity_V128);
20608                      assign(t1, getWReg(ws));
20609                      assign(t2, getWReg(wt));
20610                      assign(t3,
20611                             binop(Iop_Add32x4,
20612                                   binop(Iop_ShrN32x4,
20613                                         mkexpr(t1), mkU8(16)),
20614                                   binop(Iop_ShrN32x4,
20615                                         binop(Iop_ShlN32x4,
20616                                               mkexpr(t2), mkU8(16)),
20617                                         mkU8(16))));
20618                      putWReg(wd, mkexpr(t3));
20619                      break;
20620                   }
20621 
20622                case 0x03: { /* HADD_U.D */
20623                      DIP("HADD_U.D w%d, w%d, w%d", wd, ws, wt);
20624                      t1 = newTemp(Ity_V128);
20625                      t2 = newTemp(Ity_V128);
20626                      t3 = newTemp(Ity_V128);
20627                      assign(t1, getWReg(ws));
20628                      assign(t2, getWReg(wt));
20629                      assign(t3,
20630                             binop(Iop_Add64x2,
20631                                   binop(Iop_ShrN64x2,
20632                                         mkexpr(t1), mkU8(32)),
20633                                   binop(Iop_ShrN64x2,
20634                                         binop(Iop_ShlN64x2,
20635                                               mkexpr(t2), mkU8(32)),
20636                                         mkU8(32))));
20637                      putWReg(wd, mkexpr(t3));
20638                      break;
20639                   }
20640 
20641                default:
20642                   return -1;
20643             }
20644 
20645             break;
20646          }
20647 
20648       case 0x06: { /* HSUB_S.df */
20649             switch (df) {
20650                case 0x01: { /* HSUB_S.H */
20651                      DIP("HSUB_S.H w%d, w%d, w%d", wd, ws, wt);
20652                      t1 = newTemp(Ity_V128);
20653                      t2 = newTemp(Ity_V128);
20654                      t3 = newTemp(Ity_V128);
20655                      assign(t1, getWReg(ws));
20656                      assign(t2, getWReg(wt));
20657                      assign(t3,
20658                             binop(Iop_Sub16x8,
20659                                   binop(Iop_SarN16x8,
20660                                         mkexpr(t1), mkU8(8)),
20661                                   binop(Iop_SarN16x8,
20662                                         binop(Iop_ShlN16x8,
20663                                               mkexpr(t2), mkU8(8)),
20664                                         mkU8(8))));
20665                      putWReg(wd, mkexpr(t3));
20666                      break;
20667                   }
20668 
20669                case 0x02: { /* HSUB_S.W */
20670                      DIP("HSUB_S.W w%d, w%d, w%d", wd, ws, wt);
20671                      t1 = newTemp(Ity_V128);
20672                      t2 = newTemp(Ity_V128);
20673                      t3 = newTemp(Ity_V128);
20674                      assign(t1, getWReg(ws));
20675                      assign(t2, getWReg(wt));
20676                      assign(t3,
20677                             binop(Iop_Sub32x4,
20678                                   binop(Iop_SarN32x4,
20679                                         mkexpr(t1), mkU8(16)),
20680                                   binop(Iop_SarN32x4,
20681                                         binop(Iop_ShlN32x4,
20682                                               mkexpr(t2), mkU8(16)),
20683                                         mkU8(16))));
20684                      putWReg(wd, mkexpr(t3));
20685                      break;
20686                   }
20687 
20688                case 0x03: { /* HSUB_S.D */
20689                      DIP("HSUB_S.D w%d, w%d, w%d", wd, ws, wt);
20690                      t1 = newTemp(Ity_V128);
20691                      t2 = newTemp(Ity_V128);
20692                      t3 = newTemp(Ity_V128);
20693                      assign(t1, getWReg(ws));
20694                      assign(t2, getWReg(wt));
20695                      assign(t3,
20696                             binop(Iop_Sub64x2,
20697                                   binop(Iop_SarN64x2,
20698                                         mkexpr(t1), mkU8(32)),
20699                                   binop(Iop_SarN64x2,
20700                                         binop(Iop_ShlN64x2,
20701                                               mkexpr(t2), mkU8(32)),
20702                                         mkU8(32))));
20703                      putWReg(wd, mkexpr(t3));
20704                      break;
20705                   }
20706 
20707                default:
20708                   return -1;
20709             }
20710 
20711             break;
20712          }
20713 
20714       case 0x07: { /* HSUB_U.df */
20715             switch (df) {
20716                case 0x01: { /* HSUB_U.H */
20717                      DIP("HSUB_U.H w%d, w%d, w%d", wd, ws, wt);
20718                      t1 = newTemp(Ity_V128);
20719                      t2 = newTemp(Ity_V128);
20720                      t3 = newTemp(Ity_V128);
20721                      assign(t1, getWReg(ws));
20722                      assign(t2, getWReg(wt));
20723                      assign(t3,
20724                             binop(Iop_Sub16x8,
20725                                   binop(Iop_ShrN16x8,
20726                                         mkexpr(t1), mkU8(8)),
20727                                   binop(Iop_ShrN16x8,
20728                                         binop(Iop_ShlN16x8,
20729                                               mkexpr(t2), mkU8(8)),
20730                                         mkU8(8))));
20731                      putWReg(wd, mkexpr(t3));
20732                      break;
20733                   }
20734 
20735                case 0x02: { /* HSUB_U.W */
20736                      DIP("HSUB_U.W w%d, w%d, w%d", wd, ws, wt);
20737                      t1 = newTemp(Ity_V128);
20738                      t2 = newTemp(Ity_V128);
20739                      t3 = newTemp(Ity_V128);
20740                      assign(t1, getWReg(ws));
20741                      assign(t2, getWReg(wt));
20742                      assign(t3,
20743                             binop(Iop_Sub32x4,
20744                                   binop(Iop_ShrN32x4,
20745                                         mkexpr(t1), mkU8(16)),
20746                                   binop(Iop_ShrN32x4,
20747                                         binop(Iop_ShlN32x4,
20748                                               mkexpr(t2), mkU8(16)),
20749                                         mkU8(16))));
20750                      putWReg(wd, mkexpr(t3));
20751                      break;
20752                   }
20753 
20754                case 0x03: { /* HSUB_U.D */
20755                      DIP("HSUB_U.D w%d, w%d, w%d", wd, ws, wt);
20756                      t1 = newTemp(Ity_V128);
20757                      t2 = newTemp(Ity_V128);
20758                      t3 = newTemp(Ity_V128);
20759                      assign(t1, getWReg(ws));
20760                      assign(t2, getWReg(wt));
20761                      assign(t3,
20762                             binop(Iop_Sub64x2,
20763                                   binop(Iop_ShrN64x2,
20764                                         mkexpr(t1), mkU8(32)),
20765                                   binop(Iop_ShrN64x2,
20766                                         binop(Iop_ShlN64x2,
20767                                               mkexpr(t2), mkU8(32)),
20768                                         mkU8(32))));
20769                      putWReg(wd, mkexpr(t3));
20770                      break;
20771                   }
20772 
20773                default:
20774                   return -1;
20775             }
20776 
20777             break;
20778          }
20779 
20780       default:
20781          return -1;
20782    }
20783 
20784    return 0;
20785 }
20786 
msa_3R_1A(UInt cins,UChar wd,UChar ws)20787 static Int msa_3R_1A(UInt cins, UChar wd, UChar ws) { /* 3R (0x1A) */
20788    UShort operation;
20789    UChar df, wt;
20790 
20791    operation = (cins & 0x03C00000) >> 22;
20792    df = (cins & 0x00200000) >> 21;
20793    wt = (cins & 0x001F0000) >> 16;
20794 
20795    switch (operation) {
20796       case 0x00: { /* FCAF.df */
20797             switch (df) {
20798                case 0x00: { /* FCAF.W */
20799                      DIP("FCAF.W w%d, w%d, w%d", wd, ws, wt);
20800                      calculateMSACSR(ws, wt, FCAFW, 2);
20801                      putWReg(wd, binop(Iop_64HLtoV128, mkU64(0ul), mkU64(0ul)));
20802                      break;
20803                   }
20804 
20805                case 0x01: { /* FCAF.D */
20806                      DIP("FCAF.D w%d, w%d, w%d", wd, ws, wt);
20807                      calculateMSACSR(ws, wt, FCAFD, 2);
20808                      putWReg(wd, binop(Iop_64HLtoV128, mkU64(0ul), mkU64(0ul)));
20809                      break;
20810                   }
20811 
20812                default:
20813                   return -1;
20814             }
20815 
20816             break;
20817          }
20818 
20819       case 0x01: { /* FCUN.df */
20820             switch (df) {
20821                case 0x00: { /* FCUN.W */
20822                      DIP("FCUN.W w%d, w%d, w%d", wd, ws, wt);
20823                      calculateMSACSR(ws, wt, FCUNW, 2);
20824                      putWReg(wd, binop(Iop_CmpUN32Fx4,
20825                                        getWReg(ws),
20826                                        getWReg(wt)));
20827                      break;
20828                   }
20829 
20830                case 0x01: { /* FCUN.D */
20831                      DIP("FCUN.D w%d, w%d, w%d", wd, ws, wt);
20832                      calculateMSACSR(ws, wt, FCUND, 2);
20833                      putWReg(wd, binop(Iop_CmpUN64Fx2,
20834                                        getWReg(ws),
20835                                        getWReg(wt)));
20836                      break;
20837                   }
20838 
20839                default:
20840                   return -1;
20841             }
20842 
20843             break;
20844          }
20845 
20846       case 0x02: { /* FCEQ.df */
20847             switch (df) {
20848                case 0x00: { /* FCEQ.W */
20849                      DIP("FCEQ.W w%d, w%d, w%d", wd, ws, wt);
20850                      calculateMSACSR(ws, wt, FCEQW, 2);
20851                      putWReg(wd, binop(Iop_CmpEQ32Fx4,
20852                                        getWReg(ws),
20853                                        getWReg(wt)));
20854                      break;
20855                   }
20856 
20857                case 0x01: { /* FCEQ.D */
20858                      DIP("FCEQ.D w%d, w%d, w%d", wd, ws, wt);
20859                      calculateMSACSR(ws, wt, FCEQD, 2);
20860                      putWReg(wd, binop(Iop_CmpEQ64Fx2,
20861                                        getWReg(ws),
20862                                        getWReg(wt)));
20863                      break;
20864                   }
20865 
20866                default:
20867                   return -1;
20868             }
20869 
20870             break;
20871          }
20872 
20873       case 0x03: { /* FCUEQ.df */
20874             switch (df) {
20875                case 0x00: { /* FCUEQ.W */
20876                      DIP("FCUEQ.W w%d, w%d, w%d", wd, ws, wt);
20877                      calculateMSACSR(ws, wt, FCUEQW, 2);
20878                      putWReg(wd,
20879                              binop(Iop_OrV128,
20880                                    binop(Iop_CmpEQ32Fx4,
20881                                          getWReg(ws),
20882                                          getWReg(wt)),
20883                                    binop(Iop_CmpUN32Fx4,
20884                                          getWReg(ws),
20885                                          getWReg(wt))));
20886                      break;
20887                   }
20888 
20889                case 0x01: { /* FCUEQ.D */
20890                      DIP("FCUEQ.D w%d, w%d, w%d", wd, ws, wt);
20891                      calculateMSACSR(ws, wt, FCUEQD, 2);
20892                      putWReg(wd,
20893                              binop(Iop_OrV128,
20894                                    binop(Iop_CmpEQ64Fx2,
20895                                          getWReg(ws),
20896                                          getWReg(wt)),
20897                                    binop(Iop_CmpUN64Fx2,
20898                                          getWReg(ws),
20899                                          getWReg(wt))));
20900                      break;
20901                   }
20902 
20903                default:
20904                   return -1;
20905             }
20906 
20907             break;
20908          }
20909 
20910       case 0x04: { /* FCLT.df */
20911             switch (df) {
20912                case 0x00: { /* FCLT.W */
20913                      DIP("FCLT.W w%d, w%d, w%d", wd, ws, wt);
20914                      calculateMSACSR(ws, wt, FCLTW, 2);
20915                      putWReg(wd,
20916                              binop(Iop_CmpLT32Fx4,
20917                                    getWReg(ws),
20918                                    getWReg(wt)));
20919                      break;
20920                   }
20921 
20922                case 0x01: { /* FCLT.D */
20923                      DIP("FCLT.D w%d, w%d, w%d", wd, ws, wt);
20924                      calculateMSACSR(ws, wt, FCLTD, 2);
20925                      putWReg(wd,
20926                              binop(Iop_CmpLT64Fx2,
20927                                    getWReg(ws),
20928                                    getWReg(wt)));
20929                      break;
20930                   }
20931 
20932                default:
20933                   return -1;
20934             }
20935 
20936             break;
20937          }
20938 
20939       case 0x05: { /* FCULT.df */
20940             switch (df) {
20941                case 0x00: { /* FCULT.W */
20942                      DIP("FCULT.W w%d, w%d, w%d", wd, ws, wt);
20943                      calculateMSACSR(ws, wt, FCULTW, 2);
20944                      putWReg(wd,
20945                              binop(Iop_OrV128,
20946                                    binop(Iop_CmpLT32Fx4,
20947                                          getWReg(ws),
20948                                          getWReg(wt)),
20949                                    binop(Iop_CmpUN32Fx4,
20950                                          getWReg(ws),
20951                                          getWReg(wt))));
20952                      break;
20953                   }
20954 
20955                case 0x01: { /* FCULT.D */
20956                      DIP("FCULT.D w%d, w%d, w%d", wd, ws, wt);
20957                      calculateMSACSR(ws, wt, FCULTD, 2);
20958                      putWReg(wd,
20959                              binop(Iop_OrV128,
20960                                    binop(Iop_CmpLT64Fx2,
20961                                          getWReg(ws),
20962                                          getWReg(wt)),
20963                                    binop(Iop_CmpUN64Fx2,
20964                                          getWReg(ws),
20965                                          getWReg(wt))));
20966                      break;
20967                   }
20968 
20969                default:
20970                   return -1;
20971             }
20972 
20973             break;
20974          }
20975 
20976       case 0x06: { /* FCLE.df */
20977             switch (df) {
20978                case 0x00: { /* FCLE.W */
20979                      DIP("FCLE.W w%d, w%d, w%d", wd, ws, wt);
20980                      calculateMSACSR(ws, wt, FCLEW, 2);
20981                      putWReg(wd,
20982                              binop(Iop_CmpLE32Fx4,
20983                                    getWReg(ws),
20984                                    getWReg(wt)));
20985                      break;
20986                   }
20987 
20988                case 0x01: { /* FCLE.D */
20989                      DIP("FCLE.D w%d, w%d, w%d", wd, ws, wt);
20990                      calculateMSACSR(ws, wt, FCLED, 2);
20991                      putWReg(wd,
20992                              binop(Iop_CmpLE64Fx2,
20993                                    getWReg(ws),
20994                                    getWReg(wt)));
20995                      break;
20996                   }
20997 
20998                default:
20999                   return -1;
21000             }
21001 
21002             break;
21003          }
21004 
21005       case 0x07: { /* FCULE.df */
21006             switch (df) {
21007                case 0x00: { /* FCULE.W */
21008                      DIP("FCULE.W w%d, w%d, w%d", wd, ws, wt);
21009                      calculateMSACSR(ws, wt, FCULEW, 2);
21010                      putWReg(wd,
21011                              binop(Iop_OrV128,
21012                                    binop(Iop_CmpLE32Fx4,
21013                                          getWReg(ws),
21014                                          getWReg(wt)),
21015                                    binop(Iop_CmpUN32Fx4,
21016                                          getWReg(ws),
21017                                          getWReg(wt))));
21018                      break;
21019                   }
21020 
21021                case 0x01: { /* FCULE.D */
21022                      DIP("FCULE.D w%d, w%d, w%d", wd, ws, wt);
21023                      calculateMSACSR(ws, wt, FCULED, 2);
21024                      putWReg(wd,
21025                              binop(Iop_OrV128,
21026                                    binop(Iop_CmpLE64Fx2,
21027                                          getWReg(ws),
21028                                          getWReg(wt)),
21029                                    binop(Iop_CmpUN64Fx2,
21030                                          getWReg(ws),
21031                                          getWReg(wt))));
21032                      break;
21033                   }
21034 
21035                default:
21036                   return -1;
21037             }
21038 
21039             break;
21040          }
21041 
21042       case 0x08: { /* FSAF.df */
21043             switch (df) {
21044                case 0x00: { /* FSAF.W */
21045                      DIP("FSAF.W w%d, w%d, w%d", wd, ws, wt);
21046                      calculateMSACSR(ws, wt, FSAFW, 2);
21047                      putWReg(wd,
21048                              binop(Iop_64HLtoV128,
21049                                    mkU64(0ul), mkU64(0ul)));
21050                      break;
21051                   }
21052 
21053                case 0x01: { /* FSAF.D */
21054                      DIP("FSAF.D w%d, w%d, w%d", wd, ws, wt);
21055                      calculateMSACSR(ws, wt, FSAFD, 2);
21056                      putWReg(wd,
21057                              binop(Iop_64HLtoV128,
21058                                    mkU64(0ul), mkU64(0ul)));
21059                      break;
21060                   }
21061 
21062                default:
21063                   return -1;
21064             }
21065 
21066             break;
21067          }
21068 
21069       case 0x09: { /* FSUN.df */
21070             switch (df) {
21071                case 0x00: { /* FSUN.W */
21072                      DIP("FSUN.W w%d, w%d, w%d", wd, ws, wt);
21073                      calculateMSACSR(ws, wt, FSUNW, 2);
21074                      putWReg(wd,
21075                              binop(Iop_CmpUN32Fx4,
21076                                    getWReg(ws),
21077                                    getWReg(wt)));
21078                      break;
21079                   }
21080 
21081                case 0x01: { /* FSUN.D */
21082                      DIP("FSUN.D w%d, w%d, w%d", wd, ws, wt);
21083                      calculateMSACSR(ws, wt, FSUND, 2);
21084                      putWReg(wd,
21085                              binop(Iop_CmpUN64Fx2,
21086                                    getWReg(ws),
21087                                    getWReg(wt)));
21088                      break;
21089                   }
21090 
21091                default:
21092                   return -1;
21093             }
21094 
21095             break;
21096          }
21097 
21098       case 0x0A: { /* FSEQ.df */
21099             switch (df) {
21100                case 0x00: { /* FSEQ.W */
21101                      DIP("FSEQ.W w%d, w%d, w%d", wd, ws, wt);
21102                      calculateMSACSR(ws, wt, FSEQW, 2);
21103                      putWReg(wd,
21104                              binop(Iop_CmpEQ32Fx4,
21105                                    getWReg(ws),
21106                                    getWReg(wt)));
21107                      break;
21108                   }
21109 
21110                case 0x01: { /* FSEQ.D */
21111                      DIP("FSEQ.D w%d, w%d, w%d", wd, ws, wt);
21112                      calculateMSACSR(ws, wt, FSEQD, 2);
21113                      putWReg(wd,
21114                              binop(Iop_CmpEQ64Fx2,
21115                                    getWReg(ws),
21116                                    getWReg(wt)));
21117                      break;
21118                   }
21119 
21120                default:
21121                   return -1;
21122             }
21123 
21124             break;
21125          }
21126 
21127       case 0x0B: { /* FSUEQ.df */
21128             switch (df) {
21129                case 0x00: { /* FSUEQ.W */
21130                      DIP("FSUEQ.W w%d, w%d, w%d", wd, ws, wt);
21131                      calculateMSACSR(ws, wt, FSUEQW, 2);
21132                      putWReg(wd,
21133                              binop(Iop_OrV128,
21134                                    binop(Iop_CmpEQ32Fx4,
21135                                          getWReg(ws),
21136                                          getWReg(wt)),
21137                                    binop(Iop_CmpUN32Fx4,
21138                                          getWReg(ws),
21139                                          getWReg(wt))));
21140                      break;
21141                   }
21142 
21143                case 0x01: { /* FSUEQ.D */
21144                      DIP("FSUEQ.D w%d, w%d, w%d", wd, ws, wt);
21145                      calculateMSACSR(ws, wt, FSUEQD, 2);
21146                      putWReg(wd,
21147                              binop(Iop_OrV128,
21148                                    binop(Iop_CmpEQ64Fx2,
21149                                          getWReg(ws),
21150                                          getWReg(wt)),
21151                                    binop(Iop_CmpUN64Fx2,
21152                                          getWReg(ws),
21153                                          getWReg(wt))));
21154                      break;
21155                   }
21156 
21157                default:
21158                   return -1;
21159             }
21160 
21161             break;
21162          }
21163 
21164       case 0x0C: { /* FSLT.df */
21165             switch (df) {
21166                case 0x00: { /* FSLT.W */
21167                      DIP("FSLT.W w%d, w%d, w%d", wd, ws, wt);
21168                      calculateMSACSR(ws, wt, FSLTW, 2);
21169                      putWReg(wd,
21170                              binop(Iop_CmpLT32Fx4,
21171                                    getWReg(ws),
21172                                    getWReg(wt)));
21173                      break;
21174                   }
21175 
21176                case 0x01: { /* FSLT.D */
21177                      DIP("FSLT.D w%d, w%d, w%d", wd, ws, wt);
21178                      calculateMSACSR(ws, wt, FSLTD, 2);
21179                      putWReg(wd,
21180                              binop(Iop_CmpLT64Fx2,
21181                                    getWReg(ws),
21182                                    getWReg(wt)));
21183                      break;
21184                   }
21185 
21186                default:
21187                   return -1;
21188             }
21189 
21190             break;
21191          }
21192 
21193       case 0x0D: { /* FSULT.df */
21194             switch (df) {
21195                case 0x00: { /* FSULT.W */
21196                      DIP("FSULT.W w%d, w%d, w%d", wd, ws, wt);
21197                      calculateMSACSR(ws, wt, FSULTW, 2);
21198                      putWReg(wd,
21199                              binop(Iop_OrV128,
21200                                    binop(Iop_CmpLT32Fx4,
21201                                          getWReg(ws),
21202                                          getWReg(wt)),
21203                                    binop(Iop_CmpUN32Fx4,
21204                                          getWReg(ws),
21205                                          getWReg(wt))));
21206                      break;
21207                   }
21208 
21209                case 0x01: { /* FSULT.D */
21210                      DIP("FSULT.D w%d, w%d, w%d", wd, ws, wt);
21211                      calculateMSACSR(ws, wt, FSULTD, 2);
21212                      putWReg(wd,
21213                              binop(Iop_OrV128,
21214                                    binop(Iop_CmpLT64Fx2,
21215                                          getWReg(ws),
21216                                          getWReg(wt)),
21217                                    binop(Iop_CmpUN64Fx2,
21218                                          getWReg(ws),
21219                                          getWReg(wt))));
21220                      break;
21221                   }
21222 
21223                default:
21224                   return -1;
21225             }
21226 
21227             break;
21228          }
21229 
21230       case 0x0E: { /* FSLE.df */
21231             switch (df) {
21232                case 0x00: { /* FSLE.W */
21233                      DIP("FSLE.W w%d, w%d, w%d", wd, ws, wt);
21234                      calculateMSACSR(ws, wt, FSLEW, 2);
21235                      putWReg(wd,
21236                              binop(Iop_CmpLE32Fx4,
21237                                    getWReg(ws),
21238                                    getWReg(wt)));
21239                      break;
21240                   }
21241 
21242                case 0x01: { /* FSLE.D */
21243                      DIP("FSLE.D w%d, w%d, w%d", wd, ws, wt);
21244                      calculateMSACSR(ws, wt, FSLED, 2);
21245                      putWReg(wd,
21246                              binop(Iop_CmpLE64Fx2,
21247                                    getWReg(ws),
21248                                    getWReg(wt)));
21249                      break;
21250                   }
21251 
21252                default:
21253                   return -1;
21254             }
21255 
21256             break;
21257          }
21258 
21259       case 0x0F: { /* FSULE.df */
21260             switch (df) {
21261                case 0x00: { /* FSULE.W */
21262                      DIP("FSULE.W w%d, w%d, w%d", wd, ws, wt);
21263                      calculateMSACSR(ws, wt, FSULEW, 2);
21264                      putWReg(wd,
21265                              binop(Iop_OrV128,
21266                                    binop(Iop_CmpLE32Fx4,
21267                                          getWReg(ws),
21268                                          getWReg(wt)),
21269                                    binop(Iop_CmpUN32Fx4,
21270                                          getWReg(ws),
21271                                          getWReg(wt))));
21272                      break;
21273                   }
21274 
21275                case 0x01: { /* FSULE.D */
21276                      DIP("FSULE.D w%d, w%d, w%d", wd, ws, wt);
21277                      calculateMSACSR(ws, wt, FSULED, 2);
21278                      putWReg(wd,
21279                              binop(Iop_OrV128,
21280                                    binop(Iop_CmpLE64Fx2,
21281                                          getWReg(ws),
21282                                          getWReg(wt)),
21283                                    binop(Iop_CmpUN64Fx2,
21284                                          getWReg(ws),
21285                                          getWReg(wt))));
21286                      break;
21287                   }
21288 
21289                default:
21290                   return -1;
21291             }
21292 
21293             break;
21294          }
21295 
21296       default:
21297          return -1;
21298    }
21299 
21300    return 0;
21301 }
21302 
msa_3R_1B(UInt cins,UChar wd,UChar ws)21303 static Int msa_3R_1B(UInt cins, UChar wd, UChar ws) { /* 3R (0x1B) */
21304    IRTemp t1, t2, t3, t4;
21305    UShort operation;
21306    UChar df, wt;
21307 
21308    operation = (cins & 0x03C00000) >> 22;
21309    df = (cins & 0x00200000) >> 21;
21310    wt = (cins & 0x001F0000) >> 16;
21311 
21312    switch (operation) {
21313       case 0x00: { /* FADD.df */
21314             switch (df) {
21315                case 0x00: { /* FADD.W */
21316                      DIP("FADD.W w%d, w%d, w%d", wd, ws, wt);
21317                      calculateMSACSR(ws, wt, FADDW, 2);
21318                      IRExpr *rm = get_IR_roundingmode_MSA();
21319                      putWReg(wd,
21320                              triop(Iop_Add32Fx4, rm,
21321                                    getWReg(ws),
21322                                    getWReg(wt)));
21323                      break;
21324                   }
21325 
21326                case 0x01: { /* FADD.D */
21327                      DIP("FADD.D w%d, w%d, w%d", wd, ws, wt);
21328                      calculateMSACSR(ws, wt, FADDD, 2);
21329                      IRExpr *rm = get_IR_roundingmode_MSA();
21330                      putWReg(wd,
21331                              triop(Iop_Add64Fx2, rm,
21332                                    getWReg(ws),
21333                                    getWReg(wt)));
21334                      break;
21335                   }
21336 
21337                default:
21338                   return -1;
21339             }
21340 
21341             break;
21342          }
21343 
21344       case 0x01: { /* FSUB.df */
21345             switch (df) {
21346                case 0x00: { /* FSUB.W */
21347                      DIP("FSUB.W w%d, w%d, w%d", wd, ws, wt);
21348                      calculateMSACSR(ws, wt, FSUBW, 2);
21349                      IRExpr *rm = get_IR_roundingmode_MSA();
21350                      putWReg(wd,
21351                              triop(Iop_Sub32Fx4, rm,
21352                                    getWReg(ws),
21353                                    getWReg(wt)));
21354                      break;
21355                   }
21356 
21357                case 0x01: { /* FSUB.D */
21358                      DIP("FSUB.D w%d, w%d, w%d", wd, ws, wt);
21359                      calculateMSACSR(ws, wt, FSUBD, 2);
21360                      IRExpr *rm = get_IR_roundingmode_MSA();
21361                      putWReg(wd,
21362                              triop(Iop_Sub64Fx2, rm,
21363                                    getWReg(ws),
21364                                    getWReg(wt)));
21365                      break;
21366                   }
21367 
21368                default:
21369                   return -1;
21370             }
21371 
21372             break;
21373          }
21374 
21375       case 0x02: { /* FMUL.df */
21376             switch (df) {
21377                case 0x00: { /* FMUL.W */
21378                      DIP("FMUL.W w%d, w%d, w%d", wd, ws, wt);
21379                      calculateMSACSR(ws, wt, FMULW, 2);
21380                      IRExpr *rm = get_IR_roundingmode_MSA();
21381                      putWReg(wd,
21382                              triop(Iop_Mul32Fx4, rm,
21383                                    getWReg(ws),
21384                                    getWReg(wt)));
21385                      break;
21386                   }
21387 
21388                case 0x01: { /* FMUL.D */
21389                      DIP("FMUL.D w%d, w%d, w%d", wd, ws, wt);
21390                      calculateMSACSR(ws, wt, FMULW, 2);
21391                      IRExpr *rm = get_IR_roundingmode_MSA();
21392                      putWReg(wd,
21393                              triop(Iop_Mul64Fx2, rm,
21394                                    getWReg(ws),
21395                                    getWReg(wt)));
21396                      break;
21397                   }
21398 
21399                default:
21400                   return -1;
21401             }
21402 
21403             break;
21404          }
21405 
21406       case 0x03: { /* FDIV.df */
21407             switch (df) {
21408                case 0x00: { /* FDIV.W */
21409                      DIP("FDIV.W w%d, w%d, w%d", wd, ws, wt);
21410                      calculateMSACSR(ws, wt, FDIVW, 2);
21411                      IRExpr *rm = get_IR_roundingmode_MSA();
21412                      putWReg(wd,
21413                              triop(Iop_Div32Fx4, rm,
21414                                    getWReg(ws),
21415                                    getWReg(wt)));
21416                      break;
21417                   }
21418 
21419                case 0x01: { /* FDIV.D */
21420                      DIP("FDIV.D w%d, w%d, w%d", wd, ws, wt);
21421                      calculateMSACSR(ws, wt, FDIVD, 2);
21422                      IRExpr *rm = get_IR_roundingmode_MSA();
21423                      putWReg(wd,
21424                              triop(Iop_Div64Fx2, rm,
21425                                    getWReg(ws),
21426                                    getWReg(wt)));
21427                      break;
21428                   }
21429 
21430                default:
21431                   return -1;
21432             }
21433 
21434             break;
21435          }
21436 
21437       case 0x04: { /* FMADD.df */
21438             switch (df) {
21439                case 0x00: { /* FMADD.W */
21440                      DIP("FMADD.W w%d, w%d, w%d", wd, ws, wt);
21441                      calculateMSACSR(ws, wt, FMADDW, 2);
21442                      IRExpr *rm = get_IR_roundingmode_MSA();
21443                      IRTemp tmp[4];
21444                      Int i;
21445 
21446                      for (i = 0; i < 4; i++) {
21447                         tmp[i] = newTemp(Ity_F32);
21448                         assign(tmp[i],
21449                                qop(Iop_MAddF32, rm,
21450                                    unop(Iop_ReinterpI32asF32,
21451                                         binop(Iop_GetElem32x4,
21452                                               getWReg(ws),
21453                                               mkU8(i))),
21454                                    unop(Iop_ReinterpI32asF32,
21455                                         binop(Iop_GetElem32x4,
21456                                               getWReg(wt),
21457                                               mkU8(i))),
21458                                    unop(Iop_ReinterpI32asF32,
21459                                         binop(Iop_GetElem32x4,
21460                                               getWReg(wd),
21461                                               mkU8(i)))));
21462                      }
21463 
21464                      putWReg(wd,
21465                              binop(Iop_64HLtoV128,
21466                                    binop(Iop_32HLto64,
21467                                          unop(Iop_ReinterpF32asI32,
21468                                               mkexpr(tmp[3])),
21469                                          unop(Iop_ReinterpF32asI32,
21470                                               mkexpr(tmp[2]))),
21471                                    binop(Iop_32HLto64,
21472                                          unop(Iop_ReinterpF32asI32,
21473                                               mkexpr(tmp[1])),
21474                                          unop(Iop_ReinterpF32asI32,
21475                                               mkexpr(tmp[0])))));
21476                      break;
21477                   }
21478 
21479                case 0x01: { /* FMADD.D */
21480                      DIP("FMADD.D w%d, w%d, w%d", wd, ws, wt);
21481                      calculateMSACSR(ws, wt, FMADDW, 2);
21482                      IRExpr *rm = get_IR_roundingmode_MSA();
21483                      IRTemp tmp[2];
21484                      Int i;
21485 
21486                      for (i = 0; i < 2; i++) {
21487                         tmp[i] = newTemp(Ity_F64);
21488                         assign(tmp[i],
21489                                qop(Iop_MAddF64, rm,
21490                                    unop(Iop_ReinterpI64asF64,
21491                                         binop(Iop_GetElem64x2,
21492                                               getWReg(ws),
21493                                               mkU8(i))),
21494                                    unop(Iop_ReinterpI64asF64,
21495                                         binop(Iop_GetElem64x2,
21496                                               getWReg(wt),
21497                                               mkU8(i))),
21498                                    unop(Iop_ReinterpI64asF64,
21499                                         binop(Iop_GetElem64x2,
21500                                               getWReg(wd),
21501                                               mkU8(i)))));
21502                      }
21503 
21504                      putWReg(wd,
21505                              binop(Iop_64HLtoV128,
21506                                    unop(Iop_ReinterpF64asI64,
21507                                         mkexpr(tmp[1])),
21508                                    unop(Iop_ReinterpF64asI64,
21509                                         mkexpr(tmp[0]))));
21510                      break;
21511                   }
21512 
21513                default:
21514                   return -1;
21515             }
21516 
21517             break;
21518          }
21519 
21520       case 0x05: { /* FMSUB.df */
21521             switch (df) {
21522                case 0x00: { /* FMSUB.W */
21523                      DIP("FMSUB.W w%d, w%d, w%d", wd, ws, wt);
21524                      calculateMSACSR(ws, wt, FMADDW, 2);
21525                      IRExpr *rm = get_IR_roundingmode_MSA();
21526                      IRTemp tmp[4];
21527                      Int i;
21528 
21529                      for (i = 0; i < 4; i++) {
21530                         tmp[i] = newTemp(Ity_F32);
21531                         assign(tmp[i],
21532                                qop(Iop_MSubF32, rm,
21533                                    unop(Iop_ReinterpI32asF32,
21534                                         binop(Iop_GetElem32x4,
21535                                               getWReg(ws),
21536                                               mkU8(i))),
21537                                    unop(Iop_ReinterpI32asF32,
21538                                         binop(Iop_GetElem32x4,
21539                                               getWReg(wt),
21540                                               mkU8(i))),
21541                                    unop(Iop_ReinterpI32asF32,
21542                                         binop(Iop_GetElem32x4,
21543                                               getWReg(wd),
21544                                               mkU8(i)))));
21545                      }
21546 
21547                      putWReg(wd,
21548                              binop(Iop_64HLtoV128,
21549                                    binop(Iop_32HLto64,
21550                                          unop(Iop_ReinterpF32asI32,
21551                                               mkexpr(tmp[3])),
21552                                          unop(Iop_ReinterpF32asI32,
21553                                               mkexpr(tmp[2]))),
21554                                    binop(Iop_32HLto64,
21555                                          unop(Iop_ReinterpF32asI32,
21556                                               mkexpr(tmp[1])),
21557                                          unop(Iop_ReinterpF32asI32,
21558                                               mkexpr(tmp[0])))));
21559                      break;
21560                   }
21561 
21562                case 0x01: { /* FMSUB.D */
21563                      DIP("FMSUB.D w%d, w%d, w%d", wd, ws, wt);
21564                      calculateMSACSR(ws, wt, FMADDD, 2);
21565                      IRExpr *rm = get_IR_roundingmode_MSA();
21566                      IRTemp tmp[2];
21567                      Int i;
21568 
21569                      for (i = 0; i < 2; i++) {
21570                         tmp[i] = newTemp(Ity_F64);
21571                         assign(tmp[i],
21572                                qop(Iop_MSubF64, rm,
21573                                    unop(Iop_ReinterpI64asF64,
21574                                         binop(Iop_GetElem64x2,
21575                                               getWReg(ws),
21576                                               mkU8(i))),
21577                                    unop(Iop_ReinterpI64asF64,
21578                                         binop(Iop_GetElem64x2,
21579                                               getWReg(wt),
21580                                               mkU8(i))),
21581                                    unop(Iop_ReinterpI64asF64,
21582                                         binop(Iop_GetElem64x2,
21583                                               getWReg(wd),
21584                                               mkU8(i)))));
21585                      }
21586 
21587                      putWReg(wd,
21588                              binop(Iop_64HLtoV128,
21589                                    unop(Iop_ReinterpF64asI64,
21590                                         mkexpr(tmp[1])),
21591                                    unop(Iop_ReinterpF64asI64,
21592                                         mkexpr(tmp[0]))));
21593                      break;
21594                   }
21595 
21596                default:
21597                   return -1;
21598             }
21599 
21600             break;
21601          }
21602 
21603       case 0x07: { /* FEXP2.df */
21604             switch (df) {
21605                case 0x00: { /* FEXP2.W */
21606                      DIP("FEXP2.W w%d, w%d, w%d", wd, ws, wt);
21607                      calculateMSACSR(ws, wt, FEXP2W, 2);
21608                      IRExpr *rm = get_IR_roundingmode_MSA();
21609                      putWReg(wd,
21610                              triop(Iop_Scale2_32Fx4, rm,
21611                                    getWReg(ws),
21612                                    getWReg(wt)));
21613                      break;
21614                   }
21615 
21616                case 0x01: { /* FEXP2.D */
21617                      DIP("FEXP2.D w%d, w%d, w%d", wd, ws, wt);
21618                      calculateMSACSR(ws, wt, FEXP2D, 2);
21619                      IRExpr *rm = get_IR_roundingmode_MSA();
21620                      putWReg(wd,
21621                              triop(Iop_Scale2_64Fx2, rm,
21622                                    getWReg(ws),
21623                                    getWReg(wt)));
21624                      break;
21625                   }
21626 
21627                default:
21628                   return -1;
21629             }
21630 
21631             break;
21632          }
21633 
21634       case 0x08: { /* FEXDO.df */
21635             switch (df) {
21636                case 0x00: { /* FEXDO.H */
21637                      DIP("FEXDO.H w%d, w%d, w%d", wd, ws, wt);
21638                      calculateMSACSR(ws, wt, FEXDOH, 2);
21639                      t1 = newTemp(Ity_I64);
21640                      t2 = newTemp(Ity_I64);
21641                      assign(t1,
21642                             unop(Iop_F32toF16x4,
21643                                  getWReg(ws)));
21644                      assign(t2,
21645                             unop(Iop_F32toF16x4,
21646                                  getWReg(wt)));
21647                      putWReg(wd,
21648                              binop(Iop_64HLtoV128,
21649                                    mkexpr(t1), mkexpr(t2)));
21650                      break;
21651                   }
21652 
21653                case 0x01: { /* FEXDO.W */
21654                      DIP("FEXDO.W w%d, w%d, w%d", wd, ws, wt);
21655                      calculateMSACSR(ws, wt, FEXDOW, 2);
21656                      t1 = newTemp(Ity_I32);
21657                      t2 = newTemp(Ity_I32);
21658                      t3 = newTemp(Ity_I32);
21659                      t4 = newTemp(Ity_I32);
21660                      IRExpr *rm = get_IR_roundingmode_MSA();
21661                      assign(t1,
21662                             unop(Iop_ReinterpF32asI32,
21663                                  binop(Iop_F64toF32, rm,
21664                                        unop(Iop_ReinterpI64asF64,
21665                                             unop(Iop_V128to64,
21666                                                  getWReg(ws))))));
21667                      assign(t2,
21668                             unop(Iop_ReinterpF32asI32,
21669                                  binop(Iop_F64toF32, rm,
21670                                        unop(Iop_ReinterpI64asF64,
21671                                             unop(Iop_V128HIto64,
21672                                                  getWReg(ws))))));
21673                      assign(t3,
21674                             unop(Iop_ReinterpF32asI32,
21675                                  binop(Iop_F64toF32, rm,
21676                                        unop(Iop_ReinterpI64asF64,
21677                                             unop(Iop_V128to64,
21678                                                  getWReg(wt))))));
21679                      assign(t4,
21680                             unop(Iop_ReinterpF32asI32,
21681                                  binop(Iop_F64toF32, rm,
21682                                        unop(Iop_ReinterpI64asF64,
21683                                             unop(Iop_V128HIto64,
21684                                                  getWReg(wt))))));
21685                      putWReg(wd,
21686                              binop(Iop_64HLtoV128,
21687                                    binop(Iop_32HLto64,
21688                                          mkexpr(t2), mkexpr(t1)),
21689                                    binop(Iop_32HLto64,
21690                                          mkexpr(t4), mkexpr(t3))));
21691                      break;
21692                   }
21693 
21694                default:
21695                   return -1;
21696             }
21697 
21698             break;
21699          }
21700 
21701       case 0x0A: { /* FTQ.df */
21702             switch (df) {
21703                case 0x00: { /* FTQ.H */
21704                      DIP("FTQ.H w%d, w%d, w%d", wd, ws, wt);
21705                      calculateMSACSR(ws, wt, FTQH, 2);
21706                      IRExpr *rm = get_IR_roundingmode_MSA();
21707                      putWReg(wd,
21708                              triop(Iop_F32x4_2toQ16x8, rm,
21709                                    getWReg(ws),
21710                                    getWReg(wt)));
21711                      break;
21712                   }
21713 
21714                case 0x01: { /* FTQ.W */
21715                      DIP("FTQ.W w%d, w%d, w%d", wd, ws, wt);
21716                      calculateMSACSR(ws, wt, FTQW, 2);
21717                      IRExpr *rm = get_IR_roundingmode_MSA();
21718                      putWReg(wd,
21719                              triop(Iop_F64x2_2toQ32x4, rm,
21720                                    getWReg(ws),
21721                                    getWReg(wt)));
21722                      break;
21723                   }
21724 
21725                default:
21726                   return -1;
21727             }
21728 
21729             break;
21730          }
21731 
21732       case 0x0C: { /* FMIN.df */
21733             switch (df) {
21734                case 0x00: { /* FMIN.W */
21735                      DIP("FMIN.W w%d, w%d, w%d", wd, ws, wt);
21736                      calculateMSACSR(ws, wt, FMINW, 2);
21737                      putWReg(wd,
21738                              binop(Iop_Min32Fx4,
21739                                    getWReg(ws),
21740                                    getWReg(wt)));
21741                      break;
21742                   }
21743 
21744                case 0x01: { /* FMIN.D */
21745                      DIP("FMIN.D w%d, w%d, w%d", wd, ws, wt);
21746                      calculateMSACSR(ws, wt, FMINW, 2);
21747                      putWReg(wd,
21748                              binop(Iop_Min64Fx2,
21749                                    getWReg(ws),
21750                                    getWReg(wt)));
21751                      break;
21752                   }
21753 
21754                default:
21755                   return -1;
21756             }
21757 
21758             break;
21759          }
21760 
21761       case 0x0D: { /* FMIN_A.df */
21762             switch (df) {
21763                case 0x00: { /* FMIN_A.W */
21764                      DIP("FMIN_A.W w%d, w%d, w%d", wd, ws, wt);
21765                      calculateMSACSR(ws, wt, FMINAW, 2);
21766                      t1 = newTemp(Ity_V128);
21767                      t2 = newTemp(Ity_V128);
21768                      t3 = newTemp(Ity_V128);
21769                      t4 = newTemp(Ity_V128);
21770                      assign(t1,
21771                             binop(Iop_AndV128,
21772                                   getWReg(ws),
21773                                   binop(Iop_64HLtoV128,
21774                                         mkU64(0x7FFFFFFF7FFFFFFF),
21775                                         mkU64(0x7FFFFFFF7FFFFFFF))));
21776                      assign(t2,
21777                             binop(Iop_AndV128,
21778                                   getWReg(wt),
21779                                   binop(Iop_64HLtoV128,
21780                                         mkU64(0x7FFFFFFF7FFFFFFF),
21781                                         mkU64(0x7FFFFFFF7FFFFFFF))));
21782                      assign(t3,
21783                             binop(Iop_Min32Fx4,
21784                                   mkexpr(t2), mkexpr(t1)));
21785                      assign(t4,
21786                          binop(Iop_AndV128,
21787                             binop(Iop_AndV128,
21788                                   unop(Iop_NotV128,
21789                                        binop(Iop_CmpUN32Fx4,
21790                                              mkexpr(t3),
21791                                              mkexpr(t3))),
21792                                   binop(Iop_OrV128,
21793                                      binop(Iop_AndV128,
21794                                            binop(Iop_CmpEQ32Fx4,
21795                                                  mkexpr(t1),
21796                                                  mkexpr(t2)),
21797                                            binop(Iop_OrV128,
21798                                                  getWReg(ws),
21799                                                  getWReg(wt))),
21800                                      binop(Iop_OrV128,
21801                                            binop(Iop_AndV128,
21802                                               binop(Iop_OrV128,
21803                                                  binop(Iop_CmpUN32Fx4,
21804                                                        mkexpr(t1),
21805                                                        mkexpr(t1)),
21806                                                  binop(Iop_CmpLT32Fx4,
21807                                                        mkexpr(t3),
21808                                                        mkexpr(t1))),
21809                                            getWReg(wt)),
21810                                            binop(Iop_AndV128,
21811                                               binop(Iop_OrV128,
21812                                                  binop(Iop_CmpUN32Fx4,
21813                                                        mkexpr(t2),
21814                                                        mkexpr(t2)),
21815                                                  binop(Iop_CmpLT32Fx4,
21816                                                        mkexpr(t3),
21817                                                        mkexpr(t2))),
21818                                                  getWReg(ws))))),
21819                             binop(Iop_64HLtoV128,
21820                                   mkU64(0x8000000080000000),
21821                                   mkU64(0x8000000080000000))));
21822                      putWReg(wd,
21823                              binop(Iop_OrV128,
21824                                    mkexpr(t3), mkexpr(t4)));
21825                      break;
21826                   }
21827 
21828                case 0x01: { /* FMIN_A.D */
21829                      DIP("FMIN_A.D w%d, w%d, w%d", wd, ws, wt);
21830                      calculateMSACSR(ws, wt, FMINAD, 2);
21831                      t1 = newTemp(Ity_V128);
21832                      t2 = newTemp(Ity_V128);
21833                      t3 = newTemp(Ity_V128);
21834                      t4 = newTemp(Ity_V128);
21835                      assign(t1,
21836                             binop(Iop_AndV128,
21837                                   getWReg(ws),
21838                                   binop(Iop_64HLtoV128,
21839                                         mkU64(0x7FFFFFFFFFFFFFFF),
21840                                         mkU64(0x7FFFFFFFFFFFFFFF))));
21841                      assign(t2,
21842                             binop(Iop_AndV128,
21843                                   getWReg(wt),
21844                                   binop(Iop_64HLtoV128,
21845                                         mkU64(0x7FFFFFFFFFFFFFFF),
21846                                         mkU64(0x7FFFFFFFFFFFFFFF))));
21847                      assign(t3,
21848                             binop(Iop_Min64Fx2,
21849                                   mkexpr(t2), mkexpr(t1)));
21850                      assign(t4,
21851                          binop(Iop_AndV128,
21852                             binop(Iop_AndV128,
21853                                   unop(Iop_NotV128,
21854                                        binop(Iop_CmpUN64Fx2,
21855                                              mkexpr(t3),
21856                                              mkexpr(t3))),
21857                                   binop(Iop_OrV128,
21858                                      binop(Iop_AndV128,
21859                                            binop(Iop_CmpEQ64Fx2,
21860                                                  mkexpr(t1),
21861                                                  mkexpr(t2)),
21862                                            binop(Iop_OrV128,
21863                                                  getWReg(ws),
21864                                                  getWReg(wt))),
21865                                      binop(Iop_OrV128,
21866                                         binop(Iop_AndV128,
21867                                               binop(Iop_OrV128,
21868                                                  binop(Iop_CmpUN64Fx2,
21869                                                        mkexpr(t1),
21870                                                        mkexpr(t1)),
21871                                                  binop(Iop_CmpLT64Fx2,
21872                                                        mkexpr(t3),
21873                                                        mkexpr(t1))),
21874                                               getWReg(wt)),
21875                                         binop(Iop_AndV128,
21876                                               binop(Iop_OrV128,
21877                                                  binop(Iop_CmpUN64Fx2,
21878                                                        mkexpr(t2),
21879                                                        mkexpr(t2)),
21880                                                  binop(Iop_CmpLT64Fx2,
21881                                                        mkexpr(t3),
21882                                                        mkexpr(t2))),
21883                                               getWReg(ws))))),
21884                             binop(Iop_64HLtoV128,
21885                                   mkU64(0x8000000000000000),
21886                                   mkU64(0x8000000000000000))));
21887                      putWReg(wd,
21888                              binop(Iop_OrV128,
21889                                    mkexpr(t3), mkexpr(t4)));
21890                      break;
21891                   }
21892 
21893                default:
21894                   return -1;
21895             }
21896 
21897             break;
21898          }
21899 
21900       case 0x0E: { /* FMAX.df */
21901             switch (df) {
21902                case 0x00: { /* FMAX.W */
21903                      DIP("FMAX.W w%d, w%d, w%d", wd, ws, wt);
21904                      calculateMSACSR(ws, wt, FMAXW, 2);
21905                      putWReg(wd,
21906                              binop(Iop_Max32Fx4,
21907                                    getWReg(ws),
21908                                    getWReg(wt)));
21909                      break;
21910                   }
21911 
21912                case 0x01: { /* FMAX.D */
21913                      DIP("FMAX.D w%d, w%d, w%d", wd, ws, wt);
21914                      calculateMSACSR(ws, wt, FMAXW, 2);
21915                      putWReg(wd,
21916                              binop(Iop_Max64Fx2,
21917                                    getWReg(ws),
21918                                    getWReg(wt)));
21919                      break;
21920                   }
21921 
21922                default:
21923                   return -1;
21924             }
21925 
21926             break;
21927          }
21928 
21929       case 0x0F: { /* FMAX_A.df */
21930             switch (df) {
21931                case 0x00: { /* FMAX_A.W */
21932                      DIP("FMAX_A.W w%d, w%d, w%d", wd, ws, wt);
21933                      calculateMSACSR(ws, wt, FMAXAW, 2);
21934                      t1 = newTemp(Ity_V128);
21935                      t2 = newTemp(Ity_V128);
21936                      t3 = newTemp(Ity_V128);
21937                      t4 = newTemp(Ity_V128);
21938                      assign(t1,
21939                             binop(Iop_AndV128,
21940                                   getWReg(ws),
21941                                   binop(Iop_64HLtoV128,
21942                                         mkU64(0x7FFFFFFF7FFFFFFF),
21943                                         mkU64(0x7FFFFFFF7FFFFFFF))));
21944                      assign(t2,
21945                             binop(Iop_AndV128,
21946                                   getWReg(wt),
21947                                   binop(Iop_64HLtoV128,
21948                                         mkU64(0x7FFFFFFF7FFFFFFF),
21949                                         mkU64(0x7FFFFFFF7FFFFFFF))));
21950                      assign(t3,
21951                             binop(Iop_Max32Fx4,
21952                                   mkexpr(t2), mkexpr(t1)));
21953                      assign(t4,
21954                          binop(Iop_AndV128,
21955                             binop(Iop_AndV128,
21956                                   unop(Iop_NotV128,
21957                                        binop(Iop_CmpUN32Fx4,
21958                                              mkexpr(t3),
21959                                              mkexpr(t3))),
21960                                   binop(Iop_OrV128,
21961                                      binop(Iop_AndV128,
21962                                            binop(Iop_CmpEQ32Fx4,
21963                                                  mkexpr(t1),
21964                                                  mkexpr(t2)),
21965                                            binop(Iop_AndV128,
21966                                                  getWReg(ws),
21967                                                  getWReg(wt))),
21968                                      binop(Iop_OrV128,
21969                                         binop(Iop_AndV128,
21970                                               binop(Iop_OrV128,
21971                                                  binop(Iop_CmpUN32Fx4,
21972                                                        mkexpr(t1),
21973                                                        mkexpr(t1)),
21974                                                  binop(Iop_CmpLT32Fx4,
21975                                                        mkexpr(t1),
21976                                                        mkexpr(t3))),
21977                                               getWReg(wt)),
21978                                         binop(Iop_AndV128,
21979                                               binop(Iop_OrV128,
21980                                                  binop(Iop_CmpUN32Fx4,
21981                                                        mkexpr(t2),
21982                                                        mkexpr(t2)),
21983                                                  binop(Iop_CmpLT32Fx4,
21984                                                        mkexpr(t2),
21985                                                        mkexpr(t3))),
21986                                               getWReg(ws))))),
21987                             binop(Iop_64HLtoV128,
21988                                   mkU64(0x8000000080000000),
21989                                   mkU64(0x8000000080000000))));
21990                      putWReg(wd,
21991                              binop(Iop_OrV128,
21992                                    mkexpr(t3), mkexpr(t4)));
21993                      break;
21994                   }
21995 
21996                case 0x01: { /* FMAX_A.D */
21997                      DIP("FMAX_A.D w%d, w%d, w%d", wd, ws, wt);
21998                      calculateMSACSR(ws, wt, FMAXAD, 2);
21999                      t1 = newTemp(Ity_V128);
22000                      t2 = newTemp(Ity_V128);
22001                      t3 = newTemp(Ity_V128);
22002                      t4 = newTemp(Ity_V128);
22003                      assign(t1,
22004                             binop(Iop_AndV128,
22005                                   getWReg(ws),
22006                                   binop(Iop_64HLtoV128,
22007                                         mkU64(0x7FFFFFFFFFFFFFFF),
22008                                         mkU64(0x7FFFFFFFFFFFFFFF))));
22009                      assign(t2,
22010                             binop(Iop_AndV128,
22011                                   getWReg(wt),
22012                                   binop(Iop_64HLtoV128,
22013                                         mkU64(0x7FFFFFFFFFFFFFFF),
22014                                         mkU64(0x7FFFFFFFFFFFFFFF))));
22015                      assign(t3,
22016                             binop(Iop_Max64Fx2,
22017                                   mkexpr(t2), mkexpr(t1)));
22018                      assign(t4,
22019                          binop(Iop_AndV128,
22020                             binop(Iop_AndV128,
22021                                   unop(Iop_NotV128,
22022                                        binop(Iop_CmpUN64Fx2,
22023                                              mkexpr(t3),
22024                                              mkexpr(t3))),
22025                                   binop(Iop_OrV128,
22026                                      binop(Iop_AndV128,
22027                                            binop(Iop_CmpEQ64Fx2,
22028                                                  mkexpr(t1),
22029                                                  mkexpr(t2)),
22030                                            binop(Iop_AndV128,
22031                                                  getWReg(ws),
22032                                                  getWReg(wt))),
22033                                      binop(Iop_OrV128,
22034                                            binop(Iop_AndV128,
22035                                               binop(Iop_OrV128,
22036                                                  binop(Iop_CmpUN64Fx2,
22037                                                        mkexpr(t1),
22038                                                        mkexpr(t1)),
22039                                                  binop(Iop_CmpLT64Fx2,
22040                                                        mkexpr(t1),
22041                                                        mkexpr(t3))),
22042                                                  getWReg(wt)),
22043                                            binop(Iop_AndV128,
22044                                               binop(Iop_OrV128,
22045                                                  binop(Iop_CmpUN64Fx2,
22046                                                        mkexpr(t2),
22047                                                        mkexpr(t2)),
22048                                                  binop(Iop_CmpLT64Fx2,
22049                                                        mkexpr(t2),
22050                                                        mkexpr(t3))),
22051                                                  getWReg(ws))))),
22052                             binop(Iop_64HLtoV128,
22053                                   mkU64(0x8000000000000000),
22054                                   mkU64(0x8000000000000000))));
22055                      putWReg(wd,
22056                              binop(Iop_OrV128,
22057                                    mkexpr(t3), mkexpr(t4)));
22058                      break;
22059                   }
22060 
22061                default:
22062                   return -1;
22063             }
22064 
22065             break;
22066          }
22067 
22068       default:
22069          return -1;
22070    }
22071 
22072    return 0;
22073 }
22074 
msa_3R_1C(UInt cins,UChar wd,UChar ws)22075 static Int msa_3R_1C(UInt cins, UChar wd, UChar ws) { /* 3R (0x1C) */
22076    IRTemp t1, t2, t3, t4, t5, t6;
22077    UShort operation;
22078    UChar df, wt;
22079 
22080    operation = (cins & 0x03C00000) >> 22;
22081    df = (cins & 0x00200000) >> 21;
22082    wt = (cins & 0x001F0000) >> 16;
22083 
22084    switch (operation) {
22085       case 0x01: { /* FCOR.df */
22086             switch (df) {
22087                case 0x00: { /* FCOR.W */
22088                      DIP("FCOR.W w%d, w%d, w%d", wd, ws, wt);
22089                      calculateMSACSR(ws, wt, FCORW, 2);
22090                      putWReg(wd,
22091                              unop(Iop_NotV128,
22092                                   binop(Iop_CmpUN32Fx4,
22093                                         getWReg(ws),
22094                                         getWReg(wt))));
22095                      break;
22096                   }
22097 
22098                case 0x01: { /* FCOR.D */
22099                      DIP("FCOR.D w%d, w%d, w%d", wd, ws, wt);
22100                      calculateMSACSR(ws, wt, FCORD, 2);
22101                      putWReg(wd,
22102                              unop(Iop_NotV128,
22103                                   binop(Iop_CmpUN64Fx2,
22104                                         getWReg(ws),
22105                                         getWReg(wt))));
22106                      break;
22107                   }
22108 
22109                default:
22110                   return -1;
22111             }
22112 
22113             break;
22114          }
22115 
22116       case 0x02: { /* FCUNE.df */
22117             switch (df) {
22118                case 0x00: { /* FCUNE.W */
22119                      DIP("FCUNE.W w%d, w%d, w%d", wd, ws, wt);
22120                      calculateMSACSR(ws, wt, FCUNEW, 2);
22121                      putWReg(wd,
22122                              unop(Iop_NotV128,
22123                                   binop(Iop_CmpEQ32Fx4,
22124                                         getWReg(ws),
22125                                         getWReg(wt))));
22126                      break;
22127                   }
22128 
22129                case 0x01: { /* FCUNE.D */
22130                      DIP("FCUNE.D w%d, w%d, w%d", wd, ws, wt);
22131                      calculateMSACSR(ws, wt, FCUNED, 2);
22132                      putWReg(wd,
22133                              unop(Iop_NotV128,
22134                                   binop(Iop_CmpEQ64Fx2,
22135                                         getWReg(ws),
22136                                         getWReg(wt))));
22137                      break;
22138                   }
22139 
22140                default:
22141                   return -1;
22142             }
22143 
22144             break;
22145          }
22146 
22147       case 0x03: { /* FCNE.df */
22148             switch (df) {
22149                case 0x00: { /* FCNE.W */
22150                      DIP("FCNE.W w%d, w%d, w%d", wd, ws, wt);
22151                      calculateMSACSR(ws, wt, FCNEW, 2);
22152                      putWReg(wd,
22153                              binop(Iop_XorV128,
22154                                    unop(Iop_NotV128,
22155                                         binop(Iop_CmpEQ32Fx4,
22156                                               getWReg(ws),
22157                                               getWReg(wt))),
22158                                    binop(Iop_CmpUN32Fx4,
22159                                          getWReg(ws),
22160                                          getWReg(wt))));
22161                      break;
22162                   }
22163 
22164                case 0x01: { /* FCNE.D */
22165                      DIP("FCNE.D w%d, w%d, w%d", wd, ws, wt);
22166                      calculateMSACSR(ws, wt, FCNED, 2);
22167                      putWReg(wd,
22168                              binop(Iop_XorV128,
22169                                    unop(Iop_NotV128,
22170                                         binop(Iop_CmpEQ64Fx2,
22171                                               getWReg(ws),
22172                                               getWReg(wt))),
22173                                    binop(Iop_CmpUN64Fx2,
22174                                          getWReg(ws),
22175                                          getWReg(wt))));
22176                      break;
22177                   }
22178 
22179                default:
22180                   return -1;
22181             }
22182 
22183             break;
22184          }
22185 
22186       case 0x04: { /* MUL_Q.df */
22187             switch (df) {
22188                case 0x00: { /* MUL_Q.H */
22189                      DIP("MUL_Q.H w%d, w%d, w%d", wd, ws, wt);
22190                      t1 = newTemp(Ity_V128);
22191                      t2 = newTemp(Ity_V128);
22192                      t3 = newTemp(Ity_V128);
22193                      assign(t1, getWReg(ws));
22194                      assign(t2, getWReg(wt));
22195                      assign(t3,
22196                             binop(Iop_QDMulHi16Sx8,
22197                                   mkexpr(t1), mkexpr(t2)));
22198                      putWReg(wd, mkexpr(t3));
22199                      break;
22200                   }
22201 
22202                case 0x01: { /* MUL_Q.W */
22203                      DIP("MUL_Q.W w%d, w%d, w%d", wd, ws, wt);
22204                      t1 = newTemp(Ity_V128);
22205                      t2 = newTemp(Ity_V128);
22206                      t3 = newTemp(Ity_V128);
22207                      assign(t1, getWReg(ws));
22208                      assign(t2, getWReg(wt));
22209                      assign(t3,
22210                             binop(Iop_QDMulHi32Sx4,
22211                                   mkexpr(t1), mkexpr(t2)));
22212                      putWReg(wd, mkexpr(t3));
22213                      break;
22214                   }
22215 
22216                default:
22217                   return -1;
22218             }
22219 
22220             break;
22221          }
22222 
22223       case 0x05: { /* MADD_Q.df */
22224             switch (df) {
22225                case 0x00: { /* MADD_Q.W */
22226                      DIP("MADD_Q.W w%d, w%d, w%d", wd, ws, wt);
22227                      t1 = newTemp(Ity_V128);
22228                      t2 = newTemp(Ity_V128);
22229                      t3 = newTemp(Ity_V128);
22230                      t4 = newTemp(Ity_V128);
22231                      t5 = newTemp(Ity_V128);
22232                      t6 = newTemp(Ity_V128);
22233                      assign(t1, // even
22234                             binop(Iop_SarN32x4,
22235                                   binop(Iop_InterleaveEvenLanes16x8,
22236                                         getWReg(ws),
22237                                         getWReg(ws)),
22238                                   mkU8(16)));
22239                      assign(t2, // odd
22240                             binop(Iop_SarN32x4,
22241                                   getWReg(ws), mkU8(16)));
22242                      assign(t3, // even
22243                             binop(Iop_SarN32x4,
22244                                   binop(Iop_InterleaveEvenLanes16x8,
22245                                         getWReg(wt),
22246                                         getWReg(wt)),
22247                                   mkU8(16)));
22248                      assign(t4, // odd
22249                             binop(Iop_SarN32x4,
22250                                   getWReg(wt), mkU8(16)));
22251                      assign(t5,
22252                          binop(Iop_Add32x4,
22253                             binop(Iop_ShlN32x4,
22254                                   binop(Iop_SarN32x4,
22255                                      binop(Iop_InterleaveEvenLanes16x8,
22256                                            getWReg(wd),
22257                                            getWReg(wd)),
22258                                      mkU8(16)),
22259                                   mkU8(15)),
22260                             binop(Iop_Mul32x4,
22261                                   mkexpr(t1), mkexpr(t3))));
22262                      assign(t6,
22263                             binop(Iop_Add32x4,
22264                                   binop(Iop_ShlN32x4,
22265                                         binop(Iop_SarN32x4,
22266                                               getWReg(wd),
22267                                               mkU8(16)),
22268                                         mkU8(15)),
22269                                   binop(Iop_Mul32x4,
22270                                         mkexpr(t2), mkexpr(t4))));
22271                      putWReg(wd,
22272                              binop(Iop_InterleaveEvenLanes16x8,
22273                                    binop(Iop_QandQSarNnarrow32Sto16Sx4,
22274                                          mkexpr(t6), mkU8(15)),
22275                                    binop(Iop_QandQSarNnarrow32Sto16Sx4,
22276                                          mkexpr(t5), mkU8(15))));
22277                      break;
22278                   }
22279 
22280                case 0x01: { /* MADD_Q.W */
22281                      DIP("MADD_Q.W w%d, w%d, w%d", wd, ws, wt);
22282                      t1 = newTemp(Ity_V128);
22283                      t2 = newTemp(Ity_V128);
22284                      t3 = newTemp(Ity_V128);
22285                      t4 = newTemp(Ity_V128);
22286                      t5 = newTemp(Ity_V128);
22287                      t6 = newTemp(Ity_V128);
22288                      assign(t1, // even
22289                             binop(Iop_SarN64x2,
22290                                   binop(Iop_InterleaveEvenLanes32x4,
22291                                         getWReg(ws),
22292                                         getWReg(ws)),
22293                                   mkU8(32)));
22294                      assign(t2, // odd
22295                             binop(Iop_SarN64x2,
22296                                   getWReg(ws), mkU8(32)));
22297                      assign(t3, // even
22298                             binop(Iop_SarN64x2,
22299                                   binop(Iop_InterleaveEvenLanes32x4,
22300                                         getWReg(wt),
22301                                         getWReg(wt)),
22302                                   mkU8(32)));
22303                      assign(t4, // odd
22304                             binop(Iop_SarN64x2,
22305                                   getWReg(wt), mkU8(32)));
22306                      assign(t5,
22307                          binop(Iop_Add64x2,
22308                             binop(Iop_ShlN64x2,
22309                                   binop(Iop_SarN64x2,
22310                                      binop(Iop_InterleaveEvenLanes32x4,
22311                                            getWReg(wd),
22312                                            getWReg(wd)),
22313                                      mkU8(32)),
22314                                   mkU8(31)),
22315                             binop(Iop_64HLtoV128,
22316                                   binop(Iop_Mul64,
22317                                         unop(Iop_V128HIto64,
22318                                              mkexpr(t1)),
22319                                         unop(Iop_V128HIto64,
22320                                              mkexpr(t3))),
22321                                   binop(Iop_Mul64,
22322                                         unop(Iop_V128to64,
22323                                              mkexpr(t1)),
22324                                         unop(Iop_V128to64,
22325                                              mkexpr(t3))))));
22326                      assign(t6,
22327                             binop(Iop_Add64x2,
22328                                   binop(Iop_ShlN64x2,
22329                                         binop(Iop_SarN64x2,
22330                                               getWReg(wd),
22331                                               mkU8(32)),
22332                                         mkU8(31)),
22333                                   binop(Iop_64HLtoV128,
22334                                         binop(Iop_Mul64,
22335                                               unop(Iop_V128HIto64,
22336                                                    mkexpr(t2)),
22337                                               unop(Iop_V128HIto64,
22338                                                    mkexpr(t4))),
22339                                         binop(Iop_Mul64,
22340                                               unop(Iop_V128to64,
22341                                                    mkexpr(t2)),
22342                                               unop(Iop_V128to64,
22343                                                    mkexpr(t4))))));
22344                      putWReg(wd,
22345                              binop(Iop_InterleaveEvenLanes32x4,
22346                                    binop(Iop_QandQSarNnarrow64Sto32Sx2,
22347                                          mkexpr(t6), mkU8(31)),
22348                                    binop(Iop_QandQSarNnarrow64Sto32Sx2,
22349                                          mkexpr(t5), mkU8(31))));
22350                      break;
22351                   }
22352 
22353                default:
22354                   return -1;
22355             }
22356 
22357             break;
22358          }
22359 
22360       case 0x06: { /* MSUB_Q.df */
22361             switch (df) {
22362                case 0x00: { /* MSUB_Q.H */
22363                      DIP("MSUB_Q.H w%d, w%d, w%d", wd, ws, wt);
22364                      t1 = newTemp(Ity_V128);
22365                      t2 = newTemp(Ity_V128);
22366                      t3 = newTemp(Ity_V128);
22367                      t4 = newTemp(Ity_V128);
22368                      t5 = newTemp(Ity_V128);
22369                      t6 = newTemp(Ity_V128);
22370                      assign(t1, // even
22371                             binop(Iop_SarN32x4,
22372                                   binop(Iop_InterleaveEvenLanes16x8,
22373                                         getWReg(ws),
22374                                         getWReg(ws)),
22375                                   mkU8(16)));
22376                      assign(t2, // odd
22377                             binop(Iop_SarN32x4,
22378                                   getWReg(ws), mkU8(16)));
22379                      assign(t3, // even
22380                             binop(Iop_SarN32x4,
22381                                   binop(Iop_InterleaveEvenLanes16x8,
22382                                         getWReg(wt),
22383                                         getWReg(wt)),
22384                                   mkU8(16)));
22385                      assign(t4, // odd
22386                             binop(Iop_SarN32x4,
22387                                   getWReg(wt), mkU8(16)));
22388                      assign(t5,
22389                          binop(Iop_Sub32x4,
22390                             binop(Iop_ShlN32x4,
22391                                binop(Iop_SarN32x4,
22392                                      binop(Iop_InterleaveEvenLanes16x8,
22393                                            getWReg(wd),
22394                                            getWReg(wd)),
22395                                      mkU8(16)),
22396                                mkU8(15)),
22397                             binop(Iop_Mul32x4,
22398                                   mkexpr(t1), mkexpr(t3))));
22399                      assign(t6,
22400                             binop(Iop_Sub32x4,
22401                                   binop(Iop_ShlN32x4,
22402                                         binop(Iop_SarN32x4,
22403                                               getWReg(wd),
22404                                               mkU8(16)),
22405                                         mkU8(15)),
22406                                   binop(Iop_Mul32x4,
22407                                         mkexpr(t2), mkexpr(t4))));
22408                      putWReg(wd,
22409                              binop(Iop_InterleaveEvenLanes16x8,
22410                                    binop(Iop_QandQSarNnarrow32Sto16Sx4,
22411                                          mkexpr(t6), mkU8(15)),
22412                                    binop(Iop_QandQSarNnarrow32Sto16Sx4,
22413                                          mkexpr(t5), mkU8(15))));
22414                      break;
22415                   }
22416 
22417                case 0x01: { /* MSUB_Q.W */
22418                      DIP("MSUB_Q.W w%d, w%d, w%d", wd, ws, wt);
22419                      t1 = newTemp(Ity_V128);
22420                      t2 = newTemp(Ity_V128);
22421                      t3 = newTemp(Ity_V128);
22422                      t4 = newTemp(Ity_V128);
22423                      t5 = newTemp(Ity_V128);
22424                      t6 = newTemp(Ity_V128);
22425                      assign(t1, // even
22426                             binop(Iop_SarN64x2,
22427                                   binop(Iop_InterleaveEvenLanes32x4,
22428                                         getWReg(ws),
22429                                         getWReg(ws)),
22430                                   mkU8(32)));
22431                      assign(t2, // odd
22432                             binop(Iop_SarN64x2,
22433                                   getWReg(ws), mkU8(32)));
22434                      assign(t3, // even
22435                             binop(Iop_SarN64x2,
22436                                   binop(Iop_InterleaveEvenLanes32x4,
22437                                         getWReg(wt),
22438                                         getWReg(wt)),
22439                                   mkU8(32)));
22440                      assign(t4, // odd
22441                             binop(Iop_SarN64x2,
22442                                   getWReg(wt), mkU8(32)));
22443                      assign(t5,
22444                          binop(Iop_Sub64x2,
22445                                binop(Iop_ShlN64x2,
22446                                   binop(Iop_SarN64x2,
22447                                      binop(Iop_InterleaveEvenLanes32x4,
22448                                            getWReg(wd),
22449                                            getWReg(wd)),
22450                                      mkU8(32)),
22451                                   mkU8(31)),
22452                                binop(Iop_64HLtoV128,
22453                                      binop(Iop_Mul64,
22454                                            unop(Iop_V128HIto64,
22455                                                 mkexpr(t1)),
22456                                            unop(Iop_V128HIto64,
22457                                                 mkexpr(t3))),
22458                                      binop(Iop_Mul64,
22459                                            unop(Iop_V128to64,
22460                                                 mkexpr(t1)),
22461                                            unop(Iop_V128to64,
22462                                                 mkexpr(t3))))));
22463                      assign(t6,
22464                             binop(Iop_Sub64x2,
22465                                   binop(Iop_ShlN64x2,
22466                                         binop(Iop_SarN64x2,
22467                                               getWReg(wd),
22468                                               mkU8(32)),
22469                                         mkU8(31)),
22470                                   binop(Iop_64HLtoV128,
22471                                         binop(Iop_Mul64,
22472                                               unop(Iop_V128HIto64,
22473                                                    mkexpr(t2)),
22474                                               unop(Iop_V128HIto64,
22475                                                    mkexpr(t4))),
22476                                         binop(Iop_Mul64,
22477                                               unop(Iop_V128to64,
22478                                                    mkexpr(t2)),
22479                                               unop(Iop_V128to64,
22480                                                    mkexpr(t4))))));
22481                      putWReg(wd,
22482                              binop(Iop_InterleaveEvenLanes32x4,
22483                                    binop(Iop_QandQSarNnarrow64Sto32Sx2,
22484                                          mkexpr(t6), mkU8(31)),
22485                                    binop(Iop_QandQSarNnarrow64Sto32Sx2,
22486                                          mkexpr(t5), mkU8(31))));
22487                      break;
22488                   }
22489 
22490                default:
22491                   return -1;
22492             }
22493 
22494             break;
22495          }
22496 
22497       case 0x09: { /* FSOR.df */
22498             switch (df) {
22499                case 0x00: { /* FSOR.W */
22500                      DIP("FSOR.W w%d, w%d, w%d", wd, ws, wt);
22501                      calculateMSACSR(ws, wt, FSORW, 2);
22502                      putWReg(wd,
22503                              unop(Iop_NotV128,
22504                                   binop(Iop_CmpUN32Fx4,
22505                                         getWReg(ws),
22506                                         getWReg(wt))));
22507                      break;
22508                   }
22509 
22510                case 0x01: { /* FSOR.D */
22511                      DIP("FSOR.D w%d, w%d, w%d", wd, ws, wt);
22512                      calculateMSACSR(ws, wt, FSORD, 2);
22513                      putWReg(wd,
22514                              unop(Iop_NotV128,
22515                                   binop(Iop_CmpUN64Fx2,
22516                                         getWReg(ws),
22517                                         getWReg(wt))));
22518                      break;
22519                   }
22520 
22521                default:
22522                   return -1;
22523             }
22524 
22525             break;
22526          }
22527 
22528       case 0x0A: { /* FSUNE.df */
22529             switch (df) {
22530                case 0x00: { /* FSUNE.W */
22531                      DIP("FSUNE.W w%d, w%d, w%d", wd, ws, wt);
22532                      calculateMSACSR(ws, wt, FSUNEW, 2);
22533                      putWReg(wd,
22534                              unop(Iop_NotV128,
22535                                   binop(Iop_CmpEQ32Fx4,
22536                                         getWReg(ws),
22537                                         getWReg(wt))));
22538                      break;
22539                   }
22540 
22541                case 0x01: { /* FSUNE.D */
22542                      DIP("FSUNE.D w%d, w%d, w%d", wd, ws, wt);
22543                      calculateMSACSR(ws, wt, FSUNED, 2);
22544                      putWReg(wd,
22545                              unop(Iop_NotV128,
22546                                   binop(Iop_CmpEQ64Fx2,
22547                                         getWReg(ws),
22548                                         getWReg(wt))));
22549                      break;
22550                   }
22551 
22552                default:
22553                   return -1;
22554             }
22555 
22556             break;
22557          }
22558 
22559       case 0x0B: { /* FSNE.df */
22560             switch (df) {
22561                case 0x00: { /* FSNE.W */
22562                      DIP("FSNE.W w%d, w%d, w%d", wd, ws, wt);
22563                      calculateMSACSR(ws, wt, FSNEW, 2);
22564                      putWReg(wd,
22565                              binop(Iop_XorV128,
22566                                    unop(Iop_NotV128,
22567                                         binop(Iop_CmpEQ32Fx4,
22568                                               getWReg(ws),
22569                                               getWReg(wt))),
22570                                    binop(Iop_CmpUN32Fx4,
22571                                          getWReg(ws),
22572                                          getWReg(wt))));
22573                      break;
22574                   }
22575 
22576                case 0x01: { /* FSNE.D */
22577                      DIP("FSNE.D w%d, w%d, w%d", wd, ws, wt);
22578                      calculateMSACSR(ws, wt, FSNED, 2);
22579                      putWReg(wd,
22580                              binop(Iop_XorV128,
22581                                    unop(Iop_NotV128,
22582                                         binop(Iop_CmpEQ64Fx2,
22583                                               getWReg(ws),
22584                                               getWReg(wt))),
22585                                    binop(Iop_CmpUN64Fx2,
22586                                          getWReg(ws),
22587                                          getWReg(wt))));
22588                      break;
22589                   }
22590 
22591                default:
22592                   return -1;
22593             }
22594 
22595             break;
22596          }
22597 
22598       case 0x0C: { /* MULR_Q.df */
22599             switch (df) {
22600                case 0x00: { /* MULR_Q.H */
22601                      DIP("MULR_Q.H w%d, w%d, w%d", wd, ws, wt);
22602                      t1 = newTemp(Ity_V128);
22603                      t2 = newTemp(Ity_V128);
22604                      t3 = newTemp(Ity_V128);
22605                      assign(t1, getWReg(ws));
22606                      assign(t2, getWReg(wt));
22607                      assign(t3, binop(Iop_QRDMulHi16Sx8,
22608                                       mkexpr(t1), mkexpr(t2)));
22609                      putWReg(wd, mkexpr(t3));
22610                      break;
22611                   }
22612 
22613                case 0x01: { /* MULR_Q.W */
22614                      DIP("MULR_Q.W w%d, w%d, w%d", wd, ws, wt);
22615                      t1 = newTemp(Ity_V128);
22616                      t2 = newTemp(Ity_V128);
22617                      t3 = newTemp(Ity_V128);
22618                      assign(t1, getWReg(ws));
22619                      assign(t2, getWReg(wt));
22620                      assign(t3, binop(Iop_QRDMulHi32Sx4,
22621                                       mkexpr(t1), mkexpr(t2)));
22622                      putWReg(wd, mkexpr(t3));
22623                      break;
22624                   }
22625 
22626                default:
22627                   return -1;
22628             }
22629 
22630             break;
22631          }
22632 
22633       case 0x0D: { /* MADDR_Q.df */
22634             switch (df) {
22635                case 0x00: { /* MADDR_Q.W */
22636                      DIP("MADDR_Q.W w%d, w%d, w%d", wd, ws, wt);
22637                      t1 = newTemp(Ity_V128);
22638                      t2 = newTemp(Ity_V128);
22639                      t3 = newTemp(Ity_V128);
22640                      t4 = newTemp(Ity_V128);
22641                      t5 = newTemp(Ity_V128);
22642                      t6 = newTemp(Ity_V128);
22643                      assign(t1, // even
22644                             binop(Iop_SarN32x4,
22645                                   binop(Iop_InterleaveEvenLanes16x8,
22646                                         getWReg(ws),
22647                                         getWReg(ws)),
22648                                   mkU8(16)));
22649                      assign(t2, // odd
22650                             binop(Iop_SarN32x4,
22651                                   getWReg(ws), mkU8(16)));
22652                      assign(t3, // even
22653                             binop(Iop_SarN32x4,
22654                                   binop(Iop_InterleaveEvenLanes16x8,
22655                                         getWReg(wt),
22656                                         getWReg(wt)),
22657                                   mkU8(16)));
22658                      assign(t4, // odd
22659                             binop(Iop_SarN32x4,
22660                                   getWReg(wt), mkU8(16)));
22661                      assign(t5,
22662                          binop(Iop_Add32x4,
22663                             binop(Iop_ShlN32x4,
22664                                binop(Iop_SarN32x4,
22665                                      binop(Iop_InterleaveEvenLanes16x8,
22666                                            getWReg(wd),
22667                                            getWReg(wd)),
22668                                      mkU8(16)),
22669                                mkU8(15)),
22670                             binop(Iop_Mul32x4,
22671                                   mkexpr(t1), mkexpr(t3))));
22672                      assign(t6,
22673                             binop(Iop_Add32x4,
22674                                   binop(Iop_ShlN32x4,
22675                                         binop(Iop_SarN32x4,
22676                                               getWReg(wd),
22677                                               mkU8(16)),
22678                                         mkU8(15)),
22679                                   binop(Iop_Mul32x4,
22680                                         mkexpr(t2), mkexpr(t4))));
22681                      putWReg(wd,
22682                           binop(Iop_InterleaveEvenLanes16x8,
22683                                 binop(Iop_QandQRSarNnarrow32Sto16Sx4,
22684                                       mkexpr(t6), mkU8(15)),
22685                                 binop(Iop_QandQRSarNnarrow32Sto16Sx4,
22686                                       mkexpr(t5), mkU8(15))));
22687                      break;
22688                   }
22689 
22690                case 0x01: { /* MADDR_Q.D */
22691                      DIP("MADDR_Q.D w%d, w%d, w%d", wd, ws, wt);
22692                      t1 = newTemp(Ity_V128);
22693                      t2 = newTemp(Ity_V128);
22694                      t3 = newTemp(Ity_V128);
22695                      t4 = newTemp(Ity_V128);
22696                      t5 = newTemp(Ity_V128);
22697                      t6 = newTemp(Ity_V128);
22698                      assign(t1, // even
22699                             binop(Iop_SarN64x2,
22700                                   binop(Iop_InterleaveEvenLanes32x4,
22701                                         getWReg(ws),
22702                                         getWReg(ws)),
22703                                   mkU8(32)));
22704                      assign(t2, // odd
22705                             binop(Iop_SarN64x2,
22706                                   getWReg(ws), mkU8(32)));
22707                      assign(t3, // even
22708                             binop(Iop_SarN64x2,
22709                                   binop(Iop_InterleaveEvenLanes32x4,
22710                                         getWReg(wt),
22711                                         getWReg(wt)),
22712                                   mkU8(32)));
22713                      assign(t4, // odd
22714                             binop(Iop_SarN64x2,
22715                                   getWReg(wt), mkU8(32)));
22716                      assign(t5,
22717                          binop(Iop_Add64x2,
22718                             binop(Iop_ShlN64x2,
22719                                binop(Iop_SarN64x2,
22720                                   binop(Iop_InterleaveEvenLanes32x4,
22721                                         getWReg(wd),
22722                                         getWReg(wd)),
22723                                   mkU8(32)),
22724                                mkU8(31)),
22725                             binop(Iop_64HLtoV128,
22726                                   binop(Iop_Mul64,
22727                                         unop(Iop_V128HIto64,
22728                                              mkexpr(t1)),
22729                                         unop(Iop_V128HIto64,
22730                                              mkexpr(t3))),
22731                                   binop(Iop_Mul64,
22732                                         unop(Iop_V128to64,
22733                                              mkexpr(t1)),
22734                                         unop(Iop_V128to64,
22735                                              mkexpr(t3))))));
22736                      assign(t6,
22737                             binop(Iop_Add64x2,
22738                                   binop(Iop_ShlN64x2,
22739                                         binop(Iop_SarN64x2,
22740                                               getWReg(wd),
22741                                               mkU8(32)),
22742                                         mkU8(31)),
22743                                   binop(Iop_64HLtoV128,
22744                                         binop(Iop_Mul64,
22745                                               unop(Iop_V128HIto64,
22746                                                    mkexpr(t2)),
22747                                               unop(Iop_V128HIto64,
22748                                                    mkexpr(t4))),
22749                                         binop(Iop_Mul64,
22750                                               unop(Iop_V128to64,
22751                                                    mkexpr(t2)),
22752                                               unop(Iop_V128to64,
22753                                                    mkexpr(t4))))));
22754                      putWReg(wd,
22755                           binop(Iop_InterleaveEvenLanes32x4,
22756                                 binop(Iop_QandQRSarNnarrow64Sto32Sx2,
22757                                       mkexpr(t6), mkU8(31)),
22758                                 binop(Iop_QandQRSarNnarrow64Sto32Sx2,
22759                                       mkexpr(t5), mkU8(31))));
22760                      break;
22761                   }
22762 
22763                default:
22764                   return -1;
22765             }
22766 
22767             break;
22768          }
22769 
22770       case 0x0E: { /* MSUBR_Q.df */
22771             switch (df) {
22772                case 0x00: { /* MSUBR_Q.W */
22773                      DIP("MSUBR_Q.W w%d, w%d, w%d", wd, ws, wt);
22774                      t1 = newTemp(Ity_V128);
22775                      t2 = newTemp(Ity_V128);
22776                      t3 = newTemp(Ity_V128);
22777                      t4 = newTemp(Ity_V128);
22778                      t5 = newTemp(Ity_V128);
22779                      t6 = newTemp(Ity_V128);
22780                      assign(t1, // even
22781                             binop(Iop_SarN32x4,
22782                                   binop(Iop_InterleaveEvenLanes16x8,
22783                                         getWReg(ws),
22784                                         getWReg(ws)),
22785                                   mkU8(16)));
22786                      assign(t2, // odd
22787                             binop(Iop_SarN32x4,
22788                                   getWReg(ws), mkU8(16)));
22789                      assign(t3, // even
22790                             binop(Iop_SarN32x4,
22791                                   binop(Iop_InterleaveEvenLanes16x8,
22792                                         getWReg(wt),
22793                                         getWReg(wt)),
22794                                   mkU8(16)));
22795                      assign(t4, // odd
22796                             binop(Iop_SarN32x4,
22797                                   getWReg(wt), mkU8(16)));
22798                      assign(t5,
22799                          binop(Iop_Sub32x4,
22800                             binop(Iop_ShlN32x4,
22801                                   binop(Iop_SarN32x4,
22802                                      binop(Iop_InterleaveEvenLanes16x8,
22803                                            getWReg(wd),
22804                                            getWReg(wd)),
22805                                      mkU8(16)),
22806                                   mkU8(15)),
22807                             binop(Iop_Mul32x4,
22808                                   mkexpr(t1), mkexpr(t3))));
22809                      assign(t6,
22810                             binop(Iop_Sub32x4,
22811                                   binop(Iop_ShlN32x4,
22812                                         binop(Iop_SarN32x4,
22813                                               getWReg(wd),
22814                                               mkU8(16)),
22815                                         mkU8(15)),
22816                                   binop(Iop_Mul32x4,
22817                                         mkexpr(t2), mkexpr(t4))));
22818                      putWReg(wd,
22819                           binop(Iop_InterleaveEvenLanes16x8,
22820                                 binop(Iop_QandQRSarNnarrow32Sto16Sx4,
22821                                       mkexpr(t6), mkU8(15)),
22822                                 binop(Iop_QandQRSarNnarrow32Sto16Sx4,
22823                                       mkexpr(t5), mkU8(15))));
22824                      break;
22825                   }
22826 
22827                case 0x01: { /* MSUBR_Q.D */
22828                      DIP("MSUBR_Q.D w%d, w%d, w%d", wd, ws, wt);
22829                      t1 = newTemp(Ity_V128);
22830                      t2 = newTemp(Ity_V128);
22831                      t3 = newTemp(Ity_V128);
22832                      t4 = newTemp(Ity_V128);
22833                      t5 = newTemp(Ity_V128);
22834                      t6 = newTemp(Ity_V128);
22835                      assign(t1, // even
22836                             binop(Iop_SarN64x2,
22837                                   binop(Iop_InterleaveEvenLanes32x4,
22838                                         getWReg(ws),
22839                                         getWReg(ws)),
22840                                   mkU8(32)));
22841                      assign(t2, // odd
22842                             binop(Iop_SarN64x2,
22843                                   getWReg(ws), mkU8(32)));
22844                      assign(t3, // even
22845                             binop(Iop_SarN64x2,
22846                                   binop(Iop_InterleaveEvenLanes32x4,
22847                                         getWReg(wt),
22848                                         getWReg(wt)),
22849                                   mkU8(32)));
22850                      assign(t4, // odd
22851                             binop(Iop_SarN64x2,
22852                                   getWReg(wt), mkU8(32)));
22853                      assign(t5,
22854                          binop(Iop_Sub64x2,
22855                             binop(Iop_ShlN64x2,
22856                                binop(Iop_SarN64x2,
22857                                   binop(Iop_InterleaveEvenLanes32x4,
22858                                         getWReg(wd),
22859                                         getWReg(wd)),
22860                                   mkU8(32)),
22861                                mkU8(31)),
22862                             binop(Iop_64HLtoV128,
22863                                   binop(Iop_Mul64,
22864                                         unop(Iop_V128HIto64,
22865                                              mkexpr(t1)),
22866                                         unop(Iop_V128HIto64,
22867                                              mkexpr(t3))),
22868                                   binop(Iop_Mul64,
22869                                         unop(Iop_V128to64,
22870                                              mkexpr(t1)),
22871                                         unop(Iop_V128to64,
22872                                              mkexpr(t3))))));
22873                   assign(t6,
22874                             binop(Iop_Sub64x2,
22875                                   binop(Iop_ShlN64x2,
22876                                         binop(Iop_SarN64x2,
22877                                               getWReg(wd),
22878                                               mkU8(32)),
22879                                         mkU8(31)),
22880                                   binop(Iop_64HLtoV128,
22881                                         binop(Iop_Mul64,
22882                                               unop(Iop_V128HIto64,
22883                                                    mkexpr(t2)),
22884                                               unop(Iop_V128HIto64,
22885                                                    mkexpr(t4))),
22886                                         binop(Iop_Mul64,
22887                                               unop(Iop_V128to64,
22888                                                    mkexpr(t2)),
22889                                               unop(Iop_V128to64,
22890                                                    mkexpr(t4))))));
22891                      putWReg(wd,
22892                           binop(Iop_InterleaveEvenLanes32x4,
22893                                 binop(Iop_QandQRSarNnarrow64Sto32Sx2,
22894                                       mkexpr(t6), mkU8(31)),
22895                                 binop(Iop_QandQRSarNnarrow64Sto32Sx2,
22896                                       mkexpr(t5), mkU8(31))));
22897                      break;
22898                   }
22899 
22900                default:
22901                   return -1;
22902             }
22903 
22904             break;
22905          }
22906 
22907       default:
22908          return -1;
22909    }
22910 
22911    return 0;
22912 }
22913 
msa_ELM(UInt cins,UChar wd,UChar ws)22914 static Int msa_ELM(UInt cins, UChar wd, UChar ws) { /* ELM (0x19) */
22915    IRTemp t1, t2, t3, t4, t5;
22916    IRType ty;
22917    UShort operation;
22918    UChar df, n;
22919 
22920    operation = (cins & 0x03C00000) >> 22;
22921    ty = mode64 ? Ity_I64 : Ity_I32;
22922 
22923    switch ((cins & 0x03FF0000) >> 16) {
22924       case 0x07E: /* CFCMSA */
22925          DIP("CFCMSA r%d, c%d", wd, ws);
22926 
22927          switch (ws) {
22928             case 0: { /* MSAIR */
22929                   IRDirty *d;
22930                   t1 = newTemp(Ity_I32);
22931                   /* IRExpr_BBPTR() =>
22932                                        Need to pass pointer to
22933                                              guest state to helper. */
22934                   d = unsafeIRDirty_1_N(t1, 0,
22935                                         "mips_dirtyhelper_get_MSAIR",
22936                                         &mips_dirtyhelper_get_MSAIR,
22937                                         mkIRExprVec_0());
22938                   /* d->nFxState = 0; */
22939                   stmt(IRStmt_Dirty(d));
22940                   putIReg(wd,
22941                           mkWidenFrom32(ty, mkexpr(t1), True));
22942                   break;
22943                }
22944 
22945             case 1: /* MSACSR */
22946                putIReg(wd,
22947                        mkWidenFrom32(ty, getMSACSR(), True));
22948                break;
22949 
22950             default:
22951                putIReg(wd,
22952                        mkWidenFrom32(ty, mkU32(0), False));
22953                break;
22954          }
22955 
22956          break;
22957 
22958       case 0x03E: /* CTCMSA */
22959          DIP("CTCMSA r%d, c%d", ws, wd);
22960 
22961          if (wd == 1) { /* MSACSR */
22962             putMSACSR(
22963                binop(Iop_And32, mkNarrowTo32(ty, getIReg(ws)),
22964                      mkU32(0x1FFFFFF)));
22965          }
22966 
22967          break;
22968 
22969       case 0x0BE: /* MOVE.V */
22970          DIP("MOVE.V w%d, w%d", ws, wd);
22971          putWReg(wd, getWReg(ws));
22972          break;
22973 
22974       default:
22975          df = (cins & 0x003F0000) >> 16;
22976          if ((df & 0x38) == 0x38) {        // 11100n; dw
22977             n = df & 0x01;
22978             df = 0x38;
22979          } else if ((df & 0x30) == 0x30) { // 1100nn; w
22980             n = df & 0x03;
22981             df = 0x30;
22982          } else if ((df & 0x20) == 0x20) { // 100nnn; hw
22983             n = df & 0x07;
22984             df = 0x20;
22985          } else if ((df & 0x00) == 0x00) { // 00nnnn; b
22986             n = df & 0x0F;
22987             df = 0x00;
22988          }
22989 
22990          switch (operation) {
22991             case 0x00: /* SLDI.df */
22992                switch (df) {
22993                   case 0x00: /* SLDI.B */
22994                      DIP("SLDI.B w%d, w%d[%d]", wd, ws, n);
22995                      t1 = newTemp(Ity_V128);
22996                      t2 = newTemp(Ity_V128);
22997                      assign(t1,
22998                             binop(Iop_ShrV128,
22999                                   getWReg(ws),
23000                                   mkU8(n << 3)));
23001                      assign(t2,
23002                             binop(Iop_ShlV128,
23003                                   getWReg(wd),
23004                                   mkU8(n ?
23005                                        (16 - n) << 3 : 0)));
23006                      putWReg(wd,
23007                              binop(Iop_OrV128, mkexpr(t1), mkexpr(t2)));
23008                      break;
23009 
23010                   case 0x20: /* SLDI.H */
23011                      DIP("SLDI.H w%d, w%d[%d]", wd, ws, n);
23012 
23013                      if (n == 0) {
23014                         putWReg(wd, getWReg(ws));
23015                      } else {
23016                         t1 = newTemp(Ity_V128);
23017                         t2 = newTemp(Ity_V128);
23018                         assign(t1,
23019                                binop(Iop_ShrN64x2,
23020                                      getWReg(ws),
23021                                      mkU8(n << 3)));
23022                         assign(t2,
23023                                binop(Iop_ShlN64x2,
23024                                      getWReg(wd),
23025                                      mkU8((8 - n) << 3)));
23026                         putWReg(wd,
23027                                 binop(Iop_OrV128,
23028                                       mkexpr(t1),
23029                                       mkexpr(t2)));
23030                      }
23031 
23032                      break;
23033 
23034                   case 0x30: /* SLDI.W */
23035                      DIP("SLDI.W w%d, w%d[%d]", wd, ws, n);
23036 
23037                      if (n == 0) {
23038                         putWReg(wd, getWReg(ws));
23039                      } else {
23040                         t1 = newTemp(Ity_V128);
23041                         t2 = newTemp(Ity_V128);
23042                         assign(t1,
23043                                binop(Iop_ShrN32x4,
23044                                      getWReg(ws),
23045                                      mkU8(n << 3)));
23046                         assign(t2,
23047                                binop(Iop_ShlN32x4,
23048                                      getWReg(wd),
23049                                      mkU8((4 - n) << 3)));
23050                         putWReg(wd,
23051                                 binop(Iop_OrV128,
23052                                       mkexpr(t1),
23053                                       mkexpr(t2)));
23054                      }
23055 
23056                      break;
23057 
23058                   case 0x38:  /* SLDI.D */
23059                      DIP("SLDI.D w%d, w%d[%d]", wd, ws, n);
23060 
23061                      if (n == 0) {
23062                         putWReg(wd, getWReg(ws));
23063                      } else {
23064                         t1 = newTemp(Ity_V128);
23065                         t2 = newTemp(Ity_V128);
23066                         assign(t1,
23067                                binop(Iop_ShrN16x8,
23068                                      getWReg(ws),
23069                                      mkU8(n << 3)));
23070                         assign(t2,
23071                                binop(Iop_ShlN16x8,
23072                                      getWReg(wd),
23073                                      mkU8((2 - n) << 3)));
23074                         putWReg(wd,
23075                                 binop(Iop_OrV128,
23076                                       mkexpr(t1),
23077                                       mkexpr(t2)));
23078                      }
23079 
23080                      break;
23081 
23082                   default:
23083                      return -1;
23084                }
23085 
23086                break;
23087 
23088             case 0x01: /* SPLATI.df */
23089                switch (df) {
23090                   case 0x00: { /* SPLATI.B */
23091                         DIP("SPLATI.B w%d, w%d[%d]", wd, ws, n);
23092                         t1 = newTemp(Ity_V128);
23093                         t2 = newTemp(Ity_V128);
23094                         t3 = newTemp(Ity_V128);
23095                         t4 = newTemp(Ity_V128);
23096 
23097                         if (n & 1)
23098                            assign(t1,
23099                                   binop(Iop_InterleaveOddLanes8x16,
23100                                         getWReg(ws),
23101                                         getWReg(ws)));
23102                         else
23103                            assign(t1,
23104                                   binop(Iop_InterleaveEvenLanes8x16,
23105                                         getWReg(ws),
23106                                         getWReg(ws)));
23107 
23108                         n /= 2;
23109 
23110                         if (n & 1)
23111                            assign(t2,
23112                                   binop(Iop_InterleaveOddLanes16x8,
23113                                         mkexpr(t1), mkexpr(t1)));
23114                         else
23115                            assign(t2,
23116                                   binop(Iop_InterleaveEvenLanes16x8,
23117                                         mkexpr(t1), mkexpr(t1)));
23118 
23119                         n /= 2;
23120 
23121                         if (n & 1)
23122                            assign(t3,
23123                                   binop(Iop_InterleaveOddLanes32x4,
23124                                         mkexpr(t2), mkexpr(t2)));
23125                         else
23126                            assign(t3,
23127                                   binop(Iop_InterleaveEvenLanes32x4,
23128                                         mkexpr(t2), mkexpr(t2)));
23129 
23130                         n /= 2;
23131 
23132                         if (n & 1)
23133                            assign(t4,
23134                                   binop(Iop_InterleaveHI64x2,
23135                                         mkexpr(t3), mkexpr(t3)));
23136                         else
23137                            assign(t4,
23138                                   binop(Iop_InterleaveLO64x2,
23139                                         mkexpr(t3), mkexpr(t3)));
23140 
23141                         putWReg(wd, mkexpr(t4));
23142                         break;
23143                      }
23144 
23145                   case 0x20: { /* SPLATI.H */
23146                         DIP("SPLATI.H w%d, w%d[%d]", wd, ws, n);
23147                         t1 = newTemp(Ity_V128);
23148                         t2 = newTemp(Ity_V128);
23149                         t3 = newTemp(Ity_V128);
23150 
23151                         if (n & 1)
23152                            assign(t1,
23153                                   binop(Iop_InterleaveOddLanes16x8,
23154                                         getWReg(ws),
23155                                         getWReg(ws)));
23156                         else
23157                            assign(t1,
23158                                   binop(Iop_InterleaveEvenLanes16x8,
23159                                         getWReg(ws),
23160                                         getWReg(ws)));
23161 
23162                         n /= 2;
23163 
23164                         if (n & 1)
23165                            assign(t2,
23166                                   binop(Iop_InterleaveOddLanes32x4,
23167                                         mkexpr(t1), mkexpr(t1)));
23168                         else
23169                            assign(t2,
23170                                   binop(Iop_InterleaveEvenLanes32x4,
23171                                         mkexpr(t1), mkexpr(t1)));
23172 
23173                         n /= 2;
23174 
23175                         if (n & 1)
23176                            assign(t3,
23177                                   binop(Iop_InterleaveHI64x2,
23178                                         mkexpr(t2), mkexpr(t2)));
23179                         else
23180                            assign(t3,
23181                                   binop(Iop_InterleaveLO64x2,
23182                                         mkexpr(t2), mkexpr(t2)));
23183 
23184                         putWReg(wd, mkexpr(t3));
23185                         break;
23186                      }
23187 
23188                   case 0x30: { /* SPLATI.W */
23189                         DIP("SPLATI.W w%d, w%d[%d]", wd, ws, n);
23190                         t1 = newTemp(Ity_V128);
23191                         t2 = newTemp(Ity_V128);
23192                         t3 = newTemp(Ity_V128);
23193                         assign(t1, getWReg(ws));
23194 
23195                         if (n & 1)
23196                            assign(t2,
23197                                   binop(Iop_InterleaveOddLanes32x4,
23198                                         mkexpr(t1), mkexpr(t1)));
23199                         else
23200                            assign(t2,
23201                                   binop(Iop_InterleaveEvenLanes32x4,
23202                                         mkexpr(t1), mkexpr(t1)));
23203 
23204                         n /= 2;
23205 
23206                         if (n & 1)
23207                            assign(t3,
23208                                   binop(Iop_InterleaveHI64x2,
23209                                         mkexpr(t2), mkexpr(t2)));
23210                         else
23211                            assign(t3,
23212                                   binop(Iop_InterleaveLO64x2,
23213                                         mkexpr(t2), mkexpr(t2)));
23214 
23215                         putWReg(wd, mkexpr(t3));
23216                         break;
23217                      }
23218 
23219                   case 0x38: /* SPLATI.D */
23220                      DIP("SPLATI.D w%d, w%d[%d]", wd, ws, n);
23221                      t1 = newTemp(Ity_V128);
23222                      t3 = newTemp(Ity_V128);
23223                      assign(t1, getWReg(ws));
23224 
23225                      if (n)
23226                         assign(t3,
23227                                binop(Iop_InterleaveHI64x2,
23228                                      mkexpr(t1), mkexpr(t1)));
23229                      else
23230                         assign(t3,
23231                                binop(Iop_InterleaveLO64x2,
23232                                      mkexpr(t1), mkexpr(t1)));
23233 
23234                      putWReg(wd, mkexpr(t3));
23235                      break;
23236 
23237                   default:
23238                      return -1;
23239                }
23240 
23241                break;
23242 
23243             case 0x02: /* COPY_S.df */
23244                switch (df) {
23245                   case 0x00: /* COPY_S.B */
23246                      DIP("COPY_S.B r%d, w%d[%d]", wd, ws, n);
23247                      t1 = newTemp(Ity_I8);
23248 
23249                      switch (n) {
23250                         case 0:
23251                            assign(t1,
23252                                   unop(Iop_32to8,
23253                                        unop(Iop_V128to32,
23254                                             getWReg(ws))));
23255                            break;
23256 
23257                         case 1:
23258                            assign(t1,
23259                                   unop(Iop_16HIto8,
23260                                        unop(Iop_32to16,
23261                                             unop(Iop_V128to32,
23262                                                  getWReg(ws)))));
23263                            break;
23264 
23265                         case 2:
23266                            assign(t1,
23267                                   unop(Iop_16to8,
23268                                        unop(Iop_32HIto16,
23269                                             unop(Iop_64to32,
23270                                                  unop(Iop_V128to64,
23271                                                       getWReg(ws))))));
23272                            break;
23273 
23274                         case 3:
23275                            assign(t1,
23276                                   unop(Iop_16HIto8,
23277                                        unop(Iop_32HIto16,
23278                                             unop(Iop_64to32,
23279                                                  unop(Iop_V128to64,
23280                                                       getWReg(ws))))));
23281                            break;
23282 
23283                         case 4:
23284                            assign(t1,
23285                                   unop(Iop_16to8,
23286                                        unop(Iop_32to16,
23287                                             unop(Iop_64HIto32,
23288                                                  unop(Iop_V128to64,
23289                                                       getWReg(ws))))));
23290                            break;
23291 
23292                         case 5:
23293                            assign(t1,
23294                                   unop(Iop_16HIto8,
23295                                        unop(Iop_32to16,
23296                                             unop(Iop_64HIto32,
23297                                                  unop(Iop_V128to64,
23298                                                       getWReg(ws))))));
23299                            break;
23300 
23301                         case 6:
23302                            assign(t1,
23303                                   unop(Iop_16to8,
23304                                        unop(Iop_32HIto16,
23305                                             unop(Iop_64HIto32,
23306                                                  unop(Iop_V128to64,
23307                                                       getWReg(ws))))));
23308                            break;
23309 
23310                         case 7:
23311                            assign(t1,
23312                                   unop(Iop_16HIto8,
23313                                        unop(Iop_32HIto16,
23314                                             unop(Iop_64HIto32,
23315                                                  unop(Iop_V128to64,
23316                                                       getWReg(ws))))));
23317                            break;
23318 
23319                         case 8:
23320                            assign(t1,
23321                                   unop(Iop_16to8,
23322                                        unop(Iop_32to16,
23323                                             unop(Iop_64to32,
23324                                                  unop(Iop_V128HIto64,
23325                                                       getWReg(ws))))));
23326                            break;
23327 
23328                         case 9:
23329                            assign(t1,
23330                                   unop(Iop_16HIto8,
23331                                        unop(Iop_32to16,
23332                                             unop(Iop_64to32,
23333                                                  unop(Iop_V128HIto64,
23334                                                       getWReg(ws))))));
23335                            break;
23336 
23337                         case 10:
23338                            assign(t1,
23339                                   unop(Iop_16to8,
23340                                        unop(Iop_32HIto16,
23341                                             unop(Iop_64to32,
23342                                                  unop(Iop_V128HIto64,
23343                                                       getWReg(ws))))));
23344                            break;
23345 
23346                         case 11:
23347                            assign(t1,
23348                                   unop(Iop_16HIto8,
23349                                        unop(Iop_32HIto16,
23350                                             unop(Iop_64to32,
23351                                                  unop(Iop_V128HIto64,
23352                                                       getWReg(ws))))));
23353                            break;
23354 
23355                         case 12:
23356                            assign(t1,
23357                                   unop(Iop_16to8,
23358                                        unop(Iop_32to16,
23359                                             unop(Iop_64HIto32,
23360                                                  unop(Iop_V128HIto64,
23361                                                       getWReg(ws))))));
23362                            break;
23363 
23364                         case 13:
23365                            assign(t1,
23366                                   unop(Iop_16HIto8,
23367                                        unop(Iop_32to16,
23368                                             unop(Iop_64HIto32,
23369                                                  unop(Iop_V128HIto64,
23370                                                       getWReg(ws))))));
23371                            break;
23372 
23373                         case 14:
23374                            assign(t1,
23375                                   unop(Iop_16to8,
23376                                        unop(Iop_32HIto16,
23377                                             unop(Iop_64HIto32,
23378                                                  unop(Iop_V128HIto64,
23379                                                       getWReg(ws))))));
23380                            break;
23381 
23382                         case 15:
23383                            assign(t1,
23384                                   unop(Iop_16HIto8,
23385                                        unop(Iop_32HIto16,
23386                                             unop(Iop_64HIto32,
23387                                                  unop(Iop_V128HIto64,
23388                                                       getWReg(ws))))));
23389                            break;
23390                      }
23391 
23392                      putIReg(wd,
23393                              unop(mode64 ? Iop_8Sto64 : Iop_8Sto32,
23394                                   mkexpr(t1)));
23395                      break;
23396 
23397                   case 0x20: /* COPY_S.H */
23398                      DIP("COPY_S.H r%d, w%d[%d]", wd, ws, n);
23399                      t1 = newTemp(Ity_I16);
23400 
23401                      switch (n) {
23402                         case 0:
23403                            assign(t1,
23404                                   unop(Iop_32to16,
23405                                        unop(Iop_64to32,
23406                                             unop(Iop_V128to64,
23407                                                  getWReg(ws)))));
23408                            break;
23409 
23410                         case 1:
23411                            assign(t1,
23412                                   unop(Iop_32HIto16,
23413                                        unop(Iop_64to32,
23414                                             unop(Iop_V128to64,
23415                                                  getWReg(ws)))));
23416                            break;
23417 
23418                         case 2:
23419                            assign(t1,
23420                                   unop(Iop_32to16,
23421                                        unop(Iop_64HIto32,
23422                                             unop(Iop_V128to64,
23423                                                  getWReg(ws)))));
23424                            break;
23425 
23426                         case 3:
23427                            assign(t1,
23428                                   unop(Iop_32HIto16,
23429                                        unop(Iop_64HIto32,
23430                                             unop(Iop_V128to64,
23431                                                  getWReg(ws)))));
23432                            break;
23433 
23434                         case 4:
23435                            assign(t1,
23436                                   unop(Iop_32to16,
23437                                        unop(Iop_64to32,
23438                                             unop(Iop_V128HIto64,
23439                                                  getWReg(ws)))));
23440                            break;
23441 
23442                         case 5:
23443                            assign(t1,
23444                                   unop(Iop_32HIto16,
23445                                        unop(Iop_64to32,
23446                                             unop(Iop_V128HIto64,
23447                                                  getWReg(ws)))));
23448                            break;
23449 
23450                         case 6:
23451                            assign(t1,
23452                                   unop(Iop_32to16,
23453                                        unop(Iop_64HIto32,
23454                                             unop(Iop_V128HIto64,
23455                                                  getWReg(ws)))));
23456                            break;
23457 
23458                         case 7:
23459                            assign(t1,
23460                                   unop(Iop_32HIto16,
23461                                        unop(Iop_64HIto32,
23462                                             unop(Iop_V128HIto64,
23463                                                  getWReg(ws)))));
23464                            break;
23465                      }
23466 
23467                      putIReg(wd,
23468                              unop(mode64 ? Iop_16Sto64 : Iop_16Sto32,
23469                                   mkexpr(t1)));
23470                      break;
23471 
23472                   case 0x30: /* COPY_S.W */
23473                      DIP("COPY_S.W r%d, w%d[%d]", wd, ws, n);
23474 
23475                      switch (n) {
23476                         case 0:
23477                            putIReg(wd,
23478                                    mkWidenFrom32(ty,
23479                                                  unop(Iop_V128to32,
23480                                                       getWReg(ws)),
23481                                                  True));
23482                            break;
23483 
23484                         case 1:
23485                            t2 = newTemp(Ity_I64);
23486                            assign(t2,
23487                                   unop(Iop_V128to64, getWReg(ws)));
23488                            putIReg(wd,
23489                                    mkWidenFrom32(ty,
23490                                                  unop(Iop_64HIto32,
23491                                                       mkexpr(t2)),
23492                                                  True));
23493                            break;
23494 
23495                         case 2:
23496                            t2 = newTemp(Ity_I64);
23497                            assign(t2,
23498                                   unop(Iop_V128HIto64,
23499                                        getWReg(ws)));
23500                            putIReg(wd,
23501                                    mkWidenFrom32(ty,
23502                                                  unop(Iop_64to32,
23503                                                       mkexpr(t2)),
23504                                                  True));
23505                            break;
23506 
23507                         case 3:
23508                            t2 = newTemp(Ity_I64);
23509                            assign(t2,
23510                                   unop(Iop_V128HIto64,
23511                                        getWReg(ws)));
23512                            putIReg(wd,
23513                                    mkWidenFrom32(ty,
23514                                                  unop(Iop_64HIto32,
23515                                                       mkexpr(t2)),
23516                                                  True));
23517                            break;
23518 
23519                         default:
23520                            break;
23521                      }
23522 
23523                      break;
23524 
23525                   case 0x38: /* COPY_S.D */
23526                      if (mode64) {
23527                         DIP("COPY_S.D r%d, w%d[%d]", wd, ws, n);
23528 
23529                         switch (n) {
23530                            case 0:
23531                               putIReg(wd,
23532                                       unop(Iop_V128to64,
23533                                            getWReg(ws)));
23534                               break;
23535 
23536                            case 1:
23537                               putIReg(wd,
23538                                       unop(Iop_V128HIto64,
23539                                            getWReg(ws)));
23540                               break;
23541                         }
23542                      } else {
23543                         return -2;
23544                      }
23545 
23546                      break;
23547 
23548                   default:
23549                      return -1;
23550                }
23551 
23552                break;
23553 
23554             case 0x03: { /* COPY_U.df */
23555                   switch (df) {
23556                      case 0x00: /* COPY_U.B */
23557                         DIP("COPY_U.B r%d, w%d[%d]", wd, ws, n);
23558                         t1 = newTemp(Ity_I8);
23559 
23560                         switch (n) {
23561                            case 0:
23562                               assign(t1,
23563                                      unop(Iop_16to8,
23564                                           unop(Iop_32to16,
23565                                                unop(Iop_64to32,
23566                                                     unop(Iop_V128to64,
23567                                                          getWReg(ws))))));
23568                               break;
23569 
23570                            case 1:
23571                               assign(t1,
23572                                      unop(Iop_16HIto8,
23573                                           unop(Iop_32to16,
23574                                                unop(Iop_64to32,
23575                                                     unop(Iop_V128to64,
23576                                                          getWReg(ws))))));
23577                               break;
23578 
23579                            case 2:
23580                               assign(t1,
23581                                      unop(Iop_16to8,
23582                                           unop(Iop_32HIto16,
23583                                                unop(Iop_64to32,
23584                                                     unop(Iop_V128to64,
23585                                                          getWReg(ws))))));
23586                               break;
23587 
23588                            case 3:
23589                               assign(t1,
23590                                      unop(Iop_16HIto8,
23591                                           unop(Iop_32HIto16,
23592                                                unop(Iop_64to32,
23593                                                     unop(Iop_V128to64,
23594                                                          getWReg(ws))))));
23595                               break;
23596 
23597                            case 4:
23598                               assign(t1,
23599                                      unop(Iop_16to8,
23600                                           unop(Iop_32to16,
23601                                                unop(Iop_64HIto32,
23602                                                     unop(Iop_V128to64,
23603                                                          getWReg(ws))))));
23604                               break;
23605 
23606                            case 5:
23607                               assign(t1,
23608                                      unop(Iop_16HIto8,
23609                                           unop(Iop_32to16,
23610                                                unop(Iop_64HIto32,
23611                                                     unop(Iop_V128to64,
23612                                                          getWReg(ws))))));
23613                               break;
23614 
23615                            case 6:
23616                               assign(t1,
23617                                      unop(Iop_16to8,
23618                                           unop(Iop_32HIto16,
23619                                                unop(Iop_64HIto32,
23620                                                     unop(Iop_V128to64,
23621                                                          getWReg(ws))))));
23622                               break;
23623 
23624                            case 7:
23625                               assign(t1,
23626                                      unop(Iop_16HIto8,
23627                                           unop(Iop_32HIto16,
23628                                                unop(Iop_64HIto32,
23629                                                     unop(Iop_V128to64,
23630                                                          getWReg(ws))))));
23631                               break;
23632 
23633                            case 8:
23634                               assign(t1,
23635                                      unop(Iop_16to8,
23636                                           unop(Iop_32to16,
23637                                                unop(Iop_64to32,
23638                                                     unop(Iop_V128HIto64,
23639                                                          getWReg(ws))))));
23640                               break;
23641 
23642                            case 9:
23643                               assign(t1,
23644                                      unop(Iop_16HIto8,
23645                                           unop(Iop_32to16,
23646                                                unop(Iop_64to32,
23647                                                     unop(Iop_V128HIto64,
23648                                                          getWReg(ws))))));
23649                               break;
23650 
23651                            case 10:
23652                               assign(t1,
23653                                      unop(Iop_16to8,
23654                                           unop(Iop_32HIto16,
23655                                                unop(Iop_64to32,
23656                                                     unop(Iop_V128HIto64,
23657                                                          getWReg(ws))))));
23658                               break;
23659 
23660                            case 11:
23661                               assign(t1,
23662                                      unop(Iop_16HIto8,
23663                                           unop(Iop_32HIto16,
23664                                                unop(Iop_64to32,
23665                                                     unop(Iop_V128HIto64,
23666                                                          getWReg(ws))))));
23667                               break;
23668 
23669                            case 12:
23670                               assign(t1,
23671                                      unop(Iop_16to8,
23672                                           unop(Iop_32to16,
23673                                                unop(Iop_64HIto32,
23674                                                     unop(Iop_V128HIto64,
23675                                                          getWReg(ws))))));
23676                               break;
23677 
23678                            case 13:
23679                               assign(t1,
23680                                      unop(Iop_16HIto8,
23681                                           unop(Iop_32to16,
23682                                                unop(Iop_64HIto32,
23683                                                     unop(Iop_V128HIto64,
23684                                                          getWReg(ws))))));
23685                               break;
23686 
23687                            case 14:
23688                               assign(t1,
23689                                      unop(Iop_16to8,
23690                                           unop(Iop_32HIto16,
23691                                                unop(Iop_64HIto32,
23692                                                     unop(Iop_V128HIto64,
23693                                                          getWReg(ws))))));
23694                               break;
23695 
23696                            case 15:
23697                               assign(t1,
23698                                      unop(Iop_16HIto8,
23699                                           unop(Iop_32HIto16,
23700                                                unop(Iop_64HIto32,
23701                                                     unop(Iop_V128HIto64,
23702                                                          getWReg(ws))))));
23703                               break;
23704                         }
23705 
23706                         putIReg(wd,
23707                                 unop(mode64 ? Iop_8Uto64 : Iop_8Uto32,
23708                                      mkexpr(t1)));
23709                         break;
23710 
23711                      case 0x20: /* COPY_U.H */
23712                         DIP("COPY_U.H r%d, w%d[%d]", wd, ws, n);
23713                         t1 = newTemp(Ity_I16);
23714 
23715                         switch (n) {
23716                            case 0:
23717                               assign(t1,
23718                                      unop(Iop_32to16,
23719                                           unop(Iop_64to32,
23720                                                unop(Iop_V128to64,
23721                                                     getWReg(ws)))));
23722                               break;
23723 
23724                            case 1:
23725                               assign(t1,
23726                                      unop(Iop_32HIto16,
23727                                           unop(Iop_64to32,
23728                                                unop(Iop_V128to64,
23729                                                     getWReg(ws)))));
23730                               break;
23731 
23732                            case 2:
23733                               assign(t1,
23734                                      unop(Iop_32to16,
23735                                           unop(Iop_64HIto32,
23736                                                unop(Iop_V128to64,
23737                                                     getWReg(ws)))));
23738                               break;
23739 
23740                            case 3:
23741                               assign(t1,
23742                                      unop(Iop_32HIto16,
23743                                           unop(Iop_64HIto32,
23744                                                unop(Iop_V128to64,
23745                                                     getWReg(ws)))));
23746                               break;
23747 
23748                            case 4:
23749                               assign(t1,
23750                                      unop(Iop_32to16,
23751                                           unop(Iop_64to32,
23752                                                unop(Iop_V128HIto64,
23753                                                     getWReg(ws)))));
23754                               break;
23755 
23756                            case 5:
23757                               assign(t1,
23758                                      unop(Iop_32HIto16,
23759                                           unop(Iop_64to32,
23760                                                unop(Iop_V128HIto64,
23761                                                     getWReg(ws)))));
23762                               break;
23763 
23764                            case 6:
23765                               assign(t1,
23766                                      unop(Iop_32to16,
23767                                           unop(Iop_64HIto32,
23768                                                unop(Iop_V128HIto64,
23769                                                     getWReg(ws)))));
23770                               break;
23771 
23772                            case 7:
23773                               assign(t1,
23774                                      unop(Iop_32HIto16,
23775                                           unop(Iop_64HIto32,
23776                                                unop(Iop_V128HIto64,
23777                                                     getWReg(ws)))));
23778                               break;
23779                         }
23780 
23781                         putIReg(wd,
23782                                 unop(mode64 ? Iop_16Uto64 : Iop_16Uto32,
23783                                      mkexpr(t1)));
23784                         break;
23785 
23786                      case 0x30: /* COPY_U.W */
23787                         DIP("COPY_U.W r%d, w%d[%d]", wd, ws, n);
23788 
23789                         switch (n) {
23790                            case 0:
23791                               putIReg(wd,
23792                                       mkWidenFrom32(ty,
23793                                                     unop(Iop_V128to32,
23794                                                          getWReg(ws)),
23795                                                     False));
23796                               break;
23797 
23798                            case 1:
23799                               t2 = newTemp(Ity_I64);
23800                               assign(t2,
23801                                      unop(Iop_V128to64,
23802                                           getWReg(ws)));
23803                               putIReg(wd,
23804                                       mkWidenFrom32(ty,
23805                                                     unop(Iop_64HIto32,
23806                                                          mkexpr(t2)),
23807                                                     False));
23808                               break;
23809 
23810                            case 2:
23811                               t2 = newTemp(Ity_I64);
23812                               assign(t2,
23813                                      unop(Iop_V128HIto64,
23814                                           getWReg(ws)));
23815                               putIReg(wd,
23816                                       mkWidenFrom32(ty,
23817                                                     unop(Iop_64to32,
23818                                                          mkexpr(t2)),
23819                                                     False));
23820                               break;
23821 
23822                            case 3:
23823                               t2 = newTemp(Ity_I64);
23824                               assign(t2,
23825                                      unop(Iop_V128HIto64,
23826                                           getWReg(ws)));
23827                               putIReg(wd,
23828                                       mkWidenFrom32(ty,
23829                                                     unop(Iop_64HIto32,
23830                                                          mkexpr(t2)),
23831                                                     False));
23832                               break;
23833 
23834                            default:
23835                               break;
23836                         }
23837 
23838                         break;
23839 
23840                      default:
23841                         return -1;
23842                   }
23843 
23844                   break;
23845                }
23846 
23847             case 0x04: { /* INSERT.df */
23848                   t5 = newTemp(Ity_I64);
23849                   UInt hi = 1;
23850                   ULong mask;
23851                   IRTemp *src, *dst;
23852                   assign(t5, mode64 ? getIReg(ws) :
23853                          unop(Iop_32Uto64, getIReg(ws)));
23854 
23855                   if (df == 0x38) { /* INSERT.D */
23856                      if (mode64) {
23857                         DIP("INSERT.D w%d[%d], r%d", wd, n, ws);
23858 
23859                         if (n == 0) {
23860                            putWReg(wd,
23861                                    binop(Iop_64HLtoV128,
23862                                          unop(Iop_V128HIto64,
23863                                               getWReg(wd)),
23864                                          mkexpr(t5)));
23865                         } else {
23866                            putWReg(wd,
23867                                    binop(Iop_64HLtoV128,
23868                                          mkexpr(t5),
23869                                          unop(Iop_V128to64,
23870                                               getWReg(wd))));
23871                         }
23872 
23873                         break;
23874                      } else {
23875                         return -2;
23876                      }
23877                   } else {
23878                      t1 = newTemp(Ity_I64);
23879                      t2 = newTemp(Ity_I64);
23880                      assign(t1, unop(Iop_V128to64, getWReg(wd)));
23881                      assign(t2, unop(Iop_V128HIto64, getWReg(wd)));
23882                   }
23883 
23884                   switch (df) {
23885                      case 0x00: /* INSERT.B */
23886                         DIP("INSERT.B w%d[%d], r%d", wd, n, ws);
23887 
23888                         if (n >= 8) {
23889                            n -= 8;
23890                         } else {
23891                            hi = 0;
23892                         }
23893 
23894                         n <<= 3;
23895                         mask = 0xFFull;
23896                         break;
23897 
23898                      case 0x20: /* INSERT.H */
23899                         DIP("INSERT.H w%d[%d], r%d", wd, n, ws);
23900 
23901                         if (n >= 4) {
23902                            n -= 4;
23903                         } else {
23904                            hi = 0;
23905                         }
23906 
23907                         n <<= 4;
23908                         mask = 0xFFFFull;
23909                         break;
23910 
23911                      case 0x30: /* INSERT.W */
23912                         DIP("INSERT.W w%d[%d], r%d", wd, n, ws);
23913 
23914                         if (n >= 2) {
23915                            n -= 2;
23916                         } else {
23917                            hi = 0;
23918                         }
23919 
23920                         n <<= 5;
23921                         mask = 0xFFFFFFFFull;
23922                         break;
23923 
23924                      default:
23925                         return -1;
23926                   }
23927 
23928                   if (hi) {
23929                      t4 = newTemp(Ity_I64);
23930                      src = &t2;
23931                      dst = &t4;
23932                      t3 = t1;
23933                   } else {
23934                      t3 = newTemp(Ity_I64);
23935                      src = &t1;
23936                      dst = &t3;
23937                      t4 = t2;
23938                   }
23939 
23940                   mask <<= n;
23941                   assign(*dst,
23942                       binop(Iop_Or64,
23943                             binop(Iop_And64, mkexpr(*src), mkU64(~mask)),
23944                             binop(Iop_And64,
23945                                   binop(Iop_Shl64, mkexpr(t5), mkU8(n)),
23946                                   mkU64(mask))));
23947                   putWReg(wd,
23948                           binop(Iop_64HLtoV128, mkexpr(t4), mkexpr(t3)));
23949                   break;
23950                }
23951 
23952             case 0x05: { /* INSVE.df */
23953                   switch (df) {
23954                      case 0x00: { /* INSVE.B */
23955                            DIP("INSVE.B w%d[%d], w%d[0]", wd, n, ws);
23956                            t1 = newTemp(Ity_V128);
23957                            t2 = newTemp(Ity_V128);
23958                            assign(t1, getWReg(wd));
23959                            assign(t2, getWReg(ws));
23960                            Int i;
23961                            IRTemp tmp[16];
23962 
23963                            for (i = 0; i < 16; i++) {
23964                               tmp[i] = newTemp(Ity_I8);
23965 
23966                               if (n == i)
23967                                  assign(tmp[i],
23968                                         binop(Iop_GetElem8x16,
23969                                               mkexpr(t2), mkU8(0x0)));
23970                               else
23971                                  assign(tmp[i],
23972                                         binop(Iop_GetElem8x16,
23973                                               mkexpr(t1), mkU8(i)));
23974                            }
23975 
23976                            putWReg(wd,
23977                              binop(Iop_64HLtoV128,
23978                                    binop(Iop_32HLto64,
23979                                          binop(Iop_16HLto32,
23980                                                binop(Iop_8HLto16,
23981                                                      mkexpr(tmp[15]),
23982                                                      mkexpr(tmp[14])),
23983                                                binop(Iop_8HLto16,
23984                                                      mkexpr(tmp[13]),
23985                                                      mkexpr(tmp[12]))),
23986                                          binop(Iop_16HLto32,
23987                                                binop(Iop_8HLto16,
23988                                                      mkexpr(tmp[11]),
23989                                                      mkexpr(tmp[10])),
23990                                                binop(Iop_8HLto16,
23991                                                      mkexpr(tmp[9]),
23992                                                      mkexpr(tmp[8])))),
23993                                    binop(Iop_32HLto64,
23994                                          binop(Iop_16HLto32,
23995                                                binop(Iop_8HLto16,
23996                                                      mkexpr(tmp[7]),
23997                                                      mkexpr(tmp[6])),
23998                                                binop(Iop_8HLto16,
23999                                                      mkexpr(tmp[5]),
24000                                                      mkexpr(tmp[4]))),
24001                                          binop(Iop_16HLto32,
24002                                                binop(Iop_8HLto16,
24003                                                      mkexpr(tmp[3]),
24004                                                      mkexpr(tmp[2])),
24005                                                binop(Iop_8HLto16,
24006                                                      mkexpr(tmp[1]),
24007                                                      mkexpr(tmp[0]))))));
24008                            break;
24009                         }
24010 
24011                      case 0x20: { /* INSVE.H */
24012                            DIP("INSVE.H w%d[%d], r%d[0]", wd, n, ws);
24013                            t1 = newTemp(Ity_V128);
24014                            t2 = newTemp(Ity_V128);
24015                            assign(t1, getWReg(wd));
24016                            assign(t2, getWReg(ws));
24017                            Int i;
24018                            IRTemp tmp[8];
24019 
24020                            for (i = 0; i < 8; i++) {
24021                               tmp[i] = newTemp(Ity_I16);
24022 
24023                               if (n == i)
24024                                  assign(tmp[i],
24025                                         binop(Iop_GetElem16x8,
24026                                               mkexpr(t2), mkU8(0x0)));
24027                               else
24028                                  assign(tmp[i],
24029                                         binop(Iop_GetElem16x8,
24030                                               mkexpr(t1), mkU8(i)));
24031                            }
24032 
24033                            putWReg(wd,
24034                                    binop(Iop_64HLtoV128,
24035                                          binop(Iop_32HLto64,
24036                                                binop(Iop_16HLto32,
24037                                                      mkexpr(tmp[7]),
24038                                                      mkexpr(tmp[6])),
24039                                                binop(Iop_16HLto32,
24040                                                      mkexpr(tmp[5]),
24041                                                      mkexpr(tmp[4]))),
24042                                          binop(Iop_32HLto64,
24043                                                binop(Iop_16HLto32,
24044                                                      mkexpr(tmp[3]),
24045                                                      mkexpr(tmp[2])),
24046                                                binop(Iop_16HLto32,
24047                                                      mkexpr(tmp[1]),
24048                                                      mkexpr(tmp[0])))));
24049                            break;
24050                         }
24051 
24052                      case 0x30: { /* INSVE.W */
24053                            DIP("INSVE.W w%d[%d], r%d[0]", wd, n, ws);
24054                            t1 = newTemp(Ity_V128);
24055                            t2 = newTemp(Ity_V128);
24056                            assign(t1, getWReg(wd));
24057                            assign(t2, getWReg(ws));
24058                            Int i;
24059                            IRTemp tmp[4];
24060 
24061                            for (i = 0; i < 4; i++) {
24062                               tmp[i] = newTemp(Ity_I32);
24063 
24064                               if (n == i)
24065                                  assign(tmp[i],
24066                                         binop(Iop_GetElem32x4,
24067                                               mkexpr(t2), mkU8(0x0)));
24068                               else
24069                                  assign(tmp[i],
24070                                         binop(Iop_GetElem32x4,
24071                                               mkexpr(t1), mkU8(i)));
24072                            }
24073 
24074                            putWReg(wd,
24075                                    binop(Iop_64HLtoV128,
24076                                          binop(Iop_32HLto64,
24077                                                mkexpr(tmp[3]),
24078                                                mkexpr(tmp[2])),
24079                                          binop(Iop_32HLto64,
24080                                                mkexpr(tmp[1]),
24081                                                mkexpr(tmp[0]))));
24082                            break;
24083                         }
24084 
24085                      case 0x38: { /* INSVE.D */
24086                            DIP("INSVE.D w%d[%d], r%d[0]", wd, n, ws);
24087                            t1 = newTemp(Ity_V128);
24088                            t2 = newTemp(Ity_V128);
24089                            assign(t1, getWReg(wd));
24090                            assign(t2, getWReg(ws));
24091                            Int i;
24092                            IRTemp tmp[2];
24093 
24094                            for (i = 0; i < 2; i++) {
24095                               tmp[i] = newTemp(Ity_I64);
24096 
24097                               if (n == i)
24098                                  assign(tmp[i],
24099                                         binop(Iop_GetElem64x2,
24100                                               mkexpr(t2), mkU8(0x0)));
24101                               else
24102                                  assign(tmp[i],
24103                                         binop(Iop_GetElem64x2,
24104                                               mkexpr(t1), mkU8(i)));
24105                            }
24106 
24107                            putWReg(wd,
24108                                    binop(Iop_64HLtoV128,
24109                                          mkexpr(tmp[1]), mkexpr(tmp[0])));
24110                            break;
24111                         }
24112                   }
24113 
24114                   break;
24115                }
24116 
24117             default:
24118                return -1;
24119       }
24120    }
24121    return 0;
24122 }
24123 
msa_VEC(UInt cins,UChar wd,UChar ws)24124 static Int msa_VEC(UInt cins, UChar wd, UChar ws) { /* VEC */
24125    IRTemp t1, t2, t3;
24126    UShort operation;
24127    UChar wt;
24128 
24129    vassert((cins & 0x03000000) == 0);
24130 
24131    operation = (cins & 0x03E00000) >> 21;
24132    wt = (cins & 0x001F0000) >> 16;
24133 
24134    switch (operation) {
24135       case 0x00: { /* AND.V */
24136             DIP("AND.V w%d, w%d, w%d", wd, ws, wt);
24137             t1 = newTemp(Ity_V128);
24138             t2 = newTemp(Ity_V128);
24139             t3 = newTemp(Ity_V128);
24140             assign(t1, getWReg(ws));
24141             assign(t2, getWReg(wt));
24142             assign(t3, binop(Iop_AndV128, mkexpr(t1), mkexpr(t2)));
24143             putWReg(wd, mkexpr(t3));
24144             break;
24145          }
24146 
24147       case 0x01: { /* OR.V */
24148             DIP("OR.V w%d, w%d, w%d", wd, ws, wt);
24149             t1 = newTemp(Ity_V128);
24150             t2 = newTemp(Ity_V128);
24151             t3 = newTemp(Ity_V128);
24152             assign(t1, getWReg(ws));
24153             assign(t2, getWReg(wt));
24154             assign(t3, binop(Iop_OrV128, mkexpr(t1), mkexpr(t2)));
24155             putWReg(wd, mkexpr(t3));
24156             break;
24157          }
24158 
24159       case 0x02: { /* NOR.V */
24160             DIP("NOR.V w%d, w%d, w%d", wd, ws, wt);
24161             t1 = newTemp(Ity_V128);
24162             t2 = newTemp(Ity_V128);
24163             t3 = newTemp(Ity_V128);
24164             assign(t1, getWReg(ws));
24165             assign(t2, getWReg(wt));
24166             assign(t3,
24167                    unop(Iop_NotV128,
24168                         binop(Iop_OrV128, mkexpr(t1), mkexpr(t2))));
24169             putWReg(wd, mkexpr(t3));
24170             break;
24171          }
24172 
24173       case 0x03: { /* XOR.V */
24174             DIP("XOR.V w%d, w%d, w%d", wd, ws, wt);
24175             t1 = newTemp(Ity_V128);
24176             t2 = newTemp(Ity_V128);
24177             t3 = newTemp(Ity_V128);
24178             assign(t1, getWReg(ws));
24179             assign(t2, getWReg(wt));
24180             assign(t3, binop(Iop_XorV128, mkexpr(t1), mkexpr(t2)));
24181             putWReg(wd, mkexpr(t3));
24182             break;
24183          }
24184 
24185       case 0x04: { /* BMNZ  (ws AND wt) OR (wd AND NOT wt) */
24186             DIP("BMNZ.V w%d, w%d, w%d", wd, ws, wt);
24187             t1 = newTemp(Ity_V128);
24188             t2 = newTemp(Ity_V128);
24189             t3 = newTemp(Ity_V128);
24190             assign(t1,
24191                    binop(Iop_AndV128,
24192                          getWReg(ws), getWReg(wt)));
24193             assign(t2,
24194                    binop(Iop_AndV128,
24195                          getWReg(wd),
24196                          unop(Iop_NotV128, getWReg(wt))));
24197             assign(t3, binop(Iop_OrV128, mkexpr(t1), mkexpr(t2)));
24198             putWReg(wd, mkexpr(t3));
24199             break;
24200          }
24201 
24202       case 0x05: { /* BMZ.V (ws AND NOT wt) OR (wd AND wt) */
24203             DIP("BMZ.V w%d, w%d, w%d", wd, ws, wt);
24204             t1 = newTemp(Ity_V128);
24205             t2 = newTemp(Ity_V128);
24206             t3 = newTemp(Ity_V128);
24207             assign(t1,
24208                    binop(Iop_AndV128,
24209                          getWReg(wd), getWReg(wt)));
24210             assign(t2,
24211                    binop(Iop_AndV128,
24212                          getWReg(ws),
24213                          unop(Iop_NotV128, getWReg(wt))));
24214             assign(t3, binop(Iop_OrV128, mkexpr(t1), mkexpr(t2)));
24215             putWReg(wd, mkexpr(t3));
24216             break;
24217          }
24218 
24219       case 0x06: { /* BSEL (ws AND NOT wd) OR (wt AND wd) */
24220             DIP("BSEL.V w%d, w%d, w%d", wd, ws, wt);
24221             t1 = newTemp(Ity_V128);
24222             t2 = newTemp(Ity_V128);
24223             t3 = newTemp(Ity_V128);
24224             assign(t1,
24225                    binop(Iop_AndV128,
24226                          getWReg(wd), getWReg(wt)));
24227             assign(t2,
24228                    binop(Iop_AndV128,
24229                          getWReg(ws),
24230                          unop(Iop_NotV128, getWReg(wd))));
24231             assign(t3, binop(Iop_OrV128, mkexpr(t1), mkexpr(t2)));
24232             putWReg(wd, mkexpr(t3));
24233             break;
24234          }
24235 
24236       default:
24237          return -1;
24238    }
24239 
24240    return 0;
24241 }
24242 
msa_2R(UInt cins,UChar wd,UChar ws)24243 static Int msa_2R(UInt cins, UChar wd, UChar ws) { /* 2R */
24244    IRTemp t1, t2, t3, t4;
24245    IRType ty;
24246    UShort operation;
24247    UChar df;
24248 
24249    vassert((cins & 0x00200000) == 0);
24250 
24251    operation = (cins & 0x03FC0000) >> 18;
24252    df = (cins & 0x00030000) >> 16;
24253    ty = mode64 ? Ity_I64 : Ity_I32;
24254 
24255    switch (operation) {
24256       case 0xC0: { /* FILL.df */
24257             t1 = newTemp(Ity_I64);
24258 
24259             switch (df) {
24260                case 0x00: /* FILL.B */
24261                   DIP("FILL.B w%d, r%d", wd, ws);
24262                   t2 = newTemp(Ity_I32);
24263                   t3 = newTemp(Ity_I16);
24264                   t4 = newTemp(Ity_I8);
24265                   assign(t4, mkNarrowTo8(ty, getIReg(ws)));
24266                   assign(t3,
24267                          binop(Iop_8HLto16, mkexpr(t4), mkexpr(t4)));
24268                   assign(t2,
24269                          binop(Iop_16HLto32, mkexpr(t3), mkexpr(t3)));
24270                   assign(t1,
24271                          binop(Iop_32HLto64, mkexpr(t2), mkexpr(t2)));
24272                   break;
24273 
24274                case 0x01: /* FILL.H */
24275                   DIP("FILL.H w%d, r%d", wd, ws);
24276                   t2 = newTemp(Ity_I32);
24277                   t3 = newTemp(Ity_I16);
24278                   assign(t3, mkNarrowTo16(ty, getIReg(ws)));
24279                   assign(t2,
24280                          binop(Iop_16HLto32, mkexpr(t3), mkexpr(t3)));
24281                   assign(t1,
24282                          binop(Iop_32HLto64, mkexpr(t2), mkexpr(t2)));
24283                   break;
24284 
24285                case 0x02: /* FILL.W */
24286                   DIP("FILL.W w%d, r%d", wd, ws);
24287                   t2 = newTemp(Ity_I32);
24288                   assign(t2, mkNarrowTo32(ty, getIReg(ws)));
24289                   assign(t1,
24290                          binop(Iop_32HLto64, mkexpr(t2), mkexpr(t2)));
24291                   break;
24292 
24293                case 0x03: /* FILL.D */
24294                   if (mode64) {
24295                      DIP("FILL.W w%d, r%d", wd, ws);
24296                      t2 = newTemp(Ity_I32);
24297                      assign(t1, getIReg(ws));
24298                   } else {
24299                      return -2;
24300                   }
24301 
24302                   break;
24303 
24304                default:
24305                   return -1;
24306             }
24307 
24308             putWReg(wd,
24309                     binop(Iop_64HLtoV128, mkexpr(t1), mkexpr(t1)));
24310             break;
24311          }
24312 
24313       case 0xC1: { /* PCNT.df */
24314             switch (df) {
24315                case 0x00: /* PCNT.B */
24316                   DIP("PCNT.B w%d, r%d", wd, ws);
24317                   putWReg(wd,
24318                           unop(Iop_Cnt8x16, getWReg(ws)));
24319                   break;
24320 
24321                case 0x01: /* PCNT.H */
24322                   DIP("PCNT.H w%d, r%d", wd, ws);
24323                   t1 = newTemp(Ity_V128);
24324                   t2 = newTemp(Ity_V128);
24325                   assign(t1, unop(Iop_Cnt8x16, getWReg(ws)));
24326                   assign(t2,
24327                       binop(Iop_Add16x8,
24328                          binop(Iop_AndV128,
24329                                mkexpr(t1),
24330                                binop(Iop_64HLtoV128,
24331                                      mkU64(0x00FF00FF00FF00FFULL),
24332                                      mkU64(0x00FF00FF00FF00FFULL))),
24333                          binop(Iop_AndV128,
24334                                binop(Iop_ShrN16x8,
24335                                      mkexpr(t1), mkU8(8)),
24336                                binop(Iop_64HLtoV128,
24337                                      mkU64(0x00FF00FF00FF00FFULL),
24338                                      mkU64(0x00FF00FF00FF00FFULL)))));
24339                   putWReg(wd, mkexpr(t2));
24340                   break;
24341 
24342                case 0x02: /* PCNT.W */
24343                   DIP("PCNT.W w%d, r%d", wd, ws);
24344                   t1 = newTemp(Ity_V128);
24345                   t2 = newTemp(Ity_V128);
24346                   t3 = newTemp(Ity_V128);
24347                   assign(t1, unop(Iop_Cnt8x16, getWReg(ws)));
24348                   assign(t2,
24349                       binop(Iop_Add32x4,
24350                          binop(Iop_AndV128,
24351                                mkexpr(t1),
24352                                binop(Iop_64HLtoV128,
24353                                      mkU64(0x00FF00FF00FF00FFULL),
24354                                      mkU64(0x00FF00FF00FF00FFULL))),
24355                          binop(Iop_AndV128,
24356                                binop(Iop_ShrN32x4,
24357                                      mkexpr(t1), mkU8(8)),
24358                                binop(Iop_64HLtoV128,
24359                                      mkU64(0x00FF00FF00FF00FFULL),
24360                                      mkU64(0x00FF00FF00FF00FFULL)))));
24361                   assign(t3,
24362                       binop(Iop_Add32x4,
24363                          binop(Iop_AndV128,
24364                                mkexpr(t2),
24365                                binop(Iop_64HLtoV128,
24366                                      mkU64(0x0000FFFF0000FFFFULL),
24367                                      mkU64(0x0000FFFF0000FFFFULL))),
24368                          binop(Iop_AndV128,
24369                                binop(Iop_ShrN32x4,
24370                                      mkexpr(t2), mkU8(16)),
24371                                binop(Iop_64HLtoV128,
24372                                      mkU64(0x0000FFFF0000FFFFULL),
24373                                      mkU64(0x0000FFFF0000FFFFULL)))));
24374                   putWReg(wd, mkexpr(t3));
24375                   break;
24376 
24377                case 0x03: /* PCNT.D */
24378                   DIP("PCNT.D w%d, r%d", wd, ws);
24379                   t1 = newTemp(Ity_V128);
24380                   t2 = newTemp(Ity_V128);
24381                   t3 = newTemp(Ity_V128);
24382                   t4 = newTemp(Ity_V128);;
24383                   assign(t1, unop(Iop_Cnt8x16, getWReg(ws)));
24384                   assign(t2,
24385                       binop(Iop_Add64x2,
24386                          binop(Iop_AndV128,
24387                                mkexpr(t1),
24388                                binop(Iop_64HLtoV128,
24389                                      mkU64(0x00FF00FF00FF00FFULL),
24390                                      mkU64(0x00FF00FF00FF00FFULL))),
24391                          binop(Iop_AndV128,
24392                                binop(Iop_ShrN64x2,
24393                                      mkexpr(t1), mkU8(8)),
24394                                binop(Iop_64HLtoV128,
24395                                      mkU64(0x00FF00FF00FF00FFULL),
24396                                      mkU64(0x00FF00FF00FF00FFULL)))));
24397                   assign(t3,
24398                       binop(Iop_Add64x2,
24399                          binop(Iop_AndV128,
24400                                mkexpr(t2),
24401                                binop(Iop_64HLtoV128,
24402                                      mkU64(0x0000FFFF0000FFFFULL),
24403                                      mkU64(0x0000FFFF0000FFFFULL))),
24404                          binop(Iop_AndV128,
24405                                binop(Iop_ShrN64x2,
24406                                      mkexpr(t2), mkU8(16)),
24407                                binop(Iop_64HLtoV128,
24408                                      mkU64(0x0000FFFF0000FFFFULL),
24409                                      mkU64(0x0000FFFF0000FFFFULL)))));
24410                   assign(t4,
24411                       binop(Iop_Add64x2,
24412                          binop(Iop_AndV128,
24413                                mkexpr(t3),
24414                                binop(Iop_64HLtoV128,
24415                                      mkU64(0x00000000FFFFFFFFULL),
24416                                      mkU64(0x00000000FFFFFFFFULL))),
24417                          binop(Iop_AndV128,
24418                                binop(Iop_ShrN64x2,
24419                                      mkexpr(t3), mkU8(32)),
24420                                binop(Iop_64HLtoV128,
24421                                      mkU64(0x00000000FFFFFFFFULL),
24422                                      mkU64(0x00000000FFFFFFFFULL)))));
24423                   putWReg(wd, mkexpr(t4));
24424                   break;
24425 
24426                default:
24427                   return -1;
24428             }
24429 
24430             break;
24431          }
24432 
24433       case 0xC2: { /* NLOC.df */
24434             switch (df) {
24435                case 0x00: /* NLOC.B */
24436                   DIP("NLOC.B w%d, w%d", wd, ws);
24437                   putWReg(wd,
24438                           unop(Iop_Cls8x16, getWReg(ws)));
24439                   break;
24440 
24441                case 0x01: /* NLOC.H */
24442                   DIP("NLOC.H w%d, w%d", wd, ws);
24443                   putWReg(wd,
24444                           unop(Iop_Cls16x8, getWReg(ws)));
24445                   break;
24446 
24447                case 0x02: /* NLOC.W */
24448                   DIP("NLOC.W w%d, w%d", wd, ws);
24449                   putWReg(wd,
24450                           unop(Iop_Cls32x4, getWReg(ws)));
24451                   break;
24452 
24453                case 0x03: /* NLOC.D */
24454                   DIP("NLOC.D w%d, w%d", wd, ws);
24455                   t1 = newTemp(Ity_V128);
24456                   assign(t1, unop(Iop_NotV128, getWReg(ws)));
24457                   putWReg(wd, unop(Iop_Clz64x2, mkexpr(t1)));
24458                   break;
24459 
24460                default:
24461                   return -1;
24462             }
24463 
24464             break;
24465          }
24466 
24467       case 0xC3: { /* NLZC.df */
24468             switch (df) {
24469                case 0x00: /* NLZC.B */
24470                   DIP("NLZC.W w%d, w%d", wd, ws);
24471                   putWReg(wd,
24472                           unop(Iop_Clz8x16, getWReg(ws)));
24473                   break;
24474 
24475                case 0x01: /* NLZC.H */
24476                   DIP("NLZC.H w%d, w%d", wd, ws);
24477                   putWReg(wd,
24478                           unop(Iop_Clz16x8, getWReg(ws)));
24479                   break;
24480 
24481                case 0x02: /* NLZC.W */
24482                   DIP("NLZC.W w%d, w%d", wd, ws);
24483                   putWReg(wd,
24484                           unop(Iop_Clz32x4, getWReg(ws)));
24485                   break;
24486 
24487                case 0x03: {/* NLZC.D */
24488                      putWReg(wd,
24489                              unop(Iop_Clz64x2, getWReg(ws)));
24490                      break;
24491                   }
24492 
24493                default:
24494                   return -1;
24495             }
24496 
24497             break;
24498          }
24499 
24500       default:
24501          return -1;
24502    }
24503 
24504    return 0;
24505 }
24506 
msa_2RF(UInt cins,UChar wd,UChar ws)24507 static Int msa_2RF(UInt cins, UChar wd, UChar ws) { /* 2RF */
24508    IRTemp t1, t2, t3, t4, t5;
24509    UShort operation;
24510    UChar df, wt;
24511 
24512    operation = (cins & 0x03FE0000) >> 17;
24513    df = (cins & 0x00010000) >> 16;
24514    wt = (cins & 0x001F0000) >> 16;
24515 
24516    switch (operation) {
24517 
24518       case 0x190: { /* FCLASS.df */
24519             IRTemp t0 = newTemp(Ity_V128);
24520             t1 = newTemp(Ity_V128);
24521             t2 = newTemp(Ity_V128);
24522             t3 = newTemp(Ity_V128);
24523             t4 = newTemp(Ity_V128);
24524             t5 = newTemp(Ity_V128);
24525 
24526             switch (df) {
24527                case 0x00: { /* FCLASS.W */
24528                      DIP("FCLASS.W w%d, w%d", wd, ws);
24529                      assign(t0,
24530                          binop(Iop_CmpEQ32x4,
24531                             binop(Iop_AndV128,
24532                                   getWReg(ws),
24533                                   binop(Iop_64HLtoV128,
24534                                         mkU64(0x7F8000007F800000ull),
24535                                         mkU64(0x7F8000007F800000ull))),
24536                             binop(Iop_64HLtoV128,
24537                                   mkU64(0ull), mkU64(0ull))));
24538                      assign(t1,
24539                          binop(Iop_CmpEQ32x4,
24540                             binop(Iop_AndV128,
24541                                   getWReg(ws),
24542                                   binop(Iop_64HLtoV128,
24543                                         mkU64(0x7F8000007F800000ull),
24544                                         mkU64(0x7F8000007F800000ull))),
24545                             binop(Iop_64HLtoV128,
24546                                   mkU64(0x7F8000007F800000ull),
24547                                   mkU64(0x7F8000007F800000ull))));
24548                      assign(t2,
24549                             binop(Iop_SarN32x4,
24550                                   getWReg(ws), mkU8(31)));
24551                      assign(t3,
24552                          binop(Iop_CmpEQ32x4,
24553                             binop(Iop_AndV128,
24554                                   getWReg(ws),
24555                                   binop(Iop_64HLtoV128,
24556                                         mkU64(0x0040000000400000ull),
24557                                         mkU64(0x0040000000400000ull))),
24558                             binop(Iop_64HLtoV128,
24559                                   mkU64(0x0040000000400000ull),
24560                                   mkU64(0x0040000000400000ull))));
24561                      assign(t4,
24562                          binop(Iop_CmpEQ32x4,
24563                             binop(Iop_AndV128,
24564                                   getWReg(ws),
24565                                   binop(Iop_64HLtoV128,
24566                                         mkU64(0x007FFFFF007FFFFFULL),
24567                                         mkU64(0x007FFFFF007FFFFFULL))),
24568                             binop(Iop_64HLtoV128,
24569                                   mkU64(0ull), mkU64(0ull))));
24570                      assign(t5,
24571                          binop(Iop_Shl32x4,
24572                             binop(Iop_OrV128,
24573                                binop(Iop_AndV128,
24574                                   mkexpr(t1),
24575                                   binop(Iop_AndV128,
24576                                         mkexpr(t4),
24577                                         binop(Iop_64HLtoV128,
24578                                            mkU64(0x100000001ull),
24579                                            mkU64(0x100000001ull)))),
24580                                binop(Iop_OrV128,
24581                                   binop(Iop_AndV128,
24582                                      mkexpr(t0),
24583                                      binop(Iop_OrV128,
24584                                         binop(Iop_AndV128,
24585                                            mkexpr(t4),
24586                                            binop(Iop_64HLtoV128,
24587                                               mkU64(0x800000008ull),
24588                                               mkU64(0x800000008ull))),
24589                                         binop(Iop_AndV128,
24590                                            unop(Iop_NotV128,
24591                                               mkexpr(t4)),
24592                                            binop(Iop_64HLtoV128,
24593                                               mkU64(0x400000004ull),
24594                                               mkU64(0x400000004ull))))),
24595                                   binop(Iop_AndV128,
24596                                      unop(Iop_NotV128,
24597                                           mkexpr(t1)),
24598                                      binop(Iop_AndV128,
24599                                         unop(Iop_NotV128,
24600                                            mkexpr(t0)),
24601                                         binop(Iop_64HLtoV128,
24602                                            mkU64(0x200000002ull),
24603                                            mkU64(0x200000002ull)))))),
24604                          binop(Iop_OrV128,
24605                                binop(Iop_AndV128,
24606                                      mkexpr(t2),
24607                                      binop(Iop_64HLtoV128,
24608                                            mkU64(0x200000002ull),
24609                                            mkU64(0x200000002ull))),
24610                                binop(Iop_AndV128,
24611                                      unop(Iop_NotV128,
24612                                           mkexpr(t2)),
24613                                      binop(Iop_64HLtoV128,
24614                                            mkU64(0x600000006ull),
24615                                            mkU64(0x600000006ull))))));
24616                      putWReg(wd,
24617                        binop(Iop_OrV128,
24618                           mkexpr(t5),
24619                           binop(Iop_AndV128,
24620                              binop(Iop_CmpEQ32x4,
24621                                 mkexpr(t5),
24622                                 binop(Iop_64HLtoV128,
24623                                       mkU64(0ull),
24624                                       mkU64(0ull))),
24625                              binop(Iop_OrV128,
24626                                 binop(Iop_AndV128,
24627                                       mkexpr(t3),
24628                                       binop(Iop_64HLtoV128,
24629                                          mkU64(0x100000001ull),
24630                                          mkU64(0x100000001ull))),
24631                                 binop(Iop_AndV128,
24632                                       unop(Iop_NotV128, mkexpr(t3)),
24633                                       binop(Iop_64HLtoV128,
24634                                          mkU64(0x200000002ull),
24635                                          mkU64(0x200000002ull)))))));
24636                      break;
24637                   }
24638 
24639                case 0x01: { /* FCLASS.D */
24640                      DIP("FCLASS.D w%d, w%d", wd, ws);
24641                      assign(t0,
24642                          binop(Iop_CmpEQ64x2,
24643                             binop(Iop_AndV128,
24644                                   getWReg(ws),
24645                                   binop(Iop_64HLtoV128,
24646                                         mkU64(0x7FF0000000000000ull),
24647                                         mkU64(0x7FF0000000000000ull))),
24648                             binop(Iop_64HLtoV128,
24649                                   mkU64(0ull), mkU64(0ull))));
24650                      assign(t1,
24651                          binop(Iop_CmpEQ64x2,
24652                             binop(Iop_AndV128,
24653                                   getWReg(ws),
24654                                   binop(Iop_64HLtoV128,
24655                                         mkU64(0x7FF0000000000000ull),
24656                                         mkU64(0x7FF0000000000000ull))),
24657                             binop(Iop_64HLtoV128,
24658                                   mkU64(0x7FF0000000000000ull),
24659                                   mkU64(0x7FF0000000000000ull))));
24660                      assign(t2,
24661                             binop(Iop_SarN64x2,
24662                                   getWReg(ws), mkU8(63)));
24663                      assign(t3,
24664                          binop(Iop_CmpEQ64x2,
24665                             binop(Iop_AndV128,
24666                                   getWReg(ws),
24667                                   binop(Iop_64HLtoV128,
24668                                         mkU64(0x0008000000000000ull),
24669                                         mkU64(0x0008000000000000ull))),
24670                             binop(Iop_64HLtoV128,
24671                                   mkU64(0x0008000000000000ull),
24672                                   mkU64(0x0008000000000000ull))));
24673                      assign(t4,
24674                          binop(Iop_CmpEQ64x2,
24675                             binop(Iop_AndV128,
24676                                   getWReg(ws),
24677                                   binop(Iop_64HLtoV128,
24678                                         mkU64(0x000FFFFFFFFFFFFFULL),
24679                                         mkU64(0x000FFFFFFFFFFFFFULL))),
24680                             binop(Iop_64HLtoV128,
24681                                   mkU64(0ull), mkU64(0ull))));
24682                      assign(t5,
24683                          binop(Iop_Shl64x2,
24684                             binop(Iop_OrV128,
24685                                binop(Iop_AndV128,
24686                                   mkexpr(t1),
24687                                   binop(Iop_AndV128,
24688                                      mkexpr(t4),
24689                                      binop(Iop_64HLtoV128,
24690                                            mkU64(1ull),
24691                                            mkU64(1ull)))),
24692                                binop(Iop_OrV128,
24693                                   binop(Iop_AndV128,
24694                                      mkexpr(t0),
24695                                      binop(Iop_OrV128,
24696                                            binop(Iop_AndV128,
24697                                                  mkexpr(t4),
24698                                                  binop(Iop_64HLtoV128,
24699                                                        mkU64(8ull),
24700                                                        mkU64(8ull))),
24701                                            binop(Iop_AndV128,
24702                                                  unop(Iop_NotV128,
24703                                                        mkexpr(t4)),
24704                                                  binop(Iop_64HLtoV128,
24705                                                        mkU64(4ull),
24706                                                        mkU64(4ull))))),
24707                                   binop(Iop_AndV128,
24708                                      unop(Iop_NotV128,
24709                                           mkexpr(t1)),
24710                                      binop(Iop_AndV128,
24711                                            unop(Iop_NotV128,
24712                                                  mkexpr(t0)),
24713                                            binop(Iop_64HLtoV128,
24714                                                  mkU64(2ull),
24715                                                  mkU64(2ull)))))),
24716                             binop(Iop_OrV128,
24717                                binop(Iop_AndV128,
24718                                   mkexpr(t2),
24719                                   binop(Iop_64HLtoV128,
24720                                         mkU64(2ull),
24721                                         mkU64(2ull))),
24722                                binop(Iop_AndV128,
24723                                   unop(Iop_NotV128,
24724                                        mkexpr(t2)),
24725                                   binop(Iop_64HLtoV128,
24726                                         mkU64(6ull),
24727                                         mkU64(6ull))))));
24728                      putWReg(wd,
24729                           binop(Iop_OrV128,
24730                              mkexpr(t5),
24731                              binop(Iop_AndV128,
24732                                 binop(Iop_CmpEQ64x2,
24733                                       mkexpr(t5),
24734                                       binop(Iop_64HLtoV128,
24735                                             mkU64(0ull),
24736                                             mkU64(0ull))),
24737                                 binop(Iop_OrV128,
24738                                       binop(Iop_AndV128,
24739                                             mkexpr(t3),
24740                                             binop(Iop_64HLtoV128,
24741                                                   mkU64(1ull),
24742                                                   mkU64(1ull))),
24743                                       binop(Iop_AndV128,
24744                                             unop(Iop_NotV128,
24745                                                  mkexpr(t3)),
24746                                             binop(Iop_64HLtoV128,
24747                                                   mkU64(2ull),
24748                                                   mkU64(2ull)))))));
24749                      break;
24750                   }
24751 
24752                default:
24753                   return -1;
24754             }
24755 
24756             break;
24757          }
24758 
24759       case 0x191: { /* FTRUNC_S.df */
24760             switch (df) {
24761                case 0x00: { /* FTRUNC_S.W */
24762                      DIP("FTRUNC_S.W w%d, w%d", wd, ws);
24763                      calculateMSACSR(ws, wd, FTRUNCSW, 1);
24764                      putWReg(wd, unop(Iop_FtoI32Sx4_RZ, getWReg(ws)));
24765                      break;
24766                   }
24767 
24768                case 0x01: { /* FTRUNC_S.D */
24769                      DIP("FTRUNC_S.D w%d, w%d", wd, ws);
24770                      calculateMSACSR(ws, wd, FTRUNCSD, 1);
24771                      t1 = newTemp(Ity_I64);
24772                      t2 = newTemp(Ity_I64);
24773                      t3 = newTemp(Ity_V128);
24774                      assign(t3,
24775                          binop(Iop_AndV128,
24776                                unop(Iop_NotV128,
24777                                     binop(Iop_CmpUN64Fx2,
24778                                           getWReg(ws),
24779                                           getWReg(ws))),
24780                                binop(Iop_Max64Fx2,
24781                                      getWReg(ws),
24782                                      binop(Iop_64HLtoV128,
24783                                         mkU64(0xC3E0000000000000),
24784                                         mkU64(0xC3E0000000000000)))));
24785                      assign(t1,
24786                             binop(Iop_F64toI64S, mkU32(0x3),
24787                                   unop(Iop_ReinterpI64asF64,
24788                                        unop(Iop_V128to64, mkexpr(t3)))));
24789                      assign(t2,
24790                             binop(Iop_F64toI64S, mkU32(0x3),
24791                                   unop(Iop_ReinterpI64asF64,
24792                                        unop(Iop_V128HIto64, mkexpr(t3)))));
24793                      putWReg(wd,
24794                              binop(Iop_64HLtoV128,
24795                                    mkexpr(t2), mkexpr(t1)));
24796                      break;
24797                   }
24798 
24799                default:
24800                   return -1;
24801             }
24802 
24803             break;
24804          }
24805 
24806       case 0x192: { /* FTRUNC_U.df */
24807             switch (df) {
24808                case 0x00: {  /* FTRUNC_U.W */
24809                      DIP("FTRUNC_U.W w%d, w%d", wd, ws);
24810                      calculateMSACSR(ws, wd, FTRUNCUW, 1);
24811                      putWReg(wd, unop(Iop_FtoI32Ux4_RZ, getWReg(ws)));
24812                      break;
24813                   }
24814 
24815                case 0x01: { /* FTRUNC_U.D */
24816                      DIP("FTRUNC_U.D w%d, w%d", wd, ws);
24817                      calculateMSACSR(ws, wd, FTRUNCUD, 1);
24818                      t1 = newTemp(Ity_I64);
24819                      t2 = newTemp(Ity_I64);
24820                      assign(t1,
24821                             binop(Iop_F64toI64U,
24822                                   mkU32(0x3),
24823                                   unop(Iop_ReinterpI64asF64,
24824                                        unop(Iop_V128to64,
24825                                             getWReg(ws)))));
24826                      assign(t2,
24827                             binop(Iop_F64toI64U,
24828                                   mkU32(0x3),
24829                                   unop(Iop_ReinterpI64asF64,
24830                                        unop(Iop_V128HIto64,
24831                                             getWReg(ws)))));
24832                      putWReg(wd,
24833                              binop(Iop_64HLtoV128,
24834                                    mkexpr(t2), mkexpr(t1)));
24835                      break;
24836                   }
24837 
24838                default:
24839                   return -1;
24840             }
24841 
24842             break;
24843          }
24844 
24845       case 0x193: { /* FSQRT.df */
24846             switch (df) {
24847                case 0x00: { /* FSQRT.W */
24848                      DIP("FSQRT.W w%d, w%d", wd, ws);
24849                      IRExpr *rm = get_IR_roundingmode_MSA();
24850                      calculateMSACSR(ws, wd, FSQRTW, 1);
24851                      putWReg(wd, binop(Iop_Sqrt32Fx4, rm, getWReg(ws)));
24852                      break;
24853                   }
24854 
24855                case 0x01: { /* FSQRT.D */
24856                      DIP("FSQRT.D w%d, w%d", wd, ws);
24857                      IRExpr *rm = get_IR_roundingmode_MSA();
24858                      calculateMSACSR(ws, wd, FSQRTD, 1);
24859                      putWReg(wd, binop(Iop_Sqrt64Fx2, rm, getWReg(ws)));
24860                      break;
24861                   }
24862 
24863                default:
24864                   return -1;
24865             }
24866 
24867             break;
24868          }
24869 
24870       case 0x194: { /* FRSQRT.df */
24871             switch (df) {
24872                case 0x00: { /* FRSQRT.W */
24873                      DIP("FRSQRT.W w%d, w%d", wd, ws);
24874                      calculateMSACSR(ws, wd, FRSQRTW, 1);
24875                      putWReg(wd, unop(Iop_RSqrtEst32Fx4, getWReg(ws)));
24876                      break;
24877                   }
24878 
24879                case 0x01: { /* FRSQRT.D */
24880                      DIP("FRSQRT.D w%d, w%d", wd, ws);
24881                      calculateMSACSR(ws, wd, FRSQRTD, 1);
24882                      putWReg(wd, unop(Iop_RSqrtEst64Fx2, getWReg(ws)));
24883                      break;
24884                   }
24885 
24886                default:
24887                   return -1;
24888             }
24889 
24890             break;
24891          }
24892 
24893       case 0x195: { /* FRCP.df */
24894             switch (df) { /* FRCP.W */
24895                case 0x00: {
24896                      DIP("FRCP.W w%d, w%d", wd, ws);
24897                      calculateMSACSR(ws, wd, FRCPW, 1);
24898                      putWReg(wd, unop(Iop_RecipEst32Fx4, getWReg(ws)));
24899                      break;
24900                   }
24901 
24902                case 0x01: { /* FRCP.D */
24903                      DIP("FRCP.D w%d, w%d", wd, ws);
24904                      calculateMSACSR(ws, wd, FRCPD, 1);
24905                      putWReg(wd, unop(Iop_RecipEst64Fx2, getWReg(ws)));
24906                      break;
24907                   }
24908 
24909                default:
24910                   return -1;
24911             }
24912 
24913             break;
24914          }
24915 
24916       case 0x196: { /* FRINT.df */
24917             t1 = newTemp(Ity_V128);
24918             t2 = newTemp(Ity_V128);
24919             t3 = newTemp(Ity_V128);
24920             t4 = newTemp(Ity_V128);
24921             IRExpr *rm = get_IR_roundingmode_MSA();
24922             assign(t1, getWReg(ws));
24923 
24924             switch (df) {
24925                case 0x00: { /* FRINT.W */
24926                      DIP("FRINT.W w%d, w%d", wd, ws);
24927                      calculateMSACSR(ws, wt, FRINTW, 1);
24928                      assign(t2,
24929                          binop(Iop_OrV128,
24930                             binop(Iop_CmpLT32Fx4,
24931                                mkexpr(t1),
24932                                binop(Iop_64HLtoV128,
24933                                      mkU64(0xCF000000CF000000ull),
24934                                      mkU64(0xCF000000CF000000ull))),
24935                             binop(Iop_CmpLT32Fx4,
24936                                binop(Iop_64HLtoV128,
24937                                      mkU64(0x4F0000004F000000ull),
24938                                      mkU64(0x4F0000004F000000ull)),
24939                                mkexpr(t1))));
24940                      assign(t3,
24941                          binop(Iop_CmpEQ32x4,
24942                             binop(Iop_AndV128,
24943                                mkexpr(t1),
24944                                binop(Iop_64HLtoV128,
24945                                      mkU64(0x0040000000400000ull),
24946                                      mkU64(0x0040000000400000ull))),
24947                             binop(Iop_64HLtoV128,
24948                                mkU64(0x0040000000400000ull),
24949                                mkU64(0x0040000000400000ull))));
24950                      assign(t4,
24951                             binop(Iop_CmpUN32Fx4,
24952                                   mkexpr(t1), mkexpr(t1)));
24953                      IRTemp tmp[4];
24954                      Int i;
24955 
24956                      for (i = 0; i < 4; i++) {
24957                         tmp[i] = newTemp(Ity_I32);
24958                         assign(tmp[i],
24959                             unop(Iop_ReinterpF32asI32,
24960                               binop(Iop_RoundF32toInt, rm,
24961                                     unop(Iop_ReinterpI32asF32,
24962                                          binop(Iop_GetElem32x4,
24963                                                mkexpr(t1), mkU8(i))))));
24964                      }
24965 
24966                      putWReg(wd,
24967                           binop(Iop_OrV128,
24968                              binop(Iop_OrV128,
24969                                 binop(Iop_AndV128,
24970                                       binop(Iop_OrV128,
24971                                             mkexpr(t2),
24972                                             binop(Iop_AndV128,
24973                                                   mkexpr(t4),
24974                                                   unop(Iop_NotV128,
24975                                                         mkexpr(t3)))),
24976                                       mkexpr(t1)),
24977                                 binop(Iop_AndV128,
24978                                    binop(Iop_AndV128,
24979                                          mkexpr(t4),
24980                                          mkexpr(t3)),
24981                                    binop(Iop_64HLtoV128,
24982                                          mkU64(0x7FBFFFFF7FBFFFFF),
24983                                          mkU64(0x7FBFFFFF7FBFFFFF)))),
24984                              binop(Iop_AndV128,
24985                                 unop(Iop_NotV128,
24986                                      binop(Iop_OrV128,
24987                                            mkexpr(t2),
24988                                            mkexpr(t4))),
24989                                 binop(Iop_OrV128,
24990                                    binop(Iop_64HLtoV128,
24991                                          binop(Iop_32HLto64,
24992                                                mkexpr(tmp[3]),
24993                                                mkexpr(tmp[2])),
24994                                          binop(Iop_32HLto64,
24995                                                mkexpr(tmp[1]),
24996                                                mkexpr(tmp[0]))),
24997                                    binop(Iop_AndV128,
24998                                       mkexpr(t1),
24999                                       binop(Iop_64HLtoV128,
25000                                          mkU64(0x8000000080000000ull),
25001                                          mkU64(0x8000000080000000ull)))
25002                                 ))));
25003                      break;
25004                   }
25005 
25006                case 0x01: { /* FRINT.D */
25007                      DIP("FRINT.D w%d, w%d", wd, ws);
25008                      calculateMSACSR(ws, wt, FRINTD, 1);
25009                      assign(t2,
25010                          binop(Iop_OrV128,
25011                             binop(Iop_CmpLT64Fx2,
25012                                   mkexpr(t1),
25013                                   binop(Iop_64HLtoV128,
25014                                         mkU64(0xC3E0000000000000ull),
25015                                         mkU64(0xC3E0000000000000ull))),
25016                             binop(Iop_CmpLT64Fx2,
25017                                   binop(Iop_64HLtoV128,
25018                                         mkU64(0x43E0000000000000ull),
25019                                         mkU64(0x43E0000000000000ull)),
25020                                   mkexpr(t1))));
25021                      assign(t3,
25022                          binop(Iop_CmpEQ64x2,
25023                             binop(Iop_AndV128,
25024                                   getWReg(ws),
25025                                   binop(Iop_64HLtoV128,
25026                                         mkU64(0x0008000000000000ull),
25027                                         mkU64(0x0008000000000000ull))),
25028                             binop(Iop_64HLtoV128,
25029                                   mkU64(0x0008000000000000ull),
25030                                   mkU64(0x0008000000000000ull))));
25031                      assign(t4,
25032                             binop(Iop_CmpUN64Fx2,
25033                                   mkexpr(t1), mkexpr(t1)));
25034                      IRTemp tmp[2];
25035                      Int i;
25036 
25037                      for (i = 0; i < 2; i++) {
25038                         tmp[i] = newTemp(Ity_I64);
25039                         assign(tmp[i],
25040                             unop(Iop_ReinterpF64asI64,
25041                                  binop(Iop_RoundF64toInt, rm,
25042                                        unop(Iop_ReinterpI64asF64,
25043                                             binop(Iop_GetElem64x2,
25044                                                   mkexpr(t1), mkU8(i))))));
25045                      }
25046 
25047                      putWReg(wd,
25048                           binop(Iop_OrV128,
25049                              binop(Iop_OrV128,
25050                                 binop(Iop_AndV128,
25051                                       binop(Iop_OrV128,
25052                                             mkexpr(t2),
25053                                             binop(Iop_AndV128,
25054                                                   mkexpr(t4),
25055                                                   unop(Iop_NotV128,
25056                                                         mkexpr(t3)))),
25057                                       mkexpr(t1)),
25058                                 binop(Iop_AndV128,
25059                                    binop(Iop_AndV128,
25060                                          mkexpr(t4),
25061                                          mkexpr(t3)),
25062                                    binop(Iop_64HLtoV128,
25063                                          mkU64(0x7FF7FFFFFFFFFFFF),
25064                                          mkU64(0x7FF7FFFFFFFFFFFF)))),
25065                              binop(Iop_AndV128,
25066                                 unop(Iop_NotV128,
25067                                      binop(Iop_OrV128,
25068                                            mkexpr(t2),
25069                                            mkexpr(t4))),
25070                                 binop(Iop_OrV128,
25071                                    binop(Iop_64HLtoV128,
25072                                          mkexpr(tmp[1]),
25073                                          mkexpr(tmp[0])),
25074                                    binop(Iop_AndV128,
25075                                          mkexpr(t1),
25076                                          binop(Iop_64HLtoV128,
25077                                             mkU64(0x8000000000000000ull),
25078                                             mkU64(0x8000000000000000ull))
25079                                    )))));
25080                      break;
25081                   }
25082 
25083                default:
25084                   return -1;
25085             }
25086 
25087             break;
25088          }
25089 
25090       case 0x197: { /* FLOG2.df */
25091 
25092             switch (df) {
25093                case 0x00: { /* FLOG2.W */
25094                      DIP("FLOG2.W w%d, w%d", wd, ws);
25095                      calculateMSACSR(ws, wt, FLOG2W, 1);
25096                      putWReg(wd, unop(Iop_Log2_32Fx4, getWReg(ws)));
25097                      break;
25098                   }
25099 
25100                case 0x01: { /* FLOG2.D */
25101                      DIP("FLOG2.D w%d, w%d", wd, ws);
25102                      calculateMSACSR(ws, wt, FLOG2D, 1);
25103                      putWReg(wd, unop(Iop_Log2_64Fx2, getWReg(ws)));
25104                      break;
25105                   }
25106 
25107                default:
25108                   return -1;
25109             }
25110 
25111             break;
25112          }
25113 
25114       case 0x198: { /* FEXUPL.df */
25115             switch (df) {
25116                case 0x00: { /* FEXUPL.W */
25117                      DIP("FEXUPL.W w%d, w%d", wd, ws);
25118                      calculateMSACSR(ws, wt, FEXUPLW, 1);
25119                      putWReg(wd,
25120                              unop(Iop_F16toF32x4,
25121                                   unop(Iop_V128HIto64,
25122                                        getWReg(ws))));
25123                      break;
25124                   }
25125 
25126                case 0x01: { /* FEXUPL.D */
25127                      DIP("FEXUPL.D w%d, w%d", wd, ws);
25128                      calculateMSACSR(ws, wt, FEXUPLD, 1);
25129                      t1 = newTemp(Ity_I64);
25130                      t2 = newTemp(Ity_I64);
25131                      assign(t1,
25132                             unop(Iop_ReinterpF64asI64,
25133                                  unop(Iop_F32toF64,
25134                                       unop(Iop_ReinterpI32asF32,
25135                                            unop(Iop_64to32,
25136                                                 unop(Iop_V128HIto64,
25137                                                      getWReg(ws)))))));
25138                      assign(t2,
25139                             unop(Iop_ReinterpF64asI64,
25140                                  unop(Iop_F32toF64,
25141                                       unop(Iop_ReinterpI32asF32,
25142                                            unop(Iop_64HIto32,
25143                                                 unop(Iop_V128HIto64,
25144                                                      getWReg(ws)))))));
25145                      putWReg(wd,
25146                              binop(Iop_64HLtoV128,
25147                                    mkexpr(t2), mkexpr(t1)));
25148                      break;
25149                   }
25150 
25151                default:
25152                   return -1;
25153             }
25154 
25155             break;
25156          }
25157 
25158       case 0x199: { /* FEXUPR.df */
25159             switch (df) {
25160                case 0x00: { /* FEXUPR.W */
25161                      DIP("FEXUPR.W w%d, w%d", wd, ws);
25162                      calculateMSACSR(ws, wt, FEXUPRW, 1);
25163                      putWReg(wd,
25164                              unop(Iop_F16toF32x4,
25165                                   unop(Iop_V128to64,
25166                                        getWReg(ws))));
25167                      break;
25168                   }
25169 
25170                case 0x01: { /* FEXUPR.D */
25171                      DIP("FEXUPR.D w%d, w%d", wd, ws);
25172                      calculateMSACSR(ws, wt, FEXUPRD, 1);
25173                      t1 = newTemp(Ity_I64);
25174                      t2 = newTemp(Ity_I64);
25175                      assign(t1,
25176                             unop(Iop_ReinterpF64asI64,
25177                                  unop(Iop_F32toF64,
25178                                       unop(Iop_ReinterpI32asF32,
25179                                            unop(Iop_64to32,
25180                                                 unop(Iop_V128to64,
25181                                                      getWReg(ws)))))));
25182                      assign(t2,
25183                             unop(Iop_ReinterpF64asI64,
25184                                  unop(Iop_F32toF64,
25185                                       unop(Iop_ReinterpI32asF32,
25186                                            unop(Iop_64HIto32,
25187                                                 unop(Iop_V128to64,
25188                                                      getWReg(ws)))))));
25189                      putWReg(wd,
25190                              binop(Iop_64HLtoV128,
25191                                    mkexpr(t2), mkexpr(t1)));
25192                      break;
25193                   }
25194 
25195                default:
25196                   return -1;
25197             }
25198 
25199             break;
25200          }
25201 
25202       case 0x19A: { /* FFQL.df */
25203             switch (df) {
25204                case 0x00: { /* FFQL.W */
25205                      DIP("FFQL.W w%d, w%d", wd, ws);
25206                      calculateMSACSR(ws, wt, FFQLW, 1);
25207                      t1 = newTemp(Ity_V128);
25208                      t2 = newTemp(Ity_I64);
25209                      t3 = newTemp(Ity_I64);
25210                      IRExpr *rm = get_IR_roundingmode_MSA();
25211                      assign(t1,
25212                             binop(Iop_SarN32x4,
25213                                   binop(Iop_InterleaveHI16x8,
25214                                         getWReg(ws),
25215                                         getWReg(ws)),
25216                                   mkU8(16)));
25217                      assign(t2,
25218                             binop(Iop_32HLto64,
25219                                   unop(Iop_ReinterpF32asI32,
25220                                        binop(Iop_I32StoF32, rm,
25221                                              binop(Iop_GetElem32x4,
25222                                                    mkexpr(t1),
25223                                                    mkU8(1)))),
25224                                   unop(Iop_ReinterpF32asI32,
25225                                        binop(Iop_I32StoF32, rm,
25226                                              binop(Iop_GetElem32x4,
25227                                                    mkexpr(t1),
25228                                                    mkU8(0))))));
25229                      assign(t3,
25230                             binop(Iop_32HLto64,
25231                                   unop(Iop_ReinterpF32asI32,
25232                                        binop(Iop_I32StoF32, rm,
25233                                              binop(Iop_GetElem32x4,
25234                                                    mkexpr(t1),
25235                                                    mkU8(3)))),
25236                                   unop(Iop_ReinterpF32asI32,
25237                                        binop(Iop_I32StoF32, rm,
25238                                              binop(Iop_GetElem32x4,
25239                                                    mkexpr(t1),
25240                                                    mkU8(2))))));
25241                      putWReg(wd,
25242                              triop(Iop_Div32Fx4, rm,
25243                                    binop(Iop_64HLtoV128,
25244                                          mkexpr(t3), mkexpr(t2)),
25245                                    binop(Iop_64HLtoV128,
25246                                          mkU64(0x4700000047000000),
25247                                          mkU64(0x4700000047000000))));
25248                      break;
25249                   }
25250 
25251                case 0x01: { /* FFQL.D */
25252                      DIP("FFQL.D w%d, w%d", wd, ws);
25253                      calculateMSACSR(ws, wt, FFQLD, 1);
25254                      t1 = newTemp(Ity_V128);
25255                      t2 = newTemp(Ity_I64);
25256                      t3 = newTemp(Ity_I64);
25257                      IRExpr *rm = get_IR_roundingmode_MSA();
25258                      assign(t1,
25259                             binop(Iop_SarN64x2,
25260                                   binop(Iop_InterleaveHI32x4,
25261                                         getWReg(ws),
25262                                         getWReg(ws)),
25263                                   mkU8(32)));
25264                      assign(t2,
25265                             unop(Iop_ReinterpF64asI64,
25266                                  binop(Iop_I64StoF64, rm,
25267                                        unop(Iop_V128to64,
25268                                             mkexpr(t1)))));
25269                      assign(t3,
25270                             unop(Iop_ReinterpF64asI64,
25271                                  binop(Iop_I64StoF64, rm,
25272                                        unop(Iop_V128HIto64,
25273                                             mkexpr(t1)))));
25274                      putWReg(wd,
25275                              triop(Iop_Div64Fx2, rm,
25276                                    binop(Iop_64HLtoV128,
25277                                          mkexpr(t3), mkexpr(t2)),
25278                                    binop(Iop_64HLtoV128,
25279                                          mkU64(0x41E0000000000000),
25280                                          mkU64(0x41E0000000000000))));
25281                      break;
25282                   }
25283 
25284                default:
25285                   return -1;
25286             }
25287 
25288             break;
25289          }
25290 
25291       case 0x19B: { /* FFQR.df */
25292             switch (df) {
25293                case 0x00: { /* FFQR.W */
25294                      DIP("FFQR.W w%d, w%d", wd, ws);
25295                      calculateMSACSR(ws, wt, FFQRW, 1);
25296                      t1 = newTemp(Ity_V128);
25297                      t2 = newTemp(Ity_I64);
25298                      t3 = newTemp(Ity_I64);
25299                      IRExpr *rm = get_IR_roundingmode_MSA();
25300                      assign(t1,
25301                             binop(Iop_SarN32x4,
25302                                   binop(Iop_InterleaveLO16x8,
25303                                         getWReg(ws),
25304                                         getWReg(ws)),
25305                                   mkU8(16)));
25306                      assign(t2,
25307                             binop(Iop_32HLto64,
25308                                   unop(Iop_ReinterpF32asI32,
25309                                        binop(Iop_I32StoF32, rm,
25310                                              binop(Iop_GetElem32x4,
25311                                                    mkexpr(t1),
25312                                                    mkU8(1)))),
25313                                   unop(Iop_ReinterpF32asI32,
25314                                        binop(Iop_I32StoF32, rm,
25315                                              binop(Iop_GetElem32x4,
25316                                                    mkexpr(t1),
25317                                                    mkU8(0))))));
25318                      assign(t3,
25319                             binop(Iop_32HLto64,
25320                                   unop(Iop_ReinterpF32asI32,
25321                                        binop(Iop_I32StoF32, rm,
25322                                              binop(Iop_GetElem32x4,
25323                                                    mkexpr(t1),
25324                                                    mkU8(3)))),
25325                                   unop(Iop_ReinterpF32asI32,
25326                                        binop(Iop_I32StoF32, rm,
25327                                              binop(Iop_GetElem32x4,
25328                                                    mkexpr(t1),
25329                                                    mkU8(2))))));
25330                      putWReg(wd,
25331                              triop(Iop_Div32Fx4, rm,
25332                                    binop(Iop_64HLtoV128,
25333                                          mkexpr(t3), mkexpr(t2)),
25334                                    binop(Iop_64HLtoV128,
25335                                          mkU64(0x4700000047000000),
25336                                          mkU64(0x4700000047000000))));
25337                      break;
25338                   }
25339 
25340                case 0x01: { /* FFQR.D */
25341                      DIP("FFQR.D w%d, w%d", wd, ws);
25342                      calculateMSACSR(ws, wt, FFQRD, 1);
25343                      t1 = newTemp(Ity_V128);
25344                      t2 = newTemp(Ity_I64);
25345                      t3 = newTemp(Ity_I64);
25346                      IRExpr *rm = get_IR_roundingmode_MSA();
25347                      assign(t1,
25348                             binop(Iop_SarN64x2,
25349                                   binop(Iop_InterleaveLO32x4,
25350                                         getWReg(ws),
25351                                         getWReg(ws)),
25352                                   mkU8(32)));
25353                      assign(t2,
25354                             unop(Iop_ReinterpF64asI64,
25355                                  binop(Iop_I64StoF64, rm,
25356                                        unop(Iop_V128to64,
25357                                             mkexpr(t1)))));
25358                      assign(t3,
25359                             unop(Iop_ReinterpF64asI64,
25360                                  binop(Iop_I64StoF64, rm,
25361                                        unop(Iop_V128HIto64,
25362                                             mkexpr(t1)))));
25363                      putWReg(wd,
25364                              triop(Iop_Div64Fx2, rm,
25365                                    binop(Iop_64HLtoV128,
25366                                          mkexpr(t3), mkexpr(t2)),
25367                                    binop(Iop_64HLtoV128,
25368                                          mkU64(0x41E0000000000000),
25369                                          mkU64(0x41E0000000000000))));
25370                      break;
25371                   }
25372 
25373                default:
25374                   return -1;
25375             }
25376 
25377             break;
25378          }
25379 
25380       case 0x19C: { /* FTINT_S.df */
25381             switch (df) { /* FTINT_S.W */
25382                case 0x00: {
25383                      DIP("FTINT_S.W w%d, w%d", wd, ws);
25384                      calculateMSACSR(ws, wd, FTINT_SW, 1);
25385                      t1 = newTemp(Ity_I64);
25386                      t2 = newTemp(Ity_I64);
25387                      t3 = newTemp(Ity_V128);
25388                      t4 = newTemp(Ity_I32);
25389                      assign(t3,
25390                          binop(Iop_AndV128,
25391                                unop(Iop_NotV128,
25392                                     binop(Iop_CmpUN32Fx4,
25393                                           getWReg(ws),
25394                                           getWReg(ws))),
25395                                binop(Iop_Max32Fx4,
25396                                      getWReg(ws),
25397                                      binop(Iop_64HLtoV128,
25398                                         mkU64(0xCF000000CF000000),
25399                                         mkU64(0xCF000000CF000000)))));
25400                      IRExpr *rm = get_IR_roundingmode_MSA();
25401                      assign(t1,
25402                          binop(Iop_32HLto64,
25403                                binop(Iop_F32toI32S, rm,
25404                                      unop(Iop_ReinterpI32asF32,
25405                                           binop(Iop_GetElem32x4,
25406                                                 mkexpr(t3), mkU8(1)))),
25407                                binop(Iop_F32toI32S, rm,
25408                                      unop(Iop_ReinterpI32asF32,
25409                                           binop(Iop_GetElem32x4,
25410                                                 mkexpr(t3), mkU8(0))))));
25411                      assign(t2,
25412                          binop(Iop_32HLto64,
25413                                binop(Iop_F32toI32S, rm,
25414                                      unop(Iop_ReinterpI32asF32,
25415                                           binop(Iop_GetElem32x4,
25416                                                 mkexpr(t3), mkU8(3)))),
25417                                binop(Iop_F32toI32S, rm,
25418                                      unop(Iop_ReinterpI32asF32,
25419                                           binop(Iop_GetElem32x4,
25420                                                 mkexpr(t3), mkU8(2))))));
25421                      putWReg(wd,
25422                              binop(Iop_64HLtoV128,
25423                                    mkexpr(t2), mkexpr(t1)));
25424                      break;
25425                   }
25426 
25427                case 0x01: {  /* FTINT_S.D */
25428                      DIP("FTINT_S.D w%d, w%d", wd, ws);
25429                      calculateMSACSR(ws, wd, FTINT_SD, 1);
25430                      t1 = newTemp(Ity_I64);
25431                      t2 = newTemp(Ity_I64);
25432                      t3 = newTemp(Ity_V128);
25433                      assign(t3,
25434                          binop(Iop_AndV128,
25435                                unop(Iop_NotV128,
25436                                     binop(Iop_CmpUN64Fx2,
25437                                           getWReg(ws),
25438                                           getWReg(ws))),
25439                                binop(Iop_Max64Fx2,
25440                                      getWReg(ws),
25441                                      binop(Iop_64HLtoV128,
25442                                         mkU64(0xC3E0000000000000),
25443                                         mkU64(0xC3E0000000000000)))));
25444                      IRExpr *rm = get_IR_roundingmode_MSA();
25445                      assign(t1,
25446                             binop(Iop_F64toI64S, rm,
25447                                   unop(Iop_ReinterpI64asF64,
25448                                        unop(Iop_V128to64, mkexpr(t3)))));
25449                      assign(t2,
25450                             binop(Iop_F64toI64S, rm,
25451                                   unop(Iop_ReinterpI64asF64,
25452                                        unop(Iop_V128HIto64, mkexpr(t3)))));
25453                      putWReg(wd,
25454                              binop(Iop_64HLtoV128,
25455                                    mkexpr(t2), mkexpr(t1)));
25456                      break;
25457                   }
25458 
25459                default:
25460                   return -1;
25461             }
25462 
25463             break;
25464          }
25465 
25466       case 0x19D: {/* FTINT_U.df */
25467             switch (df) { /* FTINT_U.W */
25468                case 0x00: {
25469                      DIP("FTINT_U.W w%d, w%d", wd, ws);
25470                      calculateMSACSR(ws, wd, FTINT_UW, 1);
25471                      t1 = newTemp(Ity_I64);
25472                      t2 = newTemp(Ity_I64);
25473                      t3 = newTemp(Ity_V128);
25474                      t4 = newTemp(Ity_V128);
25475                      IRExpr *rm = get_IR_roundingmode_MSA();
25476                      assign(t1,
25477                          binop(Iop_32HLto64,
25478                                binop(Iop_F32toI32U, rm,
25479                                      unop(Iop_ReinterpI32asF32,
25480                                           binop(Iop_GetElem32x4,
25481                                                 getWReg(ws), mkU8(1)))),
25482                                binop(Iop_F32toI32U, rm,
25483                                      unop(Iop_ReinterpI32asF32,
25484                                           binop(Iop_GetElem32x4,
25485                                                 getWReg(ws), mkU8(0))))));
25486                      assign(t2,
25487                          binop(Iop_32HLto64,
25488                                binop(Iop_F32toI32U, rm,
25489                                      unop(Iop_ReinterpI32asF32,
25490                                           binop(Iop_GetElem32x4,
25491                                                 getWReg(ws), mkU8(3)))),
25492                                binop(Iop_F32toI32U, rm,
25493                                      unop(Iop_ReinterpI32asF32,
25494                                           binop(Iop_GetElem32x4,
25495                                                 getWReg(ws), mkU8(2))))));
25496                      assign(t3,
25497                             unop(Iop_NotV128,
25498                                  binop(Iop_SarN32x4,
25499                                        getWReg(ws),
25500                                        mkU8(31))));
25501                      assign(t4,
25502                             binop(Iop_CmpLT32Fx4,
25503                                   getWReg(ws),
25504                                   binop(Iop_64HLtoV128,
25505                                         mkU64(0x4EFFFFFF4EFFFFFF),
25506                                         mkU64(0x4EFFFFFF4EFFFFFF))));
25507                      putWReg(wd,
25508                              binop(Iop_OrV128,
25509                                    binop(Iop_AndV128,
25510                                          mkexpr(t4),
25511                                          binop(Iop_AndV128,
25512                                                binop(Iop_64HLtoV128,
25513                                                      mkexpr(t2),
25514                                                      mkexpr(t1)),
25515                                                mkexpr(t3))),
25516                                    binop(Iop_AndV128,
25517                                          unop(Iop_NotV128, mkexpr(t4)),
25518                                          unop(Iop_FtoI32Ux4_RZ,
25519                                               getWReg(ws)))));
25520                      break;
25521                   }
25522 
25523                case 0x01: {  /* FTINT_U.D */
25524                      DIP("FTINT_U.D w%d, w%d", wd, ws);
25525                      calculateMSACSR(ws, wd, FTINT_UD, 1);
25526                      t1 = newTemp(Ity_I64);
25527                      t2 = newTemp(Ity_I64);
25528                      IRExpr *rm = get_IR_roundingmode_MSA();
25529                      assign(t1,
25530                             binop(Iop_F64toI64U, rm,
25531                                   unop(Iop_ReinterpI64asF64,
25532                                        unop(Iop_V128to64,
25533                                             getWReg(ws)))));
25534                      assign(t2,
25535                             binop(Iop_F64toI64U, rm,
25536                                   unop(Iop_ReinterpI64asF64,
25537                                        unop(Iop_V128HIto64,
25538                                             getWReg(ws)))));
25539                      putWReg(wd,
25540                              binop(Iop_64HLtoV128,
25541                                    mkexpr(t2), mkexpr(t1)));
25542                      break;
25543                   }
25544 
25545                default:
25546                   return -1;
25547             }
25548 
25549             break;
25550          }
25551 
25552       case 0x19E: { /* FFINT_S.df */
25553             t1 = newTemp(Ity_V128);
25554             assign(t1, getWReg(ws));
25555             IRExpr *rm = get_IR_roundingmode_MSA();
25556 
25557             switch (df) {
25558                case 0x00: { /* FFINT_S.W */
25559                      DIP("FFINT_S.W w%d, w%d", wd, ws);
25560                      calculateMSACSR(ws, wt, FFINTSW, 1);
25561                      IRTemp tmp[4];
25562                      Int i;
25563 
25564                      for (i = 0; i < 4; i++) {
25565                         tmp[i] = newTemp(Ity_F32);
25566                         assign(tmp[i],
25567                                binop(Iop_I32StoF32, rm,
25568                                      binop(Iop_GetElem32x4,
25569                                            mkexpr(t1), mkU8(i))));
25570                      }
25571 
25572                      putWReg(wd,
25573                              binop(Iop_64HLtoV128,
25574                                    binop(Iop_32HLto64,
25575                                          unop(Iop_ReinterpF32asI32,
25576                                               mkexpr(tmp[3])),
25577                                          unop(Iop_ReinterpF32asI32,
25578                                               mkexpr(tmp[2]))),
25579                                    binop(Iop_32HLto64,
25580                                          unop(Iop_ReinterpF32asI32,
25581                                               mkexpr(tmp[1])),
25582                                          unop(Iop_ReinterpF32asI32,
25583                                               mkexpr(tmp[0])))));
25584                      break;
25585                   }
25586 
25587                case 0x01: { /* FFINT_S.D */
25588                      DIP("FFINT_S.D w%d, w%d", wd, ws);
25589                      calculateMSACSR(ws, wt, FFINTSD, 1);
25590                      IRTemp tmp[2];
25591                      Int i;
25592 
25593                      for (i = 0; i < 2; i++) {
25594                         tmp[i] = newTemp(Ity_F64);
25595                         assign(tmp[i],
25596                                binop(Iop_I64StoF64, rm,
25597                                      binop(Iop_GetElem64x2,
25598                                            mkexpr(t1), mkU8(i))));
25599                      }
25600 
25601                      putWReg(wd,
25602                              binop(Iop_64HLtoV128,
25603                                    unop(Iop_ReinterpF64asI64,
25604                                         mkexpr(tmp[1])),
25605                                    unop(Iop_ReinterpF64asI64,
25606                                         mkexpr(tmp[0]))));
25607                      break;
25608                   }
25609 
25610                default:
25611                   return -1;
25612             }
25613 
25614             break;
25615          }
25616 
25617       case 0x19F: { /* FFINT_U.df */
25618             IRExpr *rm = get_IR_roundingmode_MSA();
25619 
25620             switch (df) {
25621                case 0x00: { /* FFINT_U.W */
25622                      DIP("FFINT_U.W w%d, w%d", wd, ws);
25623                      calculateMSACSR(ws, wt, FFINT_UW, 1);
25624                      putWReg(wd, unop(Iop_I32UtoFx4, getWReg(ws)));
25625                      break;
25626                   }
25627 
25628                case 0x01: { /* FFINT_U.D */
25629                      DIP("FFINT_U.D w%d, w%d",
25630                          wd, ws);
25631                      calculateMSACSR(ws, wt,
25632                                      FFINT_UD, 1);
25633                      t1 = newTemp(Ity_I64);
25634                      t2 = newTemp(Ity_I64);
25635                      assign(t1,
25636                             unop(Iop_ReinterpF64asI64,
25637                                  binop(Iop_I64UtoF64, rm,
25638                                        unop(Iop_V128to64,
25639                                             getWReg(ws)))));
25640                      assign(t2,
25641                             unop(Iop_ReinterpF64asI64,
25642                                  binop(Iop_I64UtoF64, rm,
25643                                        unop(Iop_V128HIto64,
25644                                             getWReg(ws)))));
25645                      putWReg(wd,
25646                              binop(Iop_64HLtoV128,
25647                                    mkexpr(t2), mkexpr(t1)));
25648                      break;
25649                   }
25650 
25651                default:
25652                   return -1;
25653             }
25654 
25655             break;
25656          }
25657 
25658       default:
25659          return -1;
25660    }
25661 
25662    return 0;
25663 }
25664 
msa_MI10_load(UInt cins,UChar wd,UChar ws)25665 static Int msa_MI10_load(UInt cins, UChar wd, UChar ws) { /* MI10 (0x20) */
25666    IRTemp t1;
25667    UShort i10;
25668    UChar df;
25669 
25670    i10 = (cins & 0x03FF0000) >> 16;
25671    df = cins & 0x00000003;
25672 
25673    switch (df) {
25674       case 0x00: { /* LD.B */
25675             DIP("LD.B w%d, %d(r%d)", wd, ws, i10);
25676             LOAD_STORE_PATTERN_MSA(i10);
25677             putWReg(wd, load(Ity_V128, mkexpr(t1)));
25678             break;
25679          }
25680 
25681       case 0x01: { /* LD.H */
25682             DIP("LD.H w%d, %d(r%d)", wd, ws, i10);
25683             LOAD_STORE_PATTERN_MSA(i10 << 1);
25684 #if defined (_MIPSEL)
25685             putWReg(wd, load(Ity_V128, mkexpr(t1)));
25686 #elif defined (_MIPSEB)
25687             putWReg(wd,
25688                     unop(Iop_Reverse8sIn16_x8,
25689                          load(Ity_V128, mkexpr(t1))));
25690 #endif
25691             break;
25692          }
25693 
25694       case 0x02: { /* LD.W */
25695             DIP("LD.W w%d, %d(r%d)", wd, ws, i10);
25696             LOAD_STORE_PATTERN_MSA(i10 << 2);
25697 #if defined (_MIPSEL)
25698             putWReg(wd, load(Ity_V128, mkexpr(t1)));
25699 #elif defined (_MIPSEB)
25700             putWReg(wd,
25701                     unop(Iop_Reverse8sIn32_x4,
25702                          load(Ity_V128, mkexpr(t1))));
25703 #endif
25704             break;
25705          }
25706 
25707       case 0x03: { /* LD.D */
25708             DIP("LD.D w%d, %d(r%d)", wd, ws, i10);
25709             LOAD_STORE_PATTERN_MSA(i10 << 3);
25710 #if defined (_MIPSEL)
25711             putWReg(wd, load(Ity_V128, mkexpr(t1)));
25712 #elif defined (_MIPSEB)
25713             putWReg(wd,
25714                     unop(Iop_Reverse8sIn64_x2,
25715                          load(Ity_V128, mkexpr(t1))));
25716 #endif
25717             break;
25718          }
25719 
25720       default:
25721          return -1;
25722    }
25723 
25724    return 0;
25725 }
25726 
msa_MI10_store(UInt cins,UChar wd,UChar ws)25727 static Int msa_MI10_store(UInt cins, UChar wd, UChar ws) { /* MI10 (0x24) */
25728    IRTemp t1;
25729    UShort i10;
25730    UChar df;
25731 
25732    df = cins & 0x00000003;
25733    i10 = (cins & 0x03FF0000) >> 16;
25734 
25735    switch (df) {
25736       case 0x00: { /* ST.B */
25737             DIP("ST.B w%d, %d(r%d)", wd, ws, i10);
25738             LOAD_STORE_PATTERN_MSA(i10);
25739             store(mkexpr(t1), getWReg(wd));
25740             break;
25741          }
25742 
25743       case 0x01: { /* ST.H */
25744             DIP("ST.H w%d, %d(r%d)", wd, ws, i10);
25745             LOAD_STORE_PATTERN_MSA(i10 << 1);
25746 #if defined (_MIPSEL)
25747             store(mkexpr(t1), getWReg(wd));
25748 #elif defined (_MIPSEB)
25749             store(mkexpr(t1),
25750                   unop(Iop_Reverse8sIn16_x8, getWReg(wd)));
25751 #endif
25752             break;
25753          }
25754 
25755       case 0x02: { /* ST.W */
25756             DIP("ST.W w%d, %d(r%d)", wd, ws, i10);
25757             LOAD_STORE_PATTERN_MSA(i10 << 2);
25758 #if defined (_MIPSEL)
25759             store(mkexpr(t1), getWReg(wd));
25760 #elif defined (_MIPSEB)
25761             store(mkexpr(t1),
25762                   unop(Iop_Reverse8sIn32_x4, getWReg(wd)));
25763 #endif
25764             break;
25765          }
25766 
25767       case 0x03: { /* ST.D */
25768             DIP("ST.D w%d, %d(r%d)", wd, ws, i10);
25769             LOAD_STORE_PATTERN_MSA(i10 << 3);
25770 #if defined (_MIPSEL)
25771             store(mkexpr(t1), getWReg(wd));
25772 #elif defined (_MIPSEB)
25773             store(mkexpr(t1),
25774                   unop(Iop_Reverse8sIn64_x2, getWReg(wd)));
25775 #endif
25776             break;
25777          }
25778 
25779       default:
25780          return -1;
25781    }
25782 
25783    return 0;
25784 }
25785 
25786 /*------------------------------------------------------------*/
25787 /*---   Disassemble a single MIPS MSA (SIMD) instruction   ---*/
25788 /*---   Return values:                                     ---*/
25789 /*---       0: Success                                     ---*/
25790 /*---      -1: Decode failure (unknown instruction)        ---*/
25791 /*---      -2: Illegal instruction                         ---*/
25792 /*------------------------------------------------------------*/
disMSAInstr_MIPS_WRK(UInt cins)25793 static Int disMSAInstr_MIPS_WRK ( UInt cins ) {
25794    UChar minor_opcode, wd, ws;
25795 
25796    vassert(has_msa);
25797    vassert((cins & 0xFC000000) == 0x78000000);
25798 
25799    minor_opcode = (cins & 0x20) > 0 ? (cins & 0x3C) : (cins & 0x3F);
25800    wd = (cins & 0x000007C0) >> 6;
25801    ws = (cins & 0x0000F800) >> 11;
25802 
25803    switch (minor_opcode) {
25804       case 0x0:
25805          return msa_I8_logical(cins, wd, ws);
25806 
25807       case 0x01:
25808          return msa_I8_branch(cins, wd, ws);
25809 
25810       case 0x02:
25811          return msa_I8_shift(cins, wd, ws);
25812 
25813       case 0x06:
25814          return msa_I5_06(cins, wd, ws);
25815 
25816       case 0x07:
25817          return msa_I5_07(cins, wd, ws);
25818 
25819       case 0x09:
25820          return msa_BIT_09(cins, wd, ws);
25821 
25822       case 0x0A:
25823          return msa_BIT_0A(cins, wd, ws);
25824 
25825       case 0x0D:
25826          return msa_3R_0D(cins, wd, ws);
25827 
25828       case 0x0E:
25829          return msa_3R_0E(cins, wd, ws);
25830 
25831       case 0x0F:
25832          return msa_3R_0F(cins, wd, ws);
25833 
25834       case 0x10:
25835          return msa_3R_10(cins, wd, ws);
25836 
25837       case 0x11:
25838          return msa_3R_11(cins, wd, ws);
25839 
25840       case 0x12:
25841          return msa_3R_12(cins, wd, ws);
25842 
25843       case 0x13:
25844          return msa_3R_13(cins, wd, ws);
25845 
25846       case 0x14:
25847          return msa_3R_14(cins, wd, ws);
25848 
25849       case 0x15:
25850          return msa_3R_15(cins, wd, ws);
25851 
25852       case 0x19:
25853          return msa_ELM(cins, wd, ws);
25854 
25855       case 0x1A:
25856          return msa_3R_1A(cins, wd, ws);
25857 
25858       case 0x1B:
25859          return msa_3R_1B(cins, wd, ws);
25860 
25861       case 0x1C:
25862          return msa_3R_1C(cins, wd, ws);
25863 
25864       case 0x1E:
25865          if ((cins & 0x03000000) == 0)
25866             return msa_VEC(cins, wd, ws);
25867          else if ((cins & 0x00200000) == 0)
25868             return msa_2R(cins, wd, ws);
25869          else
25870             return msa_2RF(cins, wd, ws);
25871 
25872       case 0x20:
25873          return msa_MI10_load(cins, wd, ws);
25874 
25875       case 0x24:
25876          return msa_MI10_store(cins, wd, ws);
25877    }
25878 
25879    return -1;
25880 }
25881 
25882 /*------------------------------------------------------------*/
25883 /*---          Disassemble a single instruction            ---*/
25884 /*------------------------------------------------------------*/
25885 
25886 /* Disassemble a single instruction into IR. The instruction is
25887    located in host memory at guest_instr, and has guest IP of
25888    guest_PC_curr_instr, which will have been set before the call
25889    here. */
25890 
disInstr_MIPS_WRK(Bool (* resteerOkFn)(void *,Addr),Bool resteerCisOk,void * callback_opaque,Long delta64,const VexArchInfo * archinfo,const VexAbiInfo * abiinfo,Bool sigill_diag)25891 static DisResult disInstr_MIPS_WRK ( Bool(*resteerOkFn) (/*opaque */void *,
25892                                                                     Addr),
25893                                      Bool         resteerCisOk,
25894                                      void*        callback_opaque,
25895                                      Long         delta64,
25896                                      const VexArchInfo* archinfo,
25897                                      const VexAbiInfo*  abiinfo,
25898                                      Bool         sigill_diag )
25899 {
25900    IRTemp t0, t1 = 0, t2, t3, t4, t5, t6, t7;
25901 
25902    UInt opcode, cins, rs, rt, rd, sa, ft, fs, fd, fmt, tf, nd, function,
25903         trap_code, imm, instr_index, p, msb, lsb, size, rot, sel;
25904    /* Additional variables for instruction fields in DSP ASE insructions */
25905    UInt ac;
25906 
25907    DisResult dres;
25908 
25909    static IRExpr *lastn = NULL;  /* last jump addr */
25910    static IRStmt *bstmt = NULL;  /* branch (Exit) stmt */
25911 
25912    /* The running delta */
25913    Int delta = (Int) delta64;
25914 
25915    /* Holds eip at the start of the insn, so that we can print
25916       consistent error messages for unimplemented insns. */
25917    Int delta_start = delta;
25918 
25919    /* Are we in a delay slot ? */
25920    Bool delay_slot_branch, likely_delay_slot, delay_slot_jump;
25921 
25922    /* Set result defaults. */
25923    dres.whatNext = Dis_Continue;
25924    dres.len = 0;
25925    dres.continueAt = 0;
25926    dres.jk_StopHere = Ijk_INVALID;
25927    dres.hint        = Dis_HintNone;
25928 
25929    delay_slot_branch = likely_delay_slot = delay_slot_jump = False;
25930 
25931    const UChar *code = guest_code + delta;
25932    cins = getUInt(code);
25933    DIP("\t0x%llx:\t0x%08x\t", (Addr64)guest_PC_curr_instr, cins);
25934 
25935    if (delta != 0) {
25936       if (branch_or_jump(guest_code + delta - 4)) {
25937          if (lastn == NULL && bstmt == NULL) {
25938             vassert(0);
25939          } else {
25940             dres.whatNext = Dis_StopHere;
25941             if (lastn != NULL) {
25942                delay_slot_jump = True;
25943             } else if (bstmt != NULL) {
25944                delay_slot_branch = True;
25945             }
25946          }
25947       }
25948 
25949       if (branch_or_link_likely(guest_code + delta - 4)) {
25950          likely_delay_slot = True;
25951       }
25952    }
25953 
25954    /* Spot "Special" instructions (see comment at top of file). */
25955    {
25956       /* Spot the 16-byte preamble:
25957        ****mips32****
25958        "srl $0, $0, 13
25959        "srl $0, $0, 29
25960        "srl $0, $0, 3
25961        "srl $0, $0, 19
25962 
25963        ****mips64****
25964        dsll $0, $0, 3
25965        dsll $0, $0, 13
25966        dsll $0, $0, 29
25967        dsll $0, $0, 19 */
25968 
25969       UInt word1 = mode64 ? 0xF8  : 0x342;
25970       UInt word2 = mode64 ? 0x378 : 0x742;
25971       UInt word3 = mode64 ? 0x778 : 0xC2;
25972       UInt word4 = mode64 ? 0x4F8 : 0x4C2;
25973       if (getUInt(code + 0) == word1 && getUInt(code + 4) == word2 &&
25974           getUInt(code + 8) == word3 && getUInt(code + 12) == word4) {
25975          /* Got a "Special" instruction preamble. Which one is it? */
25976          if (getUInt(code + 16) == 0x01ad6825 /* or $13, $13, $13 */ ) {
25977             /* $11 = client_request ( $12 ) */
25978             DIP("$11 = client_request ( $12 )");
25979             if (mode64)
25980                putPC(mkU64(guest_PC_curr_instr + 20));
25981             else
25982                putPC(mkU32(guest_PC_curr_instr + 20));
25983             dres.jk_StopHere = Ijk_ClientReq;
25984             dres.whatNext    = Dis_StopHere;
25985 
25986             goto decode_success;
25987          } else if (getUInt(code + 16) == 0x01ce7025 /* or $14, $14, $14 */ ) {
25988             /* $11 = guest_NRADDR */
25989             DIP("$11 = guest_NRADDR");
25990             dres.len = 20;
25991             delta += 20;
25992             if (mode64)
25993                putIReg(11, IRExpr_Get(offsetof(VexGuestMIPS64State,
25994                                                guest_NRADDR), Ity_I64));
25995             else
25996                putIReg(11, IRExpr_Get(offsetof(VexGuestMIPS32State,
25997                                                guest_NRADDR), Ity_I32));
25998             goto decode_success;
25999          } else if (getUInt(code + 16) == 0x01ef7825 /* or $15, $15, $15 */ ) {
26000             /*  branch-and-link-to-noredir $25 */
26001             DIP("branch-and-link-to-noredir $25");
26002             if (mode64)
26003                putIReg(31, mkU64(guest_PC_curr_instr + 20));
26004             else
26005                putIReg(31, mkU32(guest_PC_curr_instr + 20));
26006             putPC(getIReg(25));
26007             dres.jk_StopHere = Ijk_NoRedir;
26008             dres.whatNext    = Dis_StopHere;
26009             goto decode_success;
26010          } else if (getUInt(code + 16) == 0x016b5825 /* or $11,$11,$11 */ ) {
26011            /* IR injection */
26012             DIP("IR injection");
26013 #if defined (_MIPSEL)
26014             vex_inject_ir(irsb, Iend_LE);
26015 #elif defined (_MIPSEB)
26016             vex_inject_ir(irsb, Iend_BE);
26017 #endif
26018             if (mode64) {
26019                stmt(IRStmt_Put(offsetof(VexGuestMIPS64State, guest_CMSTART),
26020                                mkU64(guest_PC_curr_instr)));
26021                stmt(IRStmt_Put(offsetof(VexGuestMIPS64State, guest_CMLEN),
26022                                mkU64(20)));
26023 
26024                putPC(mkU64(guest_PC_curr_instr + 20));
26025             } else {
26026                stmt(IRStmt_Put(offsetof(VexGuestMIPS32State, guest_CMSTART),
26027                                mkU32(guest_PC_curr_instr)));
26028                stmt(IRStmt_Put(offsetof(VexGuestMIPS32State, guest_CMLEN),
26029                                mkU32(20)));
26030 
26031                putPC(mkU32(guest_PC_curr_instr + 20));
26032             }
26033             dres.whatNext    = Dis_StopHere;
26034             dres.jk_StopHere = Ijk_InvalICache;
26035             dres.len = 20;
26036             delta += 20;
26037             goto decode_success;
26038          }
26039 
26040          /* We don't know what it is.  Set opc1/opc2 so decode_failure
26041             can print the insn following the Special-insn preamble. */
26042          delta += 16;
26043          goto decode_failure;
26044        /*NOTREACHED*/}
26045    }
26046 
26047    opcode = get_opcode(cins);
26048    imm = get_imm(cins);
26049    rs = get_rs(cins);
26050    rt = get_rt(cins);
26051    rd = get_rd(cins);
26052    sa = get_sa(cins);
26053    fs = get_fs(cins);
26054    fd = get_fd(cins);
26055    ft = get_ft(cins);
26056    tf = get_tf(cins);
26057    nd = get_nd(cins);
26058    sel = get_sel(cins);
26059    fmt = get_fmt(cins);
26060    instr_index = get_instr_index(cins);
26061    trap_code = get_code(cins);
26062    function = get_function(cins);
26063    IRType ty = mode64 ? Ity_I64 : Ity_I32;
26064    IRType tyF = fp_mode64 ? Ity_F64 : Ity_F32;
26065 
26066    ac = get_acNo(cins);
26067 
26068    switch (opcode) {
26069 
26070    case 0x03:     /* JAL */
26071       DIP("jal 0x%x", instr_index);
26072       if (mode64) {
26073          putIReg(31, mkU64(guest_PC_curr_instr + 8));
26074          t0 = newTemp(ty);
26075          assign(t0, mkU64((guest_PC_curr_instr & 0xFFFFFFFFF0000000ULL) |
26076                           (instr_index << 2)));
26077       } else {
26078          putIReg(31, mkU32(guest_PC_curr_instr + 8));
26079          t0 = newTemp(ty);
26080          assign(t0, mkU32((guest_PC_curr_instr & 0xF0000000) |
26081                           (instr_index << 2)));
26082       }
26083       lastn = mkexpr(t0);
26084       break;
26085    case 0x02:     /* J */
26086       DIP("j 0x%x", instr_index);
26087       t0 = newTemp(ty);
26088       if (mode64)
26089          assign(t0, mkU64((guest_PC_curr_instr & 0xFFFFFFFFF0000000ULL) |
26090                           (instr_index << 2)));
26091       else
26092          assign(t0, mkU32((guest_PC_curr_instr & 0xF0000000) |
26093                           (instr_index << 2)));
26094       lastn = mkexpr(t0);
26095       break;
26096 
26097    case 0x11: {  /* COP1 */
26098       if (fmt == 0x3 && fd == 0 && function == 0) {  /* MFHC1 */
26099          DIP("mfhc1 r%u, f%u", rt, fs);
26100          if (VEX_MIPS_CPU_HAS_MIPS32R2(archinfo->hwcaps) ||
26101              VEX_MIPS_CPU_HAS_MIPSR6(archinfo->hwcaps)) {
26102             if (fp_mode64) {
26103                t0 = newTemp(Ity_I64);
26104                t1 = newTemp(Ity_I32);
26105                assign(t0, unop(Iop_ReinterpF64asI64, getDReg(fs)));
26106                assign(t1, unop(Iop_64HIto32, mkexpr(t0)));
26107                putIReg(rt, mkWidenFrom32(ty, mkexpr(t1), True));
26108             } else {
26109                putIReg(rt, mkWidenFrom32(ty, unop(Iop_ReinterpF32asI32,
26110                                                   getFReg(fs | 1)), True));
26111             }
26112          } else {
26113             ILLEGAL_INSTRUCTON;
26114          }
26115          break;
26116       } else if (fmt == 0x7 && fd == 0 && function == 0) {  /* MTHC1 */
26117          DIP("mthc1 r%u, f%u", rt, fs);
26118          if (VEX_MIPS_CPU_HAS_MIPS32R2(archinfo->hwcaps) ||
26119              VEX_MIPS_CPU_HAS_MIPSR6(archinfo->hwcaps)) {
26120             if (fp_mode64) {
26121                t0 = newTemp(Ity_I64);
26122                assign(t0, binop(Iop_32HLto64, mkNarrowTo32(ty, getIReg(rt)),
26123                                 unop(Iop_ReinterpF32asI32,
26124                                      getLoFromF64(Ity_F64, getDReg(fs)))));
26125                putDReg(fs, unop(Iop_ReinterpI64asF64, mkexpr(t0)));
26126             } else {
26127                putFReg(fs | 1, unop(Iop_ReinterpI32asF32,
26128                                     mkNarrowTo32(ty, getIReg(rt))));
26129             }
26130          } else {
26131             ILLEGAL_INSTRUCTON;
26132          }
26133          break;
26134       } else if (fmt == 0x8) {  /* BC */
26135          /* FcConditionalCode(bc1_cc) */
26136          UInt bc1_cc = get_bc1_cc(cins);
26137          t1 = newTemp(Ity_I1);
26138          t2 = newTemp(Ity_I32);
26139          t3 = newTemp(Ity_I1);
26140 
26141          assign(t1, binop(Iop_CmpEQ32, mkU32(0), mkU32(bc1_cc)));
26142          assign(t2, IRExpr_ITE(mkexpr(t1),
26143                                binop(Iop_And32,
26144                                      binop(Iop_Shr32, getFCSR(), mkU8(23)),
26145                                      mkU32(0x1)),
26146                                binop(Iop_And32,
26147                                      binop(Iop_Shr32, getFCSR(),
26148                                            mkU8(24 + bc1_cc)),
26149                                      mkU32(0x1))));
26150 
26151          if (tf == 1 && nd == 0) {
26152             /* branch on true */
26153             DIP("bc1t %u, %u", bc1_cc, imm);
26154             assign(t3, binop(Iop_CmpEQ32, mkU32(1), mkexpr(t2)));
26155             dis_branch(False, mkexpr(t3), imm, &bstmt);
26156             break;
26157          } else if (tf == 0 && nd == 0) {
26158             /* branch on false */
26159             DIP("bc1f %u, %u", bc1_cc, imm);
26160             assign(t3, binop(Iop_CmpEQ32, mkU32(0), mkexpr(t2)));
26161             dis_branch(False, mkexpr(t3), imm, &bstmt);
26162             break;
26163          } else if (nd == 1 && tf == 0) {
26164             DIP("bc1fl %u, %u", bc1_cc, imm);
26165             lastn = dis_branch_likely(binop(Iop_CmpNE32, mkexpr(t2),
26166                                             mkU32(0x0)), imm);
26167             break;
26168          } else if (nd == 1 && tf == 1) {
26169             DIP("bc1tl %u, %u", bc1_cc, imm);
26170             lastn = dis_branch_likely(binop(Iop_CmpEQ32, mkexpr(t2),
26171                                             mkU32(0x0)), imm);
26172             break;
26173          } else
26174             goto decode_failure;
26175       } else if (fmt >= 0x1c && has_msa) { /* BNZ.df */
26176          Int df = fmt & 3;
26177          t0 = newTemp(Ity_I32);
26178          t1 = newTemp(Ity_V128);
26179          t2 = newTemp(Ity_V128);
26180          t3 = newTemp(Ity_V128);
26181          assign(t1, getWReg(ft));
26182          assign(t2, binop(Iop_64HLtoV128, mkU64(0), mkU64(0)));
26183 
26184          switch (df) {
26185             case 0x00: { /* BNZ.B */
26186                   DIP("BNZ.B w%d, %d", ft, imm);
26187                   assign(t3, binop(Iop_CmpEQ8x16, mkexpr(t1), mkexpr(t2)));
26188                   break;
26189                }
26190 
26191             case 0x01: { /* BNZ.H */
26192                   DIP("BNZ.H w%d, %d", ft, imm);
26193                   assign(t3, binop(Iop_CmpEQ16x8, mkexpr(t1), mkexpr(t2)));
26194                   break;
26195                }
26196 
26197             case 0x02: { /* BNZ.W */
26198                   DIP("BNZ.W w%d, %d", ft, imm);
26199                   assign(t3, binop(Iop_CmpEQ32x4, mkexpr(t1), mkexpr(t2)));
26200                   break;
26201                }
26202 
26203             case 0x03: { /* BNZ.D */
26204                   DIP("BNZ.D w%d, %d", ft, imm);
26205                   assign(t3, binop(Iop_CmpEQ64x2, mkexpr(t1), mkexpr(t2)));
26206                   break;
26207                }
26208          }
26209 
26210          assign(t0,
26211                 binop(Iop_Or32,
26212                       binop(Iop_Or32,
26213                             unop(Iop_V128to32, mkexpr(t3)),
26214                             unop(Iop_64HIto32, unop(Iop_V128to64, mkexpr(t3)))),
26215                       binop(Iop_Or32,
26216                             unop(Iop_64to32,
26217                                  unop(Iop_V128HIto64, mkexpr(t3))),
26218                             unop(Iop_64HIto32,
26219                                  unop(Iop_V128HIto64, mkexpr(t3))))));
26220          dis_branch(False,
26221                     binop(Iop_CmpEQ32, mkexpr(t0), mkU32(0)), imm, &bstmt);
26222       } else if (fmt == 0x0F && has_msa) { /* BNZ.V */
26223          t0 = newTemp(Ity_I32);
26224          t1 = newTemp(Ity_V128);
26225          assign(t1, getWReg(ft));
26226          assign(t0,
26227                 binop(Iop_Or32,
26228                       binop(Iop_Or32,
26229                             unop(Iop_V128to32, mkexpr(t1)),
26230                             unop(Iop_64HIto32, unop(Iop_V128to64, mkexpr(t1)))),
26231                       binop(Iop_Or32,
26232                             unop(Iop_64to32, unop(Iop_V128HIto64, mkexpr(t1))),
26233                             unop(Iop_64HIto32,
26234                                  unop(Iop_V128HIto64, mkexpr(t1))))));
26235          dis_branch(False,
26236                     binop(Iop_CmpNE32, mkexpr(t0), mkU32(0)), imm, &bstmt);
26237       } else if (fmt >= 0x18 && has_msa) { /* BZ.df */
26238          Int df = fmt & 3;
26239          t0 = newTemp(Ity_I32);
26240          t1 = newTemp(Ity_V128);
26241          t2 = newTemp(Ity_V128);
26242          t3 = newTemp(Ity_V128);
26243          assign(t1, getWReg(ft));
26244          assign(t2, binop(Iop_64HLtoV128, mkU64(0), mkU64(0)));
26245 
26246          switch (df) {
26247             case 0x00: { /* BZ.B */
26248                   DIP("BZ.B w%d, %d", ft, imm);
26249                   assign(t3, binop(Iop_CmpEQ8x16, mkexpr(t1), mkexpr(t2)));
26250                   break;
26251                }
26252 
26253             case 0x01: { /* BZ.H */
26254                   DIP("BZ.H w%d, %d", ft, imm);
26255                   assign(t3, binop(Iop_CmpEQ16x8, mkexpr(t1), mkexpr(t2)));
26256                   break;
26257                }
26258 
26259             case 0x02: { /* BZ.W */
26260                   DIP("BZ.W w%d, %d", ft, imm);
26261                   assign(t3, binop(Iop_CmpEQ32x4, mkexpr(t1), mkexpr(t2)));
26262                   break;
26263                }
26264 
26265             case 0x03: { /* BZ.D */
26266                   DIP("BZ.D w%d, %d", ft, imm);
26267                   assign(t3, binop(Iop_CmpEQ64x2, mkexpr(t1), mkexpr(t2)));
26268                   break;
26269                }
26270          }
26271 
26272          assign(t0,
26273                 binop(Iop_Or32,
26274                       binop(Iop_Or32,
26275                             unop(Iop_V128to32, mkexpr(t3)),
26276                             unop(Iop_64HIto32, unop(Iop_V128to64, mkexpr(t3)))),
26277                       binop(Iop_Or32,
26278                             unop(Iop_64to32, unop(Iop_V128HIto64, mkexpr(t3))),
26279                             unop(Iop_64HIto32,
26280                                  unop(Iop_V128HIto64, mkexpr(t3))))));
26281          dis_branch(False,
26282                     binop(Iop_CmpNE32, mkexpr(t0), mkU32(0)), imm, &bstmt);
26283       } else if (fmt == 0x0B && has_msa) { /* BZ.V */
26284          t0 = newTemp(Ity_I32);
26285          t1 = newTemp(Ity_V128);
26286          assign(t1, getWReg(ft));
26287          assign(t0,
26288                 binop(Iop_Or32,
26289                       binop(Iop_Or32,
26290                             unop(Iop_V128to32, mkexpr(t1)),
26291                             unop(Iop_64HIto32, unop(Iop_V128to64, mkexpr(t1)))),
26292                       binop(Iop_Or32,
26293                             unop(Iop_64to32, unop(Iop_V128HIto64, mkexpr(t1))),
26294                             unop(Iop_64HIto32,
26295                                  unop(Iop_V128HIto64, mkexpr(t1))))));
26296          dis_branch(False,
26297                     binop(Iop_CmpEQ32, mkexpr(t0), mkU32(0)), imm, &bstmt);
26298       } else if (fmt == 0x09) { /* BC1EQZ */
26299          if (VEX_MIPS_CPU_HAS_MIPSR6(archinfo->hwcaps)) {
26300             DIP("bc1eqz f%u, %u", ft, imm);
26301             t1 = newTemp(Ity_I1);
26302             if (mode64) {
26303                assign(t1, binop(Iop_CmpEQ64,
26304                                 binop(Iop_And64,
26305                                       unop(Iop_ReinterpF64asI64, getDReg(ft)),
26306                                       mkU64(1)),
26307                                 mkU64(0)));
26308             } else {
26309                assign(t1, binop(Iop_CmpEQ32,
26310                                 binop(Iop_And32,
26311                                       unop(Iop_64to32,
26312                                            unop(Iop_ReinterpF64asI64, getDReg(ft))),
26313                                       mkU32(1)),
26314                                 mkU32(0)));
26315             }
26316             dis_branch(False, mkexpr(t1), imm, &bstmt);
26317          } else {
26318             ILLEGAL_INSTRUCTON;
26319          }
26320       } else if (fmt == 0x0D) { /* BC1NEZ */
26321          if (VEX_MIPS_CPU_HAS_MIPSR6(archinfo->hwcaps)) {
26322             DIP("bc1nez f%u, %u", ft, imm);
26323             t1 = newTemp(Ity_I1);
26324             if (mode64) {
26325                assign(t1, binop(Iop_CmpNE64,
26326                                 binop(Iop_And64,
26327                                       unop(Iop_ReinterpF64asI64, getDReg(ft)),
26328                                       mkU64(1)),
26329                                 mkU64(0)));
26330             } else {
26331                assign(t1, binop(Iop_CmpNE32,
26332                                 binop(Iop_And32,
26333                                       unop(Iop_64to32,
26334                                            unop(Iop_ReinterpF64asI64, getDReg(ft))),
26335                                       mkU32(1)),
26336                                 mkU32(0)));
26337             }
26338             dis_branch(False, mkexpr(t1), imm, &bstmt);
26339          } else {
26340             ILLEGAL_INSTRUCTON;
26341          }
26342       } else {
26343          if (fmt == 0x15) { /* CMP.cond.d */
26344             Bool comparison = True;
26345             UInt signaling = CMPAFD;
26346             DIP("cmp.cond.d f%u, f%u, f%u, cond %u", fd, fs, ft, function);
26347             t0 = newTemp(Ity_I32);
26348             /* Conditions starting with S should signal exception on QNaN inputs. */
26349             switch (function) {
26350                case 8:  /* SAF */
26351                   signaling = CMPSAFD;
26352                case 0: /* AF */
26353                   assign(t0, binop(Iop_CmpF64, getDReg(fs), getDReg(ft)));
26354                   calculateFCSR(fs, ft, signaling, False, 2);
26355                   putDReg(fd,
26356                           binop(Iop_I64StoF64,
26357                                 get_IR_roundingmode(), mkU64(0)));
26358                   break;
26359                case 9: /* SUN */
26360                   signaling = CMPSAFD;
26361                case 1: /* UN */
26362                   assign(t0, binop(Iop_CmpF64, getDReg(fs), getDReg(ft)));
26363                   calculateFCSR(fs, ft, signaling, False, 2);
26364                   putDReg(fd,
26365                           IRExpr_ITE(binop(Iop_CmpEQ32, mkexpr(t0), mkU32(0x45)),
26366                                      unop(Iop_ReinterpI64asF64,
26367                                           mkU64(0xFFFFFFFFFFFFFFFFULL)),
26368                                      binop(Iop_I64StoF64,
26369                                            get_IR_roundingmode(), mkU64(0))));
26370                   break;
26371                case 0x19: /* SOR */
26372                   signaling = CMPSAFD;
26373                case 0x11: /* OR */
26374                   assign(t0, binop(Iop_CmpF64, getDReg(fs), getDReg(ft)));
26375                   calculateFCSR(fs, ft, signaling, False, 2);
26376                   putDReg(fd,
26377                           IRExpr_ITE(binop(Iop_CmpEQ32, mkexpr(t0), mkU32(0x45)),
26378                                      binop(Iop_I64StoF64,
26379                                            get_IR_roundingmode(), mkU64(0)),
26380                                      unop(Iop_ReinterpI64asF64,
26381                                           mkU64(0xFFFFFFFFFFFFFFFFULL))));
26382                   break;
26383                case 0xa: /* SEQ */
26384                   signaling = CMPSAFD;
26385                case 2: /* EQ */
26386                   assign(t0, binop(Iop_CmpF64, getDReg(fs), getDReg(ft)));
26387                   calculateFCSR(fs, ft, signaling, False, 2);
26388                   putDReg(fd,
26389                           IRExpr_ITE(binop(Iop_CmpEQ32, mkexpr(t0), mkU32(0x40)),
26390                                      unop(Iop_ReinterpI64asF64,
26391                                           mkU64(0xFFFFFFFFFFFFFFFFULL)),
26392                                      binop(Iop_I64StoF64,
26393                                            get_IR_roundingmode(), mkU64(0))));
26394                   break;
26395                case 0x1A: /* SNEQ */
26396                   signaling = CMPSAFD;
26397                case 0x12: /* NEQ */
26398                   assign(t0, binop(Iop_CmpF64, getDReg(fs), getDReg(ft)));
26399                   calculateFCSR(fs, ft, signaling, False, 2);
26400                   putDReg(fd,
26401                           IRExpr_ITE(binop(Iop_CmpEQ32, mkexpr(t0), mkU32(0x40)),
26402                                      binop(Iop_I64StoF64,
26403                                            get_IR_roundingmode(), mkU64(0)),
26404                                      unop(Iop_ReinterpI64asF64,
26405                                           mkU64(0xFFFFFFFFFFFFFFFFULL))));
26406                   break;
26407                case 0xB: /* SUEQ */
26408                   signaling = CMPSAFD;
26409                case 0x3: /* UEQ */
26410                   assign(t0, binop(Iop_CmpF64, getDReg(fs), getDReg(ft)));
26411                   calculateFCSR(fs, ft, signaling, False, 2);
26412                   putDReg(fd,
26413                           IRExpr_ITE(binop(Iop_CmpEQ32, mkexpr(t0), mkU32(0x40)),
26414                                      unop(Iop_ReinterpI64asF64,
26415                                           mkU64(0xFFFFFFFFFFFFFFFFULL)),
26416                                      IRExpr_ITE(binop(Iop_CmpEQ32,
26417                                                       mkexpr(t0), mkU32(0x45)),
26418                                                 unop(Iop_ReinterpI64asF64,
26419                                                      mkU64(0xFFFFFFFFFFFFFFFFULL)),
26420                                                 binop(Iop_I64StoF64,
26421                                                       get_IR_roundingmode(),
26422                                                       mkU64(0)))));
26423                   break;
26424                case 0x1B:  /* SNEQ */
26425                   signaling = CMPSAFD;
26426                case 0x13:  /* NEQ */
26427                   assign(t0, binop(Iop_CmpF64, getDReg(fs), getDReg(ft)));
26428                   calculateFCSR(fs, ft, signaling, False, 2);
26429                   putDReg(fd,
26430                           IRExpr_ITE(binop(Iop_CmpEQ32, mkexpr(t0),mkU32(0x01)),
26431                                      unop(Iop_ReinterpI64asF64,
26432                                           mkU64(0xFFFFFFFFFFFFFFFFULL)),
26433                                      IRExpr_ITE(binop(Iop_CmpEQ32,
26434                                                       mkexpr(t0),mkU32(0x00)),
26435                                                 unop(Iop_ReinterpI64asF64,
26436                                                      mkU64(0xFFFFFFFFFFFFFFFFULL)),
26437                                                 binop(Iop_I64StoF64,
26438                                                       get_IR_roundingmode(),
26439                                                       mkU64(0)))));
26440                   break;
26441                case 0xC: /* SLT */
26442                   signaling = CMPSAFD;
26443                case 0x4: /* LT */
26444                   assign(t0, binop(Iop_CmpF64, getDReg(fs), getDReg(ft)));
26445                   calculateFCSR(fs, ft, signaling, False, 2);
26446                   putDReg(fd,
26447                           IRExpr_ITE(binop(Iop_CmpEQ32, mkexpr(t0), mkU32(0x01)),
26448                                      unop(Iop_ReinterpI64asF64,
26449                                           mkU64(0xFFFFFFFFFFFFFFFFULL)),
26450                                      binop(Iop_I64StoF64,
26451                                            get_IR_roundingmode(), mkU64(0))));
26452                   break;
26453                case 0xD: /* SULT */
26454                   signaling = CMPSAFD;
26455                case 0x5: /* ULT */
26456                   assign(t0, binop(Iop_CmpF64, getDReg(fs), getDReg(ft)));
26457                   calculateFCSR(fs, ft, signaling, False, 2);
26458                   putDReg(fd,
26459                           IRExpr_ITE(binop(Iop_CmpEQ32, mkexpr(t0), mkU32(0x01)),
26460                                      unop(Iop_ReinterpI64asF64,
26461                                           mkU64(0xFFFFFFFFFFFFFFFFULL)),
26462                                     IRExpr_ITE(binop(Iop_CmpEQ32,
26463                                                      mkexpr(t0), mkU32(0x45)),
26464                                                unop(Iop_ReinterpI64asF64,
26465                                                     mkU64(0xFFFFFFFFFFFFFFFFULL)),
26466                                                binop(Iop_I64StoF64,
26467                                                      get_IR_roundingmode(),
26468                                                      mkU64(0)))));
26469                   break;
26470                case 0xE: /* SLE */
26471                   signaling = CMPSAFD;
26472                case 0x6: /* LE */
26473                   assign(t0, binop(Iop_CmpF64, getDReg(fs), getDReg(ft)));
26474                   calculateFCSR(fs, ft, signaling, False, 2);
26475                   putDReg(fd,
26476                           IRExpr_ITE(binop(Iop_CmpEQ32, mkexpr(t0),mkU32(0x01)),
26477                                      unop(Iop_ReinterpI64asF64,
26478                                           mkU64(0xFFFFFFFFFFFFFFFFULL)),
26479                                      IRExpr_ITE(binop(Iop_CmpEQ32,
26480                                                       mkexpr(t0),mkU32(0x40)),
26481                                                 unop(Iop_ReinterpI64asF64,
26482                                                      mkU64(0xFFFFFFFFFFFFFFFFULL)),
26483                                                 binop(Iop_I64StoF64,
26484                                                       get_IR_roundingmode(),
26485                                                       mkU64(0)))));
26486                   break;
26487                case 0xF: /* SULE */
26488                   signaling = CMPSAFD;
26489                case 0x7: /* ULE */
26490                   assign(t0, binop(Iop_CmpF64, getDReg(fs), getDReg(ft)));
26491                   calculateFCSR(fs, ft, signaling, False, 2);
26492                   putDReg(fd,
26493                           IRExpr_ITE(binop(Iop_CmpEQ32, mkexpr(t0), mkU32(0x0)),
26494                                      binop(Iop_I64StoF64,
26495                                            get_IR_roundingmode(), mkU64(0)),
26496                                      unop(Iop_ReinterpI64asF64,
26497                                           mkU64(0xFFFFFFFFFFFFFFFFULL))));
26498                   break;
26499                default:
26500                   comparison = False;
26501             }
26502             if (comparison) {
26503                if (!VEX_MIPS_CPU_HAS_MIPSR6(archinfo->hwcaps)) {
26504                   ILLEGAL_INSTRUCTON;
26505                }
26506                break;
26507             }
26508 
26509          } else if (fmt == 0x14) {
26510             Bool comparison = True;
26511             UInt signaling = CMPAFS;
26512             DIP("cmp.cond.s f%u, f%u, f%u, cond %u", fd, fs, ft, function);
26513             t0 = newTemp(Ity_I32);
26514             /* Conditions starting with S should signal exception on QNaN inputs. */
26515             switch (function) {
26516                case 8:  /* SAF */
26517                   signaling = CMPSAFS;
26518                case 0: /* AF */
26519                   assign(t0, binop(Iop_CmpF32,
26520                                    getLoFromF64(Ity_F64, getFReg(fs)),
26521                                    getLoFromF64(Ity_F64, getFReg(ft))));
26522                   calculateFCSR(fs, ft, signaling, True, 2);
26523                   putFReg(fd,
26524                           mkWidenFromF32(tyF,
26525                                          binop(Iop_I32StoF32,
26526                                                get_IR_roundingmode(), mkU32(0))));
26527                   break;
26528                case 9: /* SUN */
26529                   signaling = CMPSAFS;
26530                case 1: /* UN */
26531                   assign(t0, binop(Iop_CmpF32,
26532                                    getLoFromF64(Ity_F64, getFReg(fs)),
26533                                    getLoFromF64(Ity_F64, getFReg(ft))));
26534                   calculateFCSR(fs, ft, signaling, True, 2);
26535                   putFReg(fd,
26536                           IRExpr_ITE(binop(Iop_CmpEQ32, mkexpr(t0), mkU32(0x45)),
26537                                      mkWidenFromF32(tyF,
26538                                                     unop(Iop_ReinterpI32asF32,
26539                                                          mkU32(0xFFFFFFFFU))),
26540                                      mkWidenFromF32(tyF,
26541                                                     binop(Iop_I32StoF32,
26542                                                           get_IR_roundingmode(),
26543                                                           mkU32(0)))));
26544                   break;
26545                case 0x19: /* SOR */
26546                   signaling = CMPSAFS;
26547                case 0x11: /* OR */
26548                   assign(t0, binop(Iop_CmpF32,
26549                                    getLoFromF64(Ity_F64, getFReg(fs)),
26550                                    getLoFromF64(Ity_F64, getFReg(ft))));
26551                   calculateFCSR(fs, ft, signaling, True, 2);
26552                   putFReg(fd,
26553                           IRExpr_ITE(binop(Iop_CmpEQ32, mkexpr(t0), mkU32(0x45)),
26554                                      mkWidenFromF32(tyF,
26555                                                     binop(Iop_I32StoF32,
26556                                                           get_IR_roundingmode(),
26557                                                           mkU32(0))),
26558                                      mkWidenFromF32(tyF,
26559                                                     unop(Iop_ReinterpI32asF32,
26560                                                     mkU32(0xFFFFFFFFU)))));
26561                   break;
26562                case 0xa: /* SEQ */
26563                   signaling = CMPSAFS;
26564                case 2: /* EQ */
26565                   assign(t0, binop(Iop_CmpF32,
26566                                    getLoFromF64(Ity_F64, getFReg(fs)),
26567                                    getLoFromF64(Ity_F64, getFReg(ft))));
26568                   calculateFCSR(fs, ft, signaling, True, 2);
26569                   putFReg(fd,
26570                           IRExpr_ITE(binop(Iop_CmpEQ32, mkexpr(t0), mkU32(0x40)),
26571                                      mkWidenFromF32(tyF,
26572                                                     unop(Iop_ReinterpI32asF32,
26573                                                          mkU32(0xFFFFFFFFU))),
26574                                      mkWidenFromF32(tyF,
26575                                                     binop(Iop_I32StoF32,
26576                                                           get_IR_roundingmode(),
26577                                                           mkU32(0)))));
26578                   break;
26579                case 0x1A: /* SNEQ */
26580                   signaling = CMPSAFS;
26581                case 0x12: /* NEQ */
26582                   assign(t0, binop(Iop_CmpF32,
26583                                    getLoFromF64(Ity_F64, getFReg(fs)),
26584                                    getLoFromF64(Ity_F64, getFReg(ft))));
26585                   calculateFCSR(fs, ft, signaling, True, 2);
26586                   putFReg(fd,
26587                           IRExpr_ITE(binop(Iop_CmpEQ32, mkexpr(t0), mkU32(0x40)),
26588                                      mkWidenFromF32(tyF,
26589                                                     binop(Iop_I32StoF32,
26590                                                           get_IR_roundingmode(),
26591                                                           mkU32(0))),
26592                                      mkWidenFromF32(tyF,
26593                                                     unop(Iop_ReinterpI32asF32,
26594                                                          mkU32(0xFFFFFFFFU)))));
26595                   break;
26596                case 0xB: /* SUEQ */
26597                   signaling = CMPSAFS;
26598                case 0x3: /* UEQ */
26599                   assign(t0, binop(Iop_CmpF32,
26600                                    getLoFromF64(Ity_F64, getFReg(fs)),
26601                                    getLoFromF64(Ity_F64, getFReg(ft))));
26602                   calculateFCSR(fs, ft, signaling, True, 2);
26603                   putFReg(fd,
26604                           IRExpr_ITE(binop(Iop_CmpEQ32, mkexpr(t0), mkU32(0x40)),
26605                                      mkWidenFromF32(tyF,
26606                                                     unop(Iop_ReinterpI32asF32,
26607                                                          mkU32(0xFFFFFFFFU))),
26608                                      IRExpr_ITE(binop(Iop_CmpEQ32,
26609                                                       mkexpr(t0), mkU32(0x45)),
26610                                                 mkWidenFromF32(tyF,
26611                                                                unop(Iop_ReinterpI32asF32,
26612                                                                mkU32(0xFFFFFFFFU))),
26613                                                 mkWidenFromF32(tyF,
26614                                                                binop(Iop_I32StoF32,
26615                                                                      get_IR_roundingmode(),
26616                                                                      mkU32(0))))));
26617                   break;
26618                case 0x1B:  /* SNEQ */
26619                   signaling = CMPSAFS;
26620                case 0x13:  /* NEQ */
26621                   assign(t0, binop(Iop_CmpF32,
26622                                    getLoFromF64(Ity_F64, getFReg(fs)),
26623                                    getLoFromF64(Ity_F64, getFReg(ft))));
26624                   calculateFCSR(fs, ft, signaling, True, 2);
26625                   putFReg(fd,
26626                           IRExpr_ITE(binop(Iop_CmpEQ32, mkexpr(t0),mkU32(0x01)),
26627                                      mkWidenFromF32(tyF,
26628                                                     unop(Iop_ReinterpI32asF32,
26629                                                     mkU32(0xFFFFFFFFU))),
26630                                      IRExpr_ITE(binop(Iop_CmpEQ32,
26631                                                       mkexpr(t0),mkU32(0x00)),
26632                                                 mkWidenFromF32(tyF,
26633                                                                unop(Iop_ReinterpI32asF32,
26634                                                                     mkU32(0xFFFFFFFFU))),
26635                                                 mkWidenFromF32(tyF,
26636                                                                binop(Iop_I32StoF32,
26637                                                                      get_IR_roundingmode(),
26638                                                                      mkU32(0))))));
26639                   break;
26640                case 0xC: /* SLT */
26641                   signaling = CMPSAFS;
26642                case 0x4: /* LT */
26643                   assign(t0, binop(Iop_CmpF32,
26644                                    getLoFromF64(Ity_F64, getFReg(fs)),
26645                                    getLoFromF64(Ity_F64, getFReg(ft))));
26646                   calculateFCSR(fs, ft, signaling, True, 2);
26647                   putFReg(fd,
26648                           IRExpr_ITE(binop(Iop_CmpEQ32, mkexpr(t0), mkU32(0x01)),
26649                                      mkWidenFromF32(tyF,
26650                                                     unop(Iop_ReinterpI32asF32,
26651                                                          mkU32(0xFFFFFFFFU))),
26652                                      mkWidenFromF32(tyF,
26653                                                     binop(Iop_I32StoF32,
26654                                                           get_IR_roundingmode(),
26655                                                           mkU32(0)))));
26656                   break;
26657                case 0xD: /* SULT */
26658                   signaling = CMPSAFS;
26659                case 0x5: /* ULT */
26660                   assign(t0, binop(Iop_CmpF32,
26661                                    getLoFromF64(Ity_F64, getFReg(fs)),
26662                                    getLoFromF64(Ity_F64, getFReg(ft))));
26663                   calculateFCSR(fs, ft, signaling, True, 2);
26664                   putFReg(fd,
26665                           IRExpr_ITE(binop(Iop_CmpEQ32, mkexpr(t0), mkU32(0x01)),
26666                                      mkWidenFromF32(tyF,
26667                                                     unop(Iop_ReinterpI32asF32,
26668                                                     mkU32(0xFFFFFFFFU))),
26669                                      IRExpr_ITE(binop(Iop_CmpEQ32,
26670                                                       mkexpr(t0), mkU32(0x45)),
26671                                                 mkWidenFromF32(tyF,
26672                                                                unop(Iop_ReinterpI32asF32,
26673                                                                     mkU32(0xFFFFFFFFU))),
26674                                                 mkWidenFromF32(tyF,
26675                                                                binop(Iop_I32StoF32,
26676                                                                      get_IR_roundingmode(),
26677                                                                      mkU32(0))))));
26678                   break;
26679                case 0xE: /* SLE */
26680                   signaling = CMPSAFS;
26681                case 0x6: /* LE */
26682                   assign(t0, binop(Iop_CmpF32,
26683                                    getLoFromF64(Ity_F64, getFReg(fs)),
26684                                    getLoFromF64(Ity_F64, getFReg(ft))));
26685                   calculateFCSR(fs, ft, signaling, True, 2);
26686                   putFReg(fd,
26687                           IRExpr_ITE(binop(Iop_CmpEQ32, mkexpr(t0),mkU32(0x01)),
26688                                      mkWidenFromF32(tyF,
26689                                                     unop(Iop_ReinterpI32asF32,
26690                                                     mkU32(0xFFFFFFFFU))),
26691                                      IRExpr_ITE(binop(Iop_CmpEQ32,
26692                                                       mkexpr(t0),mkU32(0x40)),
26693                                                 mkWidenFromF32(tyF,
26694                                                                unop(Iop_ReinterpI32asF32,
26695                                                                mkU32(0xFFFFFFFFU))),
26696                                                 mkWidenFromF32(tyF,
26697                                                                binop(Iop_I32StoF32,
26698                                                                      get_IR_roundingmode(),
26699                                                                      mkU32(0))))));
26700                   break;
26701                case 0xF: /* SULE */
26702                   signaling = CMPSAFS;
26703                case 0x7: /* ULE */
26704                   assign(t0, binop(Iop_CmpF32,
26705                                    getLoFromF64(Ity_F64, getFReg(fs)),
26706                                    getLoFromF64(Ity_F64, getFReg(ft))));
26707                   calculateFCSR(fs, ft, signaling, True, 2);
26708                   putFReg(fd,
26709                           IRExpr_ITE(binop(Iop_CmpEQ32, mkexpr(t0), mkU32(0x0)),
26710                                      mkWidenFromF32(tyF,
26711                                                     binop(Iop_I32StoF32,
26712                                                           get_IR_roundingmode(),
26713                                                           mkU32(0))),
26714                                      mkWidenFromF32(tyF,
26715                                                     unop(Iop_ReinterpI32asF32,
26716                                                     mkU32(0xFFFFFFFFU)))));
26717                   break;
26718                default:
26719                   comparison = False;
26720             }
26721             if (comparison) {
26722                if (!VEX_MIPS_CPU_HAS_MIPSR6(archinfo->hwcaps)) {
26723                   ILLEGAL_INSTRUCTON;
26724                }
26725                break;
26726             }
26727          }
26728 
26729          switch (function) {
26730             case 0x4: {  /* SQRT.fmt */
26731                switch (fmt) {
26732                   case 0x10: {  /* S */
26733                      IRExpr *rm = get_IR_roundingmode();
26734                      putFReg(fd, mkWidenFromF32(tyF, binop(Iop_SqrtF32, rm,
26735                                  getLoFromF64(tyF, getFReg(fs)))));
26736                      break;
26737                   }
26738                   case 0x11: {  /* D */
26739                      IRExpr *rm = get_IR_roundingmode();
26740                      putDReg(fd, binop(Iop_SqrtF64, rm, getDReg(fs)));
26741                      break;
26742                   }
26743                   default:
26744                      goto decode_failure;
26745                   }
26746                }
26747                break;
26748             case 0x5:  /* abs.fmt */
26749                switch (fmt) {
26750                   case 0x10:  /* S */
26751                      DIP("abs.s f%u, f%u", fd, fs);
26752                      putFReg(fd, mkWidenFromF32(tyF, unop(Iop_AbsF32,
26753                                  getLoFromF64(tyF, getFReg(fs)))));
26754                      break;
26755                   case 0x11:  /* D  */
26756                      DIP("abs.d f%u, f%u", fd, fs);
26757                      putDReg(fd, unop(Iop_AbsF64, getDReg(fs)));
26758                      break;
26759                   default:
26760                      goto decode_failure;
26761                }
26762                break;  /* case 0x5 */
26763 
26764             case 0x02:  /* MUL.fmt */
26765                switch (fmt) {
26766                   case 0x11: {  /* D */
26767                      DIP("mul.d f%u, f%u, f%u", fd, fs, ft);
26768                      IRExpr *rm = get_IR_roundingmode();
26769                      putDReg(fd, triop(Iop_MulF64, rm, getDReg(fs),
26770                                        getDReg(ft)));
26771                      break;
26772                   }
26773                   case 0x10: {  /* S */
26774                      DIP("mul.s f%u, f%u, f%u", fd, fs, ft);
26775                      IRExpr *rm = get_IR_roundingmode();
26776                      putFReg(fd, mkWidenFromF32(tyF, triop(Iop_MulF32, rm,
26777                                  getLoFromF64(tyF, getFReg(fs)),
26778                                  getLoFromF64(tyF, getFReg(ft)))));
26779                      break;
26780                   }
26781                   default:
26782                      goto decode_failure;
26783                }
26784                break;  /* MUL.fmt */
26785 
26786             case 0x03:  /* DIV.fmt */
26787                switch (fmt) {
26788                   case 0x11: {  /* D */
26789                      DIP("div.d f%u, f%u, f%u", fd, fs, ft);
26790                      IRExpr *rm = get_IR_roundingmode();
26791                      putDReg(fd, triop(Iop_DivF64, rm, getDReg(fs),
26792                                  getDReg(ft)));
26793                      break;
26794                   }
26795                   case 0x10: {  /* S */
26796                      DIP("div.s f%u, f%u, f%u", fd, fs, ft);
26797                      calculateFCSR(fs, ft, DIVS, False, 2);
26798                      IRExpr *rm = get_IR_roundingmode();
26799                      putFReg(fd, mkWidenFromF32(tyF, triop(Iop_DivF32, rm,
26800                                  getLoFromF64(tyF, getFReg(fs)),
26801                                  getLoFromF64(tyF, getFReg(ft)))));
26802                      break;
26803                   }
26804                   default:
26805                      goto decode_failure;
26806                }
26807                break;  /* DIV.fmt */
26808 
26809             case 0x01:  /* SUB.fmt */
26810                switch (fmt) {
26811                   case 0x11: {  /* D */
26812                      DIP("sub.d f%u, f%u, f%u", fd, fs, ft);
26813                      calculateFCSR(fs, ft, SUBD, False, 2);
26814                      IRExpr *rm = get_IR_roundingmode();
26815                      putDReg(fd, triop(Iop_SubF64, rm, getDReg(fs),
26816                                        getDReg(ft)));
26817                      break;
26818                   }
26819                   case 0x10: {  /* S */
26820                      DIP("sub.s f%u, f%u, f%u", fd, fs, ft);
26821                      calculateFCSR(fs, ft, SUBS, True, 2);
26822                      IRExpr *rm = get_IR_roundingmode();
26823                      putFReg(fd, mkWidenFromF32(tyF, triop(Iop_SubF32, rm,
26824                                  getLoFromF64(tyF, getFReg(fs)),
26825                                  getLoFromF64(tyF, getFReg(ft)))));
26826                      break;
26827                   }
26828                   default:
26829                      goto decode_failure;
26830                }
26831                break;  /* SUB.fmt */
26832 
26833             case 0x06:  /* MOV.fmt */
26834                switch (fmt) {
26835                   case 0x11:  /* D */
26836                      DIP("mov.d f%u, f%u", fd, fs);
26837                      if (fp_mode64) {
26838                         putDReg(fd, getDReg(fs));
26839                      } else {
26840                         putFReg(fd, getFReg(fs));
26841                         putFReg(fd + 1, getFReg(fs + 1));
26842                      }
26843                      break;
26844                   case 0x10:  /* S */
26845                      DIP("mov.s f%u, f%u", fd, fs);
26846                      putFReg(fd, getFReg(fs));
26847                      break;
26848                   default:
26849                      goto decode_failure;
26850                }
26851                break;  /* MOV.fmt */
26852 
26853             case 0x7:  /* neg.fmt */
26854                switch (fmt) {
26855                   case 0x10:  /* S */
26856                      DIP("neg.s f%u, f%u", fd, fs);
26857                      putFReg(fd, mkWidenFromF32(tyF, unop(Iop_NegF32,
26858                                  getLoFromF64(tyF, getFReg(fs)))));
26859                      break;
26860                   case 0x11:  /* D */
26861                      DIP("neg.d f%u, f%u", fd, fs);
26862                      putDReg(fd, unop(Iop_NegF64, getDReg(fs)));
26863                      break;
26864                   default:
26865                      goto decode_failure;
26866                }
26867                break;  /* case 0x7 */
26868 
26869             case 0x08:  /* ROUND.L.fmt */
26870                switch (fmt) {
26871                   case 0x10:  /* S */
26872                      DIP("round.l.s f%u, f%u", fd, fs);
26873                      if (fp_mode64) {
26874                         calculateFCSR(fs, 0, ROUNDLS, True, 1);
26875                         t0 = newTemp(Ity_I64);
26876 
26877                         assign(t0, binop(Iop_F32toI64S, mkU32(0x0),
26878                                          getLoFromF64(Ity_F64, getFReg(fs))));
26879 
26880                         putDReg(fd, unop(Iop_ReinterpI64asF64, mkexpr(t0)));
26881                      } else {
26882                         ILLEGAL_INSTRUCTON;
26883                      }
26884                      break;
26885                   case 0x11:  /* D */
26886                      DIP("round.l.d f%u, f%u", fd, fs);
26887                      if (fp_mode64) {
26888                         calculateFCSR(fs, 0, ROUNDLD, False, 1);
26889                         putDReg(fd, unop(Iop_ReinterpI64asF64,
26890                                          binop(Iop_F64toI64S,
26891                                                mkU32(0x0),
26892                                                getDReg(fs))));
26893                      } else {
26894                         ILLEGAL_INSTRUCTON;
26895                      }
26896                      break;
26897                   default:
26898                     goto decode_failure;
26899 
26900                }
26901                break;  /* ROUND.L.fmt */
26902 
26903             case 0x09:  /* TRUNC.L.fmt */
26904                switch (fmt) {
26905                   case 0x10:  /* S */
26906                      DIP("trunc.l.s f%u, f%u", fd, fs);
26907                      if (fp_mode64) {
26908                         calculateFCSR(fs, 0, TRUNCLS, True, 1);
26909                         t0 = newTemp(Ity_I64);
26910                         assign(t0, binop(Iop_F32toI64S, mkU32(0x3),
26911                                          getLoFromF64(Ity_F64, getFReg(fs))));
26912 
26913                         putDReg(fd, unop(Iop_ReinterpI64asF64, mkexpr(t0)));
26914                      } else {
26915                         ILLEGAL_INSTRUCTON;
26916                      }
26917                      break;
26918                   case 0x11:  /* D */
26919                      DIP("trunc.l.d f%u, f%u", fd, fs);
26920                      if (fp_mode64) {
26921                         calculateFCSR(fs, 0, TRUNCLD, False, 1);
26922                         putDReg(fd, unop(Iop_ReinterpI64asF64,
26923                                          binop(Iop_F64toI64S,
26924                                                mkU32(0x3),
26925                                                getDReg(fs))));
26926                      } else {
26927                         ILLEGAL_INSTRUCTON;
26928                      }
26929                      break;
26930                   default:
26931                      goto decode_failure;
26932                  }
26933               break;  /* TRUNC.L.fmt */
26934 
26935             case 0x15:  /* RECIP.fmt */
26936                switch (fmt) {
26937                   case 0x10: {  /* S */
26938                      DIP("recip.s f%u, f%u", fd, fs);
26939                      IRExpr *rm = get_IR_roundingmode();
26940                      putFReg(fd, mkWidenFromF32(tyF, triop(Iop_DivF32,
26941                                  rm, unop(Iop_ReinterpI32asF32,
26942                                  mkU32(ONE_SINGLE)), getLoFromF64(tyF,
26943                                  getFReg(fs)))));
26944                      break;
26945                   }
26946                   case 0x11: {  /* D */
26947                      DIP("recip.d f%u, f%u", fd, fs);
26948                      IRExpr *rm = get_IR_roundingmode();
26949                      /* putDReg(fd, 1.0/getDreg(fs)); */
26950                      putDReg(fd, triop(Iop_DivF64, rm,
26951                                  unop(Iop_ReinterpI64asF64,
26952                                  mkU64(ONE_DOUBLE)), getDReg(fs)));
26953                      break;
26954                   }
26955                default:
26956                   goto decode_failure;
26957 
26958                }
26959                break;  /* case 0x15 */
26960 
26961             case 0x13:  /* MOVN.fmt */
26962                switch (fmt) {
26963                case 0x10:  /* S */
26964                   DIP("movn.s f%u, f%u, r%u", fd, fs, rt);
26965                   t1 = newTemp(Ity_I1);
26966 
26967                   if (mode64)
26968                      assign(t1, binop(Iop_CmpNE64, mkU64(0), getIReg(rt)));
26969                   else
26970                      assign(t1, binop(Iop_CmpNE32, mkU32(0), getIReg(rt)));
26971 
26972                   putFReg(fd, IRExpr_ITE(mkexpr(t1), getFReg(fs), getFReg(fd)));
26973                   break;
26974                case 0x11:  /* D */
26975                   DIP("movn.d f%u, f%u, r%u", fd, fs, rt);
26976                   t1 = newTemp(Ity_I1);
26977 
26978                   if (mode64)
26979                      assign(t1, binop(Iop_CmpNE64, mkU64(0), getIReg(rt)));
26980                   else
26981                      assign(t1, binop(Iop_CmpNE32, mkU32(0), getIReg(rt)));
26982 
26983                   putDReg(fd, IRExpr_ITE(mkexpr(t1), getDReg(fs), getDReg(fd)));
26984                   break;
26985                default:
26986                   goto decode_failure;
26987                }
26988                break;  /* MOVN.fmt */
26989 
26990             case 0x12:  /* MOVZ.fmt */
26991                switch (fmt) {
26992                case 0x10:  /* S */
26993                   DIP("movz.s f%u, f%u, r%u", fd, fs, rt);
26994                   t1 = newTemp(Ity_I1);
26995 
26996                   if (mode64)
26997                      assign(t1, binop(Iop_CmpEQ64, mkU64(0), getIReg(rt)));
26998                   else
26999                      assign(t1, binop(Iop_CmpEQ32, mkU32(0), getIReg(rt)));
27000 
27001                   putFReg(fd, IRExpr_ITE(mkexpr(t1), getFReg(fs), getFReg(fd)));
27002                   break;
27003                case 0x11:  /* D */
27004                   DIP("movz.d f%u, f%u, r%u", fd, fs, rt);
27005                   t1 = newTemp(Ity_I1);
27006 
27007                   if (mode64)
27008                      assign(t1, binop(Iop_CmpEQ64, mkU64(0), getIReg(rt)));
27009                   else
27010                      assign(t1, binop(Iop_CmpEQ32, mkU32(0), getIReg(rt)));
27011 
27012                   putDReg(fd, IRExpr_ITE(mkexpr(t1), getDReg(fs), getDReg(fd)));
27013                   break;
27014                default:
27015                   goto decode_failure;
27016                }
27017                break;  /* MOVZ.fmt */
27018 
27019             case 0x11:  /* MOVT.fmt */
27020                if (tf == 1) {
27021                   UInt mov_cc = get_mov_cc(cins);
27022                   switch (fmt) {  /* MOVCF = 010001 */
27023                   case 0x11:  /* D */
27024                      DIP("movt.d f%u, f%u, %u", fd, fs, mov_cc);
27025                      t1 = newTemp(Ity_I1);
27026                      t2 = newTemp(Ity_I32);
27027                      t3 = newTemp(Ity_I1);
27028                      t4 = newTemp(Ity_F64);
27029 
27030                      assign(t1, binop(Iop_CmpEQ32, mkU32(0), mkU32(mov_cc)));
27031                      assign(t2, IRExpr_ITE(mkexpr(t1),
27032                                            binop(Iop_And32,
27033                                                  binop(Iop_Shr32, getFCSR(),
27034                                                        mkU8(23)),
27035                                                  mkU32(0x1)),
27036                                            binop(Iop_And32,
27037                                                  binop(Iop_Shr32, getFCSR(),
27038                                                        mkU8(24 + mov_cc)),
27039                                                  mkU32(0x1))
27040                                            ));
27041 
27042                      assign(t3, binop(Iop_CmpEQ32, mkU32(1), mkexpr(t2)));
27043                      assign(t4, IRExpr_ITE(mkexpr(t3),
27044                                            getDReg(fs), getDReg(fd)));
27045                      putDReg(fd, mkexpr(t4));
27046                      break;
27047                   case 0x10:  /* S */
27048                      DIP("movt.s f%u, f%u, %u", fd, fs, mov_cc);
27049                      t1 = newTemp(Ity_I1);
27050                      t2 = newTemp(Ity_I32);
27051                      t3 = newTemp(Ity_I1);
27052                      t4 = newTemp(Ity_F64);
27053                      t5 = newTemp(Ity_F64);
27054                      t6 = newTemp(Ity_F64);
27055                      t7 = newTemp(Ity_I64);
27056 
27057                      if (fp_mode64) {
27058                         assign(t5, getFReg(fs));
27059                         assign(t6, getFReg(fd));
27060                      } else {
27061                         assign(t5, unop(Iop_F32toF64, getFReg(fs)));
27062                         assign(t6, unop(Iop_F32toF64, getFReg(fd)));
27063                      }
27064 
27065                      assign(t1, binop(Iop_CmpEQ32, mkU32(0), mkU32(mov_cc)));
27066                      assign(t2, IRExpr_ITE(mkexpr(t1),
27067                                            binop(Iop_And32,
27068                                                  binop(Iop_Shr32, getFCSR(),
27069                                                        mkU8(23)),
27070                                                  mkU32(0x1)),
27071                                            binop(Iop_And32,
27072                                                  binop(Iop_Shr32, getFCSR(),
27073                                                        mkU8(24 + mov_cc)),
27074                                                  mkU32(0x1))
27075                                            ));
27076 
27077                      assign(t3, binop(Iop_CmpEQ32, mkU32(1), mkexpr(t2)));
27078                      assign(t4, IRExpr_ITE(mkexpr(t3),
27079                                            mkexpr(t5), mkexpr(t6)));
27080 
27081                      if (fp_mode64) {
27082                         IRTemp f = newTemp(Ity_F64);
27083                         IRTemp fd_hi = newTemp(Ity_I32);
27084                         assign(f, getFReg(fd));
27085                         assign(fd_hi, unop(Iop_64HIto32,
27086                                       unop(Iop_ReinterpF64asI64, mkexpr(f))));
27087                         assign(t7, mkWidenFrom32(Ity_I64, unop(Iop_64to32,
27088                                       unop(Iop_ReinterpF64asI64, mkexpr(t4))),
27089                                       True));
27090 
27091                         putFReg(fd, unop(Iop_ReinterpI64asF64, mkexpr(t7)));
27092                      } else
27093                         putFReg(fd, binop(Iop_F64toF32, get_IR_roundingmode(),
27094                                           mkexpr(t4)));
27095                      break;
27096                   default:
27097                      goto decode_failure;
27098                   }
27099                } else if (tf == 0)  /* movf.fmt */
27100                {
27101                   UInt mov_cc = get_mov_cc(cins);
27102                   switch (fmt)  /* MOVCF = 010001 */
27103                   {
27104                   case 0x11:  /* D */
27105                      DIP("movf.d f%u, f%u, %u", fd, fs, mov_cc);
27106                      t1 = newTemp(Ity_I1);
27107                      t2 = newTemp(Ity_I32);
27108                      t3 = newTemp(Ity_I1);
27109                      t4 = newTemp(Ity_F64);
27110 
27111                      assign(t1, binop(Iop_CmpEQ32, mkU32(0), mkU32(mov_cc)));
27112                      assign(t2, IRExpr_ITE(mkexpr(t1),
27113                                            binop(Iop_And32,
27114                                                  binop(Iop_Shr32, getFCSR(),
27115                                                        mkU8(23)),
27116                                                  mkU32(0x1)),
27117                                            binop(Iop_And32,
27118                                                  binop(Iop_Shr32, getFCSR(),
27119                                                        mkU8(24 + mov_cc)),
27120                                                  mkU32(0x1))
27121                                            ));
27122 
27123                      assign(t3, binop(Iop_CmpEQ32, mkU32(0), mkexpr(t2)));
27124                      assign(t4, IRExpr_ITE(mkexpr(t3),
27125                                            getDReg(fs), getDReg(fd)));
27126                      putDReg(fd, mkexpr(t4));
27127                      break;
27128                   case 0x10:  /* S */
27129                      DIP("movf.s f%u, f%u, %u", fd, fs, mov_cc);
27130                      t1 = newTemp(Ity_I1);
27131                      t2 = newTemp(Ity_I32);
27132                      t3 = newTemp(Ity_I1);
27133                      t4 = newTemp(Ity_F64);
27134                      t5 = newTemp(Ity_F64);
27135                      t6 = newTemp(Ity_F64);
27136 
27137                      if (fp_mode64) {
27138                         assign(t5, getFReg(fs));
27139                         assign(t6, getFReg(fd));
27140                      } else {
27141                         assign(t5, unop(Iop_F32toF64, getFReg(fs)));
27142                         assign(t6, unop(Iop_F32toF64, getFReg(fd)));
27143                      }
27144 
27145                      assign(t1, binop(Iop_CmpEQ32, mkU32(0), mkU32(mov_cc)));
27146                      assign(t2, IRExpr_ITE(mkexpr(t1),
27147                                            binop(Iop_And32,
27148                                                  binop(Iop_Shr32, getFCSR(),
27149                                                        mkU8(23)),
27150                                                  mkU32(0x1)),
27151                                            binop(Iop_And32,
27152                                                  binop(Iop_Shr32, getFCSR(),
27153                                                        mkU8(24 + mov_cc)),
27154                                                  mkU32(0x1))
27155                                            ));
27156 
27157                      assign(t3, binop(Iop_CmpEQ32, mkU32(0), mkexpr(t2)));
27158                      assign(t4, IRExpr_ITE(mkexpr(t3),
27159                                            mkexpr(t5), mkexpr(t6)));
27160 
27161                      if (fp_mode64) {
27162                         IRTemp f = newTemp(Ity_F64);
27163                         IRTemp fd_hi = newTemp(Ity_I32);
27164                         t7 = newTemp(Ity_I64);
27165                         assign(f, getFReg(fd));
27166                         assign(fd_hi, unop(Iop_64HIto32,
27167                                       unop(Iop_ReinterpF64asI64, mkexpr(f))));
27168                         assign(t7, mkWidenFrom32(Ity_I64, unop(Iop_64to32,
27169                                    unop(Iop_ReinterpF64asI64, mkexpr(t4))),
27170                                    True));
27171 
27172                         putFReg(fd, unop(Iop_ReinterpI64asF64, mkexpr(t7)));
27173                      } else
27174                         putFReg(fd, binop(Iop_F64toF32, get_IR_roundingmode(),
27175                                           mkexpr(t4)));
27176                      break;
27177                   default:
27178                      goto decode_failure;
27179                   }
27180                }
27181 
27182                break;  /* MOVT.fmt */
27183 
27184             case 0x0:  /* add.fmt */
27185                switch (fmt) {
27186                case 0x10: {  /* S */
27187                   DIP("add.s f%u, f%u, f%u", fd, fs, ft);
27188                   calculateFCSR(fs, ft, ADDS, True, 2);
27189                   IRExpr *rm = get_IR_roundingmode();
27190                   putFReg(fd, mkWidenFromF32(tyF, triop(Iop_AddF32, rm,
27191                               getLoFromF64(tyF, getFReg(fs)),
27192                               getLoFromF64(tyF, getFReg(ft)))));
27193                   break;
27194                }
27195                case 0x11: {  /* D */
27196                   DIP("add.d f%u, f%u, f%u", fd, fs, ft);
27197                   calculateFCSR(fs, ft, ADDD, False, 2);
27198                   IRExpr *rm = get_IR_roundingmode();
27199                   putDReg(fd, triop(Iop_AddF64, rm, getDReg(fs), getDReg(ft)));
27200                   break;
27201                }
27202 
27203                case 0x4:  /* MTC1 (Move Word to Floating Point) */
27204                   DIP("mtc1 r%u, f%u", rt, fs);
27205                   if (fp_mode64) {
27206                      t0 = newTemp(Ity_I32);
27207                      t1 = newTemp(Ity_F32);
27208                      assign(t0, mkNarrowTo32(ty, getIReg(rt)));
27209                      assign(t1, unop(Iop_ReinterpI32asF32, mkexpr(t0)));
27210 
27211                      putFReg(fs, mkWidenFromF32(tyF, mkexpr(t1)));
27212                   } else
27213                      putFReg(fs, unop(Iop_ReinterpI32asF32,
27214                                       mkNarrowTo32(ty, getIReg(rt))));
27215                   break;
27216 
27217                case 0x5:  /* Doubleword Move to Floating Point DMTC1; MIPS64 */
27218                   DIP("dmtc1 r%u, f%u", rt, fs);
27219                   vassert(mode64);
27220                   putDReg(fs, unop(Iop_ReinterpI64asF64, getIReg(rt)));
27221                   break;
27222 
27223                case 0x0:  /* MFC1 */
27224                   DIP("mfc1 r%u, f%u", rt, fs);
27225                   if (fp_mode64) {
27226                      t0 = newTemp(Ity_I64);
27227                      t1 = newTemp(Ity_I32);
27228                      assign(t0, unop(Iop_ReinterpF64asI64, getFReg(fs)));
27229                      assign(t1, unop(Iop_64to32, mkexpr(t0)));
27230                      putIReg(rt, mkWidenFrom32(ty, mkexpr(t1), True));
27231                   } else
27232                      putIReg(rt, mkWidenFrom32(ty,
27233                                  unop(Iop_ReinterpF32asI32, getFReg(fs)),
27234                                  True));
27235                   break;
27236 
27237                case 0x1:  /* Doubleword Move from Floating Point DMFC1;
27238                              MIPS64 */
27239                   DIP("dmfc1 r%u, f%u", rt, fs);
27240                   putIReg(rt, unop(Iop_ReinterpF64asI64, getDReg(fs)));
27241                   break;
27242 
27243                case 0x6:  /* CTC1 */
27244                   DIP("ctc1 r%u, f%u", rt, fs);
27245                   t0 = newTemp(Ity_I32);
27246                   t1 = newTemp(Ity_I32);
27247                   t2 = newTemp(Ity_I32);
27248                   t3 = newTemp(Ity_I32);
27249                   t4 = newTemp(Ity_I32);
27250                   t5 = newTemp(Ity_I32);
27251                   t6 = newTemp(Ity_I32);
27252                   assign(t0, mkNarrowTo32(ty, getIReg(rt)));
27253                   if (fs == 25) {  /* FCCR */
27254                      assign(t1, binop(Iop_Shl32, binop(Iop_And32, mkexpr(t0),
27255                                       mkU32(0x000000FE)), mkU8(24)));
27256                      assign(t2, binop(Iop_And32, mkexpr(t0),
27257                                       mkU32(0x01000000)));
27258                      assign(t3, binop(Iop_Shl32, binop(Iop_And32, mkexpr(t0),
27259                                       mkU32(0x00000001)), mkU8(23)));
27260                      assign(t4, binop(Iop_And32, mkexpr(t0),
27261                                       mkU32(0x007FFFFF)));
27262                      putFCSR(binop(Iop_Or32, binop(Iop_Or32, mkexpr(t1),
27263                                    mkexpr(t2)), binop(Iop_Or32, mkexpr(t3),
27264                                    mkexpr(t4))));
27265                   } else if (fs == 26) {  /* FEXR */
27266                      assign(t1, binop(Iop_And32, getFCSR(), mkU32(0xFFFC0000)));
27267                      assign(t2, binop(Iop_And32, mkexpr(t0),
27268                                       mkU32(0x0003F000)));
27269                      assign(t3, binop(Iop_And32, getFCSR(), mkU32(0x00000F80)));
27270                      assign(t4, binop(Iop_And32, mkexpr(t0),
27271                                       mkU32(0x0000007C)));
27272                      assign(t5, binop(Iop_And32, getFCSR(), mkU32(0x00000003)));
27273                      putFCSR(binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Or32,
27274                                    mkexpr(t1), mkexpr(t2)), binop(Iop_Or32,
27275                                    mkexpr(t3), mkexpr(t4))), mkexpr(t5)));
27276                   } else if (fs == 28) {
27277                      assign(t1, binop(Iop_And32, getFCSR(), mkU32(0xFE000000)));
27278                      assign(t2, binop(Iop_Shl32, binop(Iop_And32, mkexpr(t0),
27279                                 mkU32(0x00000002)), mkU8(22)));
27280                      assign(t3, binop(Iop_And32, getFCSR(), mkU32(0x00FFF000)));
27281                      assign(t4, binop(Iop_And32, mkexpr(t0),
27282                                 mkU32(0x00000F80)));
27283                      assign(t5, binop(Iop_And32, getFCSR(), mkU32(0x0000007C)));
27284                      assign(t6, binop(Iop_And32, mkexpr(t0),
27285                                 mkU32(0x00000003)));
27286                      putFCSR(binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Or32,
27287                                    mkexpr(t1), mkexpr(t2)), binop(Iop_Or32,
27288                                    mkexpr(t3), mkexpr(t4))), binop(Iop_Or32,
27289                                    mkexpr(t5), mkexpr(t6))));
27290                   } else if (fs == 31) {
27291                      putFCSR(mkexpr(t0));
27292                   }
27293                   break;
27294                case 0x2:  /* CFC1 */
27295                   DIP("cfc1 r%u, f%u", rt, fs);
27296                   t0 = newTemp(Ity_I32);
27297                   t1 = newTemp(Ity_I32);
27298                   t2 = newTemp(Ity_I32);
27299                   t3 = newTemp(Ity_I32);
27300                   t4 = newTemp(Ity_I32);
27301                   t5 = newTemp(Ity_I32);
27302                   t6 = newTemp(Ity_I32);
27303                   assign(t0, getFCSR());
27304                   if (fs == 0) {
27305                      putIReg(rt, mkWidenFrom32(ty,
27306                              IRExpr_Get(offsetof(VexGuestMIPS32State,
27307                                                  guest_FIR),
27308                                        Ity_I32),
27309                              False));
27310                   } else if (fs == 25) {
27311                      assign(t1, mkU32(0x000000FF));
27312                      assign(t2, binop(Iop_Shr32, binop(Iop_And32, mkexpr(t0),
27313                                       mkU32(0xFE000000)), mkU8(25)));
27314                      assign(t3, binop(Iop_Shr32, binop(Iop_And32, mkexpr(t0),
27315                                       mkU32(0x00800000)), mkU8(23)));
27316                      putIReg(rt, mkWidenFrom32(ty, binop(Iop_Or32,
27317                                  binop(Iop_Or32, mkexpr(t1), mkexpr(t2)),
27318                                  mkexpr(t3)), False));
27319                   } else if (fs == 26) {
27320                      assign(t1, mkU32(0xFFFFF07C));
27321                      assign(t2, binop(Iop_And32, mkexpr(t0),
27322                                 mkU32(0x0003F000)));
27323                      assign(t3, binop(Iop_And32, mkexpr(t0),
27324                                       mkU32(0x0000007C)));
27325                      putIReg(rt, mkWidenFrom32(ty, binop(Iop_Or32,
27326                                  binop(Iop_Or32, mkexpr(t1), mkexpr(t2)),
27327                                  mkexpr(t3)), False));
27328                   } else if (fs == 28) {
27329                      assign(t1, mkU32(0x00000F87));
27330                      assign(t2, binop(Iop_And32, mkexpr(t0),
27331                                       mkU32(0x00000F83)));
27332                      assign(t3, binop(Iop_Shr32, binop(Iop_And32, mkexpr(t0),
27333                                       mkU32(0x01000000)), mkU8(22)));
27334                      putIReg(rt, mkWidenFrom32(ty, binop(Iop_Or32,
27335                                  binop(Iop_Or32, mkexpr(t1), mkexpr(t2)),
27336                                  mkexpr(t3)), False));
27337                   } else if (fs == 31) {
27338                      putIReg(rt, mkWidenFrom32(ty, getFCSR(), False));
27339                   }
27340                   break;
27341                default:
27342                   goto decode_failure;
27343                }
27344                break;
27345 
27346             case 0x21:  /* CVT.D */
27347                switch (fmt) {
27348                   case 0x10:  /* S */
27349                      DIP("cvt.d.s f%u, f%u", fd, fs);
27350                      calculateFCSR(fs, 0, CVTDS, True, 1);
27351                      if (fp_mode64) {
27352                         t0 = newTemp(Ity_I64);
27353                         t1 = newTemp(Ity_I32);
27354                         t3 = newTemp(Ity_F32);
27355                         t4 = newTemp(Ity_F32);
27356                         /* get lo half of FPR */
27357                         assign(t0, unop(Iop_ReinterpF64asI64, getFReg(fs)));
27358 
27359                         assign(t1, unop(Iop_64to32, mkexpr(t0)));
27360 
27361                         assign(t3, unop(Iop_ReinterpI32asF32, mkexpr(t1)));
27362 
27363                         putFReg(fd, unop(Iop_F32toF64, mkexpr(t3)));
27364                      } else
27365                         putDReg(fd, unop(Iop_F32toF64, getFReg(fs)));
27366                      break;
27367 
27368                   case 0x14:
27369                      DIP("cvt.d.w %u, %u", fd, fs);
27370                      calculateFCSR(fs, 0, CVTDW, True, 1);
27371                      if (fp_mode64) {
27372                         t0 = newTemp(Ity_I64);
27373                         t1 = newTemp(Ity_I32);
27374                         t3 = newTemp(Ity_F32);
27375                         t4 = newTemp(Ity_F32);
27376                         /* get lo half of FPR */
27377                         assign(t0, unop(Iop_ReinterpF64asI64, getFReg(fs)));
27378 
27379                         assign(t1, unop(Iop_64to32, mkexpr(t0)));
27380                         putDReg(fd,unop(Iop_I32StoF64, mkexpr(t1)));
27381                         break;
27382                      } else {
27383                         t0 = newTemp(Ity_I32);
27384                         assign(t0, unop(Iop_ReinterpF32asI32, getFReg(fs)));
27385                         putDReg(fd, unop(Iop_I32StoF64, mkexpr(t0)));
27386                         break;
27387                      }
27388 
27389                   case 0x15: {  /* L */
27390                      if (fp_mode64) {
27391                         DIP("cvt.d.l %u, %u", fd, fs);
27392                         calculateFCSR(fs, 0, CVTDL, False, 1);
27393                         t0 = newTemp(Ity_I64);
27394                         assign(t0, unop(Iop_ReinterpF64asI64, getFReg(fs)));
27395 
27396                         putFReg(fd, binop(Iop_I64StoF64,
27397                                           get_IR_roundingmode(), mkexpr(t0)));
27398                         break;
27399                      } else
27400                         goto decode_failure;
27401                   }
27402                   default:
27403                      goto decode_failure;
27404                }
27405                break;  /* CVT.D */
27406 
27407             case 0x20:  /* cvt.s */
27408                switch (fmt) {
27409                   case 0x14:  /* W */
27410                      DIP("cvt.s.w %u, %u", fd, fs);
27411                      calculateFCSR(fs, 0, CVTSW, True, 1);
27412                      if (fp_mode64) {
27413                         t0 = newTemp(Ity_I64);
27414                         t1 = newTemp(Ity_I32);
27415                         t3 = newTemp(Ity_F32);
27416                         t4 = newTemp(Ity_F32);
27417                         /* get lo half of FPR */
27418                         assign(t0, unop(Iop_ReinterpF64asI64, getFReg(fs)));
27419 
27420                         assign(t1, unop(Iop_64to32, mkexpr(t0)));
27421                         putFReg(fd, mkWidenFromF32(tyF, binop(Iop_I32StoF32,
27422                                     get_IR_roundingmode(), mkexpr(t1))));
27423                      } else {
27424                         t0 = newTemp(Ity_I32);
27425                         assign(t0, unop(Iop_ReinterpF32asI32, getFReg(fs)));
27426                         putFReg(fd, binop(Iop_I32StoF32, get_IR_roundingmode(),
27427                                     mkexpr(t0)));
27428                      }
27429                      break;
27430 
27431                   case 0x11:  /* D */
27432                      DIP("cvt.s.d %u, %u", fd, fs);
27433                      calculateFCSR(fs, 0, CVTSD, False, 1);
27434                      t0 = newTemp(Ity_F32);
27435                      assign(t0, binop(Iop_F64toF32, get_IR_roundingmode(),
27436                                       getDReg(fs)));
27437                      putFReg(fd, mkWidenFromF32(tyF, mkexpr(t0)));
27438                      break;
27439 
27440                   case 0x15:  /* L */
27441                      DIP("cvt.s.l %u, %u", fd, fs);
27442                      if (fp_mode64) {
27443                         calculateFCSR(fs, 0, CVTSL, False, 1);
27444                         t0 = newTemp(Ity_I64);
27445                         assign(t0, unop(Iop_ReinterpF64asI64, getFReg(fs)));
27446 
27447                         putFReg(fd, mkWidenFromF32(tyF, binop(Iop_I64StoF32,
27448                                     get_IR_roundingmode(), mkexpr(t0))));
27449                      } else {
27450                         ILLEGAL_INSTRUCTON;
27451                      }
27452                      break;
27453 
27454                   default:
27455                      goto decode_failure;
27456                }
27457                break;  /* cvt.s */
27458 
27459             case 0x24:  /* cvt.w */
27460                switch (fmt) {
27461                case 0x10:  /* S */
27462                   DIP("cvt.w.s %u, %u", fd, fs);
27463                   calculateFCSR(fs, 0, CVTWS, True, 1);
27464                   putFReg(fd,
27465                           mkWidenFromF32(tyF,
27466                                          unop(Iop_ReinterpI32asF32,
27467                                               binop(Iop_F32toI32S,
27468                                                     get_IR_roundingmode(),
27469                                                     getLoFromF64(tyF,
27470                                                                  getFReg(fs))))));
27471                   break;
27472 
27473                case 0x11:
27474                   DIP("cvt.w.d %u, %u", fd, fs);
27475                   calculateFCSR(fs, 0, CVTWD, False, 1);
27476                   t0 = newTemp(Ity_I32);
27477                   t1 = newTemp(Ity_F32);
27478                   assign(t0, binop(Iop_F64toI32S, get_IR_roundingmode(),
27479                                    getDReg(fs)));
27480                   assign(t1, unop(Iop_ReinterpI32asF32, mkexpr(t0)));
27481                   putFReg(fd, mkWidenFromF32(tyF, mkexpr(t1)));
27482                   break;
27483 
27484                default:
27485                   goto decode_failure;
27486 
27487                }
27488                break;
27489 
27490             case 0x25:  /* cvt.l */
27491                switch (fmt) {
27492                   case 0x10:  /* S */
27493                      DIP("cvt.l.s %u, %u", fd, fs);
27494                      if (fp_mode64) {
27495                         calculateFCSR(fs, 0, CVTLS, True, 1);
27496                         t0 = newTemp(Ity_I64);
27497 
27498                         assign(t0, binop(Iop_F32toI64S, get_IR_roundingmode(),
27499                                          getLoFromF64(tyF, getFReg(fs))));
27500 
27501                         putDReg(fd, unop(Iop_ReinterpI64asF64, mkexpr(t0)));
27502                      } else {
27503                         ILLEGAL_INSTRUCTON;
27504                      }
27505                      break;
27506 
27507                   case 0x11: {  /* D */
27508                      DIP("cvt.l.d %u, %u", fd, fs);
27509                      if (fp_mode64) {
27510                         calculateFCSR(fs, 0, CVTLD, False, 1);
27511                         putDReg(fd, unop(Iop_ReinterpI64asF64,
27512                                          binop(Iop_F64toI64S,
27513                                                get_IR_roundingmode(),
27514                                                getDReg(fs))));
27515                      } else {
27516                         ILLEGAL_INSTRUCTON;
27517                      }
27518                      break;
27519                   }
27520 
27521                   default:
27522                      goto decode_failure;
27523                }
27524                break;
27525 
27526             case 0x0B:  /* FLOOR.L.fmt */
27527                switch (fmt) {
27528                   case 0x10:  /* S */
27529                      DIP("floor.l.s %u, %u", fd, fs);
27530                      if (fp_mode64) {
27531                         calculateFCSR(fs, 0, FLOORLS, True, 1);
27532                         t0 = newTemp(Ity_I64);
27533 
27534                         assign(t0, binop(Iop_F32toI64S, mkU32(0x1),
27535                                          getLoFromF64(tyF, getFReg(fs))));
27536 
27537                         putDReg(fd, unop(Iop_ReinterpI64asF64, mkexpr(t0)));
27538                      } else {
27539                         ILLEGAL_INSTRUCTON;
27540                      }
27541                      break;
27542 
27543                   case 0x11:  /* D */
27544                      DIP("floor.l.d %u, %u", fd, fs);
27545                      if (fp_mode64) {
27546                         calculateFCSR(fs, 0, FLOORLD, False, 1);
27547                         putDReg(fd, unop(Iop_ReinterpI64asF64,
27548                                          binop(Iop_F64toI64S,
27549                                                mkU32(0x01),
27550                                                getDReg(fs))));
27551                      } else {
27552                         ILLEGAL_INSTRUCTON;
27553                      }
27554                      break;
27555                   default:
27556                      goto decode_failure;
27557                }
27558                break;
27559 
27560             case 0x0C:  /* ROUND.W.fmt */
27561                switch (fmt) {
27562                   case 0x10:  /* S */
27563                      DIP("round.w.s f%u, f%u", fd, fs);
27564                      calculateFCSR(fs, 0, ROUNDWS, True, 1);
27565                      putFReg(fd,
27566                           mkWidenFromF32(tyF,
27567                                          unop(Iop_ReinterpI32asF32,
27568                                               binop(Iop_F32toI32S,
27569                                                     mkU32(0x0),
27570                                                     getLoFromF64(tyF,
27571                                                                  getFReg(fs))))));
27572                      break;
27573 
27574                   case 0x11:  /* D */
27575                      DIP("round.w.d f%u, f%u", fd, fs);
27576                      calculateFCSR(fs, 0, ROUNDWD, False, 1);
27577                      if (fp_mode64) {
27578                         t0 = newTemp(Ity_I32);
27579                         assign(t0, binop(Iop_F64toI32S, mkU32(0x0),
27580                                          getDReg(fs)));
27581                         putFReg(fd, mkWidenFromF32(tyF,
27582                                     unop(Iop_ReinterpI32asF32, mkexpr(t0))));
27583                      } else {
27584                         t0 = newTemp(Ity_I32);
27585 
27586                         assign(t0, binop(Iop_F64toI32S, mkU32(0x0),
27587                                          getDReg(fs)));
27588 
27589                         putFReg(fd, unop(Iop_ReinterpI32asF32, mkexpr(t0)));
27590                      }
27591                      break;
27592                   default:
27593                      goto decode_failure;
27594 
27595                   }
27596                   break;  /* ROUND.W.fmt */
27597 
27598             case 0x0F:  /* FLOOR.W.fmt */
27599                switch (fmt) {
27600                   case 0x10:  /* S */
27601                      DIP("floor.w.s f%u, f%u", fd, fs);
27602                      calculateFCSR(fs, 0, FLOORWS, True, 1);
27603                      putFReg(fd,
27604                           mkWidenFromF32(tyF,
27605                                          unop(Iop_ReinterpI32asF32,
27606                                               binop(Iop_F32toI32S,
27607                                                     mkU32(0x1),
27608                                                     getLoFromF64(tyF,
27609                                                                  getFReg(fs))))));
27610                      break;
27611 
27612                   case 0x11:  /* D */
27613                      DIP("floor.w.d f%u, f%u", fd, fs);
27614                      calculateFCSR(fs, 0, FLOORWD, False, 1);
27615                      if (fp_mode64) {
27616                         t0 = newTemp(Ity_I32);
27617                         assign(t0, binop(Iop_F64toI32S, mkU32(0x1),
27618                                          getDReg(fs)));
27619                         putFReg(fd, mkWidenFromF32(tyF,
27620                                     unop(Iop_ReinterpI32asF32, mkexpr(t0))));
27621                         break;
27622                      } else {
27623                         t0 = newTemp(Ity_I32);
27624 
27625                         assign(t0, binop(Iop_F64toI32S, mkU32(0x1),
27626                                          getDReg(fs)));
27627 
27628                         putFReg(fd, unop(Iop_ReinterpI32asF32, mkexpr(t0)));
27629                         break;
27630                      }
27631                   default:
27632                      goto decode_failure;
27633 
27634                }
27635                break;  /* FLOOR.W.fmt */
27636 
27637             case 0x0D:  /* TRUNC.W */
27638                switch (fmt) {
27639                   case 0x10:  /* S */
27640                      DIP("trunc.w.s %u, %u", fd, fs);
27641                      calculateFCSR(fs, 0, TRUNCWS, True, 1);
27642                      putFReg(fd,
27643                           mkWidenFromF32(tyF,
27644                                          unop(Iop_ReinterpI32asF32,
27645                                               binop(Iop_F32toI32S,
27646                                                     mkU32(0x3),
27647                                                     getLoFromF64(tyF,
27648                                                                  getFReg(fs))))));
27649                      break;
27650                   case 0x11:  /* D */
27651                      DIP("trunc.w.d %u, %u", fd, fs);
27652                      calculateFCSR(fs, 0, TRUNCWD, False, 1);
27653                      if (fp_mode64) {
27654                         t0 = newTemp(Ity_I32);
27655 
27656                         assign(t0, binop(Iop_F64toI32S, mkU32(0x3),
27657                                          getFReg(fs)));
27658 
27659                         putFReg(fd, mkWidenFromF32(tyF,
27660                                     unop(Iop_ReinterpI32asF32, mkexpr(t0))));
27661                      } else {
27662                         t0 = newTemp(Ity_I32);
27663 
27664                         assign(t0, binop(Iop_F64toI32S, mkU32(0x3),
27665                                          getDReg(fs)));
27666 
27667                         putFReg(fd, unop(Iop_ReinterpI32asF32, mkexpr(t0)));
27668                      }
27669                      break;
27670                   default:
27671                      goto decode_failure;
27672 
27673                }
27674                break;
27675 
27676             case 0x0E:  /* CEIL.W.fmt */
27677                switch (fmt) {
27678                   case 0x10:  /* S */
27679                      DIP("ceil.w.s %u, %u", fd, fs);
27680                      calculateFCSR(fs, 0, CEILWS, True, 1);
27681                      putFReg(fd,
27682                           mkWidenFromF32(tyF,
27683                                          unop(Iop_ReinterpI32asF32,
27684                                               binop(Iop_F32toI32S,
27685                                                     mkU32(0x2),
27686                                                     getLoFromF64(tyF,
27687                                                                  getFReg(fs))))));
27688                      break;
27689 
27690                   case 0x11:  /* D */
27691                      DIP("ceil.w.d %u, %u", fd, fs);
27692                      calculateFCSR(fs, 0, CEILWD, False, 1);
27693                      if (!fp_mode64) {
27694                         t0 = newTemp(Ity_I32);
27695                         assign(t0, binop(Iop_F64toI32S, mkU32(0x2),
27696                                          getDReg(fs)));
27697                         putFReg(fd, unop(Iop_ReinterpI32asF32, mkexpr(t0)));
27698                      } else {
27699                         t0 = newTemp(Ity_I32);
27700                         assign(t0, binop(Iop_F64toI32S, mkU32(0x2),
27701                                          getDReg(fs)));
27702                         putFReg(fd, mkWidenFromF32(tyF,
27703                                     unop(Iop_ReinterpI32asF32, mkexpr(t0))));
27704                      }
27705                      break;
27706 
27707                   default:
27708                      goto decode_failure;
27709 
27710                }
27711                break;
27712 
27713             case 0x0A:  /* CEIL.L.fmt */
27714                switch (fmt) {
27715                   case 0x10:  /* S */
27716                      DIP("ceil.l.s %u, %u", fd, fs);
27717                      if (fp_mode64) {
27718                         calculateFCSR(fs, 0, CEILLS, True, 1);
27719                         t0 = newTemp(Ity_I64);
27720 
27721                         assign(t0, binop(Iop_F32toI64S, mkU32(0x2),
27722                                    getLoFromF64(tyF, getFReg(fs))));
27723 
27724                         putFReg(fd, unop(Iop_ReinterpI64asF64, mkexpr(t0)));
27725                      } else {
27726                         ILLEGAL_INSTRUCTON;
27727                      }
27728                      break;
27729 
27730                   case 0x11:  /* D */
27731                      DIP("ceil.l.d %u, %u", fd, fs);
27732                      if (fp_mode64) {
27733                         calculateFCSR(fs, 0, CEILLD, False, 1);
27734                         putDReg(fd, unop(Iop_ReinterpI64asF64,
27735                                          binop(Iop_F64toI64S,
27736                                                mkU32(0x2),
27737                                                getDReg(fs))));
27738                      } else {
27739                         ILLEGAL_INSTRUCTON;
27740                      }
27741                      break;
27742 
27743                   default:
27744                      goto decode_failure;
27745 
27746                }
27747                break;
27748 
27749             case 0x16:  /* RSQRT.fmt */
27750                switch (fmt) {
27751                   case 0x10: {  /* S */
27752                      DIP("rsqrt.s %u, %u", fd, fs);
27753                      IRExpr *rm = get_IR_roundingmode();
27754                      putFReg(fd, mkWidenFromF32(tyF, triop(Iop_DivF32, rm,
27755                                  unop(Iop_ReinterpI32asF32, mkU32(ONE_SINGLE)),
27756                                  binop(Iop_SqrtF32, rm, getLoFromF64(tyF,
27757                                  getFReg(fs))))));
27758                      break;
27759                   }
27760                   case 0x11: {  /* D */
27761                      DIP("rsqrt.d %u, %u", fd, fs);
27762                      IRExpr *rm = get_IR_roundingmode();
27763                      putDReg(fd, triop(Iop_DivF64, rm,
27764                                  unop(Iop_ReinterpI64asF64,
27765                                  mkU64(ONE_DOUBLE)),
27766                                  binop(Iop_SqrtF64, rm, getDReg(fs))));
27767                      break;
27768                   }
27769                   default:
27770                      goto decode_failure;
27771 
27772                }
27773                break;
27774 
27775             case 0x18: /* MADDF.fmt */
27776                if (VEX_MIPS_CPU_HAS_MIPSR6(archinfo->hwcaps)) {
27777                   switch (fmt) {
27778                      case 0x11: {  /* D */
27779                         DIP("maddf.d f%u, f%u, f%u", fd, fs, ft);
27780                         IRExpr *rm = get_IR_roundingmode();
27781                         putDReg(fd, qop(Iop_MAddF64, rm, getDReg(fs), getDReg(ft),
27782                                         getDReg(fd)));
27783                         break;
27784                      }
27785 
27786                      case 0x10: {  /* S */
27787                         DIP("maddf.s f%u, f%u, f%u", fd, fs, ft);
27788                         IRExpr *rm = get_IR_roundingmode();
27789                         t1 = newTemp(Ity_F32);
27790                         assign(t1, qop(Iop_MAddF32, rm,
27791                                        getLoFromF64(tyF, getFReg(fs)),
27792                                        getLoFromF64(tyF, getFReg(ft)),
27793                                        getLoFromF64(tyF, getFReg(fd))));
27794                         putFReg(fd, mkWidenFromF32(tyF, mkexpr(t1)));
27795                         break;
27796                      }
27797 
27798                      default:
27799                         goto decode_failure;
27800                   }
27801                } else {
27802                   ILLEGAL_INSTRUCTON;
27803                }
27804 
27805                break;
27806 
27807             case 0x19: /* MSUBF.fmt */
27808                if (VEX_MIPS_CPU_HAS_MIPSR6(archinfo->hwcaps)) {
27809                   switch (fmt) {
27810                      case 0x11: {  /* D */
27811                         DIP("msubf.d f%u, f%u, f%u", fd, fs, ft);
27812                         IRExpr *rm = get_IR_roundingmode();
27813                         putDReg(fd, qop(Iop_MSubF64, rm, getDReg(fs),
27814                                         getDReg(ft), getDReg(fd)));
27815                         break;
27816                      }
27817 
27818                      case 0x10: {  /* S */
27819                         DIP("msubf.s f%u, f%u, f%u", fd, fs, ft);
27820                         IRExpr *rm = get_IR_roundingmode();
27821                         t1 = newTemp(Ity_F32);
27822                         assign(t1, qop(Iop_MSubF32, rm,
27823                                        getLoFromF64(tyF, getFReg(fs)),
27824                                        getLoFromF64(tyF, getFReg(ft)),
27825                                        getLoFromF64(tyF, getFReg(fd))));
27826                         putFReg(fd, mkWidenFromF32(tyF, mkexpr(t1)));
27827                         break;
27828                      }
27829 
27830                      default:
27831                         goto decode_failure;
27832                   }
27833                } else {
27834                   ILLEGAL_INSTRUCTON;
27835                }
27836 
27837                break;
27838 
27839             case 0x1E: /* MAX.fmt */
27840                if (VEX_MIPS_CPU_HAS_MIPSR6(archinfo->hwcaps)) {
27841                   switch (fmt) {
27842                      case 0x11: {  /* D */
27843                         DIP("max.d f%u, f%u, f%u", fd, fs, ft);
27844                         calculateFCSR(fs, ft, MAXD, False, 2);
27845                         putDReg(fd, binop(Iop_MaxNumF64, getDReg(fs), getDReg(ft)));
27846                         break;
27847                      }
27848 
27849                      case 0x10: {  /* S */
27850                         DIP("max.s f%u, f%u, f%u", fd, fs, ft);
27851                         calculateFCSR(fs, ft, MAXS, True, 2);
27852                         putFReg(fd, mkWidenFromF32(tyF, binop(Iop_MaxNumF32,
27853                                                               getLoFromF64(Ity_F64,
27854                                                                            getFReg(fs)),
27855                                                               getLoFromF64(Ity_F64,
27856                                                                            getFReg(ft)))));
27857                         break;
27858                      }
27859 
27860                      default:
27861                         goto decode_failure;
27862                   }
27863                } else {
27864                   ILLEGAL_INSTRUCTON;
27865                }
27866 
27867                break;
27868 
27869             case 0x1C: /* MIN.fmt */
27870                if (VEX_MIPS_CPU_HAS_MIPSR6(archinfo->hwcaps)) {
27871                   switch (fmt) {
27872                      case 0x11: {  /* D */
27873                         DIP("min.d f%u, f%u, f%u", fd, fs, ft);
27874                         calculateFCSR(fs, ft, MIND, False, 2);
27875                         putDReg(fd, binop(Iop_MinNumF64, getDReg(fs), getDReg(ft)));
27876                         break;
27877                      }
27878 
27879                      case 0x10: {  /* S */
27880                         DIP("min.s f%u, f%u, f%u", fd, fs, ft);
27881                         calculateFCSR(fs, ft, MINS, True, 2);
27882                         putFReg(fd, mkWidenFromF32(tyF, binop(Iop_MinNumF32,
27883                                                               getLoFromF64(Ity_F64,
27884                                                                         getFReg(fs)),
27885                                                               getLoFromF64(Ity_F64,
27886                                                                      getFReg(ft)))));
27887                         break;
27888                      }
27889                      default:
27890                         goto decode_failure;
27891                   }
27892                } else {
27893                   ILLEGAL_INSTRUCTON;
27894                }
27895 
27896                break;
27897 
27898             case 0x1F: /* MAXA.fmt */
27899                if (VEX_MIPS_CPU_HAS_MIPSR6(archinfo->hwcaps)) {
27900                   switch (fmt) {
27901                      case 0x11: {  /* D */
27902                         DIP("maxa.d f%u, f%u, f%u", fd, fs, ft);
27903                         calculateFCSR(fs, ft, MAXAD, False, 2);
27904                         t1 = newTemp(Ity_F64);
27905                         t2 = newTemp(Ity_F64);
27906                         t3 = newTemp(Ity_F64);
27907                         t4 = newTemp(Ity_I1);
27908                         assign(t1, unop(Iop_AbsF64, getFReg(fs)));
27909                         assign(t2, unop(Iop_AbsF64, getFReg(ft)));
27910                         assign(t3, binop(Iop_MaxNumF64, mkexpr(t1), mkexpr(t2)));
27911                         assign(t4, binop(Iop_CmpEQ32,
27912                                          binop(Iop_CmpF64, mkexpr(t3), mkexpr(t1)),
27913                                          mkU32(0x40)));
27914                         putFReg(fd, IRExpr_ITE(mkexpr(t4),
27915                                                getFReg(fs), getFReg(ft)));
27916                         break;
27917                      }
27918 
27919                      case 0x10: {  /* S */
27920                         DIP("maxa.s f%u, f%u, f%u", fd, fs, ft);
27921                         calculateFCSR(fs, ft, MAXAS, True, 2);
27922                         t1 = newTemp(Ity_F32);
27923                         t2 = newTemp(Ity_F32);
27924                         t3 = newTemp(Ity_F32);
27925                         t4 = newTemp(Ity_I1);
27926                         assign(t1, unop(Iop_AbsF32, getLoFromF64(Ity_F64,
27927                                                                  getFReg(fs))));
27928                         assign(t2, unop(Iop_AbsF32, getLoFromF64(Ity_F64,
27929                                                                  getFReg(ft))));
27930                         assign(t3, binop(Iop_MaxNumF32, mkexpr(t1), mkexpr(t2)));
27931                         assign(t4, binop(Iop_CmpEQ32,
27932                                          binop(Iop_CmpF32, mkexpr(t3), mkexpr(t1)),
27933                                          mkU32(0x40)));
27934                         putFReg(fd, IRExpr_ITE(mkexpr(t4),
27935                                                getFReg(fs), getFReg(ft)));
27936                         break;
27937                      }
27938 
27939                      default:
27940                         goto decode_failure;
27941                   }
27942                   /* missing in documentation */
27943                } else {
27944                   ILLEGAL_INSTRUCTON;
27945                }
27946                break;
27947 
27948             case 0x1D: /* MINA.fmt */
27949                if (VEX_MIPS_CPU_HAS_MIPSR6(archinfo->hwcaps)) {
27950                   switch (fmt) {
27951                      case 0x11: {  /* D */
27952                         DIP("mina.d f%u, f%u, f%u", fd, fs, ft);
27953                         calculateFCSR(fs, ft, MINAD, False, 2);
27954                         t1 = newTemp(Ity_F64);
27955                         t2 = newTemp(Ity_F64);
27956                         t3 = newTemp(Ity_F64);
27957                         t4 = newTemp(Ity_I1);
27958                         assign(t1, unop(Iop_AbsF64, getFReg(fs)));
27959                         assign(t2, unop(Iop_AbsF64, getFReg(ft)));
27960                         assign(t3, binop(Iop_MinNumF64, mkexpr(t1), mkexpr(t2)));
27961                         assign(t4, binop(Iop_CmpEQ32,
27962                                          binop(Iop_CmpF64, mkexpr(t3), mkexpr(t1)),
27963                                          mkU32(0x40)));
27964                         putFReg(fd, IRExpr_ITE(mkexpr(t4),
27965                                                getFReg(fs), getFReg(ft)));
27966                         break;
27967                      }
27968 
27969                      case 0x10: {  /* S */
27970                         DIP("mina.s f%u, f%u, f%u", fd, fs, ft);
27971                         calculateFCSR(fs, ft, MINAS, True, 2);
27972                         t1 = newTemp(Ity_F32);
27973                         t2 = newTemp(Ity_F32);
27974                         t3 = newTemp(Ity_F32);
27975                         t4 = newTemp(Ity_I1);
27976                         assign(t1, unop(Iop_AbsF32, getLoFromF64(Ity_F64,
27977                                                                  getFReg(fs))));
27978                         assign(t2, unop(Iop_AbsF32, getLoFromF64(Ity_F64,
27979                                                                  getFReg(ft))));
27980                         assign(t3, binop(Iop_MinNumF32, mkexpr(t1), mkexpr(t2)));
27981                         assign(t4, binop(Iop_CmpEQ32,
27982                                          binop(Iop_CmpF32, mkexpr(t3), mkexpr(t1)),
27983                                          mkU32(0x40)));
27984                         putFReg(fd, IRExpr_ITE(mkexpr(t4),
27985                                                getFReg(fs), getFReg(ft)));
27986                         break;
27987                      }
27988 
27989                      default:
27990                         goto decode_failure;
27991                   }
27992                } else {
27993                   ILLEGAL_INSTRUCTON;
27994                }
27995                break;
27996 
27997             case 0x1A: /* RINT.fmt */
27998                if (ft == 0) {
27999                   switch (fmt) {
28000                      case 0x11: {  /* D */
28001                         DIP("rint.d f%u, f%u", fd, fs);
28002                         calculateFCSR(fs, 0, RINTS, True, 1);
28003                         IRExpr *rm = get_IR_roundingmode();
28004                         putDReg(fd, binop(Iop_RoundF64toInt, rm, getDReg(fs)));
28005                         break;
28006                      }
28007 
28008                      case 0x10: {  /* S */
28009                         DIP("rint.s f%u, f%u", fd, fs);
28010                         calculateFCSR(fs, 0, RINTD, True, 1);
28011                         IRExpr *rm = get_IR_roundingmode();
28012                         putFReg(fd,
28013                                 mkWidenFromF32(tyF,
28014                                                binop(Iop_RoundF32toInt, rm,
28015                                                      getLoFromF64(tyF,
28016                                                                   getFReg(fs)))));
28017                         break;
28018                      }
28019 
28020                      default:
28021                         goto decode_failure;
28022                   }
28023 
28024                }
28025                break;
28026 
28027             case 0x10: /* SEL.fmt */
28028                switch (fmt) {
28029                   case 0x11: {  /* D */
28030                      if (VEX_MIPS_CPU_HAS_MIPSR6(archinfo->hwcaps)) {
28031                         DIP("sel.d f%u, f%u, f%u", fd, fs, ft);
28032                         t1 = newTemp(Ity_I1);
28033                         if (mode64) {
28034                            assign(t1,binop(Iop_CmpNE64,
28035                                           binop(Iop_And64,
28036                                                 unop(Iop_ReinterpF64asI64,
28037                                                      getDReg(fd)),
28038                                                 mkU64(1)),
28039                                           mkU64(0)));
28040                         } else {
28041                            assign(t1,binop(Iop_CmpNE32,
28042                                           binop(Iop_And32,
28043                                                 unop(Iop_64to32,
28044                                                     unop(Iop_ReinterpF64asI64,
28045                                                          getDReg(fd))),
28046                                                 mkU32(1)),
28047                                           mkU32(0)));
28048                         }
28049                         putDReg(fd, IRExpr_ITE(mkexpr(t1),
28050                                                getDReg(ft), getDReg(fs)));
28051                         break;
28052                      } else {
28053                         ILLEGAL_INSTRUCTON;
28054                      }
28055 
28056                   }
28057 
28058                   case 0x10: {  /* S */
28059                      DIP("sel.s f%u, f%u, f%u", fd, fs, ft);
28060                      t1 = newTemp(Ity_I1);
28061                      assign(t1,binop(Iop_CmpNE32,
28062                                      binop(Iop_And32,
28063                                            unop(Iop_ReinterpF32asI32,
28064                                                 getLoFromF64(tyF, getFReg(fd))),
28065                                            mkU32(1)),
28066                                      mkU32(0)));
28067                      putFReg(fd, IRExpr_ITE( mkexpr(t1),
28068                                           getFReg(ft), getFReg(fs)));
28069                      break;
28070                   }
28071                   default:
28072                      goto decode_failure;
28073                }
28074                break;
28075 
28076             case 0x14: /* SELEQZ.fmt */
28077                if (VEX_MIPS_CPU_HAS_MIPSR6(archinfo->hwcaps)) {
28078                   switch (fmt) { /* SELEQZ.df */
28079                      case 0x11: {  /* D */
28080                         DIP("seleqz.d f%u, f%u, f%u", fd, fs, ft);
28081                         t1 = newTemp(Ity_I1);
28082                         if (mode64) {
28083                            assign(t1, binop(Iop_CmpNE64,
28084                                             binop(Iop_And64,
28085                                                   unop(Iop_ReinterpF64asI64,
28086                                                        getDReg(ft)),
28087                                                   mkU64(1)),
28088                                             mkU64(0)));
28089                         } else {
28090                            assign(t1, binop(Iop_CmpNE32,
28091                                             binop(Iop_And32,
28092                                                   unop(Iop_64to32,
28093                                                        unop(Iop_ReinterpF64asI64,
28094                                                             getDReg(ft))),
28095                                                   mkU32(1)),
28096                                             mkU32(0)));
28097                         }
28098                         putDReg(fd, IRExpr_ITE( mkexpr(t1),
28099                                                binop(Iop_I64StoF64,
28100                                                      get_IR_roundingmode(),mkU64(0)),
28101                                                getDReg(fs)));
28102                         break;
28103                      }
28104 
28105                      case 0x10: {  /* S */
28106                         DIP("seleqz.s f%u, f%u, f%u", fd, fs, ft);
28107                         t1 = newTemp(Ity_I1);
28108                         assign(t1, binop(Iop_CmpNE32,
28109                                          binop(Iop_And32,
28110                                                unop(Iop_ReinterpF32asI32,
28111                                                     getLoFromF64(tyF, getFReg(ft))),
28112                                                mkU32(1)),
28113                                          mkU32(0)));
28114                         putFReg(fd, IRExpr_ITE(mkexpr(t1),
28115                                                mkWidenFromF32(tyF,
28116                                                                binop(Iop_I32StoF32,
28117                                                                      get_IR_roundingmode(),
28118                                                                      mkU32(0))),
28119                                                getFReg(fs)));
28120                         break;
28121                      }
28122 
28123                      default:
28124                         goto decode_failure;
28125                   }
28126                } else {
28127                   ILLEGAL_INSTRUCTON;
28128                }
28129                break;
28130 
28131             case 0x17: /* SELNEZ.fmt */
28132                if (VEX_MIPS_CPU_HAS_MIPSR6(archinfo->hwcaps)) {
28133                   switch (fmt) {
28134                      case 0x11: {  /* D */
28135                         DIP("selnez.d f%u, f%u, f%u", fd, fs, ft);
28136                         t1 = newTemp(Ity_I1);
28137                         if (mode64) {
28138                            assign(t1, binop(Iop_CmpNE64,
28139                                             binop(Iop_And64,
28140                                                   unop(Iop_ReinterpF64asI64,
28141                                                        getDReg(ft)),
28142                                                   mkU64(1)),
28143                                             mkU64(0)));
28144                         } else {
28145                            assign(t1, binop(Iop_CmpNE32,
28146                                             binop(Iop_And32,
28147                                                   unop(Iop_64to32,
28148                                                        unop(Iop_ReinterpF64asI64,
28149                                                             getDReg(ft))),
28150                                                   mkU32(1)),
28151                                             mkU32(0)));
28152                         }
28153                         putDReg(fd, IRExpr_ITE( mkexpr(t1),
28154                                                getDReg(fs),
28155                                                binop(Iop_I64StoF64,
28156                                                      get_IR_roundingmode(),
28157                                                      mkU64(0))));
28158                         break;
28159                      }
28160 
28161                      case 0x10: {  /* S */
28162                         DIP("selnez.s f%u, f%u, f%u", fd, fs, ft);
28163                         t1 = newTemp(Ity_I1);
28164                         assign(t1,binop(Iop_CmpNE32,
28165                                         binop(Iop_And32,
28166                                               unop(Iop_ReinterpF32asI32,
28167                                                    getLoFromF64(tyF, getFReg(ft))),
28168                                               mkU32(1)),
28169                                         mkU32(0)));
28170                         putFReg(fd, IRExpr_ITE(mkexpr(t1),
28171                                                getFReg(fs),
28172                                                mkWidenFromF32(tyF,
28173                                                               binop(Iop_I32StoF32,
28174                                                                     get_IR_roundingmode(),
28175                                                                     mkU32(0)))));
28176                         break;
28177                      }
28178 
28179                      default:
28180                         goto decode_failure;
28181                   }
28182                } else {
28183                   ILLEGAL_INSTRUCTON;
28184                }
28185                break;
28186 
28187             case 0x1B: /* CLASS.fmt */
28188                if (VEX_MIPS_CPU_HAS_MIPSR6(archinfo->hwcaps)) {
28189                   t0 = newTemp(Ity_I1); // exp zero
28190                   t1 = newTemp(Ity_I1); // exp max
28191                   t2 = newTemp(Ity_I1); // sign
28192                   t3 = newTemp(Ity_I1); // first
28193                   t4 = newTemp(Ity_I1); // val not zero
28194                   t5 = newTemp(Ity_I32);
28195                   switch (fmt) {
28196                      case 0x11: {  /* D */
28197                         DIP("class.d f%u, f%u", fd, fs);
28198                         assign(t0, binop(Iop_CmpEQ32,
28199                                          binop(Iop_And32,
28200                                                unop(Iop_64HIto32,
28201                                                     unop(Iop_ReinterpF64asI64,
28202                                                          getDReg(fs))),
28203                                                mkU32(0x7ff00000)),
28204                                          mkU32(0)));
28205                         assign(t1, binop(Iop_CmpEQ32,
28206                                          binop(Iop_And32,
28207                                                unop(Iop_64HIto32,
28208                                                     unop(Iop_ReinterpF64asI64,
28209                                                          getDReg(fs))),
28210                                                mkU32(0x7ff00000)),
28211                                          mkU32(0x7ff00000)));
28212                         assign(t2, binop(Iop_CmpEQ32,
28213                                          binop(Iop_And32,
28214                                                unop(Iop_64HIto32,
28215                                                     unop(Iop_ReinterpF64asI64,
28216                                                          getDReg(fs))),
28217                                                mkU32(0x80000000)),
28218                                          mkU32(0x80000000)));
28219                         assign(t3, binop(Iop_CmpEQ32,
28220                                          binop(Iop_And32,
28221                                                unop(Iop_64HIto32,
28222                                                     unop(Iop_ReinterpF64asI64,
28223                                                          getDReg(fs))),
28224                                                mkU32(0x00080000)),
28225                                          mkU32(0x00080000)));
28226                         if (mode64) assign(t4, binop(Iop_CmpNE64,
28227                                                     binop(Iop_And64,
28228                                                           unop(Iop_ReinterpF64asI64,
28229                                                                getDReg(fs)),
28230                                                           mkU64(0x000fffffffffffffULL)),
28231                                                     mkU64(0)));
28232                         else assign(t4, binop(Iop_CmpNE32,
28233                                               binop(Iop_Or32,
28234                                                     binop(Iop_And32,
28235                                                           unop(Iop_64HIto32,
28236                                                                unop(Iop_ReinterpF64asI64,
28237                                                                     getDReg(fs))),
28238                                                           mkU32(0x000fffff)),
28239                                                     unop(Iop_64to32,
28240                                                          unop(Iop_ReinterpF64asI64,
28241                                                             getDReg(fs)))),
28242                                               mkU32(0)));
28243                         assign(t5, binop(Iop_Shl32,
28244                                          IRExpr_ITE(mkexpr(t1),
28245                                                     IRExpr_ITE(mkexpr(t4),
28246                                                                mkU32(0), mkU32(1)),
28247                                                     IRExpr_ITE(mkexpr(t0),
28248                                                                IRExpr_ITE(mkexpr(t4),
28249                                                                           mkU32(0x4),
28250                                                                           mkU32(0x8)),
28251                                                                mkU32(2))),
28252                                          IRExpr_ITE(mkexpr(t2), mkU8(2), mkU8(6))));
28253                         putDReg(fd, unop(Iop_ReinterpI64asF64,
28254                                          unop(Iop_32Uto64,
28255                                               IRExpr_ITE(binop(Iop_CmpNE32,
28256                                                                mkexpr(t5), mkU32(0)),
28257                                                          mkexpr(t5),
28258                                                          IRExpr_ITE(mkexpr(t3),
28259                                                                     mkU32(2),
28260                                                                     mkU32(1))))));
28261                         break;
28262                      }
28263                      case 0x10: {  /* S */
28264                         DIP("class.s f%u, f%u", fd, fs);
28265                         assign(t0, binop(Iop_CmpEQ32,
28266                                          binop(Iop_And32,
28267                                                unop(Iop_ReinterpF32asI32,
28268                                                     getLoFromF64(tyF, getFReg(fs))),
28269                                                mkU32(0x7f800000)),
28270                                          mkU32(0)));
28271                         assign(t1, binop(Iop_CmpEQ32,
28272                                          binop(Iop_And32,
28273                                                unop(Iop_ReinterpF32asI32,
28274                                                     getLoFromF64(tyF, getFReg(fs))),
28275                                                mkU32(0x7f800000)),
28276                                          mkU32(0x7f800000)));
28277                         assign(t2, binop(Iop_CmpEQ32,
28278                                          binop(Iop_And32,
28279                                                unop(Iop_ReinterpF32asI32,
28280                                                     getLoFromF64(tyF, getFReg(fs))),
28281                                                mkU32(0x80000000)),
28282                                          mkU32(0x80000000)));
28283                         assign(t3, binop(Iop_CmpEQ32,
28284                                          binop(Iop_And32,
28285                                                unop(Iop_ReinterpF32asI32,
28286                                                     getLoFromF64(tyF, getFReg(fs))),
28287                                                mkU32(0x00400000)),
28288                                          mkU32(0x00400000)));
28289                         assign(t4, binop(Iop_CmpNE32,
28290                                          binop(Iop_And32,
28291                                                unop(Iop_ReinterpF32asI32,
28292                                                     getLoFromF64(tyF, getFReg(fs))),
28293                                                mkU32(0x007fffff)),
28294                                          mkU32(0)));
28295                         assign(t5, binop(Iop_Shl32,
28296                                          IRExpr_ITE(mkexpr(t1),
28297                                                     IRExpr_ITE(mkexpr(t4),
28298                                                                mkU32(0), mkU32(1)),
28299                                                     IRExpr_ITE(mkexpr(t0),
28300                                                                IRExpr_ITE(mkexpr(t4),
28301                                                                           mkU32(0x4),
28302                                                                           mkU32(0x8)), //zero or subnorm
28303                                                                mkU32(2))),
28304                                          IRExpr_ITE(mkexpr(t2), mkU8(2), mkU8(6))));
28305                         putDReg(fd, unop(Iop_ReinterpI64asF64,
28306                                          unop(Iop_32Uto64,
28307                                               IRExpr_ITE(binop(Iop_CmpNE32,
28308                                                                mkexpr(t5), mkU32(0)),
28309                                                          mkexpr(t5),
28310                                                          IRExpr_ITE(mkexpr(t3),
28311                                                                     mkU32(2),
28312                                                                     mkU32(1))))));
28313                         break;
28314                      }
28315                      default:
28316                         goto decode_failure;
28317                   }
28318                } else {
28319                   ILLEGAL_INSTRUCTON;
28320                }
28321                break;
28322 
28323             default:
28324                if (dis_instr_CCondFmt(cins))
28325                   break;
28326                goto decode_failure;
28327 
28328             }
28329 
28330          }
28331       }
28332       break;  /* COP1 */
28333 
28334    case 0x31:  /* LWC1 */
28335       /* Load Word to Floating Point - LWC1 (MIPS32) */
28336       DIP("lwc1 f%u, %u(r%u)", ft, imm, rs);
28337       LOAD_STORE_PATTERN;
28338       if (fp_mode64) {
28339          t0 = newTemp(Ity_F32);
28340          t2 = newTemp(Ity_I64);
28341          assign(t0, load(Ity_F32, mkexpr(t1)));
28342          assign(t2, mkWidenFrom32(Ity_I64, unop(Iop_ReinterpF32asI32,
28343                                                 mkexpr(t0)), True));
28344          putDReg(ft, unop(Iop_ReinterpI64asF64, mkexpr(t2)));
28345       } else {
28346          putFReg(ft, load(Ity_F32, mkexpr(t1)));
28347       }
28348       break;
28349 
28350    case 0x39:  /* SWC1 */
28351       DIP("swc1 f%u, %u(r%u)", ft, imm, rs);
28352       if (fp_mode64) {
28353          t0 = newTemp(Ity_I64);
28354          t2 = newTemp(Ity_I32);
28355          LOAD_STORE_PATTERN;
28356          assign(t0, unop(Iop_ReinterpF64asI64, getFReg(ft)));
28357          assign(t2, unop(Iop_64to32, mkexpr(t0)));
28358          store(mkexpr(t1), unop(Iop_ReinterpI32asF32, mkexpr(t2)));
28359       } else {
28360          LOAD_STORE_PATTERN;
28361          store(mkexpr(t1), getFReg(ft));
28362       }
28363       break;
28364 
28365    case 0x33:  /* PREF */
28366       DIP("pref");
28367       break;
28368 
28369    case 0x35:
28370       /* Load Doubleword to Floating Point - LDC1 (MIPS32) */
28371       DIP("ldc1 f%u, %u(%u)", rt, imm, rs);
28372       LOAD_STORE_PATTERN;
28373       putDReg(ft, load(Ity_F64, mkexpr(t1)));
28374       break;
28375 
28376    case 0x3D:
28377       /* Store Doubleword from Floating Point - SDC1 */
28378       DIP("sdc1 f%u, %u(%u)", ft, imm, rs);
28379       LOAD_STORE_PATTERN;
28380       store(mkexpr(t1), getDReg(ft));
28381       break;
28382 
28383    case 0x23:  /* LW */
28384       DIP("lw r%u, %u(r%u)", rt, imm, rs);
28385       LOAD_STORE_PATTERN;
28386       putIReg(rt, mkWidenFrom32(ty, load(Ity_I32, mkexpr(t1)), True));
28387       break;
28388 
28389    case 0x20:  /* LB */
28390       DIP("lb r%u, %u(r%u)", rt, imm, rs);
28391       LOAD_STORE_PATTERN;
28392       if (mode64)
28393          putIReg(rt, unop(Iop_8Sto64, load(Ity_I8, mkexpr(t1))));
28394       else
28395          putIReg(rt, unop(Iop_8Sto32, load(Ity_I8, mkexpr(t1))));
28396       break;
28397 
28398    case 0x24:  /* LBU */
28399       DIP("lbu r%u, %u(r%u)", rt, imm, rs);
28400       LOAD_STORE_PATTERN;
28401       if (mode64)
28402          putIReg(rt, unop(Iop_8Uto64, load(Ity_I8, mkexpr(t1))));
28403       else
28404          putIReg(rt, unop(Iop_8Uto32, load(Ity_I8, mkexpr(t1))));
28405       break;
28406 
28407    case 0x21:  /* LH */
28408       DIP("lh r%u, %u(r%u)", rt, imm, rs);
28409       LOAD_STORE_PATTERN;
28410       if (mode64)
28411          putIReg(rt, unop(Iop_16Sto64, load(Ity_I16, mkexpr(t1))));
28412       else
28413          putIReg(rt, unop(Iop_16Sto32, load(Ity_I16, mkexpr(t1))));
28414       break;
28415 
28416    case 0x25:  /* LHU */
28417       DIP("lhu r%u, %u(r%u)", rt, imm, rs);
28418       LOAD_STORE_PATTERN;
28419       if (mode64)
28420          putIReg(rt, unop(Iop_16Uto64, load(Ity_I16, mkexpr(t1))));
28421       else
28422          putIReg(rt, unop(Iop_16Uto32, load(Ity_I16, mkexpr(t1))));
28423       break;
28424 
28425    case 0x0F:  /* LUI */
28426       if (rs == 0) {
28427          p = (imm << 16);
28428          DIP("lui r%u, imm: 0x%x", rt, imm);
28429          if (mode64)
28430             putIReg(rt, mkU64(extend_s_32to64(p)));
28431          else
28432             putIReg(rt, mkU32(p));
28433          break;
28434       } else if (VEX_MIPS_CPU_HAS_MIPSR6(archinfo->hwcaps)) { /* AUI */
28435          DIP("aui r%u, imm: 0x%x", rt, imm);
28436          if (mode64) {
28437             putIReg(rt, unop(Iop_32Sto64,
28438                              unop(Iop_64to32,
28439                                   binop(Iop_Add64,
28440                                         getIReg(rs),
28441                                         mkU64(extend_s_32to64(imm << 16))))));
28442          } else {
28443             putIReg(rt, binop(Iop_Add32, getIReg(rs), mkU32(imm << 16)));
28444          }
28445       } else {
28446          ILLEGAL_INSTRUCTON;
28447       }
28448       break;
28449 
28450    case 0x13:  /* COP1X */
28451       switch (function) {
28452       case 0x0: {  /* LWXC1 */
28453          /* Load Word  Indexed to Floating Point - LWXC1 (MIPS32r2) */
28454          DIP("lwxc1 f%u, r%u(r%u)", fd, rt, rs);
28455          t2 = newTemp(ty);
28456          assign(t2, binop(mode64 ? Iop_Add64 : Iop_Add32, getIReg(rs),
28457                           getIReg(rt)));
28458          if (fp_mode64) {
28459             t0 = newTemp(Ity_I64);
28460             t1 = newTemp(Ity_I32);
28461             t3 = newTemp(Ity_F32);
28462             t4 = newTemp(Ity_I64);
28463             assign(t3, load(Ity_F32, mkexpr(t2)));
28464 
28465             assign(t4, mkWidenFrom32(Ity_I64, unop(Iop_ReinterpF32asI32,
28466                                                    mkexpr(t3)), True));
28467 
28468             putFReg(fd, unop(Iop_ReinterpI64asF64, mkexpr(t4)));
28469          } else {
28470             putFReg(fd, load(Ity_F32, mkexpr(t2)));
28471          }
28472          break;
28473       }
28474 
28475       case 0x1: {  /* LDXC1 */
28476          /* Load Doubleword  Indexed to Floating Point
28477             LDXC1 (MIPS32r2 and MIPS64) */
28478          DIP("ldxc1 f%u, r%u(r%u)", fd, rt, rs);
28479          t0 = newTemp(ty);
28480          assign(t0, binop(mode64 ? Iop_Add64 : Iop_Add32, getIReg(rs),
28481                           getIReg(rt)));
28482          putDReg(fd, load(Ity_F64, mkexpr(t0)));
28483          break;
28484       }
28485 
28486       case 0x5:  /* Load Doubleword Indexed Unaligned to Floating Point - LUXC1;
28487                     MIPS32r2 and MIPS64 */
28488          DIP("luxc1 f%u, r%u(r%u)", fd, rt, rs);
28489          if ((mode64 || VEX_MIPS_CPU_HAS_MIPS32R2(archinfo->hwcaps))
28490              && fp_mode64) {
28491             t0 = newTemp(ty);
28492             t1 = newTemp(ty);
28493             assign(t0, binop(mode64 ? Iop_Add64 : Iop_Add32,
28494                              getIReg(rs), getIReg(rt)));
28495             assign(t1, binop(mode64 ? Iop_And64 : Iop_And32,
28496                              mkexpr(t0),
28497                              mode64 ? mkU64(0xfffffffffffffff8ULL)
28498                                     : mkU32(0xfffffff8ULL)));
28499             putFReg(fd, load(Ity_F64, mkexpr(t1)));
28500          } else {
28501             ILLEGAL_INSTRUCTON;
28502          }
28503          break;
28504 
28505       case 0x8: {  /* Store Word Indexed from Floating Point - SWXC1 */
28506          DIP("swxc1 f%u, r%u(r%u)", ft, rt, rs);
28507          t0 = newTemp(ty);
28508          assign(t0, binop(mode64 ? Iop_Add64 : Iop_Add32, getIReg(rs),
28509                           getIReg(rt)));
28510          if (fp_mode64) {
28511             store(mkexpr(t0), getLoFromF64(tyF, getFReg(fs)));
28512          } else {
28513             store(mkexpr(t0), getFReg(fs));
28514          }
28515          break;
28516       }
28517       case 0x9: {  /* Store Doubleword Indexed from Floating Point - SDXC1 */
28518          DIP("sdxc1 f%u, r%u(r%u)", fs, rt, rs);
28519          t0 = newTemp(ty);
28520          assign(t0, binop(mode64 ? Iop_Add64 : Iop_Add32, getIReg(rs),
28521                           getIReg(rt)));
28522          store(mkexpr(t0), getDReg(fs));
28523          break;
28524       }
28525       case 0xD:  /* Store Doubleword Indexed Unaligned from Floating Point -
28526                     SUXC1; MIPS64 MIPS32r2 */
28527          DIP("suxc1 f%u, r%u(r%u)", fd, rt, rs);
28528          if ((mode64 || VEX_MIPS_CPU_HAS_MIPS32R2(archinfo->hwcaps))
28529              && fp_mode64) {
28530             t0 = newTemp(ty);
28531             t1 = newTemp(ty);
28532             assign(t0, binop(mode64 ? Iop_Add64 : Iop_Add32,
28533                              getIReg(rs), getIReg(rt)));
28534             assign(t1, binop(mode64 ? Iop_And64 : Iop_And32,
28535                              mkexpr(t0),
28536                              mode64 ? mkU64(0xfffffffffffffff8ULL)
28537                                     : mkU32(0xfffffff8ULL)));
28538             store(mkexpr(t1), getFReg(fs));
28539          } else {
28540             ILLEGAL_INSTRUCTON;
28541          }
28542          break;
28543 
28544       case 0x0F: {
28545          DIP("prefx");
28546          break;
28547       }
28548       case 0x20:  {  /* MADD.S */
28549          DIP("madd.s f%u, f%u, f%u, f%u", fd, fmt, fs, ft);
28550          IRExpr *rm = get_IR_roundingmode();
28551          t1 = newTemp(Ity_F32);
28552          assign(t1, triop(Iop_AddF32, rm, getLoFromF64(tyF, getFReg(fmt)),
28553             triop(Iop_MulF32, rm, getLoFromF64(tyF, getFReg(fs)),
28554                getLoFromF64(tyF, getFReg(ft)))));
28555          putFReg(fd, mkWidenFromF32(tyF, mkexpr(t1)));
28556          break;  /* MADD.S */
28557       }
28558       case 0x21: {  /* MADD.D */
28559          DIP("madd.d f%u, f%u, f%u, f%u", fd, fmt, fs, ft);
28560          IRExpr *rm = get_IR_roundingmode();
28561          putDReg(fd, triop(Iop_AddF64, rm, getDReg(fmt),
28562             triop(Iop_MulF64, rm, getDReg(fs),
28563                          getDReg(ft))));
28564          break;  /* MADD.D */
28565       }
28566       case 0x28: {  /* MSUB.S */
28567          DIP("msub.s f%u, f%u, f%u, f%u", fd, fmt, fs, ft);
28568          IRExpr *rm = get_IR_roundingmode();
28569          t1 = newTemp(Ity_F32);
28570          assign(t1, triop(Iop_SubF32, rm,
28571             triop(Iop_MulF32, rm, getLoFromF64(tyF, getFReg(fs)),
28572                getLoFromF64(tyF, getFReg(ft))),
28573              getLoFromF64(tyF, getFReg(fmt))));
28574          putFReg(fd, mkWidenFromF32(tyF, mkexpr(t1)));
28575          break;  /* MSUB.S */
28576       }
28577       case 0x29: {  /* MSUB.D */
28578          DIP("msub.d f%u, f%u, f%u, f%u", fd, fmt, fs, ft);
28579          IRExpr *rm = get_IR_roundingmode();
28580          putDReg(fd, triop(Iop_SubF64, rm, triop(Iop_MulF64, rm, getDReg(fs),
28581                          getDReg(ft)), getDReg(fmt)));
28582          break;  /* MSUB.D */
28583       }
28584       case 0x30: {  /* NMADD.S */
28585          DIP("nmadd.s f%u, f%u, f%u, f%u", fd, fmt, fs, ft);
28586          IRExpr *rm = get_IR_roundingmode();
28587          t1 = newTemp(Ity_F32);
28588          assign(t1, triop(Iop_AddF32, rm, getLoFromF64(tyF, getFReg(fmt)),
28589             triop(Iop_MulF32, rm, getLoFromF64(tyF, getFReg(fs)),
28590                getLoFromF64(tyF, getFReg(ft)))));
28591          putFReg(fd, mkWidenFromF32(tyF, unop(Iop_NegF32, mkexpr(t1))));
28592          break;  /* NMADD.S */
28593       }
28594       case 0x31: {  /* NMADD.D */
28595          DIP("nmadd.d f%u, f%u, f%u, f%u", fd, fmt, fs, ft);
28596          IRExpr *rm = get_IR_roundingmode();
28597          t1 = newTemp(Ity_F64);
28598          assign(t1, triop(Iop_AddF64, rm, getDReg(fmt),
28599             triop(Iop_MulF64, rm, getDReg(fs),
28600                          getDReg(ft))));
28601          putDReg(fd, unop(Iop_NegF64, mkexpr(t1)));
28602          break;  /* NMADD.D */
28603       }
28604       case 0x38: {  /* NMSUBB.S */
28605          DIP("nmsub.s f%u, f%u, f%u, f%u", fd, fmt, fs, ft);
28606          IRExpr *rm = get_IR_roundingmode();
28607          t1 = newTemp(Ity_F32);
28608          assign(t1, triop(Iop_SubF32, rm,
28609             triop(Iop_MulF32, rm, getLoFromF64(tyF, getFReg(fs)),
28610                getLoFromF64(tyF, getFReg(ft))),
28611              getLoFromF64(tyF, getFReg(fmt))));
28612          putFReg(fd, mkWidenFromF32(tyF, unop(Iop_NegF32, mkexpr(t1))));
28613          break;  /* NMSUBB.S */
28614       }
28615       case 0x39: {  /* NMSUBB.D */
28616          DIP("nmsub.d f%u, f%u, f%u, f%u", fd, fmt, fs, ft);
28617          IRExpr *rm = get_IR_roundingmode();
28618          t1 = newTemp(Ity_F64);
28619          assign(t1, triop(Iop_SubF64, rm, triop(Iop_MulF64, rm, getDReg(fs),
28620                          getDReg(ft)), getDReg(fmt)));
28621          putDReg(fd, unop(Iop_NegF64, mkexpr(t1)));
28622          break;  /* NMSUBB.D */
28623       }
28624 
28625       default:
28626          goto decode_failure;
28627       }
28628       break;
28629 
28630    case 0x22:  /* LWL */
28631       DIP("lwl r%u, %u(r%u)", rt, imm, rs);
28632       if (mode64) {
28633          /* t1 = addr */
28634          t1 = newTemp(Ity_I64);
28635 #if defined (_MIPSEL)
28636          assign(t1, binop(Iop_Add64, getIReg(rs), mkU64(extend_s_16to64(imm))));
28637 #elif defined (_MIPSEB)
28638          assign(t1, binop(Iop_Xor64,
28639                           mkU64(0x03),
28640                           binop(Iop_Add64,
28641                                 getIReg(rs),
28642                                 mkU64(extend_s_16to64(imm)))));
28643 #endif
28644          /* t2 = word addr */
28645          /* t4 = addr mod 4 */
28646          LWX_SWX_PATTERN64;
28647 
28648          /* t3 = word content - shifted */
28649          t3 = newTemp(Ity_I32);
28650          assign(t3, binop(Iop_Shl32,
28651                           load(Ity_I32, mkexpr(t2)),
28652                           narrowTo(Ity_I8,
28653                                    binop(Iop_Shl32,
28654                                          binop(Iop_Sub32,
28655                                                mkU32(0x03),
28656                                                mkexpr(t4)),
28657                                          mkU8(3)))));
28658 
28659          /* rt content - adjusted */
28660          t5 = newTemp(Ity_I32);
28661          assign(t5, binop(Iop_And32,
28662                           mkNarrowTo32(ty, getIReg(rt)),
28663                           binop(Iop_Shr32,
28664                                 mkU32(0x00FFFFFF),
28665                                       narrowTo(Ity_I8, binop(Iop_Mul32,
28666                                                              mkU32(0x08),
28667                                                              mkexpr(t4))))));
28668 
28669          putIReg(rt, mkWidenFrom32(ty, binop(Iop_Or32, mkexpr(t5),
28670                                              mkexpr(t3)), True));
28671       } else {
28672          /* t1 = addr */
28673          t1 = newTemp(Ity_I32);
28674 #if defined (_MIPSEL)
28675          assign(t1, binop(Iop_Add32, getIReg(rs), mkU32(extend_s_16to32(imm))));
28676 #elif defined (_MIPSEB)
28677          assign(t1, binop(Iop_Xor32, mkU32(0x3), binop(Iop_Add32, getIReg(rs),
28678                                      mkU32(extend_s_16to32(imm)))));
28679 #endif
28680 
28681          /* t2 = word addr */
28682          /* t4 = addr mod 4 */
28683          LWX_SWX_PATTERN;
28684 
28685          /* t3 = word content - shifted */
28686          t3 = newTemp(Ity_I32);
28687          assign(t3, binop(Iop_Shl32, load(Ity_I32, mkexpr(t2)), narrowTo(Ity_I8,
28688                     binop(Iop_Shl32, binop(Iop_Sub32, mkU32(0x03), mkexpr(t4)),
28689                     mkU8(3)))));
28690 
28691          /* rt content  - adjusted */
28692          t5 = newTemp(Ity_I32);
28693          assign(t5, binop(Iop_And32,
28694                           getIReg(rt),
28695                           binop(Iop_Shr32,
28696                                 mkU32(0x00FFFFFF),
28697                                       narrowTo(Ity_I8, binop(Iop_Mul32,
28698                                                              mkU32(0x08),
28699                                                              mkexpr(t4))))));
28700 
28701          putIReg(rt, binop(Iop_Or32, mkexpr(t5), mkexpr(t3)));
28702       }
28703       break;
28704 
28705    case 0x26:  /* LWR */
28706       DIP("lwr r%u, %u(r%u)", rt, imm, rs);
28707       if (mode64) {
28708          /* t1 = addr */
28709          t1 = newTemp(Ity_I64);
28710 #if defined (_MIPSEL)
28711          assign(t1, binop(Iop_Add64, getIReg(rs), mkU64(extend_s_16to64(imm))));
28712 #elif defined (_MIPSEB)
28713          assign(t1, binop(Iop_Xor64,
28714                           mkU64(0x3),
28715                           binop(Iop_Add64,
28716                                 getIReg(rs),
28717                                 mkU64(extend_s_16to64(imm)))));
28718 #endif
28719          /* t2 = word addr */
28720          /* t4 = addr mod 4 */
28721          LWX_SWX_PATTERN64;
28722 
28723          /* t3 = word content - shifted */
28724          t3 = newTemp(Ity_I32);
28725          assign(t3, binop(Iop_Shr32,
28726                           load(Ity_I32, mkexpr(t2)),
28727                           narrowTo(Ity_I8,
28728                                    binop(Iop_Shl32, mkexpr(t4), mkU8(0x03)))));
28729 
28730          /* rt content  - adjusted */
28731          t5 = newTemp(Ity_I32);
28732          assign(t5, binop(Iop_And32, mkNarrowTo32(ty, getIReg(rt)),
28733                 unop(Iop_Not32, binop(Iop_Shr32, mkU32(0xFFFFFFFF),
28734                 narrowTo(Ity_I8, binop(Iop_Shl32, mkexpr(t4), mkU8(0x3)))))));
28735 
28736          putIReg(rt, mkWidenFrom32(ty, binop(Iop_Or32, mkexpr(t5),
28737                                        mkexpr(t3)), True));
28738 
28739       } else {
28740          /* t1 = addr */
28741          t1 = newTemp(Ity_I32);
28742 #if defined (_MIPSEL)
28743          assign(t1, binop(Iop_Add32, getIReg(rs), mkU32(extend_s_16to32(imm))));
28744 #elif defined (_MIPSEB)
28745          assign(t1, binop(Iop_Xor32, mkU32(0x3), binop(Iop_Add32, getIReg(rs),
28746                                      mkU32(extend_s_16to32(imm)))));
28747 #endif
28748 
28749          /* t2 = word addr */
28750          /* t4 = addr mod 4 */
28751          LWX_SWX_PATTERN;
28752 
28753          /* t3 = word content - shifted */
28754          t3 = newTemp(Ity_I32);
28755          assign(t3, binop(Iop_Shr32, load(Ity_I32, mkexpr(t2)),
28756                     narrowTo(Ity_I8, binop(Iop_Shl32, mkexpr(t4),
28757                     mkU8(3)))));
28758 
28759          /* rt content  - adjusted */
28760          t5 = newTemp(Ity_I32);
28761          assign(t5, binop(Iop_And32, getIReg(rt), unop(Iop_Not32,
28762                     binop(Iop_Shr32, mkU32(0xFFFFFFFF), narrowTo(Ity_I8,
28763                           binop(Iop_Shl32, mkexpr(t4), mkU8(0x3)))))));
28764 
28765          putIReg(rt, binop(Iop_Or32, mkexpr(t5), mkexpr(t3)));
28766       }
28767       break;
28768 
28769    case 0x2B:  /* SW */
28770       DIP("sw r%u, %u(r%u)", rt, imm, rs);
28771       LOAD_STORE_PATTERN;
28772       store(mkexpr(t1), mkNarrowTo32(ty, getIReg(rt)));
28773       break;
28774 
28775    case 0x2C: {  /* SDL rt, offset(base) MIPS64 */
28776       DIP("sdl r%u, %u(r%u)", rt, imm, rs);
28777       vassert(mode64);
28778       IRTemp A_byte = newTemp(Ity_I8);
28779       IRTemp B_byte = newTemp(Ity_I8);
28780       IRTemp C_byte = newTemp(Ity_I8);
28781       IRTemp D_byte = newTemp(Ity_I8);
28782       IRTemp E_byte = newTemp(Ity_I8);
28783       IRTemp F_byte = newTemp(Ity_I8);
28784       IRTemp G_byte = newTemp(Ity_I8);
28785       IRTemp H_byte = newTemp(Ity_I8);
28786       IRTemp B_pos  = newTemp(Ity_I64);
28787       IRTemp C_pos  = newTemp(Ity_I64);
28788       IRTemp D_pos  = newTemp(Ity_I64);
28789       IRTemp E_pos  = newTemp(Ity_I64);
28790       IRTemp F_pos  = newTemp(Ity_I64);
28791       IRTemp G_pos  = newTemp(Ity_I64);
28792 
28793       /* H byte */
28794       assign(H_byte, getByteFromReg(rt, 0));
28795       /* G byte */
28796       assign(G_byte, getByteFromReg(rt, 1));
28797       /* F byte */
28798       assign(F_byte, getByteFromReg(rt, 2));
28799       /* E byte */
28800       assign(E_byte, getByteFromReg(rt, 3));
28801       /* D byte */
28802       assign(D_byte, getByteFromReg(rt, 4));
28803       /* C byte */
28804       assign(C_byte, getByteFromReg(rt, 5));
28805       /* B byte */
28806       assign(B_byte, getByteFromReg(rt, 6));
28807       /* A byte */
28808       assign(A_byte, getByteFromReg(rt, 7));
28809 
28810       /* t1 = addr */
28811       t1 = newTemp(Ity_I64);
28812       assign(t1, binop(Iop_Add64, getIReg(rs), mkU64(extend_s_16to64(imm))));
28813 
28814       /* t2 = word addr */
28815       t2 = newTemp(Ity_I64);
28816       assign(t2, binop(Iop_And64, mkexpr(t1), mkU64(0xFFFFFFFFFFFFFFF8ULL)));
28817 
28818       /* t3 = addr mod 7 */
28819       t3 = newTemp(Ity_I64);
28820       assign(t3, binop(Iop_And64, mkexpr(t1), mkU64(0x7)));
28821 
28822 #if defined (_MIPSEL)
28823       /* Calculate X_byte position. */
28824       assign(B_pos, IRExpr_ITE(binop(Iop_CmpLT64U, mkexpr(t3), mkU64(0x1)),
28825                                mkU64(0x0),
28826                                mkU64(0x1)));
28827 
28828       assign(C_pos, IRExpr_ITE(binop(Iop_CmpLT64U, mkexpr(t3), mkU64(0x2)),
28829                                mkU64(0x0),
28830                                mkU64(0x2)));
28831 
28832       assign(D_pos, IRExpr_ITE(binop(Iop_CmpLT64U, mkexpr(t3), mkU64(0x3)),
28833                                mkU64(0x0),
28834                                mkU64(0x3)));
28835 
28836       assign(E_pos, IRExpr_ITE(binop(Iop_CmpLT64U, mkexpr(t3), mkU64(0x4)),
28837                                mkU64(0x0),
28838                                mkU64(0x4)));
28839 
28840       assign(F_pos, IRExpr_ITE(binop(Iop_CmpLT64U, mkexpr(t3), mkU64(0x5)),
28841                                mkU64(0x0),
28842                                mkU64(0x5)));
28843 
28844       assign(G_pos, IRExpr_ITE(binop(Iop_CmpEQ64, mkexpr(t3), mkU64(0x7)),
28845                                mkU64(0x1),
28846                                mkU64(0x0)));
28847 
28848       /* Store X_byte on the right place. */
28849       store(mkexpr(t2), mkexpr(H_byte));
28850       store(binop(Iop_Add64, mkexpr(t2), mkexpr(G_pos)), mkexpr(G_byte));
28851       store(binop(Iop_Sub64, mkexpr(t1), mkexpr(F_pos)), mkexpr(F_byte));
28852       store(binop(Iop_Sub64, mkexpr(t1), mkexpr(E_pos)), mkexpr(E_byte));
28853       store(binop(Iop_Sub64, mkexpr(t1), mkexpr(D_pos)), mkexpr(D_byte));
28854       store(binop(Iop_Sub64, mkexpr(t1), mkexpr(C_pos)), mkexpr(C_byte));
28855       store(binop(Iop_Sub64, mkexpr(t1), mkexpr(B_pos)), mkexpr(B_byte));
28856       store(mkexpr(t1), mkexpr(A_byte));
28857 
28858 #else /* _MIPSEB */
28859       /* Calculate X_byte position. */
28860       assign(B_pos, IRExpr_ITE(binop(Iop_CmpEQ64, mkexpr(t3), mkU64(0x7)),
28861                                mkU64(0x0),
28862                                mkU64(0x1)));
28863 
28864       assign(C_pos, IRExpr_ITE(binop(Iop_CmpLT64U, mkexpr(t3), mkU64(0x6)),
28865                                mkU64(0x2),
28866                                mkU64(0x0)));
28867 
28868       assign(D_pos, IRExpr_ITE(binop(Iop_CmpLT64U, mkexpr(t3), mkU64(0x5)),
28869                                mkU64(0x3),
28870                                mkU64(0x0)));
28871 
28872       assign(E_pos, IRExpr_ITE(binop(Iop_CmpLT64U, mkexpr(t3), mkU64(0x4)),
28873                                mkU64(0x4),
28874                                mkU64(0x0)));
28875 
28876       assign(F_pos, IRExpr_ITE(binop(Iop_CmpLT64U, mkexpr(t3), mkU64(0x3)),
28877                                mkU64(0x5),
28878                                mkU64(0x0)));
28879 
28880       assign(G_pos, IRExpr_ITE(binop(Iop_CmpEQ64, mkexpr(t3), mkU64(0x0)),
28881                                mkU64(0x6),
28882                                mkU64(0x7)));
28883 
28884       /* Store X_byte on the right place. */
28885       store(binop(Iop_Add64, mkexpr(t2), mkU64(0x7)), mkexpr(H_byte));
28886       store(binop(Iop_Add64, mkexpr(t2), mkexpr(G_pos)), mkexpr(G_byte));
28887       store(binop(Iop_Add64, mkexpr(t1), mkexpr(F_pos)), mkexpr(F_byte));
28888       store(binop(Iop_Add64, mkexpr(t1), mkexpr(E_pos)), mkexpr(E_byte));
28889       store(binop(Iop_Add64, mkexpr(t1), mkexpr(D_pos)), mkexpr(D_byte));
28890       store(binop(Iop_Add64, mkexpr(t1), mkexpr(C_pos)), mkexpr(C_byte));
28891       store(binop(Iop_Add64, mkexpr(t1), mkexpr(B_pos)), mkexpr(B_byte));
28892       store(mkexpr(t1), mkexpr(A_byte));
28893 #endif
28894 
28895       break;
28896    }
28897 
28898    case 0x2D: {
28899       /* SDR rt, offset(base) - MIPS64 */
28900       vassert(mode64);
28901       DIP("sdr r%u, %u(r%u)", rt, imm, rs);
28902       IRTemp A_byte = newTemp(Ity_I8);
28903       IRTemp B_byte = newTemp(Ity_I8);
28904       IRTemp C_byte = newTemp(Ity_I8);
28905       IRTemp D_byte = newTemp(Ity_I8);
28906       IRTemp E_byte = newTemp(Ity_I8);
28907       IRTemp F_byte = newTemp(Ity_I8);
28908       IRTemp G_byte = newTemp(Ity_I8);
28909       IRTemp H_byte = newTemp(Ity_I8);
28910       IRTemp B_pos  = newTemp(Ity_I64);
28911       IRTemp C_pos  = newTemp(Ity_I64);
28912       IRTemp D_pos  = newTemp(Ity_I64);
28913       IRTemp E_pos  = newTemp(Ity_I64);
28914       IRTemp F_pos  = newTemp(Ity_I64);
28915       IRTemp G_pos  = newTemp(Ity_I64);
28916 
28917       /* H byte */
28918       assign(H_byte, getByteFromReg(rt, 0));
28919       /* G byte */
28920       assign(G_byte, getByteFromReg(rt, 1));
28921       /* F byte */
28922       assign(F_byte, getByteFromReg(rt, 2));
28923       /* E byte */
28924       assign(E_byte, getByteFromReg(rt, 3));
28925       /* D byte */
28926       assign(D_byte, getByteFromReg(rt, 4));
28927       /* C byte */
28928       assign(C_byte, getByteFromReg(rt, 5));
28929       /* B byte */
28930       assign(B_byte, getByteFromReg(rt, 6));
28931       /* A byte */
28932       assign(A_byte, getByteFromReg(rt, 7));
28933 
28934       /* t1 = addr */
28935       t1 = newTemp(Ity_I64);
28936       assign(t1, binop(Iop_Add64, getIReg(rs), mkU64(extend_s_16to64(imm))));
28937 
28938       /* t2 = word addr */
28939       t2 = newTemp(Ity_I64);
28940       assign(t2, binop(Iop_And64, mkexpr(t1), mkU64(0xFFFFFFFFFFFFFFF8ULL)));
28941 
28942       /* t3 = addr mod 7 */
28943       t3 = newTemp(Ity_I64);
28944       assign(t3, binop(Iop_And64, mkexpr(t1), mkU64(0x7)));
28945 
28946 #if defined (_MIPSEL)
28947       /* Calculate X_byte position. */
28948       assign(B_pos, IRExpr_ITE(binop(Iop_CmpLT64U, mkU64(0x1), mkexpr(t3)),
28949                                mkU64(0x0),
28950                                mkU64(0x6)));
28951 
28952       assign(C_pos, IRExpr_ITE(binop(Iop_CmpLT64U, mkU64(0x2), mkexpr(t3)),
28953                                mkU64(0x0),
28954                                mkU64(0x5)));
28955 
28956       assign(D_pos, IRExpr_ITE(binop(Iop_CmpLT64U, mkU64(0x3), mkexpr(t3)),
28957                                mkU64(0x0),
28958                                mkU64(0x4)));
28959 
28960       assign(E_pos, IRExpr_ITE(binop(Iop_CmpLT64U, mkU64(0x4), mkexpr(t3)),
28961                                mkU64(0x0),
28962                                mkU64(0x3)));
28963 
28964       assign(F_pos, IRExpr_ITE(binop(Iop_CmpLT64U, mkU64(0x5), mkexpr(t3)),
28965                                mkU64(0x0),
28966                                mkU64(0x2)));
28967 
28968       assign(G_pos, IRExpr_ITE(binop(Iop_CmpEQ64, mkexpr(t3), mkU64(0x7)),
28969                                mkU64(0x0),
28970                                mkU64(0x1)));
28971 
28972       /* Store X_byte on the right place. */
28973       store(binop(Iop_Add64, mkexpr(t2), mkU64(0x7)), mkexpr(A_byte));
28974       store(binop(Iop_Add64, mkexpr(t1), mkexpr(B_pos)), mkexpr(B_byte));
28975       store(binop(Iop_Add64, mkexpr(t1), mkexpr(C_pos)), mkexpr(C_byte));
28976       store(binop(Iop_Add64, mkexpr(t1), mkexpr(D_pos)), mkexpr(D_byte));
28977       store(binop(Iop_Add64, mkexpr(t1), mkexpr(E_pos)), mkexpr(E_byte));
28978       store(binop(Iop_Add64, mkexpr(t1), mkexpr(F_pos)), mkexpr(F_byte));
28979       store(binop(Iop_Add64, mkexpr(t1), mkexpr(G_pos)), mkexpr(G_byte));
28980       store(mkexpr(t1), mkexpr(H_byte));
28981 
28982 #else /* _MIPSEB */
28983       /* Calculate X_byte position. */
28984       assign(B_pos, IRExpr_ITE(binop(Iop_CmpLT64U, mkU64(0x5), mkexpr(t3)),
28985                                mkU64(0x6),
28986                                mkU64(0x0)));
28987 
28988       assign(C_pos, IRExpr_ITE(binop(Iop_CmpLT64U, mkU64(0x4), mkexpr(t3)),
28989                                mkU64(0x5),
28990                                mkU64(0x0)));
28991 
28992       assign(D_pos, IRExpr_ITE(binop(Iop_CmpLT64U, mkU64(0x3), mkexpr(t3)),
28993                                mkU64(0x4),
28994                                mkU64(0x0)));
28995 
28996       assign(E_pos, IRExpr_ITE(binop(Iop_CmpLT64U, mkU64(0x2), mkexpr(t3)),
28997                                mkU64(0x3),
28998                                mkU64(0x0)));
28999 
29000       assign(F_pos, IRExpr_ITE(binop(Iop_CmpLT64U, mkU64(0x1), mkexpr(t3)),
29001                                mkU64(0x2),
29002                                mkU64(0x0)));
29003 
29004       assign(G_pos, IRExpr_ITE(binop(Iop_CmpEQ64, mkexpr(t3), mkU64(0x0)),
29005                                mkU64(0x0),
29006                                mkU64(0x1)));
29007 
29008       /* Store X_byte on the right place. */
29009       store(mkexpr(t2), mkexpr(A_byte));
29010       store(binop(Iop_Sub64, mkexpr(t1), mkexpr(B_pos)), mkexpr(B_byte));
29011       store(binop(Iop_Sub64, mkexpr(t1), mkexpr(C_pos)), mkexpr(C_byte));
29012       store(binop(Iop_Sub64, mkexpr(t1), mkexpr(D_pos)), mkexpr(D_byte));
29013       store(binop(Iop_Sub64, mkexpr(t1), mkexpr(E_pos)), mkexpr(E_byte));
29014       store(binop(Iop_Sub64, mkexpr(t1), mkexpr(F_pos)), mkexpr(F_byte));
29015       store(binop(Iop_Sub64, mkexpr(t1), mkexpr(G_pos)), mkexpr(G_byte));
29016       store(mkexpr(t1), mkexpr(H_byte));
29017 #endif
29018       break;
29019    }
29020 
29021    case 0x28:  /* SB */
29022       DIP("sb r%u, %u(r%u)", rt, imm, rs);
29023       LOAD_STORE_PATTERN;
29024       store(mkexpr(t1), narrowTo(Ity_I8, getIReg(rt)));
29025       break;
29026 
29027    case 0x29:  /* SH */
29028       DIP("sh r%u, %u(r%u)", rt, imm, rs);
29029       LOAD_STORE_PATTERN;
29030       store(mkexpr(t1), narrowTo(Ity_I16, getIReg(rt)));
29031       break;
29032 
29033    case 0x2A:  /* SWL */
29034       DIP("swl r%u, %u(r%u)", rt, imm, rs);
29035       if (mode64) {
29036          IRTemp E_byte = newTemp(Ity_I8);
29037          IRTemp F_byte = newTemp(Ity_I8);
29038          IRTemp G_byte = newTemp(Ity_I8);
29039          IRTemp H_byte = newTemp(Ity_I8);
29040          IRTemp F_pos  = newTemp(Ity_I64);
29041          IRTemp G_pos  = newTemp(Ity_I64);
29042 
29043          /* H byte */
29044          assign(H_byte, getByteFromReg(rt, 0));
29045          /* G byte */
29046          assign(G_byte, getByteFromReg(rt, 1));
29047          /* F byte */
29048          assign(F_byte, getByteFromReg(rt, 2));
29049          /* E byte */
29050          assign(E_byte, getByteFromReg(rt, 3));
29051 
29052          /* t1 = addr */
29053          t1 = newTemp(Ity_I64);
29054          assign(t1, binop(Iop_Add64, getIReg(rs), mkU64(extend_s_16to64(imm))));
29055 
29056          /* t2 = word addr */
29057          t2 = newTemp(Ity_I64);
29058          assign(t2, binop(Iop_And64, mkexpr(t1), mkU64(0xFFFFFFFFFFFFFFFCULL)));
29059 
29060          /* t3 = addr mod 4 */
29061          t3 = newTemp(Ity_I64);
29062          assign(t3, binop(Iop_And64, mkexpr(t1), mkU64(0x3)));
29063 
29064 #if defined (_MIPSEL)
29065          /* Calculate X_byte position. */
29066          assign(F_pos, IRExpr_ITE(binop(Iop_CmpEQ64, mkexpr(t3), mkU64(0x0)),
29067                                   mkU64(0x0),
29068                                   mkU64(0x1)));
29069 
29070          assign(G_pos, IRExpr_ITE(binop(Iop_CmpEQ64, mkexpr(t3), mkU64(0x3)),
29071                                   mkU64(0x1),
29072                                   mkU64(0x0)));
29073 
29074          /* Store X_byte on the right place. */
29075          store(mkexpr(t2), mkexpr(H_byte));
29076          store(binop(Iop_Add64, mkexpr(t2), mkexpr(G_pos)), mkexpr(G_byte));
29077          store(binop(Iop_Sub64, mkexpr(t1), mkexpr(F_pos)), mkexpr(F_byte));
29078          store(mkexpr(t1), mkexpr(E_byte));
29079 
29080 #else    /* _MIPSEB */
29081          /* Calculate X_byte position. */
29082          assign(F_pos, IRExpr_ITE(binop(Iop_CmpEQ64, mkexpr(t3), mkU64(0x3)),
29083                                   mkU64(0x0),
29084                                   mkU64(0x1)));
29085 
29086          assign(G_pos, IRExpr_ITE(binop(Iop_CmpEQ64, mkexpr(t3), mkU64(0x0)),
29087                                   mkU64(0x2),
29088                                   mkU64(0x3)));
29089 
29090          store(binop(Iop_Add64, mkexpr(t2), mkU64(3)), mkexpr(H_byte));
29091          store(binop(Iop_Add64, mkexpr(t2), mkexpr(G_pos)), mkexpr(G_byte));
29092          store(binop(Iop_Add64, mkexpr(t1), mkexpr(F_pos)), mkexpr(F_byte));
29093          store(mkexpr(t1), mkexpr(E_byte));
29094 
29095 #endif
29096       } else {
29097          IRTemp E_byte = newTemp(Ity_I8);
29098          IRTemp F_byte = newTemp(Ity_I8);
29099          IRTemp G_byte = newTemp(Ity_I8);
29100          IRTemp H_byte = newTemp(Ity_I8);
29101          IRTemp F_pos  = newTemp(Ity_I32);
29102          IRTemp G_pos  = newTemp(Ity_I32);
29103 
29104          /* H byte */
29105          assign(H_byte, getByteFromReg(rt, 0));
29106          /* G byte */
29107          assign(G_byte, getByteFromReg(rt, 1));
29108          /* F byte */
29109          assign(F_byte, getByteFromReg(rt, 2));
29110          /* E byte */
29111          assign(E_byte, getByteFromReg(rt, 3));
29112 
29113          /* t1 = addr */
29114          t1 = newTemp(Ity_I32);
29115          assign(t1, binop(Iop_Add32, getIReg(rs), mkU32(extend_s_16to32(imm))));
29116 
29117          /* t2 = word addr */
29118          t2 = newTemp(Ity_I32);
29119          assign(t2, binop(Iop_And32, mkexpr(t1), mkU32(0xFFFFFFFCULL)));
29120 
29121          /* t3 = addr mod 4 */
29122          t3 = newTemp(Ity_I32);
29123          assign(t3, binop(Iop_And32, mkexpr(t1), mkU32(0x3)));
29124 
29125 #if defined (_MIPSEL)
29126          /* Calculate X_byte position. */
29127          assign(F_pos, IRExpr_ITE(binop(Iop_CmpEQ32, mkexpr(t3), mkU32(0x0)),
29128                                   mkU32(0x0),
29129                                   mkU32(0x1)));
29130 
29131          assign(G_pos, IRExpr_ITE(binop(Iop_CmpEQ32, mkexpr(t3), mkU32(0x3)),
29132                                   mkU32(0x1),
29133                                   mkU32(0x0)));
29134 
29135          /* Store X_byte on the right place. */
29136          store(mkexpr(t2), mkexpr(H_byte));
29137          store(binop(Iop_Add32, mkexpr(t2), mkexpr(G_pos)), mkexpr(G_byte));
29138          store(binop(Iop_Sub32, mkexpr(t1), mkexpr(F_pos)), mkexpr(F_byte));
29139          store(mkexpr(t1), mkexpr(E_byte));
29140 
29141 #else    /* _MIPSEB */
29142          /* Calculate X_byte position. */
29143          assign(F_pos, IRExpr_ITE(binop(Iop_CmpEQ32, mkexpr(t3), mkU32(0x3)),
29144                                   mkU32(0x0),
29145                                   mkU32(0x1)));
29146 
29147          assign(G_pos, IRExpr_ITE(binop(Iop_CmpEQ32, mkexpr(t3), mkU32(0x0)),
29148                                   mkU32(0x2),
29149                                   mkU32(0x3)));
29150 
29151          store(binop(Iop_Add32, mkexpr(t2), mkU32(3)), mkexpr(H_byte));
29152          store(binop(Iop_Add32, mkexpr(t2), mkexpr(G_pos)), mkexpr(G_byte));
29153          store(binop(Iop_Add32, mkexpr(t1), mkexpr(F_pos)), mkexpr(F_byte));
29154          store(mkexpr(t1), mkexpr(E_byte));
29155 
29156 #endif
29157       }
29158       break;
29159 
29160    case 0x2E:  /* SWR */
29161       DIP("swr r%u, %u(r%u)", rt, imm, rs);
29162       if (mode64) {
29163          IRTemp E_byte = newTemp(Ity_I8);
29164          IRTemp F_byte = newTemp(Ity_I8);
29165          IRTemp G_byte = newTemp(Ity_I8);
29166          IRTemp H_byte = newTemp(Ity_I8);
29167          IRTemp F_pos  = newTemp(Ity_I64);
29168          IRTemp G_pos  = newTemp(Ity_I64);
29169 
29170          /* H byte */
29171          assign(H_byte, getByteFromReg(rt, 0));
29172          /* G byte */
29173          assign(G_byte, getByteFromReg(rt, 1));
29174          /* F byte */
29175          assign(F_byte, getByteFromReg(rt, 2));
29176          /* E byte */
29177          assign(E_byte, getByteFromReg(rt, 3));
29178 
29179          /* t1 = addr */
29180          t1 = newTemp(Ity_I64);
29181          assign(t1, binop(Iop_Add64, getIReg(rs), mkU64(extend_s_16to64(imm))));
29182 
29183          /* t2 = word addr */
29184          t2 = newTemp(Ity_I64);
29185          assign(t2, binop(Iop_And64, mkexpr(t1), mkU64(0xFFFFFFFFFFFFFFFCULL)));
29186 
29187          /* t3 = addr mod 4 */
29188          t3 = newTemp(Ity_I64);
29189          assign(t3, binop(Iop_And64, mkexpr(t1), mkU64(0x3)));
29190 
29191 #if defined (_MIPSEL)
29192          /* Calculate X_byte position. */
29193          assign(F_pos, IRExpr_ITE(binop(Iop_CmpEQ64, mkexpr(t3), mkU64(0x0)),
29194                                   mkU64(0x2),
29195                                   mkU64(0x3)));
29196 
29197          assign(G_pos, IRExpr_ITE(binop(Iop_CmpEQ64, mkexpr(t3), mkU64(0x3)),
29198                                   mkU64(0x0),
29199                                   mkU64(0x1)));
29200 
29201          /* Store X_byte on the right place. */
29202          store(binop(Iop_Add64, mkexpr(t2), mkU64(0x3)), mkexpr(E_byte));
29203          store(binop(Iop_Add64, mkexpr(t2), mkexpr(F_pos)), mkexpr(F_byte));
29204          store(binop(Iop_Add64, mkexpr(t1), mkexpr(G_pos)), mkexpr(G_byte));
29205          store(mkexpr(t1), mkexpr(H_byte));
29206 
29207 #else    /* _MIPSEB */
29208          /* Calculate X_byte position. */
29209          assign(F_pos, IRExpr_ITE(binop(Iop_CmpEQ64, mkexpr(t3), mkU64(0x3)),
29210                                   mkU64(0x1),
29211                                   mkU64(0x0)));
29212 
29213          assign(G_pos, IRExpr_ITE(binop(Iop_CmpEQ64, mkexpr(t3), mkU64(0x0)),
29214                                   mkU64(0x0),
29215                                   mkU64(0x1)));
29216 
29217          /* Store X_byte on the right place. */
29218          store(mkexpr(t2), mkexpr(E_byte));
29219          store(binop(Iop_Add64, mkexpr(t2), mkexpr(F_pos)), mkexpr(F_byte));
29220          store(binop(Iop_Sub64, mkexpr(t1), mkexpr(G_pos)), mkexpr(G_byte));
29221          store(mkexpr(t1), mkexpr(H_byte));
29222 #endif
29223       } else {
29224          IRTemp E_byte = newTemp(Ity_I8);
29225          IRTemp F_byte = newTemp(Ity_I8);
29226          IRTemp G_byte = newTemp(Ity_I8);
29227          IRTemp H_byte = newTemp(Ity_I8);
29228          IRTemp F_pos  = newTemp(Ity_I32);
29229          IRTemp G_pos  = newTemp(Ity_I32);
29230 
29231          /* H byte */
29232          assign(H_byte, getByteFromReg(rt, 0));
29233          /* G byte */
29234          assign(G_byte, getByteFromReg(rt, 1));
29235          /* F byte */
29236          assign(F_byte, getByteFromReg(rt, 2));
29237          /* E byte */
29238          assign(E_byte, getByteFromReg(rt, 3));
29239 
29240          /* t1 = addr */
29241          t1 = newTemp(Ity_I32);
29242          assign(t1, binop(Iop_Add32, getIReg(rs), mkU32(extend_s_16to32(imm))));
29243 
29244          /* t2 = word addr */
29245          t2 = newTemp(Ity_I32);
29246          assign(t2, binop(Iop_And32, mkexpr(t1), mkU32(0xFFFFFFFCULL)));
29247 
29248          /* t3 = addr mod 4 */
29249          t3 = newTemp(Ity_I32);
29250          assign(t3, binop(Iop_And32, mkexpr(t1), mkU32(0x3)));
29251 
29252 #if defined (_MIPSEL)
29253          /* Calculate X_byte position. */
29254          assign(F_pos, IRExpr_ITE(binop(Iop_CmpEQ32, mkexpr(t3), mkU32(0x0)),
29255                                   mkU32(0x2),
29256                                   mkU32(0x3)));
29257 
29258          assign(G_pos, IRExpr_ITE(binop(Iop_CmpEQ32, mkexpr(t3), mkU32(0x3)),
29259                                   mkU32(0x0),
29260                                   mkU32(0x1)));
29261 
29262          /* Store X_byte on the right place. */
29263          store(binop(Iop_Add32, mkexpr(t2), mkU32(0x3)), mkexpr(E_byte));
29264          store(binop(Iop_Add32, mkexpr(t2), mkexpr(F_pos)), mkexpr(F_byte));
29265          store(binop(Iop_Add32, mkexpr(t1), mkexpr(G_pos)), mkexpr(G_byte));
29266          store(mkexpr(t1), mkexpr(H_byte));
29267 
29268 #else    /* _MIPSEB */
29269          /* Calculate X_byte position. */
29270          assign(F_pos, IRExpr_ITE(binop(Iop_CmpEQ32, mkexpr(t3), mkU32(0x3)),
29271                                   mkU32(0x1),
29272                                   mkU32(0x0)));
29273 
29274          assign(G_pos, IRExpr_ITE(binop(Iop_CmpEQ32, mkexpr(t3), mkU32(0x0)),
29275                                   mkU32(0x0),
29276                                   mkU32(0x1)));
29277 
29278          /* Store X_byte on the right place. */
29279          store(mkexpr(t2), mkexpr(E_byte));
29280          store(binop(Iop_Add32, mkexpr(t2), mkexpr(F_pos)), mkexpr(F_byte));
29281          store(binop(Iop_Sub32, mkexpr(t1), mkexpr(G_pos)), mkexpr(G_byte));
29282          store(mkexpr(t1), mkexpr(H_byte));
29283 #endif
29284       }
29285       break;
29286 
29287    case 0x1C:  /* Special2 */
29288       switch (function) {
29289          /* Cavium Specific instructions */
29290          case 0x03: case 0x32: case 0x33:  /* DMUL, CINS , CINS32 */
29291          case 0x3A: case 0x3B: case 0x2B:  /* EXT,  EXT32, SNE    */
29292          /* CVM Compare Instructions */
29293          case 0x2A: case 0x2E: case 0x2F:  /* SEQ,  SEQI,  SNEI   */
29294          /* CPU Load, Store, Memory, and Control Instructions */
29295          case 0x18: case 0x19:             /* SAA, SAAD */
29296          case 0x1F:                        /* LAA, LAAD, LAI, LAID */
29297          case 0x28: case 0x2C: case 0x2D:  /* BADDU, POP, DPOP */
29298             if (VEX_MIPS_COMP_ID(archinfo->hwcaps) == VEX_PRID_COMP_CAVIUM) {
29299                if (dis_instr_CVM(cins))
29300                   break;
29301                goto decode_failure;
29302             } else {
29303                goto decode_failure;
29304             }
29305          break;
29306 
29307          case 0x02: {  /* MUL */
29308             DIP("mul r%u, r%u, r%u", rd, rs, rt);
29309             if (mode64) {
29310                IRTemp tmpRs32 = newTemp(Ity_I32);
29311                IRTemp tmpRt32 = newTemp(Ity_I32);
29312                IRTemp tmpRes = newTemp(Ity_I32);
29313 
29314                assign(tmpRs32, mkNarrowTo32(ty, getIReg(rs)));
29315                assign(tmpRt32, mkNarrowTo32(ty, getIReg(rt)));
29316                assign(tmpRes, binop(Iop_Mul32,
29317                                     mkexpr(tmpRs32), mkexpr(tmpRt32)));
29318                putIReg(rd, mkWidenFrom32(ty, mkexpr(tmpRes), True));
29319             } else
29320                putIReg(rd, binop(Iop_Mul32, getIReg(rs), getIReg(rt)));
29321             break;
29322          }
29323 
29324          case 0x00: {  /* MADD */
29325             if (mode64) {
29326                DIP("madd r%u, r%u", rs, rt);
29327                t1 = newTemp(Ity_I32);
29328                t2 = newTemp(Ity_I32);
29329                t3 = newTemp(Ity_I64);
29330                t4 = newTemp(Ity_I64);
29331                t5 = newTemp(Ity_I64);
29332                t6 = newTemp(Ity_I32);
29333 
29334                assign(t1, mkNarrowTo32(ty, getHI()));
29335                assign(t2, mkNarrowTo32(ty, getLO()));
29336 
29337                assign(t3, binop(Iop_MullS32, mkNarrowTo32(ty, getIReg(rs)),
29338                                              mkNarrowTo32(ty, getIReg(rt))));
29339 
29340                assign(t4, binop(Iop_32HLto64, mkexpr(t1), mkexpr(t2)));
29341                assign(t5, binop(Iop_Add64, mkexpr(t3), mkexpr(t4)));
29342 
29343                putHI(mkWidenFrom32(ty, unop(Iop_64HIto32, mkexpr(t5)), True));
29344                putLO(mkWidenFrom32(ty, unop(Iop_64to32, mkexpr(t5)), True));
29345             } else {
29346                if ( (1 <= ac) && ( 3 >= ac) ) {
29347                   if (VEX_MIPS_PROC_DSP(archinfo->hwcaps)) {
29348                      /* If DSP is present -> DSP ASE MADD */
29349                      UInt retVal = disDSPInstr_MIPS_WRK ( cins );
29350                      if (0 != retVal ) {
29351                         goto decode_failure_dsp;
29352                      }
29353                      break;
29354                   } else {
29355                      goto decode_failure_dsp;
29356                   }
29357                } else {
29358                   DIP("madd r%u, r%u", rs, rt);
29359                   t1 = newTemp(Ity_I32);
29360                   t2 = newTemp(Ity_I32);
29361                   t3 = newTemp(Ity_I64);
29362                   t4 = newTemp(Ity_I32);
29363                   t5 = newTemp(Ity_I32);
29364                   t6 = newTemp(Ity_I32);
29365 
29366                   assign(t1, getHI());
29367                   assign(t2, getLO());
29368 
29369                   assign(t3, binop(Iop_MullS32, getIReg(rs), getIReg(rt)));
29370 
29371                   assign(t4, binop(Iop_Add32, mkexpr(t2), unop(Iop_64to32,
29372                                                                mkexpr(t3))));
29373 
29374                   assign(t5, unop(Iop_1Uto32, binop(Iop_CmpLT32U, mkexpr(t4),
29375                                               unop(Iop_64to32, mkexpr(t3)))));
29376                   assign(t6, binop(Iop_Add32, mkexpr(t5), mkexpr(t1)));
29377 
29378                   putHI(binop(Iop_Add32, mkexpr(t6), unop(Iop_64HIto32,
29379                                                           mkexpr(t3))));
29380                   putLO(mkexpr(t4));
29381                   break;
29382                }
29383             }
29384             break;
29385          }
29386 
29387       case 0x01: {  /* MADDU */
29388          if (mode64) {
29389             DIP("maddu r%u, r%u", rs, rt);
29390             t1 = newTemp(Ity_I32);
29391             t2 = newTemp(Ity_I32);
29392             t3 = newTemp(Ity_I64);
29393             t4 = newTemp(Ity_I64);
29394             t5 = newTemp(Ity_I64);
29395             t6 = newTemp(Ity_I32);
29396 
29397             assign(t1, mkNarrowTo32(ty, getHI()));
29398             assign(t2, mkNarrowTo32(ty, getLO()));
29399 
29400             assign(t3, binop(Iop_MullU32, mkNarrowTo32(ty, getIReg(rs)),
29401                                           mkNarrowTo32(ty, getIReg(rt))));
29402 
29403             assign(t4, binop(Iop_32HLto64, mkexpr(t1), mkexpr(t2)));
29404             assign(t5, binop(Iop_Add64, mkexpr(t3), mkexpr(t4)));
29405 
29406             putHI(mkWidenFrom32(ty, unop(Iop_64HIto32, mkexpr(t5)), True));
29407             putLO(mkWidenFrom32(ty, unop(Iop_64to32, mkexpr(t5)), True));
29408          } else {
29409             if ( (1 <= ac) && ( 3 >= ac) ) {
29410                if (VEX_MIPS_PROC_DSP(archinfo->hwcaps)) {
29411                   /* If DSP is present -> DSP ASE MADDU */
29412                   UInt retVal = disDSPInstr_MIPS_WRK ( cins );
29413                   if (0 != retVal ) {
29414                      goto decode_failure_dsp;
29415                   }
29416                   break;
29417                } else {
29418                   goto decode_failure_dsp;
29419                }
29420             } else {
29421                DIP("maddu r%u, r%u", rs, rt);
29422                t1 = newTemp(Ity_I32);
29423                t2 = newTemp(Ity_I32);
29424                t3 = newTemp(Ity_I64);
29425                t4 = newTemp(Ity_I32);
29426                t5 = newTemp(Ity_I32);
29427                t6 = newTemp(Ity_I32);
29428 
29429                assign(t1, getHI());
29430                assign(t2, getLO());
29431 
29432                assign(t3, binop(Iop_MullU32, getIReg(rs), getIReg(rt)));
29433 
29434                assign(t4, binop(Iop_Add32, mkexpr(t2), unop(Iop_64to32,
29435                                                             mkexpr(t3))));
29436                assign(t5, unop(Iop_1Uto32, binop(Iop_CmpLT32U, mkexpr(t4),
29437                                            unop(Iop_64to32, mkexpr(t3)))));
29438                assign(t6, binop(Iop_Add32, mkexpr(t5), mkexpr(t1)));
29439 
29440                putHI(binop(Iop_Add32, mkexpr(t6), unop(Iop_64HIto32,
29441                                                       mkexpr(t3))));
29442                putLO(mkexpr(t4));
29443                break;
29444             }
29445          }
29446          break;
29447       }
29448 
29449       case 0x04: {  /* MSUB */
29450          if (mode64) {
29451             DIP("msub r%u, r%u", rs, rt);
29452             t1 = newTemp(Ity_I32);
29453             t2 = newTemp(Ity_I32);
29454             t3 = newTemp(Ity_I64);
29455             t4 = newTemp(Ity_I64);
29456             t5 = newTemp(Ity_I64);
29457             t6 = newTemp(Ity_I32);
29458 
29459             assign(t1, mkNarrowTo32(ty, getHI()));
29460             assign(t2, mkNarrowTo32(ty, getLO()));
29461 
29462             assign(t3, binop(Iop_MullS32, mkNarrowTo32(ty, getIReg(rs)),
29463                                           mkNarrowTo32(ty, getIReg(rt))));
29464 
29465             assign(t4, binop(Iop_32HLto64, mkexpr(t1), mkexpr(t2)));
29466             assign(t5, binop(Iop_Sub64, mkexpr(t4), mkexpr(t3)));
29467 
29468             putHI(mkWidenFrom32(ty, unop(Iop_64HIto32, mkexpr(t5)), True));
29469             putLO(mkWidenFrom32(ty, unop(Iop_64to32, mkexpr(t5)), True));
29470          } else {
29471             if ( (1 <= ac) && ( 3 >= ac) ) {
29472                if (VEX_MIPS_PROC_DSP(archinfo->hwcaps)) {
29473                   /* If DSP is present -> DSP ASE MSUB */
29474                   UInt retVal = disDSPInstr_MIPS_WRK ( cins );
29475                   if (0 != retVal ) {
29476                      goto decode_failure_dsp;
29477                   }
29478                   break;
29479                } else {
29480                   goto decode_failure_dsp;
29481                }
29482             } else {
29483                DIP("msub r%u, r%u", rs, rt);
29484                t1 = newTemp(Ity_I32);
29485                t2 = newTemp(Ity_I32);
29486                t3 = newTemp(Ity_I64);
29487                t4 = newTemp(Ity_I32);
29488                t5 = newTemp(Ity_I1);
29489                t6 = newTemp(Ity_I32);
29490 
29491                assign(t1, getHI());
29492                assign(t2, getLO());
29493 
29494                assign(t3, binop(Iop_MullS32, getIReg(rs), getIReg(rt)));
29495                assign(t4, unop(Iop_64to32, mkexpr(t3)));  /* new lo */
29496 
29497                /* if lo<lo(mul) hi = hi - 1 */
29498                assign(t5, binop(Iop_CmpLT32U,
29499                                  mkexpr(t2),
29500                                  mkexpr(t4)));
29501 
29502                assign(t6, IRExpr_ITE(mkexpr(t5),
29503                                        binop(Iop_Sub32, mkexpr(t1), mkU32(0x1)),
29504                                        mkexpr(t1)));
29505 
29506                putHI(binop(Iop_Sub32, mkexpr(t6), unop(Iop_64HIto32,
29507                                                       mkexpr(t3))));
29508                putLO(binop(Iop_Sub32, mkexpr(t2), mkexpr(t4)));
29509                break;
29510             }
29511          }
29512          break;
29513       }
29514 
29515       case 0x05: {  /* MSUBU */
29516          if (mode64) {
29517             DIP("msubu r%u, r%u", rs, rt);
29518             t1 = newTemp(Ity_I32);
29519             t2 = newTemp(Ity_I32);
29520             t3 = newTemp(Ity_I64);
29521             t4 = newTemp(Ity_I64);
29522             t5 = newTemp(Ity_I64);
29523             t6 = newTemp(Ity_I32);
29524 
29525             assign(t1, mkNarrowTo32(ty, getHI()));
29526             assign(t2, mkNarrowTo32(ty, getLO()));
29527 
29528             assign(t3, binop(Iop_MullU32, mkNarrowTo32(ty, getIReg(rs)),
29529                                           mkNarrowTo32(ty, getIReg(rt))));
29530 
29531             assign(t4, binop(Iop_32HLto64, mkexpr(t1), mkexpr(t2)));
29532             assign(t5, binop(Iop_Sub64, mkexpr(t4), mkexpr(t3)));
29533 
29534             putHI(mkWidenFrom32(ty, unop(Iop_64HIto32, mkexpr(t5)), True));
29535             putLO(mkWidenFrom32(ty, unop(Iop_64to32, mkexpr(t5)), True));
29536          } else {
29537             if ( (1 <= ac) && ( 3 >= ac) ) {
29538                if (VEX_MIPS_PROC_DSP(archinfo->hwcaps)) {
29539                   /* If DSP is present -> DSP ASE MSUBU */
29540                   UInt retVal = disDSPInstr_MIPS_WRK ( cins );
29541                   if (0 != retVal ) {
29542                      goto decode_failure_dsp;
29543                   }
29544                   break;
29545                } else {
29546                   goto decode_failure_dsp;
29547                }
29548             } else {
29549                DIP("msubu r%u, r%u", rs, rt);
29550                t1 = newTemp(Ity_I32);
29551                t2 = newTemp(Ity_I32);
29552                t3 = newTemp(Ity_I64);
29553                t4 = newTemp(Ity_I32);
29554                t5 = newTemp(Ity_I1);
29555                t6 = newTemp(Ity_I32);
29556 
29557                assign(t1, getHI());
29558                assign(t2, getLO());
29559 
29560                assign(t3, binop(Iop_MullU32, getIReg(rs), getIReg(rt)));
29561                assign(t4, unop(Iop_64to32, mkexpr(t3)));  /* new lo */
29562 
29563                /* if lo<lo(mul) hi = hi - 1 */
29564                assign(t5, binop(Iop_CmpLT32U,
29565                                  mkexpr(t2),
29566                                  mkexpr(t4)));
29567 
29568                assign(t6, IRExpr_ITE(mkexpr(t5),
29569                                     binop(Iop_Sub32,
29570                                           mkexpr(t1),
29571                                           mkU32(0x1)),
29572                                     mkexpr(t1)));
29573 
29574                putHI(binop(Iop_Sub32, mkexpr(t6), unop(Iop_64HIto32,
29575                                                       mkexpr(t3))));
29576                putLO(binop(Iop_Sub32, mkexpr(t2), mkexpr(t4)));
29577                break;
29578             }
29579          }
29580          break;
29581       }
29582 
29583       case 0x6:  /* dmul MIPS64 - Netlogic */
29584          DIP("dmul r%u, r%u, r%u", rd, rs, rt);
29585          t0 = newTemp(Ity_I128);
29586 
29587          assign(t0, binop(Iop_MullU64, getIReg(rs), getIReg(rt)));
29588 
29589          putIReg(rd, unop(Iop_128to64, mkexpr(t0)));
29590          break;
29591 
29592       case 0x10:  /* LDADDW - Swap Word - Netlogic */
29593          DIP("ldaddw r%u, r%u", rt, rs);
29594          t0 = newTemp(Ity_I32);
29595          t1 = newTemp(Ity_I32);
29596          t2 = newTemp(Ity_I32);
29597          t3 = newTemp(Ity_I64);
29598          t4 = newTemp(Ity_I32);
29599          t5 = newTemp(Ity_I32);
29600          t6 = newTemp(Ity_I32);
29601 
29602          /* v = GPR[rt] */
29603          assign(t0, mkNarrowTo32(ty, getIReg(rt)));
29604 
29605          /* GPR[rt] = memory[base]; */
29606          assign(t1, load(Ity_I32, getIReg(rs)));
29607          putIReg(rt, mkWidenFrom32(ty, mkexpr(t1), True));
29608 
29609          /* memory[base] = memory[base] + v; */
29610          store(getIReg(rs), binop(Iop_Add32, mkexpr(t0), mkexpr(t1)));
29611          break;
29612 
29613       case 0x12:  /* LDADDD - Swap Word - Netlogic */
29614          DIP("ldaddw r%u, r%u", rt, rs);
29615          t0 = newTemp(Ity_I64);
29616          t1 = newTemp(Ity_I64);
29617 
29618          /*  v = GPR[rt] */
29619          assign(t0, getIReg(rt));
29620 
29621          /* GPR[rt] = memory[base]; */
29622          assign(t1, load(Ity_I64, getIReg(rs)));
29623          putIReg(rt, mkexpr(t1));
29624 
29625          /* memory[base] = memory[base] + v; */
29626          store(getIReg(rs), binop(Iop_Add64, mkexpr(t0), mkexpr(t1)));
29627          break;
29628 
29629       case 0x14:  /* SWAPW - Swap Word - Netlogic */
29630          DIP("swapw r%u, r%u", rt, rs);
29631          t0 = newTemp(Ity_I32);
29632          t1 = newTemp(Ity_I32);
29633          assign(t0, mkNarrowTo32(ty, getIReg(rt)));
29634          assign(t1, load(Ity_I32, getIReg(rs)));
29635          putIReg(rt, mkWidenFrom32(ty, mkexpr(t1), True));
29636          store(getIReg(rs), mkexpr(t0));
29637          break;
29638 
29639       case 0x16:  /* SWAPD - Swap Double - Netlogic */
29640          DIP("swapw r%u, r%u", rt, rs);
29641          t0 = newTemp(Ity_I64);
29642          t1 = newTemp(Ity_I64);
29643          assign(t0, getIReg(rt));
29644          assign(t1, load(Ity_I64, getIReg(rs)));
29645          putIReg(rt, mkexpr(t1));
29646          store(getIReg(rs), mkexpr(t0));
29647          break;
29648 
29649       case 0x20: {  /* CLZ */
29650          DIP("clz r%u, r%u", rd, rs);
29651          if (mode64) {
29652             IRTemp tmpClz32 = newTemp(Ity_I32);
29653             IRTemp tmpRs32 = newTemp(Ity_I32);
29654 
29655             assign(tmpRs32, mkNarrowTo32(ty, getIReg(rs)));
29656             assign(tmpClz32, unop(Iop_Clz32, mkexpr(tmpRs32)));
29657             putIReg(rd, mkWidenFrom32(ty, mkexpr(tmpClz32), True));
29658          } else {
29659             t1 = newTemp(Ity_I1);
29660             assign(t1, binop(Iop_CmpEQ32, getIReg(rs), mkU32(0)));
29661             putIReg(rd, IRExpr_ITE(mkexpr(t1),
29662                                    mkU32(0x00000020),
29663                                    unop(Iop_Clz32, getIReg(rs))));
29664          }
29665          break;
29666       }
29667 
29668       case 0x21: {  /* CLO */
29669          DIP("clo r%u, r%u", rd, rs);
29670          if (mode64) {
29671             IRTemp tmpClo32 = newTemp(Ity_I32);
29672             IRTemp tmpRs32 = newTemp(Ity_I32);
29673             assign(tmpRs32, mkNarrowTo32(ty, getIReg(rs)));
29674 
29675             t1 = newTemp(Ity_I1);
29676             assign(t1, binop(Iop_CmpEQ32, mkexpr(tmpRs32), mkU32(0xffffffff)));
29677             assign(tmpClo32, IRExpr_ITE(mkexpr(t1),
29678                       mkU32(0x00000020),
29679                       unop(Iop_Clz32, unop(Iop_Not32, mkexpr(tmpRs32)))));
29680 
29681             putIReg(rd, mkWidenFrom32(ty, mkexpr(tmpClo32), True));
29682             break;
29683          } else {
29684             t1 = newTemp(Ity_I1);
29685             assign(t1, binop(Iop_CmpEQ32, getIReg(rs), mkU32(0xffffffff)));
29686             putIReg(rd, IRExpr_ITE(mkexpr(t1),
29687                                    mkU32(0x00000020),
29688                                    unop(Iop_Clz32,
29689                                         unop(Iop_Not32, getIReg(rs)))));
29690             break;
29691          }
29692       }
29693 
29694       case 0x24:  /* Count Leading Zeros in Doubleword - DCLZ; MIPS64 */
29695          DIP("dclz r%u, r%u", rd, rs);
29696          t1 = newTemp(Ity_I1);
29697          assign(t1, binop(Iop_CmpEQ64, getIReg(rs), mkU64(0)));
29698          putIReg(rd, IRExpr_ITE(mkexpr(t1),
29699                      mkU64(0x00000040),
29700                      unop(Iop_Clz64, getIReg(rs))));
29701          break;
29702 
29703       case 0x25:  /* Count Leading Ones in Doubleword - DCLO; MIPS64 */
29704          DIP("dclo r%u, r%u", rd, rs);
29705          t1 = newTemp(Ity_I1);
29706          assign(t1, binop(Iop_CmpEQ64, getIReg(rs),
29707                                         mkU64(0xffffffffffffffffULL)));
29708          putIReg(rd, IRExpr_ITE(mkexpr(t1),
29709                                 mkU64(0x40),
29710                                 unop(Iop_Clz64, unop(Iop_Not64,
29711                                                      getIReg(rs)))));
29712          break;
29713 
29714       default:
29715          goto decode_failure;
29716       }
29717       break;
29718 
29719    case 0x1F:  /* Special3 */
29720       switch (function) {
29721          case 0x01: {
29722             /* Doubleword Extract Bit Field - DEXTM; MIPS64r2 */
29723             msb = get_msb(cins);
29724             lsb = get_lsb(cins);
29725             size = msb + 1;
29726             UInt srcPos = lsb;
29727             UInt dstSz = msb + 33;
29728             t1 = newTemp(Ity_I64);
29729             DIP("dextm r%u, r%u, %u, %u", rt, rs, lsb, msb + 1);
29730 
29731             UChar lsAmt = 64 - (srcPos + dstSz);  /* left shift amount; */
29732             UChar rsAmt = 64 - dstSz;  /* right shift amount; */
29733 
29734             assign(t1, binop(Iop_Shl64, getIReg(rs), mkU8(lsAmt)));
29735             putIReg(rt, binop(Iop_Shr64, mkexpr(t1), mkU8(rsAmt)));
29736 
29737             break;
29738          }
29739          case 0x02: {
29740             /* Doubleword Extract Bit Field Upper - DEXTU; MIPS64r2 */
29741             msb = get_msb(cins);
29742             lsb = get_lsb(cins);
29743             size = msb + 1;
29744             UInt srcPos = lsb + 32;
29745             UInt dstSz = msb + 1;
29746             DIP("dextu r%u, r%u, %u, %u", rt, rs, srcPos, dstSz);
29747             t1 = newTemp(Ity_I64);
29748 
29749             vassert(srcPos >= 32 && srcPos < 64);
29750             vassert(dstSz > 0 && dstSz <= 32);
29751             vassert((srcPos + dstSz) > 32 && (srcPos + dstSz) <= 64);
29752 
29753             UChar lsAmt = 64 - (srcPos + dstSz);  /* left shift amount; */
29754             UChar rsAmt = 64 - dstSz;  /* right shift amount; */
29755 
29756             assign(t1, binop(Iop_Shl64, getIReg(rs), mkU8(lsAmt)));
29757             putIReg(rt, binop(Iop_Shr64, mkexpr(t1), mkU8(rsAmt)));
29758             break;
29759          }
29760          case 0x05: {
29761             /* Doubleword Insert Bit Field Middle - DINSM; MIPS64r2 */
29762             msb = get_msb(cins);
29763             lsb = get_lsb(cins);
29764             size = msb + 1;
29765             UInt dstPos = lsb;
29766             UInt srcSz = msb - lsb + 33;
29767             t1 = newTemp(ty);
29768             t2 = newTemp(ty);
29769             t3 = newTemp(ty);
29770             t4 = newTemp(ty);
29771             IRTemp tmpT1 = newTemp(ty);
29772             IRTemp tmpT2 = newTemp(ty);
29773             IRTemp tmpT3 = newTemp(ty);
29774             IRTemp tmpT4 = newTemp(ty);
29775             IRTemp tmpT5 = newTemp(ty);
29776             IRTemp tmpT6 = newTemp(ty);
29777             IRTemp tmpT7 = newTemp(ty);
29778             IRTemp tmpRs = newTemp(ty);
29779             IRTemp tmpRt = newTemp(ty);
29780             IRTemp tmpRd = newTemp(ty);
29781 
29782             assign(tmpRs, getIReg(rs));
29783             assign(tmpRt, getIReg(rt));
29784             DIP("dinsm r%u, r%u, %u, %u", rt, rs, lsb, msb);
29785 
29786             UChar lsAmt = dstPos + srcSz - 1;   /* left shift amount; */
29787             UChar rsAmt = dstPos + srcSz - 1;   /* right shift amount; */
29788 
29789             assign(t1, binop(Iop_Shr64, mkexpr(tmpRt), mkU8(rsAmt)));
29790             assign(tmpT1, binop(Iop_Shr64, mkexpr(t1), mkU8(1)));
29791             assign(t2, binop(Iop_Shl64, mkexpr(tmpT1), mkU8(lsAmt)));
29792             assign(tmpT2, binop(Iop_Shl64, mkexpr(t2), mkU8(1)));
29793 
29794             lsAmt = 63 - dstPos; /* left shift amount; */
29795             rsAmt = 63 - dstPos; /* right shift amount; */
29796 
29797             assign(t3, binop(Iop_Shl64, mkexpr(tmpRt), mkU8(lsAmt)));
29798             assign(tmpT3, binop(Iop_Shl64, mkexpr(t3), mkU8(1)));
29799             assign(t4, binop(Iop_Shr64, mkexpr(tmpT3), mkU8(rsAmt)));
29800             assign(tmpT4, binop(Iop_Shr64, mkexpr(t4), mkU8(1)));
29801 
29802             /* extract size from src register */
29803             lsAmt = 64 - srcSz;  /* left shift amount; */
29804             rsAmt = 64 - (lsb + srcSz);   /* right shift amount; */
29805 
29806             assign(tmpT5, binop(Iop_Shl64, mkexpr(tmpRs), mkU8(lsAmt)));
29807             assign(tmpT6, binop(Iop_Shr64, mkexpr(tmpT5), mkU8(rsAmt)));
29808 
29809             assign(tmpT7, binop(Iop_Or64, mkexpr(tmpT2), mkexpr(tmpT4)));
29810             assign(tmpRd, binop(Iop_Or64, mkexpr(tmpT6), mkexpr(tmpT7)));
29811             putIReg(rt, mkexpr(tmpRd));
29812             break;
29813          }
29814          case 0x06: {
29815             /* Doubleword Insert Bit Field Upper - DINSU; MIPS64r2 */
29816             msb = get_msb(cins);
29817             lsb = get_lsb(cins);
29818             size = msb + 1;
29819             UInt dstPos = lsb + 32;
29820             UInt srcSz = msb - lsb + 1;
29821             IRTemp tmpT1 = newTemp(ty);
29822             IRTemp tmpT2 = newTemp(ty);
29823             IRTemp tmpT3 = newTemp(ty);
29824             IRTemp tmpT4 = newTemp(ty);
29825             IRTemp tmpT5 = newTemp(ty);
29826             IRTemp tmpT6 = newTemp(ty);
29827             IRTemp tmpT7 = newTemp(ty);
29828             IRTemp tmpT8 = newTemp(ty);
29829             IRTemp tmpT9 = newTemp(ty);
29830             IRTemp tmpRs = newTemp(ty);
29831             IRTemp tmpRt = newTemp(ty);
29832             IRTemp tmpRd = newTemp(ty);
29833 
29834             assign(tmpRs, getIReg(rs));
29835             assign(tmpRt, getIReg(rt));
29836             DIP("dinsu r%u, r%u, %u, %u", rt, rs, lsb, msb);
29837 
29838             UChar lsAmt = 64 - srcSz;  /* left shift amount; */
29839             UChar rsAmt = 64 - (dstPos + srcSz);  /* right shift amount; */
29840             assign(tmpT1, binop(Iop_Shl64, mkexpr(tmpRs), mkU8(lsAmt)));
29841             assign(tmpT2, binop(Iop_Shr64, mkexpr(tmpT1), mkU8(rsAmt)));
29842 
29843             lsAmt = 64 - dstPos;  /* left shift amount; */
29844             rsAmt = 64 - dstPos;  /* right shift amount; */
29845             assign(tmpT3, binop(Iop_Shl64, mkexpr(tmpRt), mkU8(lsAmt)));
29846             assign(tmpT4, binop(Iop_Shr64, mkexpr(tmpT3), mkU8(rsAmt)));
29847 
29848             lsAmt = dstPos;  /* left shift amount; */
29849             rsAmt = srcSz;  /* right shift amount; */
29850             assign(tmpT5, binop(Iop_Shr64, mkexpr(tmpRt), mkU8(rsAmt)));
29851             assign(tmpT6, binop(Iop_Shr64, mkexpr(tmpT5), mkU8(lsAmt)));
29852 
29853             assign(tmpT7, binop(Iop_Shl64, mkexpr(tmpT6), mkU8(rsAmt)));
29854             assign(tmpT8, binop(Iop_Shl64, mkexpr(tmpT7), mkU8(lsAmt)));
29855 
29856             assign(tmpT9, binop(Iop_Or64, mkexpr(tmpT8), mkexpr(tmpT4)));
29857             assign(tmpRd, binop(Iop_Or64, mkexpr(tmpT2), mkexpr(tmpT9)));
29858             putIReg(rt, mkexpr(tmpRd));
29859             break;
29860          }
29861          case 0x07: {
29862             /* Doubleword Insert Bit Field - DINS; MIPS64r2 */
29863             IRTemp tmp1 = newTemp(ty);
29864             IRTemp tmpT1 = newTemp(ty);
29865             IRTemp tmpT2 = newTemp(ty);
29866             IRTemp tmpT3 = newTemp(ty);
29867             IRTemp tmpT4 = newTemp(ty);
29868             IRTemp tmpT5 = newTemp(ty);
29869             IRTemp tmpT6 = newTemp(ty);
29870             IRTemp tmpT7 = newTemp(ty);
29871             IRTemp tmpT8 = newTemp(ty);
29872             IRTemp tmpT9 = newTemp(ty);
29873             IRTemp tmp = newTemp(ty);
29874             IRTemp tmpRs = newTemp(ty);
29875             IRTemp tmpRt = newTemp(ty);
29876             IRTemp tmpRd = newTemp(ty);
29877 
29878             assign(tmpRs, getIReg(rs));
29879             assign(tmpRt, getIReg(rt));
29880 
29881             msb = get_msb(cins);
29882             lsb = get_lsb(cins);
29883             size = msb + 1;
29884             DIP("dins r%u, r%u, %u, %u", rt, rs, lsb,
29885                 msb - lsb + 1);
29886             UChar lsAmt = 63 - lsb;  /* left shift amount; */
29887             UChar rsAmt = 63 - lsb;  /* right shift amount; */
29888             assign(tmp, binop(Iop_Shl64, mkexpr(tmpRt), mkU8(lsAmt)));
29889             assign(tmpT1, binop(Iop_Shl64, mkexpr(tmp), mkU8(1)));
29890             assign(tmp1, binop(Iop_Shr64, mkexpr(tmpT1), mkU8(rsAmt)));
29891             assign(tmpT2, binop(Iop_Shr64, mkexpr(tmp1), mkU8(1)));
29892 
29893             lsAmt = msb;  /* left shift amount; */
29894             rsAmt = 1;  /*right shift amount; */
29895             assign(tmpT3, binop(Iop_Shr64, mkexpr(tmpRt), mkU8(rsAmt)));
29896             assign(tmpT4, binop(Iop_Shr64, mkexpr(tmpT3), mkU8(lsAmt)));
29897             assign(tmpT5, binop(Iop_Shl64, mkexpr(tmpT4), mkU8(rsAmt)));
29898             assign(tmpT6, binop(Iop_Shl64, mkexpr(tmpT5), mkU8(lsAmt)));
29899 
29900             lsAmt = 64 - (msb - lsb + 1);  /* left shift amount; */
29901             rsAmt = 64 - (msb + 1);  /* right shift amount; */
29902             assign(tmpT7, binop(Iop_Shl64, mkexpr(tmpRs), mkU8(lsAmt)));
29903             assign(tmpT8, binop(Iop_Shr64, mkexpr(tmpT7), mkU8(rsAmt)));
29904 
29905             assign(tmpT9, binop(Iop_Or64, mkexpr(tmpT2), mkexpr(tmpT8)));
29906             assign(tmpRd, binop(Iop_Or64, mkexpr(tmpT6), mkexpr(tmpT9)));
29907             putIReg(rt, mkexpr(tmpRd));
29908             break;
29909          }
29910       case 0x24:  /* DBSHFL */
29911          lsb = get_lsb(cins);
29912          IRTemp tmpRs = newTemp(ty);
29913          IRTemp tmpRt = newTemp(ty);
29914          IRTemp tmpRd = newTemp(ty);
29915          assign(tmpRs, getIReg(rs));
29916          assign(tmpRt, getIReg(rt));
29917          switch (lsb) {
29918             case 0x02: {  /* DSBH */
29919                DIP("dsbh r%u, r%u", rd, rt);
29920                IRTemp tmpT1 = newTemp(ty);
29921                IRTemp tmpT2 = newTemp(ty);
29922                IRTemp tmpT3 = newTemp(ty);
29923                IRTemp tmpT4 = newTemp(ty);
29924                IRTemp tmpT5 = newTemp(Ity_I64);
29925                IRTemp tmpT6 = newTemp(ty);
29926                assign(tmpT5, mkU64(0xFF00FF00FF00FF00ULL));
29927                assign(tmpT6, mkU64(0x00FF00FF00FF00FFULL));
29928                assign(tmpT1, binop(Iop_And64, mkexpr(tmpRt), mkexpr(tmpT5)));
29929                assign(tmpT2, binop(Iop_Shr64, mkexpr(tmpT1), mkU8(8)));
29930                assign(tmpT3, binop(Iop_And64, mkexpr(tmpRt), mkexpr(tmpT6)));
29931                assign(tmpT4, binop(Iop_Shl64, mkexpr(tmpT3), mkU8(8)));
29932                assign(tmpRd, binop(Iop_Or64, mkexpr(tmpT4), mkexpr(tmpT2)));
29933                putIReg(rd, mkexpr(tmpRd));
29934                break;
29935             }
29936             case 0x05: {  /* DSHD */
29937                DIP("dshd r%u, r%u\n", rd, rt);
29938                IRTemp tmpT1 = newTemp(ty);
29939                IRTemp tmpT2 = newTemp(ty);
29940                IRTemp tmpT3 = newTemp(ty);
29941                IRTemp tmpT4 = newTemp(ty);
29942                IRTemp tmpT5 = newTemp(Ity_I64);
29943                IRTemp tmpT6 = newTemp(ty);
29944                IRTemp tmpT7 = newTemp(ty);
29945                IRTemp tmpT8 = newTemp(ty);
29946                IRTemp tmpT9 = newTemp(ty);
29947                assign(tmpT5, mkU64(0xFFFF0000FFFF0000ULL));
29948                assign(tmpT6, mkU64(0x0000FFFF0000FFFFULL));
29949                assign(tmpT1, binop(Iop_And64, mkexpr(tmpRt), mkexpr(tmpT5)));
29950                assign(tmpT2, binop(Iop_Shr64, mkexpr(tmpT1), mkU8(16)));
29951                assign(tmpT3, binop(Iop_And64, mkexpr(tmpRt), mkexpr(tmpT6)));
29952                assign(tmpT4, binop(Iop_Shl64, mkexpr(tmpT3), mkU8(16)));
29953                assign(tmpT7, binop(Iop_Or64, mkexpr(tmpT4), mkexpr(tmpT2)));
29954                assign(tmpT8, binop(Iop_Shl64, mkexpr(tmpT7), mkU8(32)));
29955                assign(tmpT9, binop(Iop_Shr64, mkexpr(tmpT7), mkU8(32)));
29956                assign(tmpRd, binop(Iop_Or64, mkexpr(tmpT8), mkexpr(tmpT9)));
29957                putIReg(rd, mkexpr(tmpRd));
29958                break;
29959             }
29960                case 0x08 ... 0x0f: { /* DALIGN */
29961                   if (VEX_MIPS_CPU_HAS_MIPSR6(archinfo->hwcaps)) {
29962                      DIP("daling r%u, r%u, r%u, %d", rd, rs, rt,  lsb & 0x7);
29963                      UInt bp = (lsb & 0x7) << 3;
29964                      if (bp) {
29965                         putIReg(rd, binop(Iop_Or64,
29966                                           binop(Iop_Shl64, getIReg(rt), mkU8(bp)),
29967                                           binop(Iop_Shr64,
29968                                                 getIReg(rs), mkU8(64 - bp))));
29969                      } else
29970                         putIReg(rd, getIReg(rt));
29971                   } else {
29972                      ILLEGAL_INSTRUCTON;
29973                   }
29974                   break;
29975                }
29976 
29977                case 0: /* DBITSWAP */
29978                   if (VEX_MIPS_CPU_HAS_MIPSR6(archinfo->hwcaps)) {
29979                      DIP("dbitswap r%u, r%u", rd, rt);
29980                      putIReg(rd, qop(Iop_Rotx64, getIReg(rt), mkU8(7), mkU8(8), mkU8(1)));
29981                   } else {
29982                      ILLEGAL_INSTRUCTON;
29983                   }
29984                   break;
29985          default:
29986             vex_printf("\nop6o10 = %u", lsb);
29987             goto decode_failure;;
29988          }
29989          break;
29990       case 0x3B: /* RDHWR */
29991          DIP("rdhwr r%u, r%u", rt, rd);
29992          if (VEX_MIPS_CPU_HAS_MIPS32R2(archinfo->hwcaps) ||
29993              VEX_MIPS_CPU_HAS_MIPSR6(archinfo->hwcaps) ||
29994              (VEX_MIPS_COMP_ID(archinfo->hwcaps) == VEX_PRID_COMP_BROADCOM)) {
29995             if (rd == 29) {
29996                putIReg(rt, getULR());
29997             } else if (rd <= 3
29998                        || (rd == 31
29999                            && VEX_MIPS_COMP_ID(archinfo->hwcaps)
30000                                                     == VEX_PRID_COMP_CAVIUM)) {
30001                IRExpr** arg = mkIRExprVec_1(mkU32(rd));
30002                IRTemp   val  = newTemp(ty);
30003                IRDirty *d = unsafeIRDirty_1_N(val,
30004                                               0,
30005                                               "mips_dirtyhelper_rdhwr",
30006                                               &mips_dirtyhelper_rdhwr,
30007                                               arg);
30008                stmt(IRStmt_Dirty(d));
30009                putIReg(rt, mkexpr(val));
30010             } else
30011                goto decode_failure;
30012          } else {
30013             ILLEGAL_INSTRUCTON;
30014          }
30015          break;
30016       case 0x04:  /* INS */
30017          msb = get_msb(cins);
30018          lsb = get_lsb(cins);
30019          size = msb - lsb + 1;
30020          DIP("ins size:%u msb:%u lsb:%u", size, msb, lsb);
30021 
30022          vassert(lsb + size <= 32);
30023          vassert(lsb + size > 0);
30024 
30025          /* put size bits from rs at the pos in temporary */
30026          t0 = newTemp(Ity_I32);
30027          t3 = newTemp(Ity_I32);
30028          /* shift left for 32 - size to clear leading bits and get zeros
30029             at the end */
30030          assign(t0, binop(Iop_Shl32, mkNarrowTo32(ty, getIReg(rs)),
30031                           mkU8(32 - size)));
30032          /* now set it at pos */
30033          t1 = newTemp(Ity_I32);
30034          assign(t1, binop(Iop_Shr32, mkexpr(t0), mkU8(32 - size - lsb)));
30035 
30036          if (lsb > 0) {
30037             t2 = newTemp(Ity_I32);
30038             /* clear everything but lower pos bits from rt */
30039             assign(t2, binop(Iop_Shl32, mkNarrowTo32(ty, getIReg(rt)),
30040                              mkU8(32 - lsb)));
30041             assign(t3, binop(Iop_Shr32, mkexpr(t2), mkU8(32 - lsb)));
30042          } else
30043             assign(t3, mkU32(0));
30044 
30045          if (msb < 31) {
30046             t4 = newTemp(Ity_I32);
30047             /* clear everything but upper msb + 1 bits from rt */
30048             assign(t4, binop(Iop_Shr32, mkNarrowTo32(ty, getIReg(rt)),
30049                              mkU8(msb + 1)));
30050             t5 = newTemp(Ity_I32);
30051             assign(t5, binop(Iop_Shl32, mkexpr(t4), mkU8(msb + 1)));
30052 
30053             /* now combine these registers */
30054             if (lsb > 0) {
30055                t6 = newTemp(Ity_I32);
30056                assign(t6, binop(Iop_Or32, mkexpr(t5), mkexpr(t1)));
30057                putIReg(rt, mkWidenFrom32(ty, binop(Iop_Or32, mkexpr(t6),
30058                                                    mkexpr(t3)), True));
30059             } else {
30060                putIReg(rt, mkWidenFrom32(ty, binop(Iop_Or32, mkexpr(t1),
30061                                                    mkexpr(t5)), True));
30062             }
30063          } else {
30064             putIReg(rt, mkWidenFrom32(ty, binop(Iop_Or32, mkexpr(t1),
30065                                                 mkexpr(t3)), True));
30066          }
30067          break;
30068 
30069       case 0x00:  /* EXT */
30070          msb = get_msb(cins);
30071          lsb = get_lsb(cins);
30072          size = msb + 1;
30073          DIP("ext size:%u msb:%u lsb:%u", size, msb, lsb);
30074          vassert(lsb + size <= 32);
30075          vassert(lsb + size > 0);
30076          /* put size bits from rs at the top of in temporary */
30077          if (lsb + size < 32) {
30078             t0 = newTemp(Ity_I32);
30079             assign(t0, binop(Iop_Shl32, mkNarrowTo32(ty, getIReg(rs)),
30080                              mkU8(32 - lsb - size)));
30081 
30082             putIReg(rt, mkWidenFrom32(ty, binop(Iop_Shr32, mkexpr(t0),
30083                                                 mkU8(32 - size)), True));
30084          } else {
30085             putIReg(rt, mkWidenFrom32(ty, binop(Iop_Shr32,
30086                                                 mkNarrowTo32(ty, getIReg(rs)),
30087                                                 mkU8(32 - size)), True));
30088          }
30089          break;
30090 
30091       case 0x03:  /* Doubleword Extract Bit Field - DEXT; MIPS64r2 */
30092          msb = get_msb(cins);
30093          lsb = get_lsb(cins);
30094          size = msb + 1;
30095          DIP("dext r%u, r%u, %u, %u", rt, rs, lsb, msb + 1);
30096          t1 = newTemp(Ity_I64);
30097          vassert(lsb >= 0 && lsb < 32);
30098          vassert(size > 0 && size <= 32);
30099          vassert((lsb + size) > 0 && (lsb + size) <= 63);
30100 
30101          UChar lsAmt = 63 - (lsb + msb);  /* left shift amount; */
30102          UChar rsAmt = 63 - msb;  /* right shift amount; */
30103 
30104          assign(t1, binop(Iop_Shl64, getIReg(rs), mkU8(lsAmt)));
30105          putIReg(rt, binop(Iop_Shr64, mkexpr(t1), mkU8(rsAmt)));
30106 
30107          break;
30108 
30109       case 0x20:  /* BSHFL */
30110          switch (sa) {
30111                case 0x0: /* BITSWAP */
30112                   if (VEX_MIPS_CPU_HAS_MIPSR6(archinfo->hwcaps)) {
30113                      DIP("bitswap r%u, r%u", rd, rt);
30114                      if (mode64) {
30115                         putIReg(rd, unop(Iop_32Uto64, qop(Iop_Rotx32, unop(Iop_64to32, getIReg(rt)),
30116                                         mkU8(7), mkU8(8), mkU8(1))));
30117                      } else {
30118                         putIReg(rd, qop(Iop_Rotx32, getIReg(rt), mkU8(7),
30119                                         mkU8(8), mkU8(1)));
30120                      }
30121                   } else {
30122                      ILLEGAL_INSTRUCTON;
30123                   }
30124                break;
30125 
30126             case 0x02:  /* WSBH */
30127                DIP("wsbh r%u, r%u", rd, rt);
30128                t0 = newTemp(Ity_I32);
30129                t1 = newTemp(Ity_I32);
30130                t2 = newTemp(Ity_I32);
30131                t3 = newTemp(Ity_I32);
30132                assign(t0, binop(Iop_Shl32, binop(Iop_And32, mkNarrowTo32(ty,
30133                                            getIReg(rt)), mkU32(0x00FF0000)),
30134                                            mkU8(0x8)));
30135                assign(t1, binop(Iop_Shr32, binop(Iop_And32, mkNarrowTo32(ty,
30136                                 getIReg(rt)), mkU32(0xFF000000)), mkU8(0x8)));
30137                assign(t2, binop(Iop_Shl32, binop(Iop_And32, mkNarrowTo32(ty,
30138                                 getIReg(rt)), mkU32(0x000000FF)), mkU8(0x8)));
30139                assign(t3, binop(Iop_Shr32, binop(Iop_And32, mkNarrowTo32(ty,
30140                                 getIReg(rt)), mkU32(0x0000FF00)), mkU8(0x8)));
30141                putIReg(rd, mkWidenFrom32(ty, binop(Iop_Or32, binop(Iop_Or32,
30142                                          mkexpr(t0), mkexpr(t1)),
30143                                          binop(Iop_Or32, mkexpr(t2),
30144                                          mkexpr(t3))), True));
30145                break;
30146 
30147             case 0x10:  /* SEB */
30148                DIP("seb r%u, r%u", rd, rt);
30149                if (mode64)
30150                   putIReg(rd, unop(Iop_8Sto64, unop(Iop_64to8, getIReg(rt))));
30151                else
30152                   putIReg(rd, unop(Iop_8Sto32, unop(Iop_32to8, getIReg(rt))));
30153                break;
30154 
30155             case 0x18:  /* SEH */
30156                DIP("seh r%u, r%u", rd, rt);
30157                if (mode64)
30158                   putIReg(rd, unop(Iop_16Sto64, unop(Iop_64to16, getIReg(rt))));
30159                else
30160                   putIReg(rd, unop(Iop_16Sto32, unop(Iop_32to16, getIReg(rt))));
30161                break;
30162 
30163                case 0x08 ... 0x0b: /* ALIGN */
30164                   if (VEX_MIPS_CPU_HAS_MIPSR6(archinfo->hwcaps)) {
30165                      if (mode64) {
30166                         UInt bp = (sa & 0x3) << 3;
30167                         if (bp) {
30168                            putIReg(rd, unop(Iop_32Sto64,
30169                                             binop(Iop_Or32,
30170                                                   binop(Iop_Shl32,
30171                                                         unop(Iop_64to32,
30172                                                              getIReg(rt)),
30173                                                         mkU8(bp)),
30174                                                   binop(Iop_Shr32,
30175                                                         unop(Iop_64to32,
30176                                                              getIReg(rs)),
30177                                                         mkU8(32 - bp)))));
30178                         } else
30179                            putIReg(rd, getIReg(rt));
30180                      } else {
30181                         UInt bp = (sa & 0x3) << 3;
30182                         if (bp) {
30183                            putIReg(rd, binop(Iop_Or32,
30184                                              binop(Iop_Shl32,
30185                                                    getIReg(rt), mkU8(bp)),
30186                                              binop(Iop_Shr32,
30187                                                    getIReg(rs), mkU8(32 - bp))));
30188                         } else
30189                            putIReg(rd, getIReg(rt));
30190                      }
30191                   } else {
30192                      ILLEGAL_INSTRUCTON;
30193                   }
30194                   break;
30195 
30196             default:
30197                goto decode_failure;
30198 
30199          }
30200          break;  /* BSHFL */
30201 
30202       /* --- MIPS32(r2) DSP ASE(r2) / Cavium Specfic (LX) instructions --- */
30203       case 0xA:  /* LX */
30204          if (VEX_MIPS_COMP_ID(archinfo->hwcaps) == VEX_PRID_COMP_CAVIUM) {
30205             if (dis_instr_CVM(cins))
30206                break;
30207             goto decode_failure;
30208          }
30209       case 0xC:  /* INSV */
30210       case 0x38: {  /* EXTR.W */
30211          if (VEX_MIPS_PROC_DSP(archinfo->hwcaps)) {
30212             UInt retVal = disDSPInstr_MIPS_WRK ( cins );
30213             if (0 != retVal ) {
30214                goto decode_failure_dsp;
30215             }
30216             break;
30217          } else {
30218             goto decode_failure_dsp;
30219          }
30220          break;
30221       }
30222       case 0x10: {  /* ADDU.QB */
30223          switch(sa) {
30224             case  0xC:  /* SUBU_S.PH */
30225             case  0xD:  /* ADDU_S.PH */
30226             case 0x1E: {  /* MULQ_S.PH */
30227                if (VEX_MIPS_PROC_DSP2(archinfo->hwcaps)) {
30228                   UInt retVal = disDSPInstr_MIPS_WRK ( cins );
30229                   if (0 != retVal ) {
30230                      goto decode_failure_dsp;
30231                   }
30232                   break;
30233                } else {
30234                   goto decode_failure_dsp;
30235                }
30236                break;
30237             }
30238             default: {
30239                if (VEX_MIPS_PROC_DSP(archinfo->hwcaps)) {
30240                   UInt retVal = disDSPInstr_MIPS_WRK ( cins );
30241                   if (0 != retVal ) {
30242                      goto decode_failure_dsp;
30243                   }
30244                   break;
30245                } else {
30246                   goto decode_failure_dsp;
30247                }
30248                break;
30249             }
30250          }
30251          break;
30252       }
30253       case 0x11: {  /* CMPU.EQ.QB */
30254          switch(sa) {
30255             case 0x18:  /* CMPGDU.EQ.QB */
30256             case 0x19:  /* CMPGDU.LT.QB */
30257             case 0x1A:  /* CMPGDU.LE.QB */
30258             case 0x0D:  /* PRECR.QB.PH */
30259             case 0x1E:  /* PRECR_SRA.PH.W */
30260             case 0x1F: {  /* PRECR_SRA_R.PH.W */
30261                if (VEX_MIPS_PROC_DSP2(archinfo->hwcaps)) {
30262                   UInt retVal = disDSPInstr_MIPS_WRK ( cins );
30263                   if (0 != retVal ) {
30264                      goto decode_failure_dsp;
30265                   }
30266                   break;
30267                } else {
30268                   goto decode_failure_dsp;
30269                }
30270                break;
30271             }
30272             default: {
30273                if (VEX_MIPS_PROC_DSP(archinfo->hwcaps)) {
30274                   UInt retVal = disDSPInstr_MIPS_WRK ( cins );
30275                   if (0 != retVal ) {
30276                      goto decode_failure_dsp;
30277                   }
30278                   break;
30279                } else {
30280                   goto decode_failure_dsp;
30281                }
30282                break;
30283             }
30284          }
30285          break;
30286       }
30287       case 0x12: {  /* ABSQ_S.PH */
30288          switch(sa){
30289             case 0x1: {  /* ABSQ_S.QB */
30290                if (VEX_MIPS_PROC_DSP2(archinfo->hwcaps)) {
30291                   UInt retVal = disDSPInstr_MIPS_WRK ( cins );
30292                   if (0 != retVal ) {
30293                      goto decode_failure_dsp;
30294                   }
30295                   break;
30296                } else {
30297                   goto decode_failure_dsp;
30298                }
30299                break;
30300             }
30301             default: {
30302                if (VEX_MIPS_PROC_DSP(archinfo->hwcaps)) {
30303                   UInt retVal = disDSPInstr_MIPS_WRK ( cins );
30304                   if (0 != retVal ) {
30305                      goto decode_failure_dsp;
30306                   }
30307                   break;
30308                } else {
30309                   goto decode_failure_dsp;
30310                }
30311                break;
30312             }
30313          }
30314          break;
30315       }
30316       case 0x13: {  /* SHLL.QB */
30317          switch(sa) {
30318             case 0x04:  /* SHRA.QB */
30319             case 0x05:  /* SHRA_R.QB */
30320             case 0x06:  /* SHRAV.QB */
30321             case 0x07:  /* SHRAV_R.QB */
30322             case 0x19:  /* SHLR.PH */
30323             case 0x1B: {  /* SHLRV.PH */
30324                if (VEX_MIPS_PROC_DSP2(archinfo->hwcaps)) {
30325                   UInt retVal = disDSPInstr_MIPS_WRK ( cins );
30326                   if (0 != retVal ) {
30327                      goto decode_failure_dsp;
30328                   }
30329                   break;
30330                } else {
30331                   goto decode_failure_dsp;
30332                }
30333                break;
30334             }
30335             default: {
30336                if (VEX_MIPS_PROC_DSP(archinfo->hwcaps)) {
30337                   UInt retVal = disDSPInstr_MIPS_WRK ( cins );
30338                   if (0 != retVal ) {
30339                      goto decode_failure_dsp;
30340                   }
30341                   break;
30342                } else {
30343                   goto decode_failure_dsp;
30344                }
30345                break;
30346             }
30347          }
30348          break;
30349       }
30350       case 0x30: {  /* DPAQ.W.PH */
30351          switch(sa) {
30352             case  0x0:  /* DPA.W.PH */
30353             case 0x18:  /* DPAQX_S.W.PH */
30354             case 0x1A:  /* DPAQX_SA.W.PH */
30355             case  0x8:  /* DPAX.W.PH */
30356             case  0x1:  /* DPS.W.PH */
30357             case 0x19:  /* DPSQX_S.W.PH */
30358             case 0x1B:  /* DPSQX_SA.W.PH */
30359             case  0x9:  /* DPSX.W.PH */
30360             case  0x2: {  /* MULSA.W.PH */
30361                if (VEX_MIPS_PROC_DSP2(archinfo->hwcaps)) {
30362                   UInt retVal = disDSPInstr_MIPS_WRK ( cins );
30363                   if (0 != retVal ) {
30364                      goto decode_failure_dsp;
30365                   }
30366                   break;
30367                } else {
30368                   goto decode_failure_dsp;
30369                }
30370                break;
30371             }
30372             default: {
30373                if (VEX_MIPS_PROC_DSP(archinfo->hwcaps)) {
30374                   UInt retVal = disDSPInstr_MIPS_WRK ( cins );
30375                   if (0 != retVal ) {
30376                      goto decode_failure_dsp;
30377                   }
30378                   break;
30379                } else {
30380                   goto decode_failure_dsp;
30381                }
30382                break;
30383             }
30384          }
30385          break;
30386       }
30387       case 0x18:  /* ADDUH.QB/MUL.PH */
30388       case 0x31: {  /* APPEND */
30389          if (VEX_MIPS_PROC_DSP2(archinfo->hwcaps)) {
30390             UInt retVal = disDSPInstr_MIPS_WRK ( cins );
30391             if (0 != retVal ) {
30392                goto decode_failure_dsp;
30393             }
30394             break;
30395          } else {
30396             goto decode_failure_dsp;
30397          }
30398       }
30399          case 0x35: { /* PREF r6*/
30400             DIP("pref");
30401             break;
30402          }
30403          case 0x36: { /* LL */
30404             imm = extend_s_9to16((instr_index >> 7) & 0x1ff);
30405             DIP("ll r%u, %u(r%u)", rt, imm, rs);
30406             LOAD_STORE_PATTERN;
30407             t2 = newTemp(ty);
30408             assign(t2, mkWidenFrom32(ty, load(Ity_I32, mkexpr(t1)), True));
30409             putLLaddr(mkexpr(t1));
30410             putLLdata(mkexpr(t2));
30411             putIReg(rt, mkexpr(t2));
30412             break;
30413          }
30414          case 0x26: { /* SC */
30415             imm = extend_s_9to16((instr_index >> 7) & 0x1ff);
30416             DIP("sc r%u, %u(r%u)", rt, imm, rs);
30417             LOAD_STORE_PATTERN;
30418 
30419             t2 = newTemp(Ity_I1);
30420             t3 = newTemp(Ity_I32);
30421             assign(t2, binop(mode64 ? Iop_CmpNE64 : Iop_CmpNE32,
30422                              mkexpr(t1), getLLaddr()));
30423             assign(t3, mkNarrowTo32(ty, getIReg(rt)));
30424             putLLaddr(LLADDR_INVALID);
30425             putIReg(rt, getIReg(0));
30426 
30427             mips_next_insn_if(mkexpr(t2));
30428 
30429             t4 = newTemp(Ity_I32);
30430             t5 = newTemp(Ity_I32);
30431 
30432             assign(t5, mkNarrowTo32(ty, getLLdata()));
30433 
30434             stmt(IRStmt_CAS(mkIRCAS(IRTemp_INVALID, t4, /* old_mem */
30435                  MIPS_IEND, mkexpr(t1),                 /* addr */
30436                  NULL, mkexpr(t5),                      /* expected value */
30437                  NULL, mkexpr(t3)                       /* new value */)));
30438 
30439             putIReg(rt, unop(mode64 ? Iop_1Uto64 : Iop_1Uto32,
30440                              binop(Iop_CmpEQ32, mkexpr(t4), mkexpr(t5))));
30441             break;
30442          }
30443          case 0x37: { /* LLD */
30444             imm = extend_s_9to16((instr_index >> 7) & 0x1ff);
30445             DIP("lld r%u, %u(r%u)", rt, imm, rs);
30446             LOAD_STORE_PATTERN;
30447 
30448             t2 = newTemp(Ity_I64);
30449             assign(t2, load(Ity_I64, mkexpr(t1)));
30450             putLLaddr(mkexpr(t1));
30451             putLLdata(mkexpr(t2));
30452             putIReg(rt, mkexpr(t2));
30453             break;
30454          }
30455          case 0x27: { /* SCD */
30456             imm = extend_s_9to16((instr_index >> 7) & 0x1ff);
30457             DIP("sdc r%u, %u(r%u)", rt, imm, rs);
30458             LOAD_STORE_PATTERN;
30459 
30460             t2 = newTemp(Ity_I1);
30461             t3 = newTemp(Ity_I64);
30462             assign(t2, binop(Iop_CmpNE64, mkexpr(t1), getLLaddr()));
30463             assign(t3, getIReg(rt));
30464             putLLaddr(LLADDR_INVALID);
30465             putIReg(rt, getIReg(0));
30466 
30467             mips_next_insn_if(mkexpr(t2));
30468 
30469             t4 = newTemp(Ity_I64);
30470             t5 = newTemp(Ity_I64);
30471 
30472             assign(t5, getLLdata());
30473 
30474             stmt(IRStmt_CAS(mkIRCAS(IRTemp_INVALID, t4, /* old_mem */
30475                  MIPS_IEND, mkexpr(t1),                 /* addr */
30476                  NULL, mkexpr(t5),                      /* expected value */
30477                  NULL, mkexpr(t3)                       /* new value */)));
30478 
30479             putIReg(rt, unop(Iop_1Uto64,
30480                              binop(Iop_CmpEQ64, mkexpr(t4), mkexpr(t5))));
30481             break;
30482          }
30483       default:
30484          goto decode_failure;
30485 
30486    }
30487       break;  /* Special3 */
30488 
30489    case 0x3B: /* PCREL */
30490       if (rt == 0x1E) { /* AUIPC */
30491          if (VEX_MIPS_CPU_HAS_MIPSR6(archinfo->hwcaps)) {
30492             DIP("auipc r%u, %u", rs, imm);
30493             if (mode64) {
30494                putIReg(rs, mkU64(guest_PC_curr_instr + (imm << 16)));
30495             } else {
30496                putIReg(rs, mkU32(guest_PC_curr_instr + (imm << 16)));
30497             }
30498          } else {
30499             ILLEGAL_INSTRUCTON;
30500          }
30501          break;
30502       } else if (rt == 0x1F) { /* ALUIPC */
30503          if (VEX_MIPS_CPU_HAS_MIPSR6(archinfo->hwcaps)) {
30504             DIP("aluipc r%u, %u", rs, imm);
30505             if (mode64) {
30506                putIReg(rs, mkU64((~0x0FFFFULL) &
30507                                 (guest_PC_curr_instr + extend_s_32to64(imm << 16))));
30508             } else {
30509                putIReg(rs, mkU32((~0x0FFFFULL) &
30510                                 (guest_PC_curr_instr + (imm << 16))));
30511             }
30512          } else {
30513             ILLEGAL_INSTRUCTON;
30514          }
30515          break;
30516       } else if ((rt & 0x18) == 0) { /* ADDIUPC */
30517          if (VEX_MIPS_CPU_HAS_MIPSR6(archinfo->hwcaps)) {
30518             DIP("addiupc r%u, %u", rs, instr_index & 0x7FFFF);
30519             if (mode64) {
30520                putIReg(rs, mkU64(guest_PC_curr_instr +
30521                                  (extend_s_19to64(instr_index & 0x7FFFF) << 2)));
30522             } else {
30523                putIReg(rs, mkU32(guest_PC_curr_instr +
30524                                 (extend_s_19to32(instr_index & 0x7FFFF) << 2)));
30525             }
30526          } else {
30527             ILLEGAL_INSTRUCTON;
30528          }
30529          break;
30530       } else if ((rt & 0x18) == 8) { /* LWPC */
30531          if (VEX_MIPS_CPU_HAS_MIPSR6(archinfo->hwcaps)) {
30532             DIP("lwpc r%u, %x", rs, instr_index & 0x7FFFF);
30533             if (mode64) {
30534                t1 = newTemp(Ity_I64);
30535                assign(t1, mkU64(guest_PC_curr_instr +
30536                                 (extend_s_19to64(instr_index & 0x7FFFF) << 2)));
30537                putIReg(rs, unop(Iop_32Sto64, load(Ity_I32, mkexpr(t1))));
30538             } else {
30539                t1 = newTemp(Ity_I32);
30540                assign(t1, mkU32(guest_PC_curr_instr +
30541                                 (extend_s_19to32(instr_index & 0x7FFFF) << 2)));
30542                putIReg(rs, load(Ity_I32, mkexpr(t1)));
30543             }
30544          } else {
30545             ILLEGAL_INSTRUCTON;
30546          }
30547          break;
30548       } else if ((rt & 0x18) == 16) { /* LWUPC */
30549          if (VEX_MIPS_CPU_HAS_MIPSR6(archinfo->hwcaps)) {
30550             DIP("lwupc r%u, %x", rs, instr_index & 0x7FFFF);
30551             if (mode64) {
30552                t1 = newTemp(Ity_I64);
30553                assign(t1, mkU64(guest_PC_curr_instr +
30554                                 (extend_s_19to64(instr_index & 0x7FFFF) << 2)));
30555                putIReg(rs, unop(Iop_32Uto64, load(Ity_I32, mkexpr(t1))));
30556             } else {
30557                t1 = newTemp(Ity_I32);
30558                assign(t1, mkU32(guest_PC_curr_instr +
30559                                 (extend_s_19to32(instr_index & 0x7FFFF) << 2)));
30560                putIReg(rs, load(Ity_I32, mkexpr(t1)));
30561             }
30562          } else {
30563             ILLEGAL_INSTRUCTON;
30564          }
30565          break;
30566       } else if ((rt & 0x1C) == 0x18) { /* LDPC */
30567          if (VEX_MIPS_CPU_HAS_MIPSR6(archinfo->hwcaps)) {
30568             DIP("ldpc r%u, %x", rs, instr_index & 0x3FFFF);
30569             t1 = newTemp(Ity_I64);
30570             assign(t1, mkU64(guest_PC_curr_instr +
30571                              (extend_s_18to64(instr_index & 0x3FFFF) << 3)));
30572             putIReg(rs, load(Ity_I64, mkexpr(t1)));
30573          } else {
30574             ILLEGAL_INSTRUCTON;
30575          }
30576          break;
30577       } else {
30578          goto decode_failure;
30579       }
30580 
30581       if (0x3B == function &&
30582           (VEX_MIPS_COMP_ID(archinfo->hwcaps) == VEX_PRID_COMP_BROADCOM)) {
30583          /*RDHWR*/
30584          DIP("rdhwr r%u, r%u", rt, rd);
30585          if (rd == 29) {
30586             putIReg(rt, getULR());
30587          } else
30588             goto decode_failure;
30589          break;
30590       } else {
30591          goto decode_failure;
30592       }
30593 
30594    case 0x00:  /* Special */
30595 
30596       switch (function) {
30597       case 0x1: {
30598          UInt mov_cc = get_mov_cc(cins);
30599          if (tf == 0) {  /* MOVF */
30600             DIP("movf r%u, r%u, %u", rd, rs, mov_cc);
30601             t1 = newTemp(Ity_I1);
30602             t2 = newTemp(Ity_I32);
30603             t3 = newTemp(Ity_I1);
30604 
30605             assign(t1, binop(Iop_CmpEQ32, mkU32(0), mkU32(mov_cc)));
30606             assign(t2, IRExpr_ITE(mkexpr(t1),
30607                                   binop(Iop_And32,
30608                                         binop(Iop_Shr32, getFCSR(),
30609                                               mkU8(23)),
30610                                         mkU32(0x1)),
30611                                   binop(Iop_And32,
30612                                         binop(Iop_Shr32, getFCSR(),
30613                                               mkU8(24 + mov_cc)),
30614                                         mkU32(0x1))
30615                                   ));
30616             assign(t3, binop(Iop_CmpEQ32, mkU32(0), mkexpr(t2)));
30617             putIReg(rd, IRExpr_ITE(mkexpr(t3), getIReg(rs), getIReg(rd)));
30618          } else if (tf == 1) {  /* MOVT */
30619             DIP("movt r%u, r%u, %u", rd, rs, mov_cc);
30620             t1 = newTemp(Ity_I1);
30621             t2 = newTemp(Ity_I32);
30622             t3 = newTemp(Ity_I1);
30623 
30624             assign(t1, binop(Iop_CmpEQ32, mkU32(0), mkU32(mov_cc)));
30625             assign(t2, IRExpr_ITE(mkexpr(t1),
30626                                   binop(Iop_And32,
30627                                         binop(Iop_Shr32, getFCSR(),
30628                                               mkU8(23)),
30629                                         mkU32(0x1)),
30630                                   binop(Iop_And32,
30631                                         binop(Iop_Shr32, getFCSR(),
30632                                               mkU8(24 + mov_cc)),
30633                                         mkU32(0x1))
30634                                   ));
30635             assign(t3, binop(Iop_CmpEQ32, mkU32(1), mkexpr(t2)));
30636             putIReg(rd, IRExpr_ITE(mkexpr(t3), getIReg(rs), getIReg(rd)));
30637          }
30638          break;
30639       }
30640       case 0x0A: {  /* MOVZ */
30641          DIP("movz r%u, r%u, r%u", rd, rs, rt);
30642          t1 = newTemp(ty);
30643          t2 = newTemp(ty);
30644          if (mode64) {
30645             assign(t1, unop(Iop_32Sto64, unop(Iop_1Sto32, binop(Iop_CmpEQ64,
30646                             getIReg(rt), mkU64(0x0)))));
30647             assign(t2, unop(Iop_32Sto64, unop(Iop_1Sto32, binop(Iop_CmpNE64,
30648                             getIReg(rt), mkU64(0x0)))));
30649             putIReg(rd, binop(Iop_Add64, binop(Iop_And64, getIReg(rs),
30650                         mkexpr(t1)), binop(Iop_And64, getIReg(rd),mkexpr(t2))));
30651          } else {
30652             assign(t1, unop(Iop_1Sto32, binop(Iop_CmpEQ32, getIReg(rt),
30653                                               mkU32(0x0))));
30654             assign(t2, unop(Iop_1Sto32, binop(Iop_CmpNE32, getIReg(rt),
30655                                               mkU32(0x0))));
30656             putIReg(rd, binop(Iop_Add32, binop(Iop_And32, getIReg(rs),
30657                         mkexpr(t1)), binop(Iop_And32, getIReg(rd),
30658                         mkexpr(t2))));
30659          }
30660          break;
30661       }
30662 
30663       case 0x0B: {  /* MOVN */
30664          DIP("movn r%u, r%u, r%u", rd, rs, rt);
30665          t1 = newTemp(ty);
30666          t2 = newTemp(ty);
30667          if (mode64) {
30668             assign(t1, unop(Iop_32Sto64, unop(Iop_1Sto32, binop(Iop_CmpEQ64,
30669                             getIReg(rt), mkU64(0x0)))));
30670             assign(t2, unop(Iop_32Sto64, unop(Iop_1Sto32, binop(Iop_CmpNE64,
30671                             getIReg(rt), mkU64(0x0)))));
30672             putIReg(rd, binop(Iop_Add64, binop(Iop_And64, getIReg(rs),
30673                         mkexpr(t2)), binop(Iop_And64, getIReg(rd),
30674                                            mkexpr(t1))));
30675          } else {
30676             assign(t1, unop(Iop_1Sto32, binop(Iop_CmpEQ32, getIReg(rt),
30677                                               mkU32(0x0))));
30678             assign(t2, unop(Iop_1Sto32, binop(Iop_CmpNE32, getIReg(rt),
30679                                               mkU32(0x0))));
30680             putIReg(rd, binop(Iop_Add32, binop(Iop_And32, getIReg(rs),
30681                         mkexpr(t2)), binop(Iop_And32, getIReg(rd),
30682                         mkexpr(t1))));
30683          }
30684          break;
30685       }
30686 
30687       case 0x18:  {  /* MULT */
30688          switch (sa & 0x3) {
30689             case 0: {
30690                if ((1 <= ac) && ( 3 >= ac)) {
30691                   if (VEX_MIPS_PROC_DSP(archinfo->hwcaps)) {
30692                      /* If DSP is present -> DSP ASE MULT */
30693                      UInt retVal = disDSPInstr_MIPS_WRK(cins);
30694                      if (0 != retVal) {
30695                         goto decode_failure_dsp;
30696                      }
30697                      break;
30698                   } else {
30699                       goto decode_failure_dsp;
30700                   }
30701                } else {
30702                   DIP("mult r%u, r%u", rs, rt);
30703                   if (VEX_MIPS_CPU_HAS_MIPSR6(archinfo->hwcaps) &&
30704                       !VEX_MIPS_CPU_HAS_MIPS32R2(archinfo->hwcaps)) {
30705                      ILLEGAL_INSTRUCTON;
30706                   }
30707                   t2 = newTemp(Ity_I64);
30708 
30709                   assign(t2, binop(Iop_MullS32, mkNarrowTo32(ty, getIReg(rs)),
30710                                                 mkNarrowTo32(ty, getIReg(rt))));
30711 
30712                   putHI(mkWidenFrom32(ty, unop(Iop_64HIto32, mkexpr(t2)), True));
30713                   putLO(mkWidenFrom32(ty, unop(Iop_64to32, mkexpr(t2)), True));
30714                   break;
30715                }
30716             }
30717             case 2: { /* MUL R6 */
30718                if (VEX_MIPS_CPU_HAS_MIPSR6(archinfo->hwcaps)) {
30719                   DIP("mul r%u, r%u, r%u", rs, rt, rd);
30720                   if (mode64) {
30721                      putIReg(rd, unop(Iop_32Sto64,
30722                                       unop(Iop_64to32,
30723                                            binop(Iop_MullS32,
30724                                                  unop(Iop_64to32, getIReg(rs)),
30725                                                  unop(Iop_64to32, getIReg(rt))))));
30726                   } else {
30727                      putIReg(rd, unop(Iop_64to32,
30728                                       binop(Iop_MullS32,
30729                                             getIReg(rs), getIReg(rt))));
30730                   }
30731                } else {
30732                   ILLEGAL_INSTRUCTON;
30733                }
30734                break;
30735             }
30736 
30737             case 3: {  /* MUH R6 */
30738                if (VEX_MIPS_CPU_HAS_MIPSR6(archinfo->hwcaps)) {
30739                   DIP("muh r%u, r%u, r%u", rs, rt, rd);
30740                   if (mode64) {
30741                      putIReg(rd, unop(Iop_32Sto64,
30742                                       unop(Iop_64HIto32,
30743                                            binop(Iop_MullS32,
30744                                                  unop(Iop_64to32, getIReg(rs)),
30745                                                  unop(Iop_64to32, getIReg(rt))))));
30746                   } else {
30747                      putIReg(rd, unop(Iop_64HIto32,
30748                                       binop(Iop_MullS32,
30749                                             getIReg(rs), getIReg(rt))));
30750                   }
30751                } else {
30752                   ILLEGAL_INSTRUCTON;
30753                }
30754                break;
30755             }
30756          }
30757          break;
30758       }
30759 
30760       case 0x19:  {  /* MULTU */
30761          switch (sa & 0x3) {
30762             case 0: {
30763                if ((1 <= ac) && ( 3 >= ac)) {
30764                   if (VEX_MIPS_PROC_DSP(archinfo->hwcaps)) {
30765                      /* If DSP is present -> DSP ASE MULTU */
30766                      UInt retVal = disDSPInstr_MIPS_WRK ( cins );
30767                      if (0 != retVal) {
30768                         goto decode_failure_dsp;
30769                      }
30770                      break;
30771                   } else {
30772                      goto decode_failure_dsp;
30773                   }
30774                } else {
30775                   DIP("multu r%u, r%u", rs, rt);
30776                   if (VEX_MIPS_CPU_HAS_MIPSR6(archinfo->hwcaps) &&
30777                       !VEX_MIPS_CPU_HAS_MIPS32R2(archinfo->hwcaps)) {
30778                      ILLEGAL_INSTRUCTON;
30779                   }
30780                   t2 = newTemp(Ity_I64);
30781 
30782                   assign(t2, binop(Iop_MullU32, mkNarrowTo32(ty, getIReg(rs)),
30783                                                 mkNarrowTo32(ty, getIReg(rt))));
30784 
30785                   putHI(mkWidenFrom32(ty, unop(Iop_64HIto32, mkexpr(t2)), True));
30786                   putLO(mkWidenFrom32(ty, unop(Iop_64to32, mkexpr(t2)), True));
30787                   break;
30788                }
30789             }
30790             case 2: {  /* MULU R6 */
30791                if (VEX_MIPS_CPU_HAS_MIPSR6(archinfo->hwcaps)) {
30792                   DIP("mulu r%u, r%u, r%u", rs, rt, rd);
30793                   if (mode64) {
30794                      putIReg(rd, unop(Iop_32Uto64,
30795                                       unop(Iop_64to32,
30796                                            binop(Iop_MullU32,
30797                                                  unop(Iop_64to32, getIReg(rs)),
30798                                                  unop(Iop_64to32, getIReg(rt))))));
30799                   } else {
30800                      putIReg(rd, unop(Iop_64to32,
30801                                       binop(Iop_MullU32,
30802                                             getIReg(rs), getIReg(rt))));
30803                   }
30804                } else {
30805                   ILLEGAL_INSTRUCTON;
30806                }
30807                break;
30808             }
30809             case 3: {  /* MUHU R6 */
30810                if (VEX_MIPS_CPU_HAS_MIPSR6(archinfo->hwcaps)) {
30811                   DIP("muhu r%u, r%u, r%u", rs, rt, rd);
30812                   if (mode64) {
30813                      putIReg(rd, unop(Iop_32Uto64,
30814                                       unop(Iop_64HIto32,
30815                                            binop(Iop_MullU32,
30816                                                  unop(Iop_64to32, getIReg(rs)),
30817                                                  unop(Iop_64to32, getIReg(rt))))));
30818                   } else {
30819                      putIReg(rd, unop(Iop_64HIto32,
30820                                       binop(Iop_MullU32,
30821                                             getIReg(rs), getIReg(rt))));
30822                   }
30823                } else {
30824                   ILLEGAL_INSTRUCTON;
30825                }
30826                break;
30827             }
30828          }
30829       }
30830       break;
30831 
30832       case 0x20: {  /* ADD */
30833          DIP("add r%u, r%u, r%u", rd, rs, rt);
30834          IRTemp tmpRs32 = newTemp(Ity_I32);
30835          IRTemp tmpRt32 = newTemp(Ity_I32);
30836 
30837          assign(tmpRs32, mkNarrowTo32(ty, getIReg(rs)));
30838          assign(tmpRt32, mkNarrowTo32(ty, getIReg(rt)));
30839 
30840          t0 = newTemp(Ity_I32);
30841          t1 = newTemp(Ity_I32);
30842          t2 = newTemp(Ity_I32);
30843          t3 = newTemp(Ity_I32);
30844          t4 = newTemp(Ity_I32);
30845          /* dst = src0 + src1
30846             if (sign(src0 ) != sign(src1 ))
30847             goto no overflow;
30848             if (sign(dst) == sign(src0 ))
30849             goto no overflow;
30850             we have overflow! */
30851 
30852          assign(t0, binop(Iop_Add32, mkexpr(tmpRs32), mkexpr(tmpRt32)));
30853          assign(t1, binop(Iop_Xor32, mkexpr(tmpRs32), mkexpr(tmpRt32)));
30854          assign(t2, unop(Iop_1Uto32,
30855                          binop(Iop_CmpEQ32,
30856                                binop(Iop_And32, mkexpr(t1), mkU32(0x80000000)),
30857                                mkU32(0x80000000))));
30858 
30859          assign(t3, binop(Iop_Xor32, mkexpr(t0), mkexpr(tmpRs32)));
30860          assign(t4, unop(Iop_1Uto32,
30861                          binop(Iop_CmpNE32,
30862                                binop(Iop_And32, mkexpr(t3), mkU32(0x80000000)),
30863                                mkU32(0x80000000))));
30864 
30865          stmt(IRStmt_Exit(binop(Iop_CmpEQ32,
30866                                 binop(Iop_Or32, mkexpr(t2), mkexpr(t4)),
30867                                 mkU32(0)),
30868                           Ijk_SigFPE_IntOvf,
30869                           mode64 ? IRConst_U64(guest_PC_curr_instr + 4) :
30870                                    IRConst_U32(guest_PC_curr_instr + 4),
30871                           OFFB_PC));
30872 
30873          putIReg(rd,  mkWidenFrom32(ty, mkexpr(t0), True));
30874          break;
30875       }
30876 
30877       case 0x1A:  /* DIV */
30878          switch (sa & 0x3) {
30879             case 0:
30880                DIP("div r%u, r%u", rs, rt);
30881                if (VEX_MIPS_CPU_HAS_MIPSR6(archinfo->hwcaps) &&
30882                    !VEX_MIPS_CPU_HAS_MIPS32R2(archinfo->hwcaps)) {
30883                   ILLEGAL_INSTRUCTON;
30884                }
30885                if (mode64) {
30886                   t2 = newTemp(Ity_I64);
30887 
30888                   assign(t2, binop(Iop_DivModS32to32,
30889                                    mkNarrowTo32(ty, getIReg(rs)),
30890                                    mkNarrowTo32(ty, getIReg(rt))));
30891 
30892                   putHI(mkWidenFrom32(ty, unop(Iop_64HIto32, mkexpr(t2)), True));
30893                   putLO(mkWidenFrom32(ty, unop(Iop_64to32, mkexpr(t2)), True));
30894                } else {
30895                   t1 = newTemp(Ity_I64);
30896 
30897                   assign(t1, binop(Iop_DivModS32to32, getIReg(rs), getIReg(rt)));
30898 
30899                   putHI(unop(Iop_64HIto32, mkexpr(t1)));
30900                   putLO(unop(Iop_64to32, mkexpr(t1)));
30901                }
30902                break;
30903             case 2:
30904                if (VEX_MIPS_CPU_HAS_MIPSR6(archinfo->hwcaps)) {
30905                   DIP("div r%u, r%u, r%u", rs, rt, rd);
30906                   if (mode64) {
30907                      putIReg(rd, unop(Iop_32Sto64,
30908                                       binop(Iop_DivS32,
30909                                             unop(Iop_64to32, getIReg(rs)),
30910                                             unop(Iop_64to32, getIReg(rt)))));
30911                   } else
30912                      putIReg(rd, binop(Iop_DivS32, getIReg(rs), getIReg(rt)));
30913                } else {
30914                   ILLEGAL_INSTRUCTON;
30915                }
30916                break;
30917             case 3:
30918                if (VEX_MIPS_CPU_HAS_MIPSR6(archinfo->hwcaps)) {
30919                   DIP("mod r%u, r%u, r%u", rs, rt, rd);
30920                   if (mode64) {
30921                      putIReg(rd, unop(Iop_32Sto64,
30922                                       unop(Iop_64HIto32,
30923                                            binop(Iop_DivModS32to32,
30924                                                  unop(Iop_64to32, getIReg(rs)),
30925                                                  unop(Iop_64to32, getIReg(rt))))));
30926                   } else {
30927                      t1 = newTemp(Ity_I64);
30928 
30929                      assign(t1, binop(Iop_DivModS32to32, getIReg(rs), getIReg(rt)));
30930                      putIReg(rd, unop(Iop_64HIto32, mkexpr(t1)));
30931                   }
30932                } else {
30933                   ILLEGAL_INSTRUCTON;
30934                }
30935                break;
30936          }
30937          break;
30938 
30939       case 0x1B:  /* DIVU */
30940          switch (sa & 0x3) {
30941             case 0:
30942                DIP("divu r%u, r%u", rs, rt);
30943                if (VEX_MIPS_CPU_HAS_MIPSR6(archinfo->hwcaps) &&
30944                    !VEX_MIPS_CPU_HAS_MIPS32R2(archinfo->hwcaps)) {
30945                   ILLEGAL_INSTRUCTON;
30946                }
30947                if (mode64) {
30948                   t1 = newTemp(Ity_I64);
30949 
30950                   assign(t1, binop(Iop_DivModU32to32,
30951                                    mkNarrowTo32(ty, getIReg(rs)),
30952                                    mkNarrowTo32(ty, getIReg(rt))));
30953 
30954                   putHI(mkWidenFrom32(ty, unop(Iop_64HIto32, mkexpr(t1)), True));
30955                   putLO(mkWidenFrom32(ty, unop(Iop_64to32, mkexpr(t1)), True));
30956                } else {
30957                   t1 = newTemp(Ity_I64);
30958 
30959                   assign(t1, binop(Iop_DivModU32to32, getIReg(rs), getIReg(rt)));
30960                   putHI(unop(Iop_64HIto32, mkexpr(t1)));
30961                   putLO(unop(Iop_64to32, mkexpr(t1)));
30962                }
30963                break;
30964             case 2:
30965                if (VEX_MIPS_CPU_HAS_MIPSR6(archinfo->hwcaps)) {
30966                   DIP("divu r%u, r%u, r%u", rs, rt, rd);
30967                   if (mode64) {
30968                      putIReg(rd, unop(Iop_32Sto64,
30969                                       binop(Iop_DivU32,
30970                                             unop(Iop_64to32, getIReg(rs)),
30971                                             unop(Iop_64to32, getIReg(rt)))));
30972                   } else {
30973                      putIReg(rd, binop(Iop_DivU32, getIReg(rs), getIReg(rt)));
30974                   }
30975                   break;
30976                } else {
30977                   ILLEGAL_INSTRUCTON;
30978                }
30979                break;
30980             case 3:
30981                if (VEX_MIPS_CPU_HAS_MIPSR6(archinfo->hwcaps)) {
30982                   DIP("modu r%u, r%u, r%u", rs, rt, rd);
30983                   if (mode64) {
30984                      putIReg(rd, unop(Iop_32Uto64,
30985                                       unop(Iop_64HIto32,
30986                                            binop(Iop_DivModU32to32,
30987                                                  unop(Iop_64to32, getIReg(rs)),
30988                                                  unop(Iop_64to32, getIReg(rt))))));
30989                   } else {
30990                      t1 = newTemp(Ity_I64);
30991 
30992                      assign(t1, binop(Iop_DivModU32to32, getIReg(rs), getIReg(rt)));
30993                      putIReg(rd, unop(Iop_64HIto32, mkexpr(t1)));
30994                   }
30995                } else {
30996                   ILLEGAL_INSTRUCTON;
30997                }
30998                break;
30999         }
31000         break;
31001 
31002       case 0x1C:  /* Doubleword Multiply - DMULT; MIPS64 */
31003          switch (sa) {
31004             case 0:
31005                DIP("dmult r%u, r%u", rs, rt);
31006                if (VEX_MIPS_CPU_HAS_MIPSR6(archinfo->hwcaps) &&
31007                    !VEX_MIPS_CPU_HAS_MIPS32R2(archinfo->hwcaps)) {
31008                   ILLEGAL_INSTRUCTON;
31009                }
31010                t0 = newTemp(Ity_I128);
31011 
31012                assign(t0, binop(Iop_MullS64, getIReg(rs), getIReg(rt)));
31013 
31014                putHI(unop(Iop_128HIto64, mkexpr(t0)));
31015                putLO(unop(Iop_128to64, mkexpr(t0)));
31016                break;
31017             case 2: /* DMUL */
31018                if (VEX_MIPS_CPU_HAS_MIPSR6(archinfo->hwcaps)) {
31019                   DIP("dmul r%u, r%u, r%u", rd, rs, rt);
31020                   putIReg(rd, unop(Iop_128to64,
31021                                    binop(Iop_MullS64, getIReg(rs), getIReg(rt))));
31022                } else {
31023                   ILLEGAL_INSTRUCTON;
31024                }
31025                /* Value for function in documentation is 111000 */
31026                break;
31027             case 3: /* DMUH */
31028                if (VEX_MIPS_CPU_HAS_MIPSR6(archinfo->hwcaps)) {
31029                   DIP("dmuh r%u, r%u, r%u", rd, rs, rt);
31030                   putIReg(rd, unop(Iop_128HIto64,
31031                                    binop(Iop_MullS64, getIReg(rs), getIReg(rt))));
31032                } else {
31033                   ILLEGAL_INSTRUCTON;
31034                }
31035                break;
31036          }
31037          break;
31038 
31039       case 0x1D:  /* Doubleword Multiply Unsigned - DMULTU; MIPS64 */
31040          switch (sa) {
31041             case 0:
31042                DIP("dmultu r%u, r%u", rs, rt);
31043                if (VEX_MIPS_CPU_HAS_MIPSR6(archinfo->hwcaps) &&
31044                    !VEX_MIPS_CPU_HAS_MIPS32R2(archinfo->hwcaps)) {
31045                   ILLEGAL_INSTRUCTON;
31046                }
31047                t0 = newTemp(Ity_I128);
31048 
31049                assign(t0, binop(Iop_MullU64, getIReg(rs), getIReg(rt)));
31050 
31051                putHI(unop(Iop_128HIto64, mkexpr(t0)));
31052                putLO(unop(Iop_128to64, mkexpr(t0)));
31053                break;
31054             case 2: /* DMULU */
31055                if (VEX_MIPS_CPU_HAS_MIPSR6(archinfo->hwcaps)) {
31056                   DIP("dmulu r%u, r%u, r%u", rd, rs, rt);
31057                   putIReg(rd, unop(Iop_128to64,
31058                                    binop(Iop_MullU64, getIReg(rs), getIReg(rt))));
31059                } else {
31060                   ILLEGAL_INSTRUCTON;
31061                }
31062                break;
31063             case 3: /* DMUHU */
31064                if (VEX_MIPS_CPU_HAS_MIPSR6(archinfo->hwcaps)) {
31065                   DIP("dmuhu r%u, r%u, r%u", rd, rs, rt);
31066                   putIReg(rd, unop(Iop_128HIto64,
31067                                    binop(Iop_MullU64, getIReg(rs), getIReg(rt))));
31068                } else {
31069                   ILLEGAL_INSTRUCTON;
31070                }
31071                break;
31072          }
31073          break;
31074 
31075       case 0x1E:  /* Doubleword Divide DDIV; MIPS64 */
31076          switch (sa) {
31077             case 0:
31078                DIP("ddiv r%u, r%u", rs, rt);
31079                if (VEX_MIPS_CPU_HAS_MIPSR6(archinfo->hwcaps) &&
31080                    !VEX_MIPS_CPU_HAS_MIPS32R2(archinfo->hwcaps)) {
31081                   ILLEGAL_INSTRUCTON;
31082                }
31083                t1 = newTemp(Ity_I128);
31084 
31085                assign(t1, binop(Iop_DivModS64to64, getIReg(rs), getIReg(rt)));
31086 
31087                putHI(unop(Iop_128HIto64, mkexpr(t1)));
31088                putLO(unop(Iop_128to64, mkexpr(t1)));
31089                break;
31090             case 2: /* DDIV r6 */
31091                if (VEX_MIPS_CPU_HAS_MIPSR6(archinfo->hwcaps)) {
31092                   DIP("ddiv r%u, r%u, r%u", rs, rt, rd);
31093                   putIReg(rd, unop(Iop_128to64,
31094                                    binop(Iop_DivModS64to64,
31095                                          getIReg(rs), getIReg(rt))));
31096                } else {
31097                   ILLEGAL_INSTRUCTON;
31098                }
31099                break;
31100             case 3: /* DMOD r6 */
31101                if (VEX_MIPS_CPU_HAS_MIPSR6(archinfo->hwcaps)) {
31102                   DIP("dmod r%u, r%u, r%u", rs, rt, rd);
31103                   t2 = newTemp(Ity_I128);
31104                   assign(t2, binop(Iop_DivModS64to64, getIReg(rs), getIReg(rt)));
31105                   putIReg(rd, unop(Iop_128HIto64, mkexpr(t2)));
31106                } else {
31107                   ILLEGAL_INSTRUCTON;
31108                }
31109                break;
31110          }
31111          break;
31112 
31113       case 0x1F:  /* Doubleword Divide Unsigned DDIVU; MIPS64 check this */
31114          switch (sa) {
31115             case 0:
31116                DIP("ddivu r%u, r%u", rs, rt);
31117                if (VEX_MIPS_CPU_HAS_MIPSR6(archinfo->hwcaps) &&
31118                    !VEX_MIPS_CPU_HAS_MIPS32R2(archinfo->hwcaps)) {
31119                   ILLEGAL_INSTRUCTON;
31120                }
31121                t1 = newTemp(Ity_I128);
31122 
31123                assign(t1, binop(Iop_DivModU64to64, getIReg(rs), getIReg(rt)));
31124 
31125                putHI(unop(Iop_128HIto64, mkexpr(t1)));
31126                putLO(unop(Iop_128to64, mkexpr(t1)));
31127                break;
31128             case 2:
31129                if (VEX_MIPS_CPU_HAS_MIPSR6(archinfo->hwcaps)) {
31130                   DIP("ddivu r%u, r%u, r%u", rs, rt, rd);
31131                   putIReg(rd, unop(Iop_128to64, binop(Iop_DivModU64to64,
31132                                                       getIReg(rs), getIReg(rt))));
31133                } else {
31134                   ILLEGAL_INSTRUCTON;
31135                }
31136                break;
31137             case 3:
31138               if (VEX_MIPS_CPU_HAS_MIPSR6(archinfo->hwcaps)) {
31139                   DIP("dmodu r%u, r%u, r%u", rs, rt, rd);
31140                   putIReg(rd, unop(Iop_128HIto64, binop(Iop_DivModU64to64,
31141                                                         getIReg(rs), getIReg(rt))));
31142                } else {
31143                   ILLEGAL_INSTRUCTON;
31144                }
31145                break;
31146          }
31147          break;
31148 
31149       case 0x10: {  /* MFHI, CLZ R6 */
31150          if (((instr_index >> 6) & 0x1f) == 1) { /* CLZ */
31151             if (VEX_MIPS_CPU_HAS_MIPSR6(archinfo->hwcaps)) {
31152                DIP("clz r%u, r%u", rd, rs);
31153                if (mode64) {
31154                   IRTemp tmpClz32 = newTemp(Ity_I32);
31155                   IRTemp tmpRs32 = newTemp(Ity_I32);
31156 
31157                   assign(tmpRs32, mkNarrowTo32(ty, getIReg(rs)));
31158                   assign(tmpClz32, unop(Iop_Clz32, mkexpr(tmpRs32)));
31159                   putIReg(rd, mkWidenFrom32(ty, mkexpr(tmpClz32), True));
31160                } else {
31161                   t1 = newTemp(Ity_I1);
31162                   assign(t1, binop(Iop_CmpEQ32, getIReg(rs), mkU32(0)));
31163                   putIReg(rd, IRExpr_ITE(mkexpr(t1),
31164                                          mkU32(0x00000020),
31165                                          unop(Iop_Clz32, getIReg(rs))));
31166                }
31167             } else {
31168                ILLEGAL_INSTRUCTON;
31169             }
31170             break;
31171          } else if (VEX_MIPS_PROC_DSP(archinfo->hwcaps)) {
31172             /* If DSP is present -> DSP ASE MFHI */
31173             UInt retVal = disDSPInstr_MIPS_WRK ( cins );
31174             if (0 != retVal ) {
31175                goto decode_failure;
31176             }
31177             break;
31178          } else {
31179             DIP("mfhi r%u", rd);
31180             putIReg(rd, getHI());
31181             break;
31182          }
31183       }
31184 
31185       case 0x11:  {  /* MTHI, CLO R6 */
31186          if (((instr_index >> 6) & 0x1f) == 1) { /* CLO */
31187             if (VEX_MIPS_CPU_HAS_MIPSR6(archinfo->hwcaps)) {
31188                DIP("clo r%u, r%u", rd, rs);
31189                if (mode64) {
31190                   IRTemp tmpClo32 = newTemp(Ity_I32);
31191                   IRTemp tmpRs32 = newTemp(Ity_I32);
31192                   assign(tmpRs32, mkNarrowTo32(ty, getIReg(rs)));
31193 
31194                   t1 = newTemp(Ity_I1);
31195                   assign(t1, binop(Iop_CmpEQ32, mkexpr(tmpRs32), mkU32(0xffffffff)));
31196                   assign(tmpClo32, IRExpr_ITE(mkexpr(t1),
31197                             mkU32(0x00000020),
31198                             unop(Iop_Clz32, unop(Iop_Not32, mkexpr(tmpRs32)))));
31199 
31200                   putIReg(rd, mkWidenFrom32(ty, mkexpr(tmpClo32), True));
31201                   break;
31202                } else {
31203                   t1 = newTemp(Ity_I1);
31204                   assign(t1, binop(Iop_CmpEQ32, getIReg(rs), mkU32(0xffffffff)));
31205                   putIReg(rd, IRExpr_ITE(mkexpr(t1),
31206                                          mkU32(0x00000020),
31207                                          unop(Iop_Clz32,
31208                                               unop(Iop_Not32, getIReg(rs)))));
31209                }
31210             } else {
31211                ILLEGAL_INSTRUCTON;
31212             }
31213             break;
31214          } else if (VEX_MIPS_PROC_DSP(archinfo->hwcaps)) {
31215             /* If DSP is present -> DSP ASE MTHI */
31216             UInt retVal = disDSPInstr_MIPS_WRK ( cins );
31217             if (0 != retVal ) {
31218                goto decode_failure;
31219             }
31220             break;
31221          } else {
31222             DIP("mthi r%u", rs);
31223             putHI(getIReg(rs));
31224             break;
31225          }
31226       }
31227 
31228       case 0x12:  {  /* MFLO */
31229          if (VEX_MIPS_PROC_DSP(archinfo->hwcaps)) {
31230             /* If DSP is present -> DSP ASE MFLO */
31231             UInt retVal = disDSPInstr_MIPS_WRK ( cins );
31232             if (0 != retVal ) {
31233                goto decode_failure;
31234             }
31235             break;
31236          } else {
31237             switch (sa) {
31238                case 0:
31239                   DIP("mflo r%u", rd);
31240                   if (VEX_MIPS_CPU_HAS_MIPSR6(archinfo->hwcaps) &&
31241                       !VEX_MIPS_CPU_HAS_MIPS32R2(archinfo->hwcaps)) {
31242                      ILLEGAL_INSTRUCTON;
31243                   }
31244                   putIReg(rd, getLO());
31245                   break;
31246                case 1:
31247                   DIP("dclz r%u, r%u", rd, rs);
31248                   t1 = newTemp(Ity_I1);
31249                   assign(t1, binop(Iop_CmpEQ64, getIReg(rs), mkU64(0)));
31250                   putIReg(rd, IRExpr_ITE(mkexpr(t1),
31251                                          mkU64(0x00000040),
31252                                          unop(Iop_Clz64, getIReg(rs))));
31253                   break;
31254             }
31255             break;
31256          }
31257       }
31258 
31259       case 0x13:  {  /* MTLO */
31260          if (VEX_MIPS_PROC_DSP(archinfo->hwcaps)) {
31261             /* If DSP is present -> DSP ASE MTLO */
31262             UInt retVal = disDSPInstr_MIPS_WRK ( cins );
31263             if (0 != retVal ) {
31264                goto decode_failure;
31265             }
31266             break;
31267          } else {
31268             switch (sa) {
31269                case 0:
31270                   DIP("mtlo r%u", rs);
31271                   if (VEX_MIPS_CPU_HAS_MIPSR6(archinfo->hwcaps) &&
31272                       !VEX_MIPS_CPU_HAS_MIPS32R2(archinfo->hwcaps)) {
31273                      ILLEGAL_INSTRUCTON;
31274                   }
31275                   putLO(getIReg(rs));
31276                   break;
31277                case 1:
31278                   DIP("dclo r%u, r%u", rd, rs);
31279                   t1 = newTemp(Ity_I1);
31280                   assign(t1, binop(Iop_CmpEQ64, getIReg(rs),
31281                                                  mkU64(0xffffffffffffffffULL)));
31282                   putIReg(rd, IRExpr_ITE(mkexpr(t1),
31283                                          mkU64(0x40),
31284                                          unop(Iop_Clz64, unop(Iop_Not64,
31285                                                               getIReg(rs)))));
31286                break;
31287             }
31288             break;
31289          }
31290       }
31291 
31292       case 0x21:  /* ADDU */
31293          DIP("addu r%u, r%u, r%u", rd, rs, rt);
31294          if (mode64) {
31295             ALU_PATTERN64(Iop_Add32);
31296          } else {
31297             ALU_PATTERN(Iop_Add32);
31298          }
31299          break;
31300 
31301       case 0x22: {  /* SUB */
31302          DIP("sub r%u, r%u, r%u", rd, rs, rt);
31303          IRTemp tmpRs32 = newTemp(Ity_I32);
31304          IRTemp tmpRt32 = newTemp(Ity_I32);
31305 
31306          assign(tmpRs32, mkNarrowTo32(ty, getIReg(rs)));
31307          assign(tmpRt32, mkNarrowTo32(ty, getIReg(rt)));
31308          t0 = newTemp(Ity_I32);
31309          t1 = newTemp(Ity_I32);
31310          t2 = newTemp(Ity_I32);
31311          t3 = newTemp(Ity_I32);
31312          t4 = newTemp(Ity_I32);
31313          t5 = newTemp(Ity_I32);
31314          /* dst = src0 + (-1 * src1)
31315             if(sign(src0 ) != sign((-1 * src1) ))
31316             goto no overflow;
31317             if(sign(dst) == sign(src0 ))
31318             goto no overflow;
31319             we have overflow! */
31320 
31321          assign(t5, binop(Iop_Mul32, mkexpr(tmpRt32), mkU32(-1)));
31322          assign(t0, binop(Iop_Add32, mkexpr(tmpRs32), mkexpr(t5)));
31323          assign(t1, binop(Iop_Xor32, mkexpr(tmpRs32), mkexpr(t5)));
31324          assign(t2, unop(Iop_1Sto32, binop(Iop_CmpEQ32, binop(Iop_And32,
31325                          mkexpr(t1), mkU32(0x80000000)), mkU32(0x80000000))));
31326 
31327          assign(t3, binop(Iop_Xor32, mkexpr(t0), mkexpr(tmpRs32)));
31328          assign(t4, unop(Iop_1Sto32, binop(Iop_CmpNE32, binop(Iop_And32,
31329                          mkexpr(t3), mkU32(0x80000000)), mkU32(0x80000000))));
31330 
31331          stmt(IRStmt_Exit(binop(Iop_CmpEQ32, binop(Iop_Or32, mkexpr(t2),
31332                                 mkexpr(t4)), mkU32(0)), Ijk_SigFPE_IntOvf,
31333                           mode64 ? IRConst_U64(guest_PC_curr_instr + 4) :
31334                                    IRConst_U32(guest_PC_curr_instr + 4),
31335                           OFFB_PC));
31336 
31337          putIReg(rd, mkWidenFrom32(ty, mkexpr(t0), True));
31338          break;
31339       }
31340       case 0x23:  /* SUBU */
31341          DIP("subu r%u, r%u, r%u", rd, rs, rt);
31342          if (mode64) {
31343             ALU_PATTERN64(Iop_Sub32);
31344          } else {
31345             ALU_PATTERN(Iop_Sub32);
31346          }
31347          break;
31348 
31349       case 0x24:  /* AND */
31350          DIP("and r%u, r%u, r%u", rd, rs, rt);
31351          if (mode64) {
31352             ALU_PATTERN(Iop_And64);
31353          } else {
31354             ALU_PATTERN(Iop_And32);
31355          }
31356          break;
31357 
31358       case 0x25:  /* OR */
31359          DIP("or r%u, r%u, r%u", rd, rs, rt);
31360          if (mode64) {
31361             ALU_PATTERN(Iop_Or64);
31362          } else {
31363             ALU_PATTERN(Iop_Or32);
31364          }
31365          break;
31366 
31367       case 0x26:  /* XOR */
31368          DIP("xor r%u, r%u, r%u", rd, rs, rt);
31369          if (mode64) {
31370             ALU_PATTERN(Iop_Xor64);
31371          } else {
31372             ALU_PATTERN(Iop_Xor32);
31373          }
31374          break;
31375 
31376       case 0x27:  /* NOR */
31377          DIP("nor r%u, r%u, r%u", rd, rs, rt);
31378          if (mode64)
31379             putIReg(rd, unop(Iop_Not64, binop(Iop_Or64, getIReg(rs),
31380                                               getIReg(rt))));
31381          else
31382             putIReg(rd, unop(Iop_Not32, binop(Iop_Or32, getIReg(rs),
31383                                               getIReg(rt))));
31384          break;
31385 
31386       case 0x08:  /* JR */
31387          DIP("jr r%u", rs);
31388          t0 = newTemp(ty);
31389          assign(t0, getIReg(rs));
31390          lastn = mkexpr(t0);
31391          break;
31392 
31393       case 0x09:  /* JALR */
31394          DIP("jalr r%u r%u", rd, rs);
31395          if (mode64) {
31396             putIReg(rd, mkU64(guest_PC_curr_instr + 8));
31397             t0 = newTemp(Ity_I64);
31398             assign(t0, getIReg(rs));
31399             lastn = mkexpr(t0);
31400          } else {
31401             putIReg(rd, mkU32(guest_PC_curr_instr + 8));
31402             t0 = newTemp(Ity_I32);
31403             assign(t0, getIReg(rs));
31404             lastn = mkexpr(t0);
31405          }
31406          break;
31407 
31408       case 0x0C:  /* SYSCALL */
31409          DIP("syscall");
31410          if (mode64)
31411             putPC(mkU64(guest_PC_curr_instr + 4));
31412          else
31413             putPC(mkU32(guest_PC_curr_instr + 4));
31414          dres.jk_StopHere = Ijk_Sys_syscall;
31415          dres.whatNext    = Dis_StopHere;
31416          break;
31417 
31418       case 0x2A:  /* SLT */
31419          DIP("slt r%u, r%u, r%u", rd, rs, rt);
31420          if (mode64)
31421             putIReg(rd, unop(Iop_1Uto64, binop(Iop_CmpLT64S, getIReg(rs),
31422                                                getIReg(rt))));
31423          else
31424             putIReg(rd, unop(Iop_1Uto32, binop(Iop_CmpLT32S, getIReg(rs),
31425                                                getIReg(rt))));
31426          break;
31427 
31428       case 0x2B:  /* SLTU */
31429          DIP("sltu r%u, r%u, r%u", rd, rs, rt);
31430          if (mode64)
31431             putIReg(rd, unop(Iop_1Uto64, binop(Iop_CmpLT64U, getIReg(rs),
31432                                          getIReg(rt))));
31433          else
31434             putIReg(rd, unop(Iop_1Uto32, binop(Iop_CmpLT32U, getIReg(rs),
31435                                          getIReg(rt))));
31436          break;
31437 
31438       case 0x00: {  /* SLL */
31439          DIP("sll r%u, r%u, %u", rd, rt, sa);
31440          IRTemp tmpRt32 = newTemp(Ity_I32);
31441          IRTemp tmpSh32 = newTemp(Ity_I32);
31442          IRTemp tmpRd = newTemp(Ity_I64);
31443          if (mode64) {
31444             assign(tmpRt32, mkNarrowTo32(ty, getIReg(rt)));
31445             assign(tmpSh32, binop(Iop_Shl32, mkexpr(tmpRt32), mkU8(sa)));
31446             assign(tmpRd, mkWidenFrom32(ty, mkexpr(tmpSh32), True));
31447             putIReg(rd, mkexpr(tmpRd));
31448          } else
31449             SXX_PATTERN(Iop_Shl32);
31450          break;
31451       }
31452 
31453       case 0x04: {  /* SLLV */
31454          DIP("sllv r%u, r%u, r%u", rd, rt, rs);
31455          if (mode64) {
31456             IRTemp tmpRs8 = newTemp(Ity_I8);
31457             IRTemp tmpRt32 = newTemp(Ity_I32);
31458             IRTemp tmpSh32 = newTemp(Ity_I32);
31459             IRTemp tmp = newTemp(ty);
31460             assign(tmp, binop(mkSzOp(ty, Iop_And8), getIReg(rs),
31461                               mkSzImm(ty, 31)));
31462             assign(tmpRs8, mkNarrowTo8(ty, mkexpr(tmp)));
31463             assign(tmpRt32, mkNarrowTo32(ty, getIReg(rt)));
31464             assign(tmpSh32, binop(Iop_Shl32, mkexpr(tmpRt32), mkexpr(tmpRs8)));
31465             putIReg(rd, mkWidenFrom32(ty, mkexpr(tmpSh32), True));
31466          } else {
31467             SXXV_PATTERN(Iop_Shl32);
31468          }
31469          break;
31470       }
31471 
31472       case 0x03:  /* SRA */
31473          DIP("sra r%u, r%u, %u", rd, rt, sa);
31474          if (mode64) {
31475             IRTemp tmpRt32 = newTemp(Ity_I32);
31476             IRTemp tmpSh32 = newTemp(Ity_I32);
31477 
31478             t1 = newTemp(Ity_I64);
31479             t2 = newTemp(Ity_I64);
31480             t3 = newTemp(Ity_I64);
31481 
31482             assign(t1, binop(Iop_And64, getIReg(rt),  /* hi */
31483                              mkU64(0xFFFFFFFF00000000ULL)));
31484 
31485             assign(t2, binop(Iop_Sar64, mkexpr(t1), mkU8(sa)));
31486 
31487             assign(tmpRt32, mkNarrowTo32(ty, getIReg(rt)));
31488             assign(tmpSh32, binop(Iop_Sar32, mkexpr(tmpRt32), mkU8(sa)));
31489 
31490             putIReg(rd, mkWidenFrom32(ty, mkexpr(tmpSh32), True));
31491          } else {
31492             SXX_PATTERN(Iop_Sar32);
31493          }
31494          break;
31495 
31496       case 0x07:  /* SRAV */
31497          DIP("srav r%u, r%u, r%u", rd, rt, rs);
31498          if (mode64) {
31499             IRTemp tmpRt32 = newTemp(Ity_I32);
31500             IRTemp tmpSh32 = newTemp(Ity_I32);
31501 
31502             t1 = newTemp(Ity_I64);
31503             t2 = newTemp(Ity_I64);
31504             t3 = newTemp(Ity_I64);
31505             t4 = newTemp(Ity_I8);
31506 
31507             assign(t4, unop(Iop_32to8, binop(Iop_And32,
31508                        mkNarrowTo32(ty, getIReg(rs)), mkU32(0x0000001F))));
31509 
31510             assign(t1, binop(Iop_And64, getIReg(rt),  /* hi */
31511                    mkU64(0xFFFFFFFF00000000ULL)));
31512 
31513             assign(t2, binop(Iop_Sar64, mkexpr(t1), mkexpr(t4)));
31514 
31515             assign(tmpRt32, mkNarrowTo32(ty, getIReg(rt)));
31516             assign(tmpSh32, binop(Iop_Sar32, mkexpr(tmpRt32), mkexpr(t4)));
31517 
31518             putIReg(rd, mkWidenFrom32(ty, mkexpr(tmpSh32), True));
31519          } else {
31520             SXXV_PATTERN(Iop_Sar32);
31521          }
31522          break;
31523 
31524       case 0x02: {  /* SRL */
31525          rot = get_rot(cins);
31526          if (rot) {
31527             DIP("rotr r%u, r%u, %u", rd, rt, sa);
31528             putIReg(rd, mkWidenFrom32(ty, genROR32(mkNarrowTo32(ty,
31529                         getIReg(rt)), sa), True));
31530          } else {
31531             DIP("srl r%u, r%u, %u", rd, rt, sa);
31532             if (mode64) {
31533                IRTemp tmpSh32 = newTemp(Ity_I32);
31534                IRTemp tmpRt32 = newTemp(Ity_I32);
31535 
31536                assign(tmpRt32, mkNarrowTo32(ty, getIReg(rt)));
31537                assign(tmpSh32, binop(Iop_Shr32, mkexpr(tmpRt32), mkU8(sa)));
31538                putIReg(rd, mkWidenFrom32(ty, mkexpr(tmpSh32), True));
31539             } else {
31540                SXX_PATTERN(Iop_Shr32);
31541             }
31542          }
31543       break;
31544       }
31545 
31546       case 0x06: {
31547          rot = get_rotv(cins);
31548          if (rot) {
31549             DIP("rotrv r%u, r%u, r%u", rd, rt, rs);
31550             putIReg(rd, mkWidenFrom32(ty, genRORV32(mkNarrowTo32(ty,
31551                         getIReg(rt)), mkNarrowTo32(ty, getIReg(rs))), True));
31552             break;
31553          } else {  /* SRLV */
31554             DIP("srlv r%u, r%u, r%u", rd, rt, rs);
31555             if (mode64) {
31556                SXXV_PATTERN64(Iop_Shr32);
31557             } else {
31558                SXXV_PATTERN(Iop_Shr32);
31559             }
31560             break;
31561          }
31562       }
31563       case 0x05: { /* LSA */
31564          UInt imm2 = (imm & 0xC0) >> 6;
31565          if (VEX_MIPS_CPU_HAS_MIPSR6(archinfo->hwcaps) || has_msa) {
31566             DIP("lsa r%u, r%u, r%u, imm: 0x%x", rd, rs, rt, imm2);
31567             if (mode64) {
31568                DIP("lsa r%u, r%u, r%u, imm: 0x%x", rd, rs, rt, imm2);
31569                putIReg(rd, unop(Iop_32Sto64,
31570                                 binop(Iop_Add32,
31571                                       binop(Iop_Shl32,
31572                                             unop(Iop_64to32, getIReg(rs)),
31573                                             mkU8(imm2 + 1)),
31574                                       unop(Iop_64to32, getIReg(rt)))));
31575                break;
31576             } else {
31577                DIP("lsa r%u, r%u, r%u, imm: 0x%x", rd, rs, rt, imm2);
31578                putIReg(rd, binop(Iop_Add32,
31579                                  binop(Iop_Shl32,
31580                                        getIReg(rs), mkU8(imm2 + 1)), getIReg(rt)));
31581                break;
31582             }
31583          } else {
31584             ILLEGAL_INSTRUCTON;
31585          }
31586 
31587       }
31588       case 0x15:{ /* DLSA */
31589          UInt imm2 = (imm & 0xC0) >> 6;
31590          if (VEX_MIPS_CPU_HAS_MIPSR6(archinfo->hwcaps) || has_msa) {
31591             DIP("dlsa r%u, r%u, r%u, imm: 0x%x", rd, rs, rt, imm2);
31592             putIReg(rd, binop(Iop_Add64,
31593                               binop(Iop_Shl64, getIReg(rs), mkU8(imm2 + 1)),
31594                               getIReg(rt)));
31595          } else {
31596             ILLEGAL_INSTRUCTON;
31597          }
31598          break;
31599       }
31600 
31601       case 0x0D:  /* BREAK */
31602          DIP("break 0x%x", trap_code);
31603          if (mode64)
31604             jmp_lit64(&dres, Ijk_SigTRAP, (guest_PC_curr_instr + 4));
31605          else
31606             jmp_lit32(&dres, Ijk_SigTRAP, (guest_PC_curr_instr + 4));
31607          vassert(dres.whatNext == Dis_StopHere);
31608          break;
31609 
31610       case 0x30: {  /* TGE */
31611          DIP("tge r%u, r%u %u", rs, rt, trap_code);
31612          if (mode64) {
31613             if (trap_code == 7)
31614                stmt (IRStmt_Exit (unop (Iop_Not1,
31615                                         binop (Iop_CmpLT64S,
31616                                                getIReg (rs),
31617                                                getIReg (rt))),
31618                                 Ijk_SigFPE_IntDiv,
31619                                 IRConst_U64(guest_PC_curr_instr + 4),
31620                                 OFFB_PC));
31621             else if (trap_code == 6)
31622                stmt (IRStmt_Exit (unop (Iop_Not1,
31623                                         binop (Iop_CmpLT64S,
31624                                                getIReg (rs),
31625                                                getIReg (rt))),
31626                                 Ijk_SigFPE_IntOvf,
31627                                 IRConst_U64(guest_PC_curr_instr + 4),
31628                                 OFFB_PC));
31629             else
31630                stmt (IRStmt_Exit (unop (Iop_Not1,
31631                                         binop (Iop_CmpLT64S,
31632                                                getIReg (rs),
31633                                                getIReg (rt))),
31634                                 Ijk_SigTRAP,
31635                                 IRConst_U64(guest_PC_curr_instr + 4),
31636                                 OFFB_PC));
31637          } else {
31638             if (trap_code == 7)
31639                stmt (IRStmt_Exit (unop (Iop_Not1,
31640                                         binop (Iop_CmpLT32S,
31641                                                getIReg (rs),
31642                                                getIReg (rt))),
31643                                   Ijk_SigFPE_IntDiv,
31644                                   IRConst_U32(guest_PC_curr_instr + 4),
31645                                   OFFB_PC));
31646             else if (trap_code == 6)
31647                stmt (IRStmt_Exit (unop (Iop_Not1,
31648                                         binop (Iop_CmpLT32S,
31649                                                getIReg (rs),
31650                                                getIReg (rt))),
31651                                   Ijk_SigFPE_IntOvf,
31652                                   IRConst_U32(guest_PC_curr_instr + 4),
31653                                   OFFB_PC));
31654             else
31655                stmt (IRStmt_Exit (unop (Iop_Not1,
31656                                         binop (Iop_CmpLT32S,
31657                                                getIReg (rs),
31658                                                getIReg (rt))),
31659                                   Ijk_SigTRAP,
31660                                   IRConst_U32(guest_PC_curr_instr + 4),
31661                                   OFFB_PC));
31662          }
31663          break;
31664       }
31665       case 0x31: {  /* TGEU */
31666          DIP("tgeu r%u, r%u %u", rs, rt, trap_code);
31667          if (mode64) {
31668             if (trap_code == 7)
31669                stmt (IRStmt_Exit (unop (Iop_Not1,
31670                                         binop (Iop_CmpLT64U,
31671                                                getIReg (rs),
31672                                                getIReg (rt))),
31673                                   Ijk_SigFPE_IntDiv,
31674                                   IRConst_U64(guest_PC_curr_instr + 4),
31675                                   OFFB_PC));
31676             else if (trap_code == 6)
31677                stmt (IRStmt_Exit (unop (Iop_Not1,
31678                                         binop (Iop_CmpLT64U,
31679                                                getIReg (rs),
31680                                                getIReg (rt))),
31681                                   Ijk_SigFPE_IntOvf,
31682                                   IRConst_U64(guest_PC_curr_instr + 4),
31683                                   OFFB_PC));
31684             else
31685                stmt (IRStmt_Exit (unop (Iop_Not1,
31686                                         binop (Iop_CmpLT64U,
31687                                                getIReg (rs),
31688                                                getIReg (rt))),
31689                                   Ijk_SigTRAP,
31690                                   IRConst_U64(guest_PC_curr_instr + 4),
31691                                   OFFB_PC));
31692          } else {
31693             if (trap_code == 7)
31694                stmt (IRStmt_Exit (unop (Iop_Not1,
31695                                         binop (Iop_CmpLT32U,
31696                                                getIReg (rs),
31697                                                getIReg (rt))),
31698                                   Ijk_SigFPE_IntDiv,
31699                                   IRConst_U32(guest_PC_curr_instr + 4),
31700                                   OFFB_PC));
31701             else if (trap_code == 6)
31702                stmt (IRStmt_Exit (unop (Iop_Not1,
31703                                         binop (Iop_CmpLT32U,
31704                                                getIReg (rs),
31705                                                getIReg (rt))),
31706                                   Ijk_SigFPE_IntOvf,
31707                                   IRConst_U32(guest_PC_curr_instr + 4),
31708                                   OFFB_PC));
31709             else
31710                stmt (IRStmt_Exit (unop (Iop_Not1,
31711                                         binop (Iop_CmpLT32U,
31712                                                getIReg (rs),
31713                                                getIReg (rt))),
31714                                   Ijk_SigTRAP,
31715                                   IRConst_U32(guest_PC_curr_instr + 4),
31716                                   OFFB_PC));
31717          }
31718          break;
31719       }
31720       case 0x32: {  /* TLT */
31721          DIP("tlt r%u, r%u %u", rs, rt, trap_code);
31722          if (mode64) {
31723             if (trap_code == 7)
31724                stmt(IRStmt_Exit(binop(Iop_CmpLT64S, getIReg(rs),
31725                                       getIReg(rt)), Ijk_SigFPE_IntDiv,
31726                                 IRConst_U64(guest_PC_curr_instr + 4),
31727                                 OFFB_PC));
31728             else if (trap_code == 6)
31729                stmt(IRStmt_Exit(binop(Iop_CmpLT64S, getIReg(rs),
31730                                       getIReg(rt)), Ijk_SigFPE_IntOvf,
31731                                 IRConst_U64(guest_PC_curr_instr + 4),
31732                                 OFFB_PC));
31733             else
31734                stmt(IRStmt_Exit(binop(Iop_CmpLT64S, getIReg(rs),
31735                                       getIReg(rt)), Ijk_SigTRAP,
31736                                 IRConst_U64(guest_PC_curr_instr + 4),
31737                                 OFFB_PC));
31738          } else {
31739             if (trap_code == 7)
31740                stmt(IRStmt_Exit(binop(Iop_CmpLT32S, getIReg(rs),
31741                                       getIReg(rt)), Ijk_SigFPE_IntDiv,
31742                                 IRConst_U32(guest_PC_curr_instr + 4),
31743                                 OFFB_PC));
31744             else if (trap_code == 6)
31745                stmt(IRStmt_Exit(binop(Iop_CmpLT32S, getIReg(rs),
31746                                       getIReg(rt)), Ijk_SigFPE_IntOvf,
31747                                 IRConst_U32(guest_PC_curr_instr + 4),
31748                                 OFFB_PC));
31749             else
31750                stmt(IRStmt_Exit(binop(Iop_CmpLT32S, getIReg(rs),
31751                                       getIReg(rt)), Ijk_SigTRAP,
31752                                 IRConst_U32(guest_PC_curr_instr + 4),
31753                                 OFFB_PC));
31754          }
31755          break;
31756       }
31757       case 0x33: {  /* TLTU */
31758          DIP("tltu r%u, r%u %u", rs, rt, trap_code);
31759          if (mode64) {
31760             if (trap_code == 7)
31761                stmt(IRStmt_Exit(binop(Iop_CmpLT64U, getIReg(rs),
31762                                       getIReg(rt)), Ijk_SigFPE_IntDiv,
31763                                 IRConst_U64(guest_PC_curr_instr + 4),
31764                                 OFFB_PC));
31765             else if (trap_code == 6)
31766                stmt(IRStmt_Exit(binop(Iop_CmpLT64U, getIReg(rs),
31767                                       getIReg(rt)), Ijk_SigFPE_IntOvf,
31768                                 IRConst_U64(guest_PC_curr_instr + 4),
31769                                 OFFB_PC));
31770             else
31771                stmt(IRStmt_Exit(binop(Iop_CmpLT64U, getIReg(rs),
31772                                       getIReg(rt)), Ijk_SigTRAP,
31773                                 IRConst_U64(guest_PC_curr_instr + 4),
31774                                 OFFB_PC));
31775          } else {
31776             if (trap_code == 7)
31777                stmt(IRStmt_Exit(binop(Iop_CmpLT32U, getIReg(rs),
31778                                       getIReg(rt)), Ijk_SigFPE_IntDiv,
31779                                 IRConst_U32(guest_PC_curr_instr + 4),
31780                                 OFFB_PC));
31781             else if (trap_code == 6)
31782                stmt(IRStmt_Exit(binop(Iop_CmpLT32U, getIReg(rs),
31783                                       getIReg(rt)), Ijk_SigFPE_IntOvf,
31784                                 IRConst_U32(guest_PC_curr_instr + 4),
31785                                 OFFB_PC));
31786             else
31787                stmt(IRStmt_Exit(binop(Iop_CmpLT32U, getIReg(rs),
31788                                       getIReg (rt)), Ijk_SigTRAP,
31789                                 IRConst_U32(guest_PC_curr_instr + 4),
31790                                 OFFB_PC));
31791          }
31792          break;
31793       }
31794       case 0x34: {  /* TEQ */
31795          DIP("teq r%u, r%u, %u", rs, rt, trap_code);
31796          if (mode64) {
31797             if (trap_code == 7)
31798                stmt(IRStmt_Exit(binop(Iop_CmpEQ64, getIReg(rs),
31799                                       getIReg(rt)), Ijk_SigFPE_IntDiv,
31800                                 IRConst_U64(guest_PC_curr_instr + 4),
31801                                 OFFB_PC));
31802             else if (trap_code == 6)
31803                stmt(IRStmt_Exit(binop(Iop_CmpEQ64, getIReg(rs),
31804                                       getIReg(rt)), Ijk_SigFPE_IntOvf,
31805                                 IRConst_U64(guest_PC_curr_instr + 4),
31806                                 OFFB_PC));
31807             else
31808                stmt(IRStmt_Exit(binop(Iop_CmpEQ64, getIReg(rs),
31809                                       getIReg(rt)), Ijk_SigTRAP,
31810                                 IRConst_U64(guest_PC_curr_instr + 4),
31811                                 OFFB_PC));
31812          } else {
31813             if (trap_code == 7)
31814                stmt(IRStmt_Exit(binop(Iop_CmpEQ32, getIReg(rs),
31815                                       getIReg(rt)), Ijk_SigFPE_IntDiv,
31816                                 IRConst_U32(guest_PC_curr_instr + 4),
31817                                 OFFB_PC));
31818             else if (trap_code == 6)
31819                stmt(IRStmt_Exit(binop(Iop_CmpEQ32, getIReg(rs),
31820                                       getIReg(rt)), Ijk_SigFPE_IntOvf,
31821                                 IRConst_U32(guest_PC_curr_instr + 4),
31822                                 OFFB_PC));
31823             else
31824                stmt(IRStmt_Exit(binop(Iop_CmpEQ32, getIReg(rs),
31825                                       getIReg(rt)), Ijk_SigTRAP,
31826                                 IRConst_U32(guest_PC_curr_instr + 4),
31827                                 OFFB_PC));
31828          }
31829          break;
31830       }
31831       case 0x35: {   /* SELEQZ */
31832          if (VEX_MIPS_CPU_HAS_MIPSR6(archinfo->hwcaps)) {
31833             DIP("seleqz r%u, r%u, r%u", rd, rs, rt);
31834             if (mode64) {
31835                putIReg(rd, binop(Iop_And64,
31836                                  unop(Iop_Not64,
31837                                       unop(Iop_CmpwNEZ64, getIReg(rt))),
31838                                  getIReg(rs)));
31839             } else {
31840                putIReg(rd, binop(Iop_And32,
31841                                  unop(Iop_Not32,
31842                                       unop(Iop_CmpwNEZ32, getIReg(rt))),
31843                                  getIReg(rs)));
31844             }
31845          } else {
31846             ILLEGAL_INSTRUCTON;
31847          }
31848          break;
31849       }
31850 
31851       case 0x36: {  /* TNE */
31852          DIP("tne r%u, r%u %u", rs, rt, trap_code);
31853          if (mode64) {
31854             if (trap_code == 7)
31855                stmt(IRStmt_Exit(binop(Iop_CmpNE64, getIReg(rs),
31856                                       getIReg(rt)), Ijk_SigFPE_IntDiv,
31857                                 IRConst_U64(guest_PC_curr_instr + 4),
31858                                 OFFB_PC));
31859             else if (trap_code == 6)
31860                stmt(IRStmt_Exit(binop(Iop_CmpNE64, getIReg(rs),
31861                                       getIReg(rt)), Ijk_SigFPE_IntOvf,
31862                                 IRConst_U64(guest_PC_curr_instr + 4),
31863                                 OFFB_PC));
31864             else
31865                stmt(IRStmt_Exit(binop(Iop_CmpNE64, getIReg(rs),
31866                                       getIReg(rt)), Ijk_SigTRAP,
31867                                 IRConst_U64(guest_PC_curr_instr + 4),
31868                                 OFFB_PC));
31869          } else {
31870             if (trap_code == 7)
31871                stmt(IRStmt_Exit(binop(Iop_CmpNE32, getIReg(rs),
31872                                       getIReg(rt)), Ijk_SigFPE_IntDiv,
31873                                 IRConst_U32(guest_PC_curr_instr + 4),
31874                                 OFFB_PC));
31875             else if (trap_code == 6)
31876                stmt(IRStmt_Exit(binop(Iop_CmpNE32, getIReg(rs),
31877                                       getIReg(rt)), Ijk_SigFPE_IntOvf,
31878                                 IRConst_U32(guest_PC_curr_instr + 4),
31879                                 OFFB_PC));
31880             else
31881                stmt(IRStmt_Exit(binop(Iop_CmpNE32, getIReg(rs),
31882                                       getIReg(rt)), Ijk_SigTRAP,
31883                                 IRConst_U32(guest_PC_curr_instr + 4),
31884                                 OFFB_PC));
31885          }
31886          break;
31887       }
31888       case 0x37:  { /* SELNEZ */
31889          if (VEX_MIPS_CPU_HAS_MIPSR6(archinfo->hwcaps)) {
31890             DIP("selnez r%u, r%u, r%u", rd, rs, rt);
31891             if (mode64) {
31892                putIReg(rd, binop(Iop_And64,
31893                                  unop(Iop_CmpwNEZ64, getIReg(rt)), getIReg(rs)));
31894             } else {
31895                putIReg(rd, binop(Iop_And32,
31896                                  unop(Iop_CmpwNEZ32, getIReg(rt)), getIReg(rs)));
31897             }
31898          } else {
31899             ILLEGAL_INSTRUCTON;
31900          }
31901          break;
31902       }
31903       case 0x14:
31904       case 0x16:
31905       case 0x17:  /* DSLLV, DROTRV:DSRLV, DSRAV */
31906       case 0x38:
31907       case 0x3A:
31908       case 0x3B:  /* DSLL, DROTL:DSRL, DSRA  */
31909       case 0x3C:
31910       case 0x3E:
31911       case 0x3F:  /* DSLL32, DROTR32:DSRL32, DSRA32 */
31912          if (dis_instr_shrt(cins))
31913             break;
31914          goto decode_failure;
31915 
31916       case 0x0F:  /* SYNC */
31917          DIP("sync 0x%x", sel);
31918          /* Just ignore it. */
31919          break;
31920 
31921       case 0x2C: {  /* Doubleword Add - DADD; MIPS64 */
31922          DIP("dadd r%u, r%u, r%u", rd, rs, rt);
31923          IRTemp tmpRs64 = newTemp(Ity_I64);
31924          IRTemp tmpRt64 = newTemp(Ity_I64);
31925 
31926          assign(tmpRs64, getIReg(rs));
31927          assign(tmpRt64, getIReg(rt));
31928 
31929          t0 = newTemp(Ity_I64);
31930          t1 = newTemp(Ity_I64);
31931          t2 = newTemp(Ity_I64);
31932          t3 = newTemp(Ity_I64);
31933          t4 = newTemp(Ity_I64);
31934          /* dst = src0 + src1
31935             if(sign(src0 ) != sign(src1 ))
31936             goto no overflow;
31937             if(sign(dst) == sign(src0 ))
31938             goto no overflow;
31939             we have overflow! */
31940 
31941          assign(t0, binop(Iop_Add64, mkexpr(tmpRs64), mkexpr(tmpRt64)));
31942          assign(t1, binop(Iop_Xor64, mkexpr(tmpRs64), mkexpr(tmpRt64)));
31943          assign(t2, unop(Iop_1Uto64,
31944                          binop(Iop_CmpEQ64,
31945                                binop(Iop_And64, mkexpr(t1),
31946                                      mkU64(0x8000000000000000ULL)),
31947                                mkU64(0x8000000000000000ULL))));
31948 
31949          assign(t3, binop(Iop_Xor64, mkexpr(t0), mkexpr(tmpRs64)));
31950          assign(t4, unop(Iop_1Uto64,
31951                          binop(Iop_CmpNE64,
31952                                binop(Iop_And64, mkexpr(t3),
31953                                      mkU64(0x8000000000000000ULL)),
31954                                mkU64(0x8000000000000000ULL))));
31955 
31956          stmt(IRStmt_Exit(binop(Iop_CmpEQ64,
31957                                 binop(Iop_Or64, mkexpr(t2), mkexpr(t4)),
31958                                 mkU64(0)),
31959                           Ijk_SigFPE_IntOvf,
31960                           IRConst_U64(guest_PC_curr_instr + 4),
31961                           OFFB_PC));
31962 
31963          putIReg(rd,  mkexpr(t0));
31964          break;
31965       }
31966 
31967       case 0x2D:  /* Doubleword Add Unsigned - DADDU; MIPS64 */
31968          DIP("daddu r%u, r%u, r%u", rd, rs, rt);
31969          ALU_PATTERN(Iop_Add64);
31970          break;
31971 
31972       case 0x2E: {  /* Doubleword Subtract - DSUB; MIPS64 */
31973          DIP("dsub r%u, r%u, r%u", rd, rs, rt);
31974          IRTemp tmpRs64 = newTemp(Ity_I64);
31975          IRTemp tmpRt64 = newTemp(Ity_I64);
31976 
31977          assign(tmpRs64, getIReg(rs));
31978          assign(tmpRt64, getIReg(rt));
31979          t0 = newTemp(Ity_I64);
31980          t1 = newTemp(Ity_I64);
31981          t2 = newTemp(Ity_I64);
31982          t3 = newTemp(Ity_I64);
31983          t4 = newTemp(Ity_I64);
31984          t5 = newTemp(Ity_I64);
31985          /* dst = src0 + (-1 * src1)
31986             if(sign(src0 ) != sign((-1 * src1) ))
31987             goto no overflow;
31988             if(sign(dst) == sign(src0 ))
31989             goto no overflow;
31990             we have overflow! */
31991 
31992          assign(t5, binop(Iop_Mul64,
31993                           mkexpr(tmpRt64),
31994                           mkU64(0xffffffffffffffffULL)));
31995          assign(t0, binop(Iop_Add64, mkexpr(tmpRs64), mkexpr(t5)));
31996          assign(t1, binop(Iop_Xor64, mkexpr(tmpRs64), mkexpr(t5)));
31997          assign(t2, unop(Iop_1Sto64,
31998                          binop(Iop_CmpEQ64,
31999                                binop(Iop_And64,
32000                                      mkexpr(t1),
32001                                      mkU64(0x8000000000000000ULL)),
32002                                mkU64(0x8000000000000000ULL))));
32003 
32004          assign(t3, binop(Iop_Xor64, mkexpr(t0), mkexpr(tmpRs64)));
32005          assign(t4, unop(Iop_1Sto64,
32006                          binop(Iop_CmpNE64,
32007                                binop(Iop_And64,
32008                                      mkexpr(t3),
32009                                      mkU64(0x8000000000000000ULL)),
32010                                mkU64(0x8000000000000000ULL))));
32011 
32012          stmt(IRStmt_Exit(binop(Iop_CmpEQ64, binop(Iop_Or64, mkexpr(t2),
32013                                 mkexpr(t4)), mkU64(0)), Ijk_SigFPE_IntOvf,
32014                           IRConst_U64(guest_PC_curr_instr + 4),
32015                           OFFB_PC));
32016 
32017          putIReg(rd, binop(Iop_Sub64, getIReg(rs), getIReg(rt)));
32018          break;
32019       }
32020 
32021       case 0x2F:  /* Doubleword Subtract Unsigned - DSUBU; MIPS64 */
32022          DIP("dsub r%u, r%u,r%u", rd, rt, rt);
32023          ALU_PATTERN(Iop_Sub64);
32024          break;
32025 
32026       default:
32027          goto decode_failure;
32028       }
32029       break;
32030 
32031    case 0x01:  /* Regimm */
32032 
32033       switch (rt) {
32034       case 0x00:  /* BLTZ */
32035          DIP("bltz r%u, %u", rs, imm);
32036          if (mode64) {
32037             if (!dis_instr_branch(cins, &dres, resteerOkFn,
32038                         callback_opaque, &bstmt))
32039                goto decode_failure;
32040          } else
32041             dis_branch(False, binop(Iop_CmpEQ32, binop(Iop_And32, getIReg(rs),
32042                        mkU32(0x80000000)), mkU32(0x80000000)), imm, &bstmt);
32043          break;
32044 
32045       case 0x01:  /* BGEZ */
32046          DIP("bgez r%u, %u", rs, imm);
32047          if (mode64) {
32048             if (!dis_instr_branch(cins, &dres, resteerOkFn,
32049                                   callback_opaque, &bstmt))
32050                goto decode_failure;
32051          } else
32052             dis_branch(False, binop(Iop_CmpEQ32, binop(Iop_And32, getIReg(rs),
32053                               mkU32(0x80000000)), mkU32(0x0)), imm, &bstmt);
32054          break;
32055 
32056       case 0x02:  /* BLTZL */
32057          DIP("bltzl r%u, %u", rs, imm);
32058          lastn = dis_branch_likely(binop(mode64 ? Iop_CmpNE64 : Iop_CmpNE32,
32059                      binop(mode64 ? Iop_And64 : Iop_And32, getIReg(rs),
32060                      mode64 ? mkU64(0x8000000000000000ULL) : mkU32(0x80000000)),
32061                      mode64 ? mkU64(0x8000000000000000ULL) : mkU32(0x80000000)),
32062                      imm);
32063          break;
32064 
32065       case 0x03:  /* BGEZL */
32066          DIP("bgezl r%u, %u", rs, imm);
32067          lastn = dis_branch_likely(binop(mode64 ? Iop_CmpNE64 : Iop_CmpNE32,
32068                      binop(mode64 ? Iop_And64 : Iop_And32, getIReg(rs),
32069                      mode64 ? mkU64(0x8000000000000000ULL) : mkU32(0x80000000)),
32070                      mode64 ? mkU64(0x0) : mkU32(0x0)), imm);
32071          break;
32072 
32073       case 0x10:  /* BLTZAL */
32074          DIP("bltzal r%u, %u", rs, imm);
32075          if (mode64) {
32076             if (!dis_instr_branch(cins, &dres, resteerOkFn,
32077                         callback_opaque, &bstmt))
32078                goto decode_failure;
32079          } else
32080             dis_branch(True, binop(Iop_CmpEQ32, binop(Iop_And32, getIReg(rs),
32081                        mkU32(0x80000000)), mkU32(0x80000000)), imm, &bstmt);
32082          break;
32083 
32084       case 0x12:  /* BLTZALL */
32085          DIP("bltzall r%u, %u", rs, imm);
32086          putIReg(31, mode64 ? mkU64(guest_PC_curr_instr + 8) :
32087                               mkU32(guest_PC_curr_instr + 8));
32088          lastn = dis_branch_likely(binop(mode64 ? Iop_CmpNE64 : Iop_CmpNE32,
32089                      binop(mode64 ? Iop_And64 : Iop_And32, getIReg(rs),
32090                      mode64 ? mkU64(0x8000000000000000ULL) : mkU32(0x80000000)),
32091                      mode64 ? mkU64(0x8000000000000000ULL) : mkU32(0x80000000)),
32092                      imm);
32093          break;
32094 
32095       case 0x11:  /* BGEZAL */
32096          DIP("bgezal r%u, %u", rs, imm);
32097          if (mode64) {
32098             if (!dis_instr_branch(cins, &dres, resteerOkFn,
32099                         callback_opaque, &bstmt))
32100                goto decode_failure;
32101          } else
32102             dis_branch(True, binop(Iop_CmpEQ32, binop(Iop_And32, getIReg(rs),
32103                        mkU32(0x80000000)), mkU32(0x0)), imm, &bstmt);
32104          break;
32105 
32106       case 0x13:  /* BGEZALL */
32107          DIP("bgezall r%u, %u", rs, imm);
32108          if (mode64) {
32109             putIReg(31, mkU64(guest_PC_curr_instr + 8));
32110             lastn = dis_branch_likely(binop(Iop_CmpNE64,
32111                                             binop(Iop_And64,
32112                                                   getIReg(rs),
32113                                                   mkU64(0x8000000000000000ULL)),
32114                                             mkU64(0x0)),
32115                                       imm);
32116          } else {
32117             putIReg(31, mkU32(guest_PC_curr_instr + 8));
32118             lastn = dis_branch_likely(binop(Iop_CmpNE32, binop(Iop_And32,
32119                                       getIReg(rs), mkU32(0x80000000)),
32120                                       mkU32(0x0)), imm);
32121          }
32122          break;
32123 
32124       case 0x08:  /* TGEI */
32125          DIP("tgei r%u, %u %u", rs, imm, trap_code);
32126          if (mode64) {
32127             stmt (IRStmt_Exit(unop(Iop_Not1,
32128                                    binop(Iop_CmpLT64S,
32129                                          getIReg(rs),
32130                                          mkU64(extend_s_16to64 (imm)))),
32131                              Ijk_SigTRAP,
32132                              IRConst_U64(guest_PC_curr_instr + 4),
32133                              OFFB_PC));
32134          } else {
32135             stmt (IRStmt_Exit(unop(Iop_Not1,
32136                                    binop(Iop_CmpLT32S,
32137                                    getIReg(rs),
32138                                    mkU32(extend_s_16to32 (imm)))),
32139                              Ijk_SigTRAP,
32140                              IRConst_U32(guest_PC_curr_instr + 4),
32141                              OFFB_PC));
32142          }
32143          break;
32144 
32145       case 0x09: {  /* TGEIU */
32146          DIP("tgeiu r%u, %u %u", rs, imm, trap_code);
32147          if (mode64) {
32148             stmt (IRStmt_Exit (unop (Iop_Not1,
32149                                      binop (Iop_CmpLT64U,
32150                                             getIReg (rs),
32151                                             mkU64 (extend_s_16to64 (imm)))),
32152                              Ijk_SigTRAP,
32153                              IRConst_U64(guest_PC_curr_instr + 4),
32154                              OFFB_PC));
32155          } else {
32156             stmt (IRStmt_Exit (unop (Iop_Not1,
32157                                      binop (Iop_CmpLT32U,
32158                                             getIReg (rs),
32159                                             mkU32 (extend_s_16to32 (imm)))),
32160                                Ijk_SigTRAP,
32161                                IRConst_U32(guest_PC_curr_instr + 4),
32162                                OFFB_PC));
32163          }
32164          break;
32165       }
32166       case 0x0A: {  /* TLTI */
32167          DIP("tlti r%u, %u %u", rs, imm, trap_code);
32168          if (mode64) {
32169             stmt (IRStmt_Exit (binop (Iop_CmpLT64S, getIReg (rs),
32170                                       mkU64 (extend_s_16to64 (imm))),
32171                              Ijk_SigTRAP,
32172                              IRConst_U64(guest_PC_curr_instr + 4),
32173                              OFFB_PC));
32174          } else {
32175             stmt (IRStmt_Exit (binop (Iop_CmpLT32S, getIReg (rs),
32176                                       mkU32 (extend_s_16to32 (imm))),
32177                                Ijk_SigTRAP,
32178                                IRConst_U32(guest_PC_curr_instr + 4),
32179                                OFFB_PC));
32180          }
32181          break;
32182       }
32183       case 0x0B: {  /* TLTIU */
32184          DIP("tltiu r%u, %u %u", rs, imm, trap_code);
32185          if (mode64) {
32186             stmt (IRStmt_Exit (binop (Iop_CmpLT64U, getIReg (rs),
32187                                       mkU64 (extend_s_16to64 (imm))),
32188                              Ijk_SigTRAP,
32189                              IRConst_U64(guest_PC_curr_instr + 4),
32190                              OFFB_PC));
32191          } else {
32192             stmt (IRStmt_Exit (binop (Iop_CmpLT32U, getIReg (rs),
32193                                       mkU32 (extend_s_16to32 (imm))),
32194                                Ijk_SigTRAP,
32195                                IRConst_U32(guest_PC_curr_instr + 4),
32196                                OFFB_PC));
32197          }
32198          break;
32199       }
32200       case 0x0C: {  /* TEQI */
32201           DIP("teqi r%u, %u %u", rs, imm, trap_code);
32202          if (mode64) {
32203             stmt (IRStmt_Exit (binop (Iop_CmpEQ64, getIReg (rs),
32204                                       mkU64 (extend_s_16to64 (imm))),
32205                                Ijk_SigTRAP,
32206                                IRConst_U64(guest_PC_curr_instr + 4),
32207                                OFFB_PC));
32208          } else {
32209             stmt (IRStmt_Exit (binop (Iop_CmpEQ32, getIReg (rs),
32210                                       mkU32 (extend_s_16to32 (imm))),
32211                                Ijk_SigTRAP,
32212                                IRConst_U32(guest_PC_curr_instr + 4),
32213                                OFFB_PC));
32214          }
32215          break;
32216       }
32217       case 0x0E: {  /* TNEI */
32218          DIP("tnei r%u, %u %u", rs, imm, trap_code);
32219          if (mode64) {
32220             stmt (IRStmt_Exit (binop (Iop_CmpNE64, getIReg (rs),
32221                                       mkU64 (extend_s_16to64 (imm))),
32222                                Ijk_SigTRAP,
32223                                IRConst_U64(guest_PC_curr_instr + 4),
32224                                OFFB_PC));
32225          } else {
32226             stmt (IRStmt_Exit (binop (Iop_CmpNE32, getIReg (rs),
32227                                       mkU32 (extend_s_16to32 (imm))),
32228                                Ijk_SigTRAP,
32229                                IRConst_U32(guest_PC_curr_instr + 4),
32230                                OFFB_PC));
32231          }
32232          break;
32233       }
32234       case 0x1C: {  /* BPOSGE32 */
32235          DIP("bposge32 %u", imm);
32236          vassert(!mode64);
32237          t0 = newTemp(Ity_I32);
32238          /* Get pos field from DSPControl register. */
32239          assign(t0, binop(Iop_And32, getDSPControl(), mkU32(0x3f)));
32240          dis_branch(False, unop(Iop_Not1, binop(Iop_CmpLT32U, mkexpr(t0),
32241                                 mkU32(32))), imm, &bstmt);
32242       }
32243       case 0x1F:
32244          /* SYNCI */
32245          /* Just ignore it */
32246          break;
32247 
32248       case 0x06: { /* DAHI */
32249          if (VEX_MIPS_CPU_HAS_MIPSR6(archinfo->hwcaps)) {
32250             DIP("dahi  r%u,  %x", rs, imm);
32251             putIReg(rs, binop(Iop_Add64,
32252                               getIReg(rs), mkU64(extend_s_16to64 (imm) << 32)));
32253          } else {
32254             ILLEGAL_INSTRUCTON;
32255          }
32256          break;
32257       }
32258 
32259       case 0x1E: { /* DATI */
32260          if (VEX_MIPS_CPU_HAS_MIPSR6(archinfo->hwcaps)) {
32261             DIP("dati  r%u,  %x", rs, imm);
32262             putIReg(rs, binop(Iop_Add64,
32263                               getIReg(rs), mkU64((long long)imm << 48)));
32264          } else {
32265             ILLEGAL_INSTRUCTON;
32266          }
32267          break;
32268       }
32269 
32270       default:
32271          goto decode_failure;
32272       }
32273       break;
32274 
32275    case 0x04:
32276       DIP("beq r%u, r%u, %u", rs, rt, imm);
32277       if (mode64)
32278          dis_branch(False, binop(Iop_CmpEQ64, getIReg(rs), getIReg(rt)),
32279                                  imm, &bstmt);
32280       else
32281          dis_branch(False, binop(Iop_CmpEQ32, getIReg(rs), getIReg(rt)),
32282                                  imm, &bstmt);
32283       break;
32284 
32285    case 0x14:
32286       DIP("beql r%u, r%u, %u", rs, rt, imm);
32287       lastn = dis_branch_likely(binop(mode64 ? Iop_CmpNE64 : Iop_CmpNE32,
32288                                 getIReg(rs), getIReg(rt)), imm);
32289       break;
32290 
32291    case 0x05:
32292       DIP("bne r%u, r%u, %u", rs, rt, imm);
32293       if (mode64)
32294          dis_branch(False, binop(Iop_CmpNE64, getIReg(rs), getIReg(rt)),
32295                                  imm, &bstmt);
32296       else
32297          dis_branch(False, binop(Iop_CmpNE32, getIReg(rs), getIReg(rt)),
32298                                  imm, &bstmt);
32299       break;
32300 
32301    case 0x15:
32302       DIP("bnel r%u, r%u, %u", rs, rt, imm);
32303       lastn = dis_branch_likely(binop(mode64 ? Iop_CmpEQ64 : Iop_CmpEQ32,
32304                                       getIReg(rs), getIReg(rt)), imm);
32305       break;
32306 
32307    case 0x07:  /* BGTZ, BGTZALC, BLTZALC, BLTUC */
32308       if (rt == 0) { /* BGTZ */
32309          DIP("bgtz r%u, %u", rs, imm);
32310          if (mode64)
32311             dis_branch(False, unop(Iop_Not1, binop(Iop_CmpLE64S, getIReg(rs),
32312                                    mkU64(0x00))), imm, &bstmt);
32313          else
32314             dis_branch(False, unop(Iop_Not1, binop(Iop_CmpLE32S, getIReg(rs),
32315                                    mkU32(0x00))), imm, &bstmt);
32316       } else if (VEX_MIPS_CPU_HAS_MIPSR6(archinfo->hwcaps)) {
32317          if (rs == 0) { /* BGTZALC */
32318             DIP("bgtzalc r%u, %u", rt, imm);
32319             if (mode64) {
32320                dis_branch_compact(True,
32321                                   unop(Iop_Not1,
32322                                        binop(Iop_CmpLE64S,
32323                                              getIReg(rt), mkU64(0x0))),
32324                                   imm, &dres);
32325             } else {
32326                dis_branch_compact(True,
32327                                   unop(Iop_Not1,
32328                                        binop(Iop_CmpLE32S,
32329                                              getIReg(rt), mkU32(0x0))),
32330                                   imm, &dres);
32331             }
32332          } else if (rs == rt) { /* BLTZALC */
32333             DIP("bltzalc r%u, %u", rt, imm);
32334             if (mode64) {
32335                dis_branch_compact(True,
32336                                   unop(Iop_Not1,
32337                                        binop(Iop_CmpLE64S,
32338                                              mkU64(0x0), getIReg(rt))),
32339                                   imm, &dres);
32340             } else {
32341                dis_branch_compact(True,
32342                                   unop(Iop_Not1,
32343                                        binop(Iop_CmpLE32S,
32344                                              mkU32(0x0), getIReg(rt))),
32345                                   imm, &dres);
32346             }
32347          } else { /* BLTUC */
32348             DIP("bltuc r%u, r%u, %u", rt, rs, imm);
32349             if (mode64) {
32350                dis_branch_compact(False,
32351                                   binop(Iop_CmpLT64U, getIReg(rs), getIReg(rt)),
32352                                   imm, &dres);
32353             } else {
32354                dis_branch_compact(False,
32355                                   binop(Iop_CmpLT32U, getIReg(rs), getIReg(rt)),
32356                                   imm, &dres);
32357             }
32358          }
32359       } else {
32360          ILLEGAL_INSTRUCTON;
32361       }
32362       break;
32363 
32364    case 0x17:  /* BGTZL, BGTZC, BLTZC, BLTC */
32365       if (rt == 0) { /* BGTZL */
32366          DIP("bgtzl r%u, %u", rs, imm);
32367          if (mode64)
32368             lastn = dis_branch_likely(binop(Iop_CmpLE64S, getIReg(rs),
32369                                             mkU64(0x00)), imm);
32370          else
32371             lastn = dis_branch_likely(binop(Iop_CmpLE32S, getIReg(rs),
32372                                             mkU32(0x00)), imm);
32373       } else if (VEX_MIPS_CPU_HAS_MIPSR6(archinfo->hwcaps)) {
32374          if (rs == 0) { /* BGTZC */
32375             DIP("bgtzc r%u, %u", rt, imm);
32376             if (mode64) {
32377                dis_branch_compact(False,
32378                                   unop(Iop_Not1,
32379                                        binop(Iop_CmpLE64S,
32380                                              getIReg(rt), mkU64(0x0))),
32381                                   imm, &dres);
32382             } else {
32383                dis_branch_compact(False,
32384                                   unop(Iop_Not1,
32385                                        binop(Iop_CmpLE32S,
32386                                              getIReg(rt), mkU32(0x0))),
32387                                   imm, &dres);
32388             }
32389          } else if (rs == rt) { /* BLTZC */
32390             DIP("bltzc r%u, %u", rt, imm);
32391             if (mode64) {
32392                dis_branch_compact(False,
32393                                   unop(Iop_Not1,
32394                                        binop(Iop_CmpLE64S,
32395                                              mkU64(0x0), getIReg(rt))),
32396                                   imm, &dres);
32397             } else {
32398                dis_branch_compact(False,
32399                                   unop(Iop_Not1,
32400                                        binop(Iop_CmpLE32S,
32401                                              mkU32(0x0), getIReg(rt))),
32402                                   imm, &dres);
32403             }
32404          } else { /* BLTC */
32405             DIP("bltc r%u, r%u, %u", rs, rt, imm);
32406             if (mode64) {
32407                dis_branch_compact(False,
32408                                   unop(Iop_Not1,
32409                                        binop(Iop_CmpLE64S,
32410                                              getIReg(rt), getIReg(rs))),
32411                                   imm, &dres);
32412             } else {
32413                dis_branch_compact(False,
32414                                   unop(Iop_Not1,
32415                                        binop(Iop_CmpLE32S,
32416                                              getIReg(rt), getIReg(rs))),
32417                                   imm, &dres);
32418             }
32419          }
32420       } else {
32421          ILLEGAL_INSTRUCTON;
32422       }
32423       break;
32424 
32425    case 0x06:  /* BLEZ, BLEZALC, BGEZALC, BGEUC */
32426       if (rt == 0) { /* BLEZ */
32427          DIP("blez r%u, %u", rs, imm);
32428          if (mode64)
32429             dis_branch(False, binop(Iop_CmpLE64S, getIReg(rs), mkU64(0x0)),
32430                                    imm, &bstmt);
32431          else
32432             dis_branch(False, binop(Iop_CmpLE32S, getIReg(rs), mkU32(0x0)), imm,
32433                                    &bstmt);
32434       } else if (VEX_MIPS_CPU_HAS_MIPSR6(archinfo->hwcaps)) {
32435          if (rs == 0) { /* BLEZALC */
32436             DIP("blezalc r%u, %u", rt, imm);
32437             if (mode64)
32438                dis_branch_compact(True,
32439                                   binop(Iop_CmpLE64S, getIReg(rt), mkU64(0x0)),
32440                                   imm, &dres);
32441             else
32442                dis_branch_compact(True,
32443                                   binop(Iop_CmpLE32S, getIReg(rt), mkU32(0x0)),
32444                                   imm, &dres);
32445          } else if (rt == rs) {/* BGEZALC */
32446             DIP("bgezalc r%u, %u", rt, imm);
32447             if (mode64)
32448                dis_branch_compact(True,
32449                                   binop(Iop_CmpLE64S, mkU64(0x0), getIReg(rt)),
32450                                   imm, &dres);
32451             else
32452                dis_branch_compact(True,
32453                                   binop(Iop_CmpLE32S, mkU32(0x0), getIReg(rt)),
32454                                   imm, &dres);
32455          } else { /* BGEUC */
32456             DIP("bgeuc r%u, r%u, %u", rt, rs, imm);
32457             if (mode64)
32458                dis_branch_compact(False,
32459                                   unop(Iop_Not1,
32460                                        binop(Iop_CmpLT64U,
32461                                              getIReg(rs), getIReg(rt))),
32462                                   imm, &dres);
32463             else
32464                dis_branch_compact(False,
32465                                   unop(Iop_Not1,
32466                                        binop(Iop_CmpLT32U,
32467                                              getIReg(rs), getIReg(rt))),
32468                                   imm, &dres);
32469          }
32470       } else {
32471          ILLEGAL_INSTRUCTON;
32472       }
32473       break;
32474 
32475    case 0x16:  /* BLEZL, BLEZC, BGEZC, BGEC */
32476       if (rt == 0) { /* BLEZL */
32477          DIP("blezl r%u, %u", rs, imm);
32478          lastn = dis_branch_likely(unop(Iop_Not1, (binop(mode64 ? Iop_CmpLE64S :
32479                                         Iop_CmpLE32S, getIReg(rs), mode64 ?
32480                                         mkU64(0x0) : mkU32(0x0)))), imm);
32481       } else if (VEX_MIPS_CPU_HAS_MIPSR6(archinfo->hwcaps)) {
32482           if (rs == 0) { /* BLEZC */
32483             DIP("blezc r%u, %u", rt, imm);
32484             if (mode64) {
32485                dis_branch_compact(False,
32486                                   binop(Iop_CmpLE64S, getIReg(rt), mkU64(0x0)),
32487                                   imm, &dres);
32488             } else {
32489                dis_branch_compact(False,
32490                                   binop(Iop_CmpLE32S, getIReg(rt), mkU32(0x0)),
32491                                   imm, &dres);
32492             }
32493          } else if (rt == rs) { /* BGEZC */
32494             DIP("bgezc r%u, %u", rt, imm);
32495             if (mode64) {
32496                dis_branch_compact(False,
32497                                   binop(Iop_CmpLE64S, mkU64(0x0), getIReg(rt)),
32498                                   imm, &dres);
32499             } else {
32500                dis_branch_compact(False,
32501                                   binop(Iop_CmpLE32S, mkU32(0x0), getIReg(rt)),
32502                                   imm, &dres);
32503             }
32504          } else { /* BGEC */
32505             DIP("bgec r%u, r%u, %u", rs, rt, imm);
32506             if (mode64) {
32507                dis_branch_compact(False,
32508                                   binop(Iop_CmpLE64S, getIReg(rt), getIReg(rs)),
32509                                   imm, &dres);
32510             } else {
32511                dis_branch_compact(False,
32512                                   binop(Iop_CmpLE32S, getIReg(rt), getIReg(rs)),
32513                                   imm, &dres);
32514             }
32515          }
32516       } else {
32517          ILLEGAL_INSTRUCTON;
32518       }
32519       break;
32520 
32521 #if defined(__mips__) && ((defined(__mips_isa_rev) && __mips_isa_rev < 6))
32522    case 0x08: {  /* ADDI */
32523       DIP("addi r%u, r%u, %u", rt, rs, imm);
32524       IRTemp tmpRs32 = newTemp(Ity_I32);
32525       assign(tmpRs32, mkNarrowTo32(ty, getIReg(rs)));
32526 
32527       t0 = newTemp(Ity_I32);
32528       t1 = newTemp(Ity_I32);
32529       t2 = newTemp(Ity_I32);
32530       t3 = newTemp(Ity_I32);
32531       t4 = newTemp(Ity_I32);
32532       /* dst = src0 + sign(imm)
32533          if(sign(src0 ) != sign(imm ))
32534          goto no overflow;
32535          if(sign(dst) == sign(src0 ))
32536          goto no overflow;
32537          we have overflow! */
32538 
32539       assign(t0, binop(Iop_Add32, mkexpr(tmpRs32),
32540                        mkU32(extend_s_16to32(imm))));
32541       assign(t1, binop(Iop_Xor32, mkexpr(tmpRs32),
32542                        mkU32(extend_s_16to32(imm))));
32543       assign(t2, unop(Iop_1Sto32, binop(Iop_CmpEQ32, binop(Iop_And32,
32544                       mkexpr(t1), mkU32(0x80000000)), mkU32(0x80000000))));
32545 
32546       assign(t3, binop(Iop_Xor32, mkexpr(t0), mkexpr(tmpRs32)));
32547       assign(t4, unop(Iop_1Sto32, binop(Iop_CmpNE32, binop(Iop_And32,
32548                       mkexpr(t3), mkU32(0x80000000)), mkU32(0x80000000))));
32549 
32550       stmt(IRStmt_Exit(binop(Iop_CmpEQ32, binop(Iop_Or32, mkexpr(t2),
32551                              mkexpr(t4)), mkU32(0)), Ijk_SigFPE_IntOvf,
32552                        mode64 ? IRConst_U64(guest_PC_curr_instr + 4) :
32553                                 IRConst_U32(guest_PC_curr_instr + 4),
32554                        OFFB_PC));
32555 
32556       putIReg(rt,  mkWidenFrom32(ty, mkexpr(t0), True));
32557       break;
32558    }
32559 #elif defined(__mips__) && ((defined(__mips_isa_rev) && __mips_isa_rev >= 6))
32560    case 0x08: { /* BEQZALC, BEQC, BOVC */
32561       if (rs == 0) { /* BEQZALC */
32562          DIP("beqzalc r%u, %u", rt, imm);
32563          if (mode64) {
32564             dis_branch_compact(True,
32565                                binop(Iop_CmpEQ64, getIReg(rt), mkU64(0x0)),
32566                                imm, &dres);
32567          } else {
32568             dis_branch_compact(True,
32569                                binop(Iop_CmpEQ32, getIReg(rt), mkU32(0x0)),
32570                                imm, &dres);
32571          }
32572       } else  if (rs < rt) { /* BEQC */
32573          DIP("beqc r%u, r%u, %u",rs, rt, imm);
32574          if (mode64) {
32575             dis_branch_compact(False,
32576                                binop(Iop_CmpEQ64, getIReg(rt), getIReg(rs)),
32577                                imm, &dres);
32578          } else {
32579             dis_branch_compact(False,
32580                                binop(Iop_CmpEQ32, getIReg(rt), getIReg(rs)),
32581                                imm, &dres);
32582          }
32583       } else { /* BOVC */
32584          DIP("bovc r%u, r%u, %u",rs, rt, imm);
32585          if (mode64) {
32586             t0 = newTemp(Ity_I32);
32587             t1 = newTemp(Ity_I32);
32588             t2 = newTemp(Ity_I32);
32589             t3 = newTemp(Ity_I32);
32590             assign(t0, IRExpr_ITE(binop(Iop_CmpLT64S,
32591                                         getIReg(rt),
32592                                         mkU64(0xffffffff80000000ULL)),
32593                                   mkU32(1),
32594                                   IRExpr_ITE(binop(Iop_CmpLT64S,
32595                                                    getIReg(rt),
32596                                                    mkU64(0x7FFFFFFFULL)),
32597                                              mkU32(0),mkU32(1))));
32598             assign(t1, IRExpr_ITE(binop(Iop_CmpLT64S,
32599                                         getIReg(rs),
32600                                         mkU64(0xffffffff80000000ULL)),
32601                                   mkU32(1),
32602                                   IRExpr_ITE(binop(Iop_CmpLT64S,
32603                                                    getIReg(rs),
32604                                                    mkU64(0x7FFFFFFFULL)),
32605                                              mkU32(0), mkU32(1))));
32606             assign(t2, IRExpr_ITE(binop(Iop_CmpLT64S,
32607                                         binop(Iop_Add64,
32608                                               getIReg(rt), getIReg(rs)),
32609                                         mkU64(0xffffffff80000000ULL)),
32610                                   mkU32(1),
32611                                   IRExpr_ITE(binop(Iop_CmpLT64S,
32612                                                    binop(Iop_Add64,
32613                                                          getIReg(rt),
32614                                                          getIReg(rs)),
32615                                                    mkU64(0x7FFFFFFFULL)),
32616                                              mkU32(0), mkU32(1))));
32617             assign(t3, binop(Iop_Add32,
32618                              mkexpr(t0),
32619                              binop(Iop_Add32, mkexpr(t1), mkexpr(t2))));
32620             dis_branch_compact(False,
32621                                binop(Iop_CmpNE32, mkexpr(t3), mkU32(0)),
32622                                imm, &dres);
32623          } else {
32624             IRTemp tmpRs32 = newTemp(Ity_I32);
32625             IRTemp tmpRt32 = newTemp(Ity_I32);
32626             assign(tmpRs32, getIReg(rs));
32627             assign(tmpRt32, getIReg(rt));
32628 
32629             t0 = newTemp(Ity_I32);
32630             t1 = newTemp(Ity_I32);
32631             t2 = newTemp(Ity_I32);
32632             t3 = newTemp(Ity_I32);
32633             t4 = newTemp(Ity_I32);
32634             /* dst = src0 + src1
32635                if (sign(src0 ) != sign(src1 ))
32636                goto no overflow;
32637                if (sign(dst) == sign(src0 ))
32638                goto no overflow;
32639                we have overflow! */
32640 
32641             assign(t0, binop(Iop_Add32, mkexpr(tmpRs32), mkexpr(tmpRt32)));
32642             assign(t1, binop(Iop_Xor32, mkexpr(tmpRs32), mkexpr(tmpRt32)));
32643             assign(t2, unop(Iop_1Uto32,
32644                             binop(Iop_CmpEQ32,
32645                                   binop(Iop_And32, mkexpr(t1), mkU32(0x80000000)),
32646                                   mkU32(0x80000000))));
32647 
32648             assign(t3, binop(Iop_Xor32, mkexpr(t0), mkexpr(tmpRs32)));
32649             assign(t4, unop(Iop_1Uto32,
32650                             binop(Iop_CmpNE32,
32651                                   binop(Iop_And32, mkexpr(t3), mkU32(0x80000000)),
32652                                   mkU32(0x80000000))));
32653 
32654             dis_branch_compact(False, binop(Iop_CmpEQ32,
32655                                    binop(Iop_Or32, mkexpr(t2), mkexpr(t4)),
32656                                    mkU32(0)), imm, &dres);
32657          }
32658       }
32659       break;
32660       /* In documentation for BEQC stands rs > rt and for BOVC stands rs >= rt! */
32661    }
32662 #endif
32663 
32664    case 0x09:  /* ADDIU */
32665       DIP("addiu r%u, r%u, %u", rt, rs, imm);
32666       if (mode64) {
32667          putIReg(rt, mkWidenFrom32(ty, binop(Iop_Add32,
32668                      mkNarrowTo32(ty, getIReg(rs)),mkU32(extend_s_16to32(imm))),
32669                      True));
32670       } else
32671          putIReg(rt, binop(Iop_Add32, getIReg(rs),mkU32(extend_s_16to32(imm))));
32672       break;
32673    case 0x0C:  /* ANDI */
32674       DIP("andi r%u, r%u, %u", rt, rs, imm);
32675       if (mode64) {
32676          ALUI_PATTERN64(Iop_And64);
32677       } else {
32678          ALUI_PATTERN(Iop_And32);
32679       }
32680       break;
32681 
32682    case 0x0E:  /* XORI */
32683       DIP("xori r%u, r%u, %u", rt, rs, imm);
32684       if (mode64) {
32685          ALUI_PATTERN64(Iop_Xor64);
32686       } else {
32687          ALUI_PATTERN(Iop_Xor32);
32688       }
32689       break;
32690 
32691    case 0x0D:  /* ORI */
32692       DIP("ori r%u, r%u, %u", rt, rs, imm);
32693       if (mode64) {
32694          ALUI_PATTERN64(Iop_Or64);
32695       } else {
32696          ALUI_PATTERN(Iop_Or32);
32697       }
32698       break;
32699 
32700    case 0x0A:  /* SLTI */
32701       DIP("slti r%u, r%u, %u", rt, rs, imm);
32702       if (mode64)
32703          putIReg(rt, unop(Iop_1Uto64, binop(Iop_CmpLT64S, getIReg(rs),
32704                                             mkU64(extend_s_16to64(imm)))));
32705       else
32706          putIReg(rt, unop(Iop_1Uto32, binop(Iop_CmpLT32S, getIReg(rs),
32707                                             mkU32(extend_s_16to32(imm)))));
32708       break;
32709 
32710    case 0x0B:  /* SLTIU */
32711       DIP("sltiu r%u, r%u, %u", rt, rs, imm);
32712       if (mode64)
32713          putIReg(rt, unop(Iop_1Uto64, binop(Iop_CmpLT64U, getIReg(rs),
32714                                             mkU64(extend_s_16to64(imm)))));
32715       else
32716          putIReg(rt, unop(Iop_1Uto32, binop(Iop_CmpLT32U, getIReg(rs),
32717                                             mkU32(extend_s_16to32(imm)))));
32718       break;
32719 
32720 #if defined(__mips__) && ((defined(__mips_isa_rev) && __mips_isa_rev < 6))
32721    case 0x18: {  /* Doubleword Add Immidiate - DADDI; MIPS64 */
32722       DIP("daddi r%u, r%u, %u", rt, rs, imm);
32723       IRTemp tmpRs64 = newTemp(Ity_I64);
32724       assign(tmpRs64, getIReg(rs));
32725 
32726       t0 = newTemp(Ity_I64);
32727       t1 = newTemp(Ity_I64);
32728       t2 = newTemp(Ity_I64);
32729       t3 = newTemp(Ity_I64);
32730       t4 = newTemp(Ity_I64);
32731       /* dst = src0 + sign(imm)
32732          if(sign(src0 ) != sign(imm ))
32733          goto no overflow;
32734          if(sign(dst) == sign(src0 ))
32735          goto no overflow;
32736          we have overflow! */
32737 
32738       assign(t0, binop(Iop_Add64, mkexpr(tmpRs64),
32739                        mkU64(extend_s_16to64(imm))));
32740       assign(t1, binop(Iop_Xor64, mkexpr(tmpRs64),
32741                        mkU64(extend_s_16to64(imm))));
32742       assign(t2, unop(Iop_1Sto64, binop(Iop_CmpEQ64, binop(Iop_And64,
32743                       mkexpr(t1), mkU64(0x8000000000000000ULL)),
32744                                         mkU64(0x8000000000000000ULL))));
32745 
32746       assign(t3, binop(Iop_Xor64, mkexpr(t0), mkexpr(tmpRs64)));
32747       assign(t4, unop(Iop_1Sto64, binop(Iop_CmpNE64, binop(Iop_And64,
32748                       mkexpr(t3), mkU64(0x8000000000000000ULL)),
32749                                         mkU64(0x8000000000000000ULL))));
32750 
32751       stmt(IRStmt_Exit(binop(Iop_CmpEQ64, binop(Iop_Or64, mkexpr(t2),
32752                              mkexpr(t4)), mkU64(0)), Ijk_SigFPE_IntOvf,
32753                        IRConst_U64(guest_PC_curr_instr + 4),
32754                        OFFB_PC));
32755 
32756       putIReg(rt,  mkexpr(t0));
32757       break;
32758    }
32759 #elif defined(__mips__) && ((defined(__mips_isa_rev) && __mips_isa_rev >= 6))
32760    case 0x18: { /* BNEZALC, BNEC, BNVC */
32761       if (rs == 0) { /* BNEZALC */
32762          DIP("bnezalc r%u, %u", rt, imm);
32763          if (mode64) {
32764             dis_branch_compact(True,
32765                                unop(Iop_Not1,
32766                                     binop(Iop_CmpEQ64, getIReg(rt), mkU64(0x0))),
32767                                imm, &dres);
32768          } else {
32769             dis_branch_compact(True,
32770                                unop(Iop_Not1,
32771                                     binop(Iop_CmpEQ32, getIReg(rt), mkU32(0x0))),
32772                                imm, &dres);
32773          }
32774       } else if (rs < rt) { /* BNEC */
32775          DIP("bnec r%u, %u", rt, imm);
32776          if (mode64) {
32777             dis_branch_compact(False,
32778                                unop(Iop_Not1,
32779                                     binop(Iop_CmpEQ64,
32780                                           getIReg(rt), getIReg(rs))),
32781                                imm, &dres);
32782          } else {
32783             dis_branch_compact(False,
32784                                unop(Iop_Not1,
32785                                     binop(Iop_CmpEQ32,
32786                                           getIReg(rt), getIReg(rs))),
32787                                imm, &dres);
32788          }
32789       } else { /* BNVC */
32790          DIP("bnvc r%u, r%u, %u", rs, rt, imm);
32791          if (mode64) {
32792             t0 = newTemp(Ity_I32);
32793             t1 = newTemp(Ity_I32);
32794             t2 = newTemp(Ity_I32);
32795             t3 = newTemp(Ity_I32);
32796             assign(t0, IRExpr_ITE(binop(Iop_CmpLT64S,
32797                                         getIReg(rt),
32798                                         mkU64(0xffffffff80000000ULL)),
32799                                   mkU32(1),
32800                                   IRExpr_ITE(binop(Iop_CmpLT64S,
32801                                                    getIReg(rt),
32802                                                    mkU64(0x7FFFFFFFULL)),
32803                                              mkU32(0),mkU32(1))));
32804             assign(t1, IRExpr_ITE(binop(Iop_CmpLT64S,
32805                                         getIReg(rs),
32806                                         mkU64(0xffffffff80000000ULL)),
32807                                   mkU32(1),
32808                                   IRExpr_ITE(binop(Iop_CmpLT64S,
32809                                                    getIReg(rs),
32810                                                    mkU64(0x7FFFFFFFULL)),
32811                                              mkU32(0),mkU32(1))));
32812             assign(t2, IRExpr_ITE(binop(Iop_CmpLT64S,
32813                                         binop(Iop_Add64,
32814                                               getIReg(rt), getIReg(rs)),
32815                                         mkU64(0xffffffff80000000ULL)),
32816                                   mkU32(1),
32817                                   IRExpr_ITE(binop(Iop_CmpLT64S,
32818                                                    binop(Iop_Add64,
32819                                                          getIReg(rt),
32820                                                          getIReg(rs)),
32821                                                    mkU64(0x7FFFFFFFULL)),
32822                                              mkU32(0),mkU32(1))));
32823             assign(t3, binop(Iop_Add32,
32824                              mkexpr(t0),
32825                              binop(Iop_Add32, mkexpr(t1), mkexpr(t2))));
32826             dis_branch_compact(False,
32827                                binop(Iop_CmpEQ32, mkexpr(t3), mkU32(0)),
32828                                imm, &dres);
32829          } else {
32830             IRTemp tmpRs32 = newTemp(Ity_I32);
32831             IRTemp tmpRt32 = newTemp(Ity_I32);
32832 
32833             assign(tmpRs32, getIReg(rs));
32834             assign(tmpRt32, getIReg(rt));
32835             t0 = newTemp(Ity_I32);
32836             t1 = newTemp(Ity_I32);
32837             t2 = newTemp(Ity_I32);
32838             t3 = newTemp(Ity_I32);
32839             t4 = newTemp(Ity_I32);
32840             /* dst = src0 + src1
32841                if (sign(src0 ) != sign(src1 ))
32842                goto no overflow;
32843                if (sign(dst) == sign(src0 ))
32844                goto no overflow;
32845                we have overflow! */
32846 
32847             assign(t0, binop(Iop_Add32, mkexpr(tmpRs32), mkexpr(tmpRt32)));
32848             assign(t1, binop(Iop_Xor32, mkexpr(tmpRs32), mkexpr(tmpRt32)));
32849             assign(t2, unop(Iop_1Uto32,
32850                             binop(Iop_CmpEQ32,
32851                                   binop(Iop_And32, mkexpr(t1), mkU32(0x80000000)),
32852                                   mkU32(0x80000000))));
32853 
32854             assign(t3, binop(Iop_Xor32, mkexpr(t0), mkexpr(tmpRs32)));
32855             assign(t4, unop(Iop_1Uto32,
32856                             binop(Iop_CmpNE32,
32857                                   binop(Iop_And32, mkexpr(t3), mkU32(0x80000000)),
32858                                   mkU32(0x80000000))));
32859 
32860             dis_branch_compact(False, binop(Iop_CmpNE32 ,
32861                                    binop(Iop_Or32, mkexpr(t2), mkexpr(t4)),
32862                                    mkU32(0)), imm, &dres);
32863          }
32864       }
32865       break;
32866    }
32867 #endif
32868 
32869    case 0x19:  /* Doubleword Add Immidiate Unsigned - DADDIU; MIPS64 */
32870       DIP("daddiu r%u, r%u, %u", rt, rs, imm);
32871       putIReg(rt, binop(Iop_Add64, getIReg(rs), mkU64(extend_s_16to64(imm))));
32872       break;
32873 
32874    case 0x1A: {
32875       /* Load Doubleword Left - LDL; MIPS64 */
32876       vassert(mode64);
32877       DIP("ldl r%u, %u(r%u)", rt, imm, rs);
32878       /* t1 = addr */
32879 #if defined (_MIPSEL)
32880       t1 = newTemp(Ity_I64);
32881       assign(t1, binop(Iop_Add64, getIReg(rs), mkU64(extend_s_16to64(imm))));
32882 #elif defined (_MIPSEB)
32883       t1 = newTemp(Ity_I64);
32884       assign(t1, binop(Iop_Xor64, mkU64(0x7), binop(Iop_Add64, getIReg(rs),
32885                                   mkU64(extend_s_16to64(imm)))));
32886 #endif
32887       /* t2 = word addr */
32888       /* t4 = addr mod 8 */
32889       LWX_SWX_PATTERN64_1;
32890 
32891       /* t3 = word content - shifted */
32892       t3 = newTemp(Ity_I64);
32893       assign(t3, binop(Iop_Shl64, load(Ity_I64, mkexpr(t2)),
32894                  narrowTo(Ity_I8, binop(Iop_Shl64, binop(Iop_Sub64, mkU64(0x07),
32895                  mkexpr(t4)), mkU8(3)))));
32896 
32897       /* rt content  - adjusted */
32898       t5 = newTemp(Ity_I64);
32899       t6 = newTemp(Ity_I64);
32900       t7 = newTemp(Ity_I64);
32901 
32902       assign(t5, binop(Iop_Mul64, mkexpr(t4), mkU64(0x8)));
32903 
32904       assign(t6, binop(Iop_Shr64, mkU64(0x00FFFFFFFFFFFFFFULL),
32905                        narrowTo(Ity_I8, mkexpr(t5))));
32906 
32907       assign(t7, binop(Iop_And64, getIReg(rt), mkexpr(t6)));
32908 
32909       putIReg(rt, binop(Iop_Or64, mkexpr(t7), mkexpr(t3)));
32910       break;
32911    }
32912 
32913    case 0x1B: {
32914       /* Load Doubleword Right - LDR; MIPS64 */
32915       vassert(mode64);
32916       DIP("ldr r%u,%u(r%u)", rt, imm, rs);
32917       /* t1 = addr */
32918 #if defined (_MIPSEL)
32919       t1 = newTemp(Ity_I64);
32920       assign(t1, binop(Iop_Add64, getIReg(rs), mkU64(extend_s_16to64(imm))));
32921 #elif defined (_MIPSEB)
32922       t1 = newTemp(Ity_I64);
32923       assign(t1, binop(Iop_Xor64, mkU64(0x7), binop(Iop_Add64, getIReg(rs),
32924                                   mkU64(extend_s_16to64(imm)))));
32925 #endif
32926       /* t2 = word addr */
32927       /* t4 = addr mod 8 */
32928       LWX_SWX_PATTERN64_1;
32929 
32930       /* t3 = word content - shifted */
32931       t3 = newTemp(Ity_I64);
32932       assign(t3, binop(Iop_Shr64, load(Ity_I64, mkexpr(t2)),
32933                  narrowTo(Ity_I8, binop(Iop_Shl64, mkexpr(t4), mkU8(3)))));
32934 
32935       /* rt content  - adjusted */
32936       t5 = newTemp(Ity_I64);
32937       assign(t5, binop(Iop_And64, getIReg(rt), unop(Iop_Not64,
32938                  binop(Iop_Shr64, mkU64(0xFFFFFFFFFFFFFFFFULL),
32939                  narrowTo(Ity_I8, binop(Iop_Shl64, mkexpr(t4), mkU8(0x3)))))));
32940 
32941       putIReg(rt, binop(Iop_Or64, mkexpr(t5), mkexpr(t3)));
32942       break;
32943    }
32944 
32945    case 0x27:  /* Load Word unsigned - LWU; MIPS64 */
32946       DIP("lwu r%u,%u(r%u)", rt, imm, rs);
32947       LOAD_STORE_PATTERN;
32948 
32949       putIReg(rt, mkWidenFrom32(ty, load(Ity_I32, mkexpr(t1)), False));
32950       break;
32951 
32952    case 0x30:  /* LL */
32953       DIP("ll r%u, %u(r%u)", rt, imm, rs);
32954       LOAD_STORE_PATTERN;
32955       if (abiinfo->guest__use_fallback_LLSC) {
32956          t2 = newTemp(ty);
32957          assign(t2, mkWidenFrom32(ty, load(Ity_I32, mkexpr(t1)), True));
32958          putLLaddr(mkexpr(t1));
32959          putLLdata(mkexpr(t2));
32960          putIReg(rt, mkexpr(t2));
32961       } else {
32962          t2 = newTemp(Ity_I32);
32963          stmt(IRStmt_LLSC(MIPS_IEND, t2, mkexpr(t1), NULL));
32964          putIReg(rt, mkWidenFrom32(ty, mkexpr(t2), True));
32965       }
32966       break;
32967 
32968    case 0x34:  /* Load Linked Doubleword - LLD; MIPS64 */
32969       DIP("lld r%u, %u(r%u)", rt, imm, rs);
32970       if (mode64) {
32971          LOAD_STORE_PATTERN;
32972          t2 = newTemp(Ity_I64);
32973          if (abiinfo->guest__use_fallback_LLSC) {
32974             assign(t2, load(Ity_I64, mkexpr(t1)));
32975             putLLaddr(mkexpr(t1));
32976             putLLdata(mkexpr(t2));
32977          } else {
32978             stmt(IRStmt_LLSC(MIPS_IEND, t2, mkexpr(t1), NULL));
32979          }
32980          putIReg(rt, mkexpr(t2));
32981       } else {
32982          ILLEGAL_INSTRUCTON;
32983       }
32984       break;
32985 
32986    case 0x38:  /* SC */
32987       DIP("sc r%u, %u(r%u)", rt, imm, rs);
32988       t2 = newTemp(Ity_I1);
32989       LOAD_STORE_PATTERN;
32990       if (abiinfo->guest__use_fallback_LLSC) {
32991          t3 = newTemp(Ity_I32);
32992          assign(t2, binop(mode64 ? Iop_CmpNE64 : Iop_CmpNE32,
32993                           mkexpr(t1), getLLaddr()));
32994          assign(t3, mkNarrowTo32(ty, getIReg(rt)));
32995          putLLaddr(LLADDR_INVALID);
32996          putIReg(rt, getIReg(0));
32997 
32998          mips_next_insn_if(mkexpr(t2));
32999 
33000          t4 = newTemp(Ity_I32);
33001          t5 = newTemp(Ity_I32);
33002 
33003          assign(t5, mkNarrowTo32(ty, getLLdata()));
33004 
33005          stmt(IRStmt_CAS(mkIRCAS(IRTemp_INVALID, t4, /* old_mem */
33006               MIPS_IEND, mkexpr(t1),                 /* addr */
33007               NULL, mkexpr(t5),                      /* expected value */
33008               NULL, mkexpr(t3)                       /* new value */)));
33009 
33010          putIReg(rt, unop(mode64 ? Iop_1Uto64 : Iop_1Uto32,
33011                           binop(Iop_CmpEQ32, mkexpr(t4), mkexpr(t5))));
33012       } else {
33013          stmt(IRStmt_LLSC(MIPS_IEND, t2, mkexpr(t1),
33014                           mkNarrowTo32(ty, getIReg(rt))));
33015          putIReg(rt, unop(mode64 ? Iop_1Uto64 : Iop_1Uto32, mkexpr(t2)));
33016       }
33017       break;
33018 
33019    case 0x3C:  /* Store Conditional Doubleword - SCD; MIPS64 */
33020       DIP("scd r%u, %u(r%u)", rt, imm, rs);
33021       if (mode64) {
33022          t2 = newTemp(Ity_I1);
33023          LOAD_STORE_PATTERN;
33024          if (abiinfo->guest__use_fallback_LLSC) {
33025             t3 = newTemp(Ity_I64);
33026             assign(t2, binop(Iop_CmpNE64, mkexpr(t1), getLLaddr()));
33027             assign(t3, getIReg(rt));
33028             putLLaddr(LLADDR_INVALID);
33029             putIReg(rt, getIReg(0));
33030 
33031             mips_next_insn_if(mkexpr(t2));
33032 
33033             t4 = newTemp(Ity_I64);
33034             t5 = newTemp(Ity_I64);
33035 
33036             assign(t5, getLLdata());
33037 
33038             stmt(IRStmt_CAS(mkIRCAS(IRTemp_INVALID, t4, /* old_mem */
33039                  MIPS_IEND, mkexpr(t1),                 /* addr */
33040                  NULL, mkexpr(t5),                      /* expected value */
33041                  NULL, mkexpr(t3)                       /* new value */)));
33042 
33043             putIReg(rt, unop(Iop_1Uto64,
33044                              binop(Iop_CmpEQ64, mkexpr(t4), mkexpr(t5))));
33045          } else {
33046             stmt(IRStmt_LLSC(MIPS_IEND, t2, mkexpr(t1), getIReg(rt)));
33047             putIReg(rt, unop(Iop_1Uto64, mkexpr(t2)));
33048          }
33049       } else {
33050          ILLEGAL_INSTRUCTON;
33051       }
33052       break;
33053 
33054    case 0x37:  /* Load Doubleword - LD; MIPS64 */
33055       DIP("ld r%u, %u(r%u)", rt, imm, rs);
33056       LOAD_STORE_PATTERN;
33057       putIReg(rt, load(Ity_I64, mkexpr(t1)));
33058       break;
33059 
33060    case 0x3F:  /* Store Doubleword - SD; MIPS64 */
33061       DIP("sd r%u, %u(r%u)", rt, imm, rs);
33062       LOAD_STORE_PATTERN;
33063       store(mkexpr(t1), getIReg(rt));
33064       break;
33065 
33066    case 0x32:  /* Branch on Bit Clear - BBIT0; Cavium OCTEON */
33067       /* Cavium Specific instructions. */
33068       if (VEX_MIPS_COMP_ID(archinfo->hwcaps) == VEX_PRID_COMP_CAVIUM) {
33069          DIP("bbit0 r%u, 0x%x, %x", rs, rt, imm);
33070          t0 = newTemp(Ity_I32);
33071          t1 = newTemp(Ity_I32);
33072          assign(t0, mkU32(0x1));
33073          assign(t1, binop(Iop_Shl32, mkexpr(t0), mkU8(rt)));
33074          dis_branch(False, binop(Iop_CmpEQ32,
33075                                  binop(Iop_And32,
33076                                        mkexpr(t1),
33077                                        mkNarrowTo32(ty, getIReg(rs))),
33078                                  mkU32(0x0)),
33079                     imm, &bstmt);
33080       } else if (archinfo->hwcaps & VEX_MIPS_CPU_ISA_M32R6) { /* BC */
33081          if (VEX_MIPS_CPU_HAS_MIPSR6(archinfo->hwcaps)) {
33082             DIP("bc  %x", instr_index & 0x3FFFFFF);
33083             if (mode64) {
33084                t0 = newTemp(Ity_I64);
33085                assign(t0, mkU64(guest_PC_curr_instr +
33086                       ((extend_s_26to64(instr_index & 0x3FFFFFF) + 1 ) << 2)));
33087             } else {
33088                t0 = newTemp(Ity_I32);
33089                assign(t0, mkU32(guest_PC_curr_instr +
33090                       ((extend_s_26to32(instr_index & 0x3FFFFFF) + 1) << 2)));
33091             }
33092             putPC(mkexpr(t0));
33093             dres.whatNext = Dis_StopHere;
33094             dres.jk_StopHere = Ijk_Boring;
33095          } else {
33096             ILLEGAL_INSTRUCTON;
33097          }
33098       } else {
33099          goto decode_failure;
33100       }
33101       break;
33102    case 0x36:  /* Branch on Bit Clear Plus 32 - BBIT032; Cavium OCTEON */
33103       /* Cavium Specific instructions. */
33104       if (VEX_MIPS_COMP_ID(archinfo->hwcaps) == VEX_PRID_COMP_CAVIUM) {
33105          DIP("bbit032 r%u, 0x%x, %x", rs, rt, imm);
33106          t0 = newTemp(Ity_I64);
33107          t1 = newTemp(Ity_I8);  /* Shift. */
33108          t2 = newTemp(Ity_I64);
33109          assign(t0, mkU64(0x1));
33110          assign(t1, binop(Iop_Add8, mkU8(rt), mkU8(32)));
33111          assign(t2, binop(Iop_Shl64, mkexpr(t0), mkexpr(t1)));
33112          dis_branch(False, binop(Iop_CmpEQ64,
33113                                  binop(Iop_And64,
33114                                        mkexpr(t2),
33115                                        getIReg(rs)),
33116                                  mkU64(0x0)),
33117                     imm, &bstmt);
33118       } else if (VEX_MIPS_CPU_HAS_MIPSR6(archinfo->hwcaps)) {
33119          if (rs == 0) { /* JIC */
33120             DIP("jic r%u, %u", rt, instr_index & 0xFFFF);
33121             if (mode64) {
33122                t0 = newTemp(Ity_I64);
33123                assign(t0, binop(Iop_Add64, getIReg(rt),
33124                                 mkU64(extend_s_16to64((instr_index & 0xFFFF)))));
33125             } else {
33126                t0 = newTemp(Ity_I32);
33127                assign(t0, binop(Iop_Add32, getIReg(rt),
33128                                 mkU32(extend_s_16to32((instr_index & 0xFFFF)))));
33129             }
33130             putPC(mkexpr(t0));
33131             dres.whatNext = Dis_StopHere;
33132             dres.jk_StopHere = Ijk_Boring;
33133          } else { /* BEQZC */
33134             DIP("beqzc r%u, %u", rs, imm);
33135             dres.jk_StopHere = Ijk_Boring;
33136             dres.whatNext = Dis_StopHere;
33137             ULong branch_offset;
33138             t0 = newTemp(Ity_I1);
33139             if (mode64) {
33140                branch_offset = extend_s_23to64((instr_index& 0x1fffff) << 2);
33141                assign(t0, binop(Iop_CmpEQ64, getIReg(rs), mkU64(0x0)));
33142                stmt(IRStmt_Exit(mkexpr(t0), Ijk_Boring,
33143                                   IRConst_U64(guest_PC_curr_instr + 4 + branch_offset),
33144                                   OFFB_PC));
33145                putPC(mkU64(guest_PC_curr_instr + 4));
33146             } else {
33147                branch_offset = extend_s_23to32((instr_index& 0x1fffff) << 2);
33148                assign(t0, binop(Iop_CmpEQ32, getIReg(rs), mkU32(0x0)));
33149                stmt(IRStmt_Exit(mkexpr(t0), Ijk_Boring,
33150                                   IRConst_U32(guest_PC_curr_instr + 4 +
33151                                               (UInt) branch_offset), OFFB_PC));
33152                putPC(mkU32(guest_PC_curr_instr + 4));
33153             }
33154          }
33155       } else {
33156          ILLEGAL_INSTRUCTON;
33157       }
33158    break;
33159    case 0x3A:  /* Branch on Bit Set - BBIT1; Cavium OCTEON */
33160       /* Cavium Specific instructions. */
33161       if (VEX_MIPS_COMP_ID(archinfo->hwcaps) == VEX_PRID_COMP_CAVIUM) {
33162          DIP("bbit1 r%u, 0x%x, %x", rs, rt, imm);
33163          t0 = newTemp(Ity_I32);
33164          t1 = newTemp(Ity_I32);
33165          assign(t0, mkU32(0x1));
33166          assign(t1, binop(Iop_Shl32, mkexpr(t0), mkU8(rt)));
33167          dis_branch(False, binop(Iop_CmpNE32,
33168                                  binop(Iop_And32,
33169                                        mkexpr(t1),
33170                                        mkNarrowTo32(ty, getIReg(rs))),
33171                                  mkU32(0x0)),
33172                     imm, &bstmt);
33173       } else if (archinfo->hwcaps & VEX_MIPS_CPU_ISA_M32R6) {/* BALC */
33174          if (VEX_MIPS_CPU_HAS_MIPSR6(archinfo->hwcaps)) {
33175             DIP("balc  %x", instr_index & 0x3FFFFFF);
33176             if (mode64) {
33177                t0 = newTemp(Ity_I64);
33178                assign(t0, mkU64(guest_PC_curr_instr + ((extend_s_26to64(instr_index & 0x3FFFFFF)+1)<<2)));
33179                putIReg(31, mkU64(guest_PC_curr_instr + 4));
33180             } else {
33181                t0 = newTemp(Ity_I32);
33182                assign(t0, mkU32(guest_PC_curr_instr+((extend_s_26to32(instr_index & 0x3FFFFFF)+1)<<2)));
33183                putIReg(31, mkU32(guest_PC_curr_instr + 4));
33184             }
33185             putPC(mkexpr(t0));
33186             dres.whatNext = Dis_StopHere;
33187             dres.jk_StopHere = Ijk_Call;
33188          } else {
33189             ILLEGAL_INSTRUCTON;
33190          }
33191       } else {
33192          goto decode_failure;
33193       }
33194       break;
33195    case 0x3E:  /* Branch on Bit Set Plus 32 - BBIT132; Cavium OCTEON */
33196       /* Cavium Specific instructions. */
33197       if (VEX_MIPS_COMP_ID(archinfo->hwcaps) == VEX_PRID_COMP_CAVIUM) {
33198          DIP("bbit132 r%u, 0x%x, %x", rs, rt, imm);
33199          t0 = newTemp(Ity_I64);
33200          t1 = newTemp(Ity_I8);  /* Shift. */
33201          t2 = newTemp(Ity_I64);
33202          assign(t0, mkU64(0x1));
33203          assign(t1, binop(Iop_Add8, mkU8(rt), mkU8(32)));
33204          assign(t2, binop(Iop_Shl64, mkexpr(t0), mkexpr(t1)));
33205          dis_branch(False, binop(Iop_CmpNE64,
33206                                  binop(Iop_And64,
33207                                        mkexpr(t2),
33208                                        getIReg(rs)),
33209                                  mkU64(0x0)),
33210                     imm, &bstmt);
33211       } else if (VEX_MIPS_CPU_HAS_MIPSR6(archinfo->hwcaps)) {
33212          if (rs == 0) {/* JIALC */
33213             DIP("jialc r%u, %u", rt, instr_index & 0xFFFF);
33214             if (rs) goto decode_failure;
33215             if (mode64) {
33216                t0 = newTemp(Ity_I64);
33217                assign(t0, binop(Iop_Add64, getIReg(rt),
33218                                 mkU64(extend_s_16to64((instr_index & 0xFFFF)))));
33219                putIReg(31, mkU64(guest_PC_curr_instr + 4));
33220             } else {
33221                t0 = newTemp(Ity_I32);
33222                assign(t0, binop(Iop_Add32, getIReg(rt),
33223                                 mkU32(extend_s_16to32((instr_index & 0xFFFF)))));
33224                putIReg(31, mkU32(guest_PC_curr_instr + 4));
33225             }
33226             putPC(mkexpr(t0));
33227             dres.whatNext = Dis_StopHere;
33228             dres.jk_StopHere = Ijk_Call;
33229          } else { /* BNEZC */
33230             DIP("bnezc r%u, %u", rs, imm);
33231             dres.jk_StopHere = Ijk_Boring;
33232             dres.whatNext = Dis_StopHere;
33233             ULong branch_offset;
33234             t0 = newTemp(Ity_I1);
33235             if (mode64) {
33236                branch_offset = extend_s_23to64((instr_index& 0x1fffff) << 2);
33237                assign(t0, unop(Iop_Not1, binop(Iop_CmpEQ64, getIReg(rs), mkU64(0x0))));
33238                stmt(IRStmt_Exit(mkexpr(t0), Ijk_Boring,
33239                                   IRConst_U64(guest_PC_curr_instr + 4 + branch_offset),
33240                                   OFFB_PC));
33241                putPC(mkU64(guest_PC_curr_instr + 4));
33242             } else {
33243                branch_offset = extend_s_23to32((instr_index& 0x1fffff) << 2);
33244                assign(t0, unop(Iop_Not1, binop(Iop_CmpEQ32, getIReg(rs), mkU32(0x0))));
33245                stmt(IRStmt_Exit(mkexpr(t0), Ijk_Boring,
33246                                   IRConst_U32(guest_PC_curr_instr + 4 +
33247                                               (UInt) branch_offset), OFFB_PC));
33248                putPC(mkU32(guest_PC_curr_instr + 4));
33249             }
33250          }
33251       } else {
33252          goto decode_failure;
33253       }
33254       break;
33255 
33256    case 0x1D: /* DAUI */
33257       if (VEX_MIPS_CPU_HAS_MIPSR6(archinfo->hwcaps)) {
33258          DIP("daui  r%u, r%u, %x", rt, rs, imm);
33259          putIReg(rt, binop(Iop_Add64, getIReg(rs), mkU64(extend_s_32to64(imm << 16))));
33260       } else {
33261          ILLEGAL_INSTRUCTON;
33262       }
33263       break;
33264 
33265    case 0x1E: /* MIPS MSA (SIMD) */
33266       if (has_msa) {
33267          Int retVal = disMSAInstr_MIPS_WRK(cins);
33268          if (retVal == 0) {
33269             break;
33270          } else if (retVal == -2) {
33271             ILLEGAL_INSTRUCTON
33272             break;
33273          }
33274       }
33275       vex_printf("Error occured while trying to decode MIPS MSA "
33276                  "instruction.\nYour platform probably doesn't support "
33277                  "MIPS MSA (SIMD) ASE.\n");
33278 
33279    default:
33280       goto decode_failure;
33281 
33282    decode_failure_dsp:
33283       vex_printf("Error occured while trying to decode MIPS32 DSP "
33284                  "instruction.\nYour platform probably doesn't support "
33285                  "MIPS32 DSP ASE.\n");
33286    decode_failure:
33287       /* All decode failures end up here. */
33288       if (sigill_diag)
33289          vex_printf("vex mips->IR: unhandled instruction bytes: "
33290                     "0x%x 0x%x 0x%x 0x%x\n",
33291                     (UInt) getIByte(delta_start + 0),
33292                     (UInt) getIByte(delta_start + 1),
33293                     (UInt) getIByte(delta_start + 2),
33294                     (UInt) getIByte(delta_start + 3));
33295 
33296       /* Tell the dispatcher that this insn cannot be decoded, and so has
33297          not been executed, and (is currently) the next to be executed.
33298          EIP should be up-to-date since it made so at the start bnezof each
33299          insn, but nevertheless be paranoid and update it again right
33300          now. */
33301       if (mode64) {
33302          stmt(IRStmt_Put(offsetof(VexGuestMIPS64State, guest_PC),
33303               mkU64(guest_PC_curr_instr)));
33304          jmp_lit64(&dres, Ijk_NoDecode, guest_PC_curr_instr);
33305       } else {
33306          stmt(IRStmt_Put(offsetof(VexGuestMIPS32State, guest_PC),
33307               mkU32(guest_PC_curr_instr)));
33308          jmp_lit32(&dres, Ijk_NoDecode, guest_PC_curr_instr);
33309       }
33310       dres.whatNext = Dis_StopHere;
33311       dres.len = 0;
33312       return dres;
33313    }  /* switch (opc) for the main (primary) opcode switch. */
33314 
33315    /* All MIPS insn have 4 bytes */
33316 
33317    if (delay_slot_branch) {
33318       delay_slot_branch = False;
33319       stmt(bstmt);
33320       bstmt = NULL;
33321       if (mode64)
33322          putPC(mkU64(guest_PC_curr_instr + 4));
33323       else
33324          putPC(mkU32(guest_PC_curr_instr + 4));
33325       dres.jk_StopHere = is_Branch_or_Jump_and_Link(guest_code + delta - 4) ?
33326                          Ijk_Call : Ijk_Boring;
33327    }
33328 
33329    if (likely_delay_slot) {
33330       dres.jk_StopHere = Ijk_Boring;
33331       dres.whatNext = Dis_StopHere;
33332       putPC(lastn);
33333       lastn = NULL;
33334    }
33335    if (delay_slot_jump) {
33336       putPC(lastn);
33337       lastn = NULL;
33338       dres.jk_StopHere = is_Branch_or_Jump_and_Link(guest_code + delta - 4) ?
33339                          Ijk_Call : Ijk_Boring;
33340    }
33341 
33342  decode_success:
33343    /* All decode successes end up here. */
33344    switch (dres.whatNext) {
33345       case Dis_Continue:
33346          if (mode64)
33347             putPC(mkU64(guest_PC_curr_instr + 4));
33348          else
33349             putPC(mkU32(guest_PC_curr_instr + 4));
33350          break;
33351       case Dis_ResteerU:
33352       case Dis_ResteerC:
33353          if (mode64)
33354             putPC(mkU64(dres.continueAt));
33355          else
33356             putPC(mkU32(dres.continueAt));
33357          break;
33358       case Dis_StopHere:
33359          break;
33360       default:
33361          vassert(0);
33362          break;
33363    }
33364 
33365    /* On MIPS we need to check if the last instruction in block is branch or
33366       jump. */
33367    if (((vex_control.guest_max_insns - 1) == (delta + 4) / 4)
33368        &&  (dres.whatNext != Dis_StopHere))
33369       if (branch_or_jump(guest_code + delta + 4)) {
33370          dres.whatNext = Dis_StopHere;
33371          dres.jk_StopHere = Ijk_Boring;
33372          if (mode64)
33373             putPC(mkU64(guest_PC_curr_instr + 4));
33374          else
33375             putPC(mkU32(guest_PC_curr_instr + 4));
33376       }
33377    dres.len = 4;
33378 
33379    DIP("\n");
33380 
33381    return dres;
33382 
33383 }
33384 
33385 /*------------------------------------------------------------*/
33386 /*--- Top-level fn                                         ---*/
33387 /*------------------------------------------------------------*/
33388 
33389 /* Disassemble a single instruction into IR.  The instruction
33390    is located in host memory at &guest_code[delta]. */
disInstr_MIPS(IRSB * irsb_IN,Bool (* resteerOkFn)(void *,Addr),Bool resteerCisOk,void * callback_opaque,const UChar * guest_code_IN,Long delta,Addr guest_IP,VexArch guest_arch,const VexArchInfo * archinfo,const VexAbiInfo * abiinfo,VexEndness host_endness_IN,Bool sigill_diag_IN)33391 DisResult disInstr_MIPS( IRSB*        irsb_IN,
33392                          Bool         (*resteerOkFn) ( void *, Addr ),
33393                          Bool         resteerCisOk,
33394                          void*        callback_opaque,
33395                          const UChar* guest_code_IN,
33396                          Long         delta,
33397                          Addr         guest_IP,
33398                          VexArch      guest_arch,
33399                          const VexArchInfo* archinfo,
33400                          const VexAbiInfo*  abiinfo,
33401                          VexEndness   host_endness_IN,
33402                          Bool         sigill_diag_IN )
33403 {
33404    DisResult dres;
33405    /* Set globals (see top of this file) */
33406    vassert(guest_arch == VexArchMIPS32 || guest_arch == VexArchMIPS64);
33407 
33408    mode64 = guest_arch != VexArchMIPS32;
33409    fp_mode64 = abiinfo->guest_mips_fp_mode & 1;
33410    fp_mode64_fre = abiinfo->guest_mips_fp_mode & 2;
33411    has_msa = VEX_MIPS_PROC_MSA(archinfo->hwcaps);
33412 
33413    vassert(VEX_MIPS_HOST_FP_MODE(archinfo->hwcaps) >= fp_mode64);
33414 
33415    guest_code = guest_code_IN;
33416    irsb = irsb_IN;
33417    host_endness = host_endness_IN;
33418 #if defined(VGP_mips32_linux)
33419    guest_PC_curr_instr = (Addr32)guest_IP;
33420 #elif defined(VGP_mips64_linux)
33421    guest_PC_curr_instr = (Addr64)guest_IP;
33422 #endif
33423 
33424    dres = disInstr_MIPS_WRK(resteerOkFn, resteerCisOk, callback_opaque,
33425                             delta, archinfo, abiinfo, sigill_diag_IN);
33426 
33427    return dres;
33428 }
33429 
33430 /*--------------------------------------------------------------------*/
33431 /*--- end                                        guest_mips_toIR.c ---*/
33432 /*--------------------------------------------------------------------*/
33433