2 /*--------------------------------------------------------------------*/
3 /*--- begin guest_mips_toIR.c ---*/
4 /*--------------------------------------------------------------------*/
7 This file is part of Valgrind, a dynamic binary instrumentation
10 Copyright (C) 2010-2017 RT-RK
11 mips-valgrind@rt-rk.com
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.
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.
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
28 The GNU General Public License is contained in the file COPYING.
31 /* Translates MIPS code to IR. */
33 #include "libvex_basictypes.h"
34 #include "libvex_ir.h"
36 #include "libvex_guest_mips32.h"
37 #include "libvex_guest_mips64.h"
39 #include "main_util.h"
40 #include "main_globals.h"
41 #include "guest_generic_bb_to_IR.h"
42 #include "guest_mips_defs.h"
44 /*------------------------------------------------------------*/
46 /*------------------------------------------------------------*/
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. */
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
55 static VexEndness host_endness
;
57 /* Pointer to the guest code area. */
58 static const UChar
*guest_code
;
60 /* CONST: The guest address for the instruction currently being
62 #if defined(VGP_mips32_linux)
63 static Addr32 guest_PC_curr_instr
;
65 static Addr64 guest_PC_curr_instr
;
68 /* MOD: The IRSB* into which we're generating code. */
71 /* Is our guest binary 32 or 64bit? Set at each call to
72 disInstr_MIPS below. */
73 static Bool mode64
= False
;
75 /* CPU has FPU and 32 dbl. prec. FP registers. */
76 static Bool fp_mode64
= False
;
78 /* FPU works in FRE mode */
79 static Bool fp_mode64_fre
= False
;
81 /* CPU has MSA unit */
82 static Bool has_msa
= False
;
84 /* Define 1.0 in single and double precision. */
85 #define ONE_SINGLE 0x3F800000
86 #define ONE_DOUBLE 0x3FF0000000000000ULL
88 /*------------------------------------------------------------*/
89 /*--- Debugging output ---*/
90 /*------------------------------------------------------------*/
92 #define DIP(format, args...) \
93 if (vex_traceflags & VEX_TRACE_FE) \
94 vex_printf(format, ## args)
96 /*------------------------------------------------------------*/
97 /*--- Helper bits and pieces for deconstructing the ---*/
98 /*--- mips insn stream. ---*/
99 /*------------------------------------------------------------*/
101 /* ---------------- Integer registers ---------------- */
103 static UInt
integerGuestRegOffset(UInt iregNo
)
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
112 ret
= offsetof(VexGuestMIPS32State
, guest_r0
); break;
114 ret
= offsetof(VexGuestMIPS32State
, guest_r1
); break;
116 ret
= offsetof(VexGuestMIPS32State
, guest_r2
); break;
118 ret
= offsetof(VexGuestMIPS32State
, guest_r3
); break;
120 ret
= offsetof(VexGuestMIPS32State
, guest_r4
); break;
122 ret
= offsetof(VexGuestMIPS32State
, guest_r5
); break;
124 ret
= offsetof(VexGuestMIPS32State
, guest_r6
); break;
126 ret
= offsetof(VexGuestMIPS32State
, guest_r7
); break;
128 ret
= offsetof(VexGuestMIPS32State
, guest_r8
); break;
130 ret
= offsetof(VexGuestMIPS32State
, guest_r9
); break;
132 ret
= offsetof(VexGuestMIPS32State
, guest_r10
); break;
134 ret
= offsetof(VexGuestMIPS32State
, guest_r11
); break;
136 ret
= offsetof(VexGuestMIPS32State
, guest_r12
); break;
138 ret
= offsetof(VexGuestMIPS32State
, guest_r13
); break;
140 ret
= offsetof(VexGuestMIPS32State
, guest_r14
); break;
142 ret
= offsetof(VexGuestMIPS32State
, guest_r15
); break;
144 ret
= offsetof(VexGuestMIPS32State
, guest_r16
); break;
146 ret
= offsetof(VexGuestMIPS32State
, guest_r17
); break;
148 ret
= offsetof(VexGuestMIPS32State
, guest_r18
); break;
150 ret
= offsetof(VexGuestMIPS32State
, guest_r19
); break;
152 ret
= offsetof(VexGuestMIPS32State
, guest_r20
); break;
154 ret
= offsetof(VexGuestMIPS32State
, guest_r21
); break;
156 ret
= offsetof(VexGuestMIPS32State
, guest_r22
); break;
158 ret
= offsetof(VexGuestMIPS32State
, guest_r23
); break;
160 ret
= offsetof(VexGuestMIPS32State
, guest_r24
); break;
162 ret
= offsetof(VexGuestMIPS32State
, guest_r25
); break;
164 ret
= offsetof(VexGuestMIPS32State
, guest_r26
); break;
166 ret
= offsetof(VexGuestMIPS32State
, guest_r27
); break;
168 ret
= offsetof(VexGuestMIPS32State
, guest_r28
); break;
170 ret
= offsetof(VexGuestMIPS32State
, guest_r29
); break;
172 ret
= offsetof(VexGuestMIPS32State
, guest_r30
); break;
174 ret
= offsetof(VexGuestMIPS32State
, guest_r31
); break;
182 ret
= offsetof(VexGuestMIPS64State
, guest_r0
); break;
184 ret
= offsetof(VexGuestMIPS64State
, guest_r1
); break;
186 ret
= offsetof(VexGuestMIPS64State
, guest_r2
); break;
188 ret
= offsetof(VexGuestMIPS64State
, guest_r3
); break;
190 ret
= offsetof(VexGuestMIPS64State
, guest_r4
); break;
192 ret
= offsetof(VexGuestMIPS64State
, guest_r5
); break;
194 ret
= offsetof(VexGuestMIPS64State
, guest_r6
); break;
196 ret
= offsetof(VexGuestMIPS64State
, guest_r7
); break;
198 ret
= offsetof(VexGuestMIPS64State
, guest_r8
); break;
200 ret
= offsetof(VexGuestMIPS64State
, guest_r9
); break;
202 ret
= offsetof(VexGuestMIPS64State
, guest_r10
); break;
204 ret
= offsetof(VexGuestMIPS64State
, guest_r11
); break;
206 ret
= offsetof(VexGuestMIPS64State
, guest_r12
); break;
208 ret
= offsetof(VexGuestMIPS64State
, guest_r13
); break;
210 ret
= offsetof(VexGuestMIPS64State
, guest_r14
); break;
212 ret
= offsetof(VexGuestMIPS64State
, guest_r15
); break;
214 ret
= offsetof(VexGuestMIPS64State
, guest_r16
); break;
216 ret
= offsetof(VexGuestMIPS64State
, guest_r17
); break;
218 ret
= offsetof(VexGuestMIPS64State
, guest_r18
); break;
220 ret
= offsetof(VexGuestMIPS64State
, guest_r19
); break;
222 ret
= offsetof(VexGuestMIPS64State
, guest_r20
); break;
224 ret
= offsetof(VexGuestMIPS64State
, guest_r21
); break;
226 ret
= offsetof(VexGuestMIPS64State
, guest_r22
); break;
228 ret
= offsetof(VexGuestMIPS64State
, guest_r23
); break;
230 ret
= offsetof(VexGuestMIPS64State
, guest_r24
); break;
232 ret
= offsetof(VexGuestMIPS64State
, guest_r25
); break;
234 ret
= offsetof(VexGuestMIPS64State
, guest_r26
); break;
236 ret
= offsetof(VexGuestMIPS64State
, guest_r27
); break;
238 ret
= offsetof(VexGuestMIPS64State
, guest_r28
); break;
240 ret
= offsetof(VexGuestMIPS64State
, guest_r29
); break;
242 ret
= offsetof(VexGuestMIPS64State
, guest_r30
); break;
244 ret
= offsetof(VexGuestMIPS64State
, guest_r31
); break;
252 #if defined(VGP_mips32_linux)
253 #define OFFB_PC offsetof(VexGuestMIPS32State, guest_PC)
255 #define OFFB_PC offsetof(VexGuestMIPS64State, guest_PC)
258 /* ---------------- Floating point registers ---------------- */
260 static UInt
floatGuestRegOffset(UInt fregNo
)
262 vassert(fregNo
< 32);
267 ret
= offsetof(VexGuestMIPS32State
, guest_f0
); break;
269 ret
= offsetof(VexGuestMIPS32State
, guest_f1
); break;
271 ret
= offsetof(VexGuestMIPS32State
, guest_f2
); break;
273 ret
= offsetof(VexGuestMIPS32State
, guest_f3
); break;
275 ret
= offsetof(VexGuestMIPS32State
, guest_f4
); break;
277 ret
= offsetof(VexGuestMIPS32State
, guest_f5
); break;
279 ret
= offsetof(VexGuestMIPS32State
, guest_f6
); break;
281 ret
= offsetof(VexGuestMIPS32State
, guest_f7
); break;
283 ret
= offsetof(VexGuestMIPS32State
, guest_f8
); break;
285 ret
= offsetof(VexGuestMIPS32State
, guest_f9
); break;
287 ret
= offsetof(VexGuestMIPS32State
, guest_f10
); break;
289 ret
= offsetof(VexGuestMIPS32State
, guest_f11
); break;
291 ret
= offsetof(VexGuestMIPS32State
, guest_f12
); break;
293 ret
= offsetof(VexGuestMIPS32State
, guest_f13
); break;
295 ret
= offsetof(VexGuestMIPS32State
, guest_f14
); break;
297 ret
= offsetof(VexGuestMIPS32State
, guest_f15
); break;
299 ret
= offsetof(VexGuestMIPS32State
, guest_f16
); break;
301 ret
= offsetof(VexGuestMIPS32State
, guest_f17
); break;
303 ret
= offsetof(VexGuestMIPS32State
, guest_f18
); break;
305 ret
= offsetof(VexGuestMIPS32State
, guest_f19
); break;
307 ret
= offsetof(VexGuestMIPS32State
, guest_f20
); break;
309 ret
= offsetof(VexGuestMIPS32State
, guest_f21
); break;
311 ret
= offsetof(VexGuestMIPS32State
, guest_f22
); break;
313 ret
= offsetof(VexGuestMIPS32State
, guest_f23
); break;
315 ret
= offsetof(VexGuestMIPS32State
, guest_f24
); break;
317 ret
= offsetof(VexGuestMIPS32State
, guest_f25
); break;
319 ret
= offsetof(VexGuestMIPS32State
, guest_f26
); break;
321 ret
= offsetof(VexGuestMIPS32State
, guest_f27
); break;
323 ret
= offsetof(VexGuestMIPS32State
, guest_f28
); break;
325 ret
= offsetof(VexGuestMIPS32State
, guest_f29
); break;
327 ret
= offsetof(VexGuestMIPS32State
, guest_f30
); break;
329 ret
= offsetof(VexGuestMIPS32State
, guest_f31
); break;
337 ret
= offsetof(VexGuestMIPS64State
, guest_f0
); break;
339 ret
= offsetof(VexGuestMIPS64State
, guest_f1
); break;
341 ret
= offsetof(VexGuestMIPS64State
, guest_f2
); break;
343 ret
= offsetof(VexGuestMIPS64State
, guest_f3
); break;
345 ret
= offsetof(VexGuestMIPS64State
, guest_f4
); break;
347 ret
= offsetof(VexGuestMIPS64State
, guest_f5
); break;
349 ret
= offsetof(VexGuestMIPS64State
, guest_f6
); break;
351 ret
= offsetof(VexGuestMIPS64State
, guest_f7
); break;
353 ret
= offsetof(VexGuestMIPS64State
, guest_f8
); break;
355 ret
= offsetof(VexGuestMIPS64State
, guest_f9
); break;
357 ret
= offsetof(VexGuestMIPS64State
, guest_f10
); break;
359 ret
= offsetof(VexGuestMIPS64State
, guest_f11
); break;
361 ret
= offsetof(VexGuestMIPS64State
, guest_f12
); break;
363 ret
= offsetof(VexGuestMIPS64State
, guest_f13
); break;
365 ret
= offsetof(VexGuestMIPS64State
, guest_f14
); break;
367 ret
= offsetof(VexGuestMIPS64State
, guest_f15
); break;
369 ret
= offsetof(VexGuestMIPS64State
, guest_f16
); break;
371 ret
= offsetof(VexGuestMIPS64State
, guest_f17
); break;
373 ret
= offsetof(VexGuestMIPS64State
, guest_f18
); break;
375 ret
= offsetof(VexGuestMIPS64State
, guest_f19
); break;
377 ret
= offsetof(VexGuestMIPS64State
, guest_f20
); break;
379 ret
= offsetof(VexGuestMIPS64State
, guest_f21
); break;
381 ret
= offsetof(VexGuestMIPS64State
, guest_f22
); break;
383 ret
= offsetof(VexGuestMIPS64State
, guest_f23
); break;
385 ret
= offsetof(VexGuestMIPS64State
, guest_f24
); break;
387 ret
= offsetof(VexGuestMIPS64State
, guest_f25
); break;
389 ret
= offsetof(VexGuestMIPS64State
, guest_f26
); break;
391 ret
= offsetof(VexGuestMIPS64State
, guest_f27
); break;
393 ret
= offsetof(VexGuestMIPS64State
, guest_f28
); break;
395 ret
= offsetof(VexGuestMIPS64State
, guest_f29
); break;
397 ret
= offsetof(VexGuestMIPS64State
, guest_f30
); break;
399 ret
= offsetof(VexGuestMIPS64State
, guest_f31
); break;
407 /* ---------------- MIPS32 DSP ASE(r2) accumulators ---------------- */
409 static UInt
accumulatorGuestRegOffset(UInt acNo
)
416 ret
= offsetof(VexGuestMIPS32State
, guest_ac0
); break;
418 ret
= offsetof(VexGuestMIPS32State
, guest_ac1
); break;
420 ret
= offsetof(VexGuestMIPS32State
, guest_ac2
); break;
422 ret
= offsetof(VexGuestMIPS32State
, guest_ac3
); break;
430 /* ---------------- MIPS32 MSA registers ---------------- */
432 static UInt
msaGuestRegOffset(UInt msaRegNo
) {
433 vassert(msaRegNo
<= 31);
439 ret
= offsetof(VexGuestMIPS64State
, guest_w0
);
443 ret
= offsetof(VexGuestMIPS64State
, guest_w1
);
447 ret
= offsetof(VexGuestMIPS64State
, guest_w2
);
451 ret
= offsetof(VexGuestMIPS64State
, guest_w3
);
455 ret
= offsetof(VexGuestMIPS64State
, guest_w4
);
459 ret
= offsetof(VexGuestMIPS64State
, guest_w5
);
463 ret
= offsetof(VexGuestMIPS64State
, guest_w6
);
467 ret
= offsetof(VexGuestMIPS64State
, guest_w7
);
471 ret
= offsetof(VexGuestMIPS64State
, guest_w8
);
475 ret
= offsetof(VexGuestMIPS64State
, guest_w9
);
479 ret
= offsetof(VexGuestMIPS64State
, guest_w10
);
483 ret
= offsetof(VexGuestMIPS64State
, guest_w11
);
487 ret
= offsetof(VexGuestMIPS64State
, guest_w12
);
491 ret
= offsetof(VexGuestMIPS64State
, guest_w13
);
495 ret
= offsetof(VexGuestMIPS64State
, guest_w14
);
499 ret
= offsetof(VexGuestMIPS64State
, guest_w15
);
503 ret
= offsetof(VexGuestMIPS64State
, guest_w16
);
507 ret
= offsetof(VexGuestMIPS64State
, guest_w17
);
511 ret
= offsetof(VexGuestMIPS64State
, guest_w18
);
515 ret
= offsetof(VexGuestMIPS64State
, guest_w19
);
519 ret
= offsetof(VexGuestMIPS64State
, guest_w20
);
523 ret
= offsetof(VexGuestMIPS64State
, guest_w21
);
527 ret
= offsetof(VexGuestMIPS64State
, guest_w22
);
531 ret
= offsetof(VexGuestMIPS64State
, guest_w23
);
535 ret
= offsetof(VexGuestMIPS64State
, guest_w24
);
539 ret
= offsetof(VexGuestMIPS64State
, guest_w25
);
543 ret
= offsetof(VexGuestMIPS64State
, guest_w26
);
547 ret
= offsetof(VexGuestMIPS64State
, guest_w27
);
551 ret
= offsetof(VexGuestMIPS64State
, guest_w28
);
555 ret
= offsetof(VexGuestMIPS64State
, guest_w29
);
559 ret
= offsetof(VexGuestMIPS64State
, guest_w30
);
563 ret
= offsetof(VexGuestMIPS64State
, guest_w31
);
573 ret
= offsetof(VexGuestMIPS32State
, guest_w0
);
577 ret
= offsetof(VexGuestMIPS32State
, guest_w1
);
581 ret
= offsetof(VexGuestMIPS32State
, guest_w2
);
585 ret
= offsetof(VexGuestMIPS32State
, guest_w3
);
589 ret
= offsetof(VexGuestMIPS32State
, guest_w4
);
593 ret
= offsetof(VexGuestMIPS32State
, guest_w5
);
597 ret
= offsetof(VexGuestMIPS32State
, guest_w6
);
601 ret
= offsetof(VexGuestMIPS32State
, guest_w7
);
605 ret
= offsetof(VexGuestMIPS32State
, guest_w8
);
609 ret
= offsetof(VexGuestMIPS32State
, guest_w9
);
613 ret
= offsetof(VexGuestMIPS32State
, guest_w10
);
617 ret
= offsetof(VexGuestMIPS32State
, guest_w11
);
621 ret
= offsetof(VexGuestMIPS32State
, guest_w12
);
625 ret
= offsetof(VexGuestMIPS32State
, guest_w13
);
629 ret
= offsetof(VexGuestMIPS32State
, guest_w14
);
633 ret
= offsetof(VexGuestMIPS32State
, guest_w15
);
637 ret
= offsetof(VexGuestMIPS32State
, guest_w16
);
641 ret
= offsetof(VexGuestMIPS32State
, guest_w17
);
645 ret
= offsetof(VexGuestMIPS32State
, guest_w18
);
649 ret
= offsetof(VexGuestMIPS32State
, guest_w19
);
653 ret
= offsetof(VexGuestMIPS32State
, guest_w20
);
657 ret
= offsetof(VexGuestMIPS32State
, guest_w21
);
661 ret
= offsetof(VexGuestMIPS32State
, guest_w22
);
665 ret
= offsetof(VexGuestMIPS32State
, guest_w23
);
669 ret
= offsetof(VexGuestMIPS32State
, guest_w24
);
673 ret
= offsetof(VexGuestMIPS32State
, guest_w25
);
677 ret
= offsetof(VexGuestMIPS32State
, guest_w26
);
681 ret
= offsetof(VexGuestMIPS32State
, guest_w27
);
685 ret
= offsetof(VexGuestMIPS32State
, guest_w28
);
689 ret
= offsetof(VexGuestMIPS32State
, guest_w29
);
693 ret
= offsetof(VexGuestMIPS32State
, guest_w30
);
697 ret
= offsetof(VexGuestMIPS32State
, guest_w31
);
710 /* Do a endian load of a 32-bit word, regardless of the endianness of the
712 static inline UInt
getUInt(const UChar
* p
)
715 #if defined (_MIPSEL)
720 #elif defined (_MIPSEB)
729 #define BITS2(_b1,_b0) \
730 (((_b1) << 1) | (_b0))
732 #define BITS3(_b2,_b1,_b0) \
733 (((_b2) << 2) | ((_b1) << 1) | (_b0))
735 #define BITS4(_b3,_b2,_b1,_b0) \
736 (((_b3) << 3) | ((_b2) << 2) | ((_b1) << 1) | (_b0))
738 #define BITS5(_b4,_b3,_b2,_b1,_b0) \
739 (((_b4) << 4) | BITS4((_b3),(_b2),(_b1),(_b0)))
741 #define BITS6(_b5,_b4,_b3,_b2,_b1,_b0) \
742 ((BITS2((_b5),(_b4)) << 4) \
743 | BITS4((_b3),(_b2),(_b1),(_b0)))
745 #define BITS8(_b7,_b6,_b5,_b4,_b3,_b2,_b1,_b0) \
746 ((BITS4((_b7),(_b6),(_b5),(_b4)) << 4) \
747 | BITS4((_b3),(_b2),(_b1),(_b0)))
749 #define LOAD_STORE_PATTERN \
750 t1 = newTemp(mode64 ? Ity_I64 : Ity_I32); \
752 assign(t1, binop(Iop_Add32, getIReg(rs), \
753 mkU32(extend_s_16to32(imm)))); \
755 assign(t1, binop(Iop_Add64, getIReg(rs), \
756 mkU64(extend_s_16to64(imm)))); \
758 #define LOAD_STORE_PATTERN_MSA(imm) \
759 t1 = newTemp(mode64 ? Ity_I64 : Ity_I32); \
761 assign(t1, binop(Iop_Add32, getIReg(ws), \
762 mkU32(extend_s_10to32(imm)))); \
764 assign(t1, binop(Iop_Add64, getIReg(ws), \
765 mkU64(extend_s_10to64(imm)))); \
767 #define LOADX_STORE_PATTERN \
768 t1 = newTemp(mode64 ? Ity_I64 : Ity_I32); \
770 assign(t1, binop(Iop_Add32, getIReg(regRs), getIReg(regRt))); \
772 assign(t1, binop(Iop_Add64, getIReg(regRs), getIReg(regRt)));
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))));
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)));
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)))
793 #define SXXV_PATTERN(op) \
794 putIReg(rd, binop(op, \
805 #define SXXV_PATTERN64(op) \
806 putIReg(rd, mkWidenFrom32(ty, binop(op, \
807 mkNarrowTo32(ty, getIReg(rt)), \
810 mkNarrowTo32(ty, getIReg(rs)), \
817 #define SXX_PATTERN(op) \
818 putIReg(rd, binop(op, getIReg(rt), mkU8(sa)));
820 #define ALU_PATTERN(op) \
821 putIReg(rd, binop(op, getIReg(rs), getIReg(rt)));
823 #define ALUI_PATTERN(op) \
824 putIReg(rt, binop(op, getIReg(rs), mkU32(imm)));
826 #define ALUI_PATTERN64(op) \
827 putIReg(rt, binop(op, getIReg(rs), mkU64(imm)));
829 #define ALU_PATTERN64(op) \
830 putIReg(rd, mkWidenFrom32(ty, binop(op, \
831 mkNarrowTo32(ty, getIReg(rs)), \
832 mkNarrowTo32(ty, getIReg(rt))), True));
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))), \
842 #define ILLEGAL_INSTRUCTON \
843 putPC(mkU32(guest_PC_curr_instr + 4)); \
844 dres.jk_StopHere = Ijk_SigILL; \
845 dres.whatNext = Dis_StopHere;
847 #define LLADDR_INVALID \
848 (mode64 ? mkU64(0xFFFFFFFFFFFFFFFFULL) : mkU32(0xFFFFFFFF))
850 /*------------------------------------------------------------*/
851 /*--- Field helpers ---*/
852 /*------------------------------------------------------------*/
854 static UInt
get_opcode(UInt mipsins
)
856 return (0xFC000000 & mipsins
) >> 26;
859 static UInt
get_rs(UInt mipsins
)
861 return (0x03E00000 & mipsins
) >> 21;
864 static UInt
get_rt(UInt mipsins
)
866 return (0x001F0000 & mipsins
) >> 16;
869 static UInt
get_imm(UInt mipsins
)
871 return (0x0000FFFF & mipsins
);
874 static UInt
get_instr_index(UInt mipsins
)
876 return (0x03FFFFFF & mipsins
);
879 static UInt
get_rd(UInt mipsins
)
881 return (0x0000F800 & mipsins
) >> 11;
884 static UInt
get_sa(UInt mipsins
)
886 return (0x000007C0 & mipsins
) >> 6;
889 static UInt
get_function(UInt mipsins
)
891 return (0x0000003F & mipsins
);
894 static UInt
get_ft(UInt mipsins
)
896 return (0x001F0000 & mipsins
) >> 16;
899 static UInt
get_fs(UInt mipsins
)
901 return (0x0000F800 & mipsins
) >> 11;
904 static UInt
get_fd(UInt mipsins
)
906 return (0x000007C0 & mipsins
) >> 6;
909 static UInt
get_mov_cc(UInt mipsins
)
911 return (0x001C0000 & mipsins
) >> 18;
914 static UInt
get_bc1_cc(UInt mipsins
)
916 return (0x001C0000 & mipsins
) >> 18;
919 static UInt
get_fpc_cc(UInt mipsins
)
921 return (0x00000700 & mipsins
) >> 8;
924 static UInt
get_tf(UInt mipsins
)
926 return (0x00010000 & mipsins
) >> 16;
929 static UInt
get_nd(UInt mipsins
)
931 return (0x00020000 & mipsins
) >> 17;
934 static UInt
get_fmt(UInt mipsins
)
936 return (0x03E00000 & mipsins
) >> 21;
939 static UInt
get_FC(UInt mipsins
)
941 return (0x000000F0 & mipsins
) >> 4;
944 static UInt
get_cond(UInt mipsins
)
946 return (0x0000000F & mipsins
);
949 /* for break & syscall */
950 static UInt
get_code(UInt mipsins
)
952 return (0xFFC0 & mipsins
) >> 6;
955 static UInt
get_lsb(UInt mipsins
)
957 return (0x7C0 & mipsins
) >> 6;
960 static UInt
get_msb(UInt mipsins
)
962 return (0x0000F800 & mipsins
) >> 11;
965 static UInt
get_rot(UInt mipsins
)
967 return (0x00200000 & mipsins
) >> 21;
970 static UInt
get_rotv(UInt mipsins
)
972 return (0x00000040 & mipsins
) >> 6;
975 static UInt
get_sel(UInt mipsins
)
977 return (0x00000007 & mipsins
);
980 /* Get acc number for all MIPS32 DSP ASE(r2) instructions that use them,
981 except for MFHI and MFLO. */
982 static UInt
get_acNo(UInt mipsins
)
984 return (0x00001800 & mipsins
) >> 11;
987 /* Get accumulator number for MIPS32 DSP ASEr2 MFHI and MFLO instructions. */
988 static UInt
get_acNo_mfhilo(UInt mipsins
)
990 return (0x00600000 & mipsins
) >> 21;
993 /* Get mask field (helper function for wrdsp instruction). */
994 static UInt
get_wrdspMask(UInt mipsins
)
996 return (0x001ff800 & mipsins
) >> 11;
999 /* Get mask field (helper function for rddsp instruction). */
1000 static UInt
get_rddspMask(UInt mipsins
)
1002 return (0x03ff0000 & mipsins
) >> 16;
1005 /* Get shift field (helper function for DSP ASE instructions). */
1006 static UInt
get_shift(UInt mipsins
)
1008 return (0x03f00000 & mipsins
) >> 20;
1011 /* Get immediate field for DSP ASE instructions. */
1012 static UInt
get_dspImm(UInt mipsins
)
1014 return (0x03ff0000 & mipsins
) >> 16;
1017 static Bool
branch_or_jump(const UChar
* addr
)
1020 UInt cins
= getUInt(addr
);
1022 UInt opcode
= get_opcode(cins
);
1023 UInt rt
= get_rt(cins
);
1024 UInt function
= get_function(cins
);
1026 /* bgtz, blez, bne, beq, jal */
1027 if (opcode
== 0x07 || opcode
== 0x06 || opcode
== 0x05 || opcode
== 0x04
1028 || opcode
== 0x03 || opcode
== 0x02) {
1033 if (opcode
== 0x01 && rt
== 0x01) {
1038 if (opcode
== 0x01 && rt
== 0x11) {
1043 if (opcode
== 0x01 && rt
== 0x10) {
1048 if (opcode
== 0x01 && rt
== 0x00) {
1053 if (opcode
== 0x00 && function
== 0x09) {
1058 if (opcode
== 0x00 && function
== 0x08) {
1062 if (opcode
== 0x11) {
1064 fmt
= get_fmt(cins
);
1096 if (opcode
== 0x01 && rt
== 0x1c) {
1100 /* Cavium Specific instructions. */
1101 if (opcode
== 0x32 || opcode
== 0x3A || opcode
== 0x36 || opcode
== 0x3E) {
1102 /* BBIT0, BBIT1, BBIT032, BBIT132 */
1109 static Bool
is_Branch_or_Jump_and_Link(const UChar
* addr
)
1111 UInt cins
= getUInt(addr
);
1113 UInt opcode
= get_opcode(cins
);
1114 UInt rt
= get_rt(cins
);
1115 UInt function
= get_function(cins
);
1118 if (opcode
== 0x02) {
1122 /* bgezal or bal(r6) */
1123 if (opcode
== 0x01 && rt
== 0x11) {
1128 if (opcode
== 0x01 && rt
== 0x10) {
1133 if (opcode
== 0x00 && function
== 0x09) {
1140 static Bool
branch_or_link_likely(const UChar
* addr
)
1142 UInt cins
= getUInt(addr
);
1143 UInt opcode
= get_opcode(cins
);
1144 UInt rt
= get_rt(cins
);
1146 /* bgtzl, blezl, bnel, beql */
1147 if (opcode
== 0x17 || opcode
== 0x16 || opcode
== 0x15 || opcode
== 0x14)
1151 if (opcode
== 0x01 && rt
== 0x03)
1155 if (opcode
== 0x01 && rt
== 0x13)
1159 if (opcode
== 0x01 && rt
== 0x12)
1163 if (opcode
== 0x01 && rt
== 0x02)
1169 /*------------------------------------------------------------*/
1170 /*--- Helper bits and pieces for creating IR fragments. ---*/
1171 /*------------------------------------------------------------*/
1173 static IRExpr
*mkU8(UInt i
)
1176 return IRExpr_Const(IRConst_U8((UChar
) i
));
1179 /* Create an expression node for a 16-bit integer constant. */
1180 static IRExpr
*mkU16(UInt i
)
1182 return IRExpr_Const(IRConst_U16(i
));
1185 /* Create an expression node for a 32-bit integer constant. */
1186 static IRExpr
*mkU32(UInt i
)
1188 return IRExpr_Const(IRConst_U32(i
));
1191 /* Create an expression node for a 64-bit integer constant. */
1192 static IRExpr
*mkU64(ULong i
)
1194 return IRExpr_Const(IRConst_U64(i
));
1197 static IRExpr
*mkexpr(IRTemp tmp
)
1199 return IRExpr_RdTmp(tmp
);
1202 static IRExpr
*unop(IROp op
, IRExpr
* a
)
1204 return IRExpr_Unop(op
, a
);
1207 static IRExpr
*binop(IROp op
, IRExpr
* a1
, IRExpr
* a2
)
1209 return IRExpr_Binop(op
, a1
, a2
);
1212 static IRExpr
*triop(IROp op
, IRExpr
* a1
, IRExpr
* a2
, IRExpr
* a3
)
1214 return IRExpr_Triop(op
, a1
, a2
, a3
);
1217 static IRExpr
*qop ( IROp op
, IRExpr
* a1
, IRExpr
* a2
, IRExpr
* a3
,
1220 return IRExpr_Qop(op
, a1
, a2
, a3
, a4
);
1223 static IRExpr
*load(IRType ty
, IRExpr
* addr
)
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
);
1234 /* Add a statement to the list held by "irsb". */
1235 static void stmt(IRStmt
* st
)
1237 addStmtToIRSB(irsb
, st
);
1240 static void assign(IRTemp dst
, IRExpr
* e
)
1242 stmt(IRStmt_WrTmp(dst
, e
));
1245 static void store(IRExpr
* addr
, IRExpr
* data
)
1247 #if defined (_MIPSEL)
1248 stmt(IRStmt_Store(Iend_LE
, addr
, data
));
1249 #elif defined (_MIPSEB)
1250 stmt(IRStmt_Store(Iend_BE
, addr
, data
));
1254 /* Generate a new temporary of the given type. */
1255 static IRTemp
newTemp(IRType ty
)
1257 vassert(isPlausibleIRType(ty
));
1258 return newIRTemp(irsb
->tyenv
, ty
);
1261 /* Generate an expression for SRC rotated right by ROT. */
1262 static IRExpr
*genROR32(IRExpr
* src
, Int rot
)
1264 vassert(rot
>= 0 && rot
< 32);
1267 return binop(Iop_Or32
, binop(Iop_Shl32
, src
, mkU8(32 - rot
)),
1268 binop(Iop_Shr32
, src
, mkU8(rot
)));
1271 static IRExpr
*genRORV32(IRExpr
* src
, IRExpr
* rs
)
1273 IRTemp t0
= newTemp(Ity_I8
);
1274 IRTemp t1
= newTemp(Ity_I8
);
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
)));
1283 static UShort
extend_s_9to16(UInt x
)
1285 return (UShort
) ((((Int
) x
) << 23) >> 23);
1288 static UShort
extend_s_10to16(UInt x
)
1290 return (UShort
) ((((Int
) x
) << 22) >> 22);
1293 static UInt
extend_s_10to32(UInt x
)
1295 return (UInt
)((((Int
) x
) << 22) >> 22);
1298 static ULong
extend_s_10to64(UInt x
)
1300 return (ULong
)((((Long
) x
) << 54) >> 54);
1303 static UInt
extend_s_16to32(UInt x
)
1305 return (UInt
) ((((Int
) x
) << 16) >> 16);
1308 static UInt
extend_s_18to32(UInt x
)
1310 return (UInt
) ((((Int
) x
) << 14) >> 14);
1313 static UInt
extend_s_19to32(UInt x
)
1315 return (UInt
) ((((Int
) x
) << 13) >> 13);
1318 static UInt
extend_s_23to32(UInt x
)
1320 return (UInt
) ((((Int
) x
) << 9) >> 9);
1323 static UInt
extend_s_26to32(UInt x
)
1325 return (UInt
) ((((Int
) x
) << 6) >> 6);
1328 static ULong
extend_s_16to64 ( UInt x
)
1330 return (ULong
) ((((Long
) x
) << 48) >> 48);
1333 static ULong
extend_s_18to64 ( UInt x
)
1335 return (ULong
) ((((Long
) x
) << 46) >> 46);
1338 static ULong
extend_s_19to64(UInt x
)
1340 return (ULong
) ((((Long
) x
) << 45) >> 45);
1343 static ULong
extend_s_23to64(UInt x
)
1345 return (ULong
) ((((Long
) x
) << 41) >> 41);
1348 static ULong
extend_s_26to64(UInt x
)
1350 return (ULong
) ((((Long
) x
) << 38) >> 38);
1353 static ULong
extend_s_32to64 ( UInt x
)
1355 return (ULong
) ((((Long
) x
) << 32) >> 32);
1358 static void jmp_lit32 ( /*MOD*/ DisResult
* dres
, IRJumpKind kind
, Addr32 d32
)
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
) ) );
1369 static void jmp_lit64 ( /*MOD*/ DisResult
* dres
, IRJumpKind kind
, Addr64 d64
)
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
)));
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. */
1383 static IRExpr
*getAcc(UInt acNo
)
1387 return IRExpr_Get(accumulatorGuestRegOffset(acNo
), Ity_I64
);
1390 /* Get value from DSPControl register (helper function for MIPS32 DSP ASE
1392 static IRExpr
*getDSPControl(void)
1395 return IRExpr_Get(offsetof(VexGuestMIPS32State
, guest_DSPControl
), Ity_I32
);
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. */
1402 static void putDSPControl(IRExpr
* e
)
1405 stmt(IRStmt_Put(offsetof(VexGuestMIPS32State
, guest_DSPControl
), e
));
1408 /* Fetch a byte from the guest insn stream. */
1409 static UChar
getIByte(Int delta
)
1411 return guest_code
[delta
];
1414 static IRExpr
*getIReg(UInt iregNo
)
1417 return mode64
? mkU64(0x0) : mkU32(0x0);
1419 IRType ty
= mode64
? Ity_I64
: Ity_I32
;
1420 vassert(iregNo
< 32);
1421 return IRExpr_Get(integerGuestRegOffset(iregNo
), ty
);
1426 static IRExpr
*getWReg(UInt wregNo
) {
1427 vassert(wregNo
<= 31);
1428 return IRExpr_Get(msaGuestRegOffset(wregNo
), Ity_V128
);
1431 static IRExpr
*getHI(void)
1434 return IRExpr_Get(offsetof(VexGuestMIPS64State
, guest_HI
), Ity_I64
);
1436 return IRExpr_Get(offsetof(VexGuestMIPS32State
, guest_HI
), Ity_I32
);
1439 static IRExpr
*getLO(void)
1442 return IRExpr_Get(offsetof(VexGuestMIPS64State
, guest_LO
), Ity_I64
);
1444 return IRExpr_Get(offsetof(VexGuestMIPS32State
, guest_LO
), Ity_I32
);
1447 static IRExpr
*getFCSR(void)
1450 return IRExpr_Get(offsetof(VexGuestMIPS64State
, guest_FCSR
), Ity_I32
);
1452 return IRExpr_Get(offsetof(VexGuestMIPS32State
, guest_FCSR
), Ity_I32
);
1455 static IRExpr
*getLLaddr(void)
1458 return IRExpr_Get(offsetof(VexGuestMIPS64State
, guest_LLaddr
), Ity_I64
);
1460 return IRExpr_Get(offsetof(VexGuestMIPS32State
, guest_LLaddr
), Ity_I32
);
1463 static IRExpr
*getLLdata(void)
1466 return IRExpr_Get(offsetof(VexGuestMIPS64State
, guest_LLdata
), Ity_I64
);
1468 return IRExpr_Get(offsetof(VexGuestMIPS32State
, guest_LLdata
), Ity_I32
);
1471 static IRExpr
*getMSACSR(void) {
1473 return IRExpr_Get(offsetof(VexGuestMIPS64State
, guest_MSACSR
), Ity_I32
);
1475 return IRExpr_Get(offsetof(VexGuestMIPS32State
, guest_MSACSR
), Ity_I32
);
1478 /* Get byte from register reg, byte pos from 0 to 3 (or 7 for MIPS64) . */
1479 static IRExpr
*getByteFromReg(UInt reg
, UInt byte_pos
)
1481 UInt pos
= byte_pos
* 8;
1483 return unop(Iop_64to8
, binop(Iop_And64
,
1484 binop(Iop_Shr64
, getIReg(reg
), mkU8(pos
)),
1487 return unop(Iop_32to8
, binop(Iop_And32
,
1488 binop(Iop_Shr32
, getIReg(reg
), mkU8(pos
)),
1492 static void putFCSR(IRExpr
* e
)
1495 stmt(IRStmt_Put(offsetof(VexGuestMIPS64State
, guest_FCSR
), e
));
1497 stmt(IRStmt_Put(offsetof(VexGuestMIPS32State
, guest_FCSR
), e
));
1500 static void putLLaddr(IRExpr
* e
)
1503 stmt(IRStmt_Put(offsetof(VexGuestMIPS64State
, guest_LLaddr
), e
));
1505 stmt(IRStmt_Put(offsetof(VexGuestMIPS32State
, guest_LLaddr
), e
));
1508 static void putLLdata(IRExpr
* e
)
1511 stmt(IRStmt_Put(offsetof(VexGuestMIPS64State
, guest_LLdata
), e
));
1513 stmt(IRStmt_Put(offsetof(VexGuestMIPS32State
, guest_LLdata
), e
));
1516 static void putMSACSR(IRExpr
* e
) {
1518 stmt(IRStmt_Put(offsetof(VexGuestMIPS64State
, guest_MSACSR
), e
));
1520 stmt(IRStmt_Put(offsetof(VexGuestMIPS32State
, guest_MSACSR
), e
));
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. */
1529 static void calculateFCSR(UInt fs
, UInt ft
, UInt inst
, Bool sz32
, UInt opN
)
1532 IRTemp fcsr
= newTemp(Ity_I32
);
1533 /* IRExpr_GSPTR() => Need to pass pointer to guest state to helper. */
1535 d
= unsafeIRDirty_1_N(fcsr
, 0,
1536 "mips_dirtyhelper_calculate_FCSR_fp64",
1537 &mips_dirtyhelper_calculate_FCSR_fp64
,
1538 mkIRExprVec_4(IRExpr_GSPTR(),
1543 d
= unsafeIRDirty_1_N(fcsr
, 0,
1544 "mips_dirtyhelper_calculate_FCSR_fp32",
1545 &mips_dirtyhelper_calculate_FCSR_fp32
,
1546 mkIRExprVec_4(IRExpr_GSPTR(),
1551 if (opN
== 1) { /* Unary operation. */
1552 /* Declare we're reading guest state. */
1553 if (sz32
|| fp_mode64
)
1557 vex_bzero(&d
->fxState
, sizeof(d
->fxState
));
1559 d
->fxState
[0].fx
= Ifx_Read
; /* read */
1561 d
->fxState
[0].offset
= offsetof(VexGuestMIPS64State
, guest_FCSR
);
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
);
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
);
1574 } else if (opN
== 2) { /* Binary operation. */
1575 /* Declare we're reading guest state. */
1576 if (sz32
|| fp_mode64
)
1580 vex_bzero(&d
->fxState
, sizeof(d
->fxState
));
1582 d
->fxState
[0].fx
= Ifx_Read
; /* read */
1584 d
->fxState
[0].offset
= offsetof(VexGuestMIPS64State
, guest_FCSR
);
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
);
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
);
1605 stmt(IRStmt_Dirty(d
));
1607 putFCSR(mkexpr(fcsr
));
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. */
1615 static void calculateMSACSR(UInt ws
, UInt wt
, UInt inst
, UInt opN
) {
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(),
1627 if (opN
== 1) { /* Unary operation. */
1628 /* Declare we're reading guest state. */
1630 vex_bzero(&d
->fxState
, sizeof(d
->fxState
));
1631 d
->fxState
[0].fx
= Ifx_Read
; /* read */
1634 d
->fxState
[0].offset
= offsetof(VexGuestMIPS64State
, guest_MSACSR
);
1636 d
->fxState
[0].offset
= offsetof(VexGuestMIPS32State
, guest_MSACSR
);
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. */
1645 vex_bzero(&d
->fxState
, sizeof(d
->fxState
));
1646 d
->fxState
[0].fx
= Ifx_Read
; /* read */
1649 d
->fxState
[0].offset
= offsetof(VexGuestMIPS64State
, guest_MSACSR
);
1651 d
->fxState
[0].offset
= offsetof(VexGuestMIPS32State
, guest_MSACSR
);
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
);
1662 stmt(IRStmt_Dirty(d
));
1663 putMSACSR(mkexpr(msacsr
));
1666 static IRExpr
*getULR(void)
1669 return IRExpr_Get(offsetof(VexGuestMIPS64State
, guest_ULR
), Ity_I64
);
1671 return IRExpr_Get(offsetof(VexGuestMIPS32State
, guest_ULR
), Ity_I32
);
1674 static void putIReg(UInt archreg
, IRExpr
* e
)
1676 IRType ty
= mode64
? Ity_I64
: Ity_I32
;
1677 vassert(archreg
< 32);
1678 vassert(typeOfIRExpr(irsb
->tyenv
, e
) == ty
);
1680 stmt(IRStmt_Put(integerGuestRegOffset(archreg
), 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
))));
1691 static IRExpr
*mkNarrowTo32(IRType ty
, IRExpr
* src
)
1693 vassert(ty
== Ity_I32
|| ty
== Ity_I64
);
1694 return ty
== Ity_I64
? unop(Iop_64to32
, src
) : src
;
1697 static void putLO(IRExpr
* e
)
1700 stmt(IRStmt_Put(offsetof(VexGuestMIPS64State
, guest_LO
), e
));
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
1706 IRTemp t_lo
= newTemp(Ity_I32
);
1707 IRTemp t_hi
= newTemp(Ity_I32
);
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
))));
1715 static void putHI(IRExpr
* e
)
1718 stmt(IRStmt_Put(offsetof(VexGuestMIPS64State
, guest_HI
), e
));
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
1724 IRTemp t_lo
= newTemp(Ity_I32
);
1725 IRTemp t_hi
= newTemp(Ity_I32
);
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
))));
1733 /* Put value to accumulator(helper function for MIPS32 DSP ASE instructions). */
1734 static void putAcc(UInt acNo
, IRExpr
* e
)
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. */
1743 putLO(unop(Iop_64to32
, e
));
1744 putHI(unop(Iop_64HIto32
, e
));
1748 static IRExpr
*mkNarrowTo8 ( IRType ty
, IRExpr
* src
)
1750 vassert(ty
== Ity_I32
|| ty
== Ity_I64
);
1751 return ty
== Ity_I64
? unop(Iop_64to8
, src
) : unop(Iop_32to8
, src
);
1754 static IRExpr
*mkNarrowTo16 ( IRType ty
, IRExpr
* src
)
1756 vassert(ty
== Ity_I32
|| ty
== Ity_I64
);
1757 return ty
== Ity_I64
? unop(Iop_64to16
, src
) : unop(Iop_32to16
, src
);
1760 static void putPC(IRExpr
* e
)
1762 stmt(IRStmt_Put(OFFB_PC
, e
));
1765 static IRExpr
*mkWidenFrom32(IRType ty
, IRExpr
* src
, Bool sined
)
1767 vassert(ty
== Ity_I32
|| ty
== Ity_I64
);
1770 return (sined
) ? unop(Iop_32Sto64
, src
) : unop(Iop_32Uto64
, src
);
1773 /* Narrow 8/16/32 bit int expr to 8/16/32. Clearly only some
1774 of these combinations make sense. */
1775 static IRExpr
*narrowTo(IRType dst_ty
, IRExpr
* e
)
1777 IRType src_ty
= typeOfIRExpr(irsb
->tyenv
, e
);
1778 if (src_ty
== dst_ty
)
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
) {
1786 return unop(Iop_64to8
, e
);
1788 if (src_ty
== Ity_I64
&& dst_ty
== Ity_I16
) {
1790 return unop(Iop_64to16
, e
);
1792 vpanic("narrowTo(mips)");
1796 static IRExpr
*getLoFromF64(IRType ty
, IRExpr
* src
)
1798 vassert(ty
== Ity_F32
|| ty
== Ity_F64
);
1799 if (ty
== Ity_F64
) {
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
));
1810 static inline IRExpr
*getHiFromF64(IRExpr
* src
)
1812 vassert(typeOfIRExpr(irsb
->tyenv
, src
) == Ity_F64
);
1813 return unop(Iop_ReinterpI32asF32
, unop(Iop_64HIto32
,
1814 unop(Iop_ReinterpF64asI64
, src
)));
1817 static IRExpr
*mkWidenFromF32(IRType ty
, IRExpr
* src
)
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
));
1830 /* Convenience function to move to next instruction on condition. */
1831 static void mips_next_insn_if(IRExpr
*condition
) {
1832 vassert(typeOfIRExpr(irsb
->tyenv
, condition
) == Ity_I1
);
1834 stmt(IRStmt_Exit(condition
, Ijk_Boring
,
1835 mode64
? IRConst_U64(guest_PC_curr_instr
+ 4) :
1836 IRConst_U32(guest_PC_curr_instr
+ 4),
1840 static IRExpr
*dis_branch_likely(IRExpr
* guard
, UInt imm
)
1842 ULong branch_offset
;
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. */
1851 branch_offset
= extend_s_18to64(imm
<< 2);
1853 branch_offset
= extend_s_18to32(imm
<< 2);
1855 t0
= newTemp(Ity_I1
);
1859 stmt(IRStmt_Exit(mkexpr(t0
), Ijk_Boring
,
1860 IRConst_U64(guest_PC_curr_instr
+ 8), OFFB_PC
));
1862 stmt(IRStmt_Exit(mkexpr(t0
), Ijk_Boring
,
1863 IRConst_U32(guest_PC_curr_instr
+ 8), OFFB_PC
));
1865 irsb
->jumpkind
= Ijk_Boring
;
1868 return mkU64(guest_PC_curr_instr
+ 4 + branch_offset
);
1870 return mkU32(guest_PC_curr_instr
+ 4 + branch_offset
);
1873 static void dis_branch(Bool link
, IRExpr
* guard
, UInt imm
, IRStmt
** set
)
1875 ULong branch_offset
;
1878 if (link
) { /* LR (GPR31) = addr of the 2nd instr after branch instr */
1880 putIReg(31, mkU64(guest_PC_curr_instr
+ 8));
1882 putIReg(31, mkU32(guest_PC_curr_instr
+ 8));
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. */
1892 branch_offset
= extend_s_18to64(imm
<< 2);
1894 branch_offset
= extend_s_18to32(imm
<< 2);
1896 t0
= newTemp(Ity_I1
);
1899 *set
= IRStmt_Exit(mkexpr(t0
), link
? Ijk_Call
: Ijk_Boring
,
1900 IRConst_U64(guest_PC_curr_instr
+ 4 + branch_offset
),
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
);
1908 static void dis_branch_compact(Bool link
, IRExpr
* guard
, UInt imm
,
1911 ULong branch_offset
;
1914 if (link
) { /* LR (GPR31) = addr of the instr after branch instr */
1916 putIReg(31, mkU64(guest_PC_curr_instr
+ 4));
1918 putIReg(31, mkU32(guest_PC_curr_instr
+ 4));
1919 dres
->jk_StopHere
= Ijk_Call
;
1921 dres
->jk_StopHere
= Ijk_Boring
;
1924 dres
->whatNext
= Dis_StopHere
;
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. */
1933 branch_offset
= extend_s_18to64(imm
<< 2);
1935 branch_offset
= extend_s_18to32(imm
<< 2);
1937 t0
= newTemp(Ity_I1
);
1941 stmt(IRStmt_Exit(mkexpr(t0
), link
? Ijk_Call
: Ijk_Boring
,
1942 IRConst_U64(guest_PC_curr_instr
+ 4 + branch_offset
),
1944 putPC(mkU64(guest_PC_curr_instr
+ 4));
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));
1953 static IRExpr
*getFReg(UInt fregNo
)
1955 vassert(fregNo
< 32);
1956 IRType ty
= fp_mode64
? Ity_F64
: Ity_F32
;
1957 return IRExpr_Get(floatGuestRegOffset(fregNo
), ty
);
1960 static IRExpr
*getDReg(UInt dregNo
)
1962 vassert(dregNo
< 32);
1964 return IRExpr_Get(floatGuestRegOffset(dregNo
), Ity_F64
);
1966 /* Read a floating point register pair and combine their contents into a
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
);
1975 assign(t0
, getFReg(dregNo
& (~1)));
1976 assign(t1
, getFReg(dregNo
| 1));
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
)));
1987 static void putFReg(UInt dregNo
, IRExpr
* e
)
1989 vassert(dregNo
< 32);
1990 IRType ty
= fp_mode64
? Ity_F64
: Ity_F32
;
1991 vassert(typeOfIRExpr(irsb
->tyenv
, e
) == ty
);
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
)));
1999 stmt(IRStmt_Put(floatGuestRegOffset(dregNo
) - 4, mkexpr(t0
)));
2001 stmt(IRStmt_Put(floatGuestRegOffset(dregNo
) + 4, mkexpr(t0
)));
2003 stmt(IRStmt_Put(floatGuestRegOffset(dregNo
& (~1)), mkexpr(t0
)));
2006 stmt(IRStmt_Put(floatGuestRegOffset(dregNo
), e
));
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
))));
2017 static void putDReg(UInt dregNo
, IRExpr
* e
)
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
);
2027 assign(t0
, getLoFromF64(ty
, e
));
2028 #if defined (_MIPSEL)
2029 stmt(IRStmt_Put(floatGuestRegOffset(dregNo
) - 4, mkexpr(t0
)));
2031 stmt(IRStmt_Put(floatGuestRegOffset(dregNo
& (~1)), mkexpr(t0
)));
2034 assign(t0
, getHiFromF64(e
));
2035 #if defined (_MIPSEL)
2036 stmt(IRStmt_Put(floatGuestRegOffset(dregNo
| 1), mkexpr(t0
)));
2038 stmt(IRStmt_Put(floatGuestRegOffset(dregNo
| 1) + 4, mkexpr(t0
)));
2043 stmt(IRStmt_Put(msaGuestRegOffset(dregNo
),
2044 binop(Iop_64HLtoV128
,
2045 unop(Iop_ReinterpF64asI64
, e
),
2046 unop(Iop_ReinterpF64asI64
, e
))));
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
);
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
)));
2063 static void setFPUCondCode(IRExpr
* e
, UInt cc
)
2066 putFCSR(binop(Iop_And32
, getFCSR(), mkU32(0xFF7FFFFF)));
2067 putFCSR(binop(Iop_Or32
, getFCSR(), binop(Iop_Shl32
, e
, mkU8(23))));
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
))));
2075 static IRExpr
* get_IR_roundingmode ( void )
2078 rounding mode | MIPS | IR
2079 ------------------------
2080 to nearest | 00 | 00
2082 to +infinity | 10 | 10
2083 to -infinity | 11 | 01
2085 IRTemp rm_MIPS
= newTemp(Ity_I32
);
2086 /* Last two bits in FCSR are rounding mode. */
2089 assign(rm_MIPS
, binop(Iop_And32
, IRExpr_Get(offsetof(VexGuestMIPS64State
,
2090 guest_FCSR
), Ity_I32
), mkU32(3)));
2092 assign(rm_MIPS
, binop(Iop_And32
, IRExpr_Get(offsetof(VexGuestMIPS32State
,
2093 guest_FCSR
), Ity_I32
), mkU32(3)));
2095 /* rm_IR = XOR( rm_MIPS32, (rm_MIPS32 << 1) & 2) */
2097 return binop(Iop_Xor32
, mkexpr(rm_MIPS
), binop(Iop_And32
,
2098 binop(Iop_Shl32
, mkexpr(rm_MIPS
), mkU8(1)), mkU32(2)));
2101 static IRExpr
* get_IR_roundingmode_MSA ( void ) {
2103 rounding mode | MIPS | IR
2104 ------------------------
2105 to nearest | 00 | 00
2107 to +infinity | 10 | 10
2108 to -infinity | 11 | 01
2110 IRTemp rm_MIPS
= newTemp(Ity_I32
);
2111 /* Last two bits in MSACSR are rounding mode. */
2114 assign(rm_MIPS
, binop(Iop_And32
, IRExpr_Get(offsetof(VexGuestMIPS64State
,
2115 guest_MSACSR
), Ity_I32
), mkU32(3)));
2117 assign(rm_MIPS
, binop(Iop_And32
, IRExpr_Get(offsetof(VexGuestMIPS32State
,
2118 guest_MSACSR
), Ity_I32
), mkU32(3)));
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)));
2125 /* sz, ULong -> IRExpr */
2126 static IRExpr
*mkSzImm ( IRType ty
, ULong imm64
)
2128 vassert(ty
== Ity_I32
|| ty
== Ity_I64
);
2129 return ty
== Ity_I64
? mkU64(imm64
) : mkU32((UInt
) imm64
);
2132 static IRConst
*mkSzConst ( IRType ty
, ULong imm64
)
2134 vassert(ty
== Ity_I32
|| ty
== Ity_I64
);
2135 return (ty
== Ity_I64
? IRConst_U64(imm64
) : IRConst_U32((UInt
) imm64
));
2138 /* Make sure we get valid 32 and 64bit addresses */
2139 static Addr64
mkSzAddr ( IRType ty
, Addr64 addr
)
2141 vassert(ty
== Ity_I32
|| ty
== Ity_I64
);
2142 return (ty
== Ity_I64
? (Addr64
) addr
:
2143 (Addr64
) extend_s_32to64(toUInt(addr
)));
2146 /* Shift and Rotate instructions for MIPS64 */
2147 static Bool
dis_instr_shrt ( UInt theInstr
)
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
);
2162 assign(tmpRs
, getIReg(regRs
));
2163 assign(tmpRt
, getIReg(regRt
));
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 */
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
));
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
);
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
));
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
);
2230 (tmpRt << s) | (tmpRt >> m) */
2232 assign(tmp64
, binop(Iop_And64
, mkexpr(tmpRs
), mkSzImm(ty
, 63)));
2233 assign(tmp
, binop(Iop_Sub64
, mkU64(63), mkexpr(tmp64
)));
2235 assign(tmpLs8
, mkNarrowTo8(ty
, mkexpr(tmp
)));
2236 assign(tmpRs8
, mkNarrowTo8(ty
, mkexpr(tmp64
)));
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
)));
2243 putIReg(regRd
, mkexpr(tmpOr
));
2248 case 0x38: /* Doubleword Shift Left Logical - DSLL; MIPS64 */
2249 DIP("dsll r%u, r%u, %lld", regRd
, regRt
, sImmsa
);
2251 assign(tmpRd
, binop(Iop_Shl64
, mkexpr(tmpRt
), mkU8(uImmsa
)));
2252 putIReg(regRd
, mkexpr(tmpRd
));
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
));
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
);
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
));
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
));
2278 case 0x3F: /* Doubleword Shift Right Arithmetic Plus 32 - DSRA32;
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
));
2285 case 0x17: { /* Doubleword Shift Right Arithmetic Variable - DSRAV;
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
));
2304 static IROp
mkSzOp ( IRType ty
, IROp op8
)
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));
2316 /*********************************************************/
2317 /*--- Floating Point Compare ---*/
2318 /*********************************************************/
2319 /* Function that returns a string that represent mips cond
2320 mnemonic for the input code. */
2321 static const HChar
* showCondCode(UInt 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;
2345 static Bool
dis_instr_CCondFmt ( UInt cins
)
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
);
2356 if (FC
== 0x3) { /* C.cond.fmt */
2357 UInt fpc_cc
= get_fpc_cc(cins
);
2359 case 0x10: { /* C.cond.S */
2360 DIP("c.%s.s %u, f%u, f%u", showCondCode(cond
), fpc_cc
, fs
, ft
);
2362 t0
= newTemp(Ity_I32
);
2363 t1
= newTemp(Ity_I32
);
2364 t2
= newTemp(Ity_I32
);
2365 t3
= newTemp(Ity_I32
);
2367 tmp5
= newTemp(Ity_F64
);
2368 tmp6
= newTemp(Ity_F64
);
2370 assign(tmp5
, unop(Iop_F32toF64
, getLoFromF64(Ity_F64
,
2372 assign(tmp6
, unop(Iop_F32toF64
, getLoFromF64(Ity_F64
,
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 --------------------------
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))),
2394 putLO(mkWidenFrom32(mode64
? Ity_I64
: Ity_I32
,
2395 mkexpr(ccMIPS
), True
));
2398 assign(t0
, binop(Iop_And32
, mkexpr(ccMIPS
), mkU32(0x1)));
2400 assign(t1
, binop(Iop_And32
, binop(Iop_Shr32
, mkexpr(ccMIPS
),
2401 mkU8(0x1)), mkU32(0x1)));
2403 assign(t2
, binop(Iop_And32
, unop(Iop_Not32
, binop(Iop_Shr32
,
2404 mkexpr(ccMIPS
), mkU8(0x2))),mkU32(0x1)));
2406 assign(t3
, binop(Iop_And32
, binop(Iop_Shr32
, mkexpr(ccMIPS
),
2407 mkU8(0x3)), mkU32(0x1)));
2410 setFPUCondCode(mkU32(0), fpc_cc
);
2413 setFPUCondCode(mkexpr(t0
), fpc_cc
);
2416 setFPUCondCode(mkexpr(t1
), fpc_cc
);
2419 setFPUCondCode(binop(Iop_Or32
, mkexpr(t0
), mkexpr(t1
)),
2423 setFPUCondCode(mkexpr(t3
), fpc_cc
);
2426 setFPUCondCode(binop(Iop_Or32
, mkexpr(t0
), mkexpr(t3
)),
2430 setFPUCondCode(binop(Iop_Or32
, mkexpr(t3
), mkexpr(t1
)),
2434 setFPUCondCode(mkexpr(t2
), fpc_cc
);
2437 setFPUCondCode(mkU32(0), fpc_cc
);
2440 setFPUCondCode(mkexpr(t0
), fpc_cc
);
2443 setFPUCondCode(mkexpr(t1
), fpc_cc
);
2446 setFPUCondCode(binop(Iop_Or32
, mkexpr(t0
), mkexpr(t1
)),
2450 setFPUCondCode(mkexpr(t3
), fpc_cc
);
2453 setFPUCondCode(binop(Iop_Or32
, mkexpr(t0
), mkexpr(t3
)),
2457 setFPUCondCode(binop(Iop_Or32
, mkexpr(t3
), mkexpr(t1
)),
2461 setFPUCondCode(mkexpr(t2
), fpc_cc
);
2469 t0
= newTemp(Ity_I32
);
2470 t1
= newTemp(Ity_I32
);
2471 t2
= newTemp(Ity_I32
);
2472 t3
= newTemp(Ity_I32
);
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 --------------------------
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))),
2494 assign(t0
, binop(Iop_And32
, mkexpr(ccMIPS
), mkU32(0x1)));
2496 assign(t1
, binop(Iop_And32
, binop(Iop_Shr32
, mkexpr(ccMIPS
),
2497 mkU8(0x1)), mkU32(0x1)));
2499 assign(t2
, binop(Iop_And32
, unop(Iop_Not32
, binop(Iop_Shr32
,
2500 mkexpr(ccMIPS
), mkU8(0x2))), mkU32(0x1)));
2502 assign(t3
, binop(Iop_And32
, binop(Iop_Shr32
, mkexpr(ccMIPS
),
2503 mkU8(0x3)), mkU32(0x1)));
2507 setFPUCondCode(mkU32(0), fpc_cc
);
2510 setFPUCondCode(mkexpr(t0
), fpc_cc
);
2513 setFPUCondCode(mkexpr(t1
), fpc_cc
);
2516 setFPUCondCode(binop(Iop_Or32
, mkexpr(t0
), mkexpr(t1
)),
2520 setFPUCondCode(mkexpr(t3
), fpc_cc
);
2523 setFPUCondCode(binop(Iop_Or32
, mkexpr(t0
), mkexpr(t3
)),
2527 setFPUCondCode(binop(Iop_Or32
, mkexpr(t3
), mkexpr(t1
)),
2531 setFPUCondCode(mkexpr(t2
), fpc_cc
);
2534 setFPUCondCode(mkU32(0), fpc_cc
);
2537 setFPUCondCode(mkexpr(t0
), fpc_cc
);
2540 setFPUCondCode(mkexpr(t1
), fpc_cc
);
2543 setFPUCondCode(binop(Iop_Or32
, mkexpr(t0
), mkexpr(t1
)),
2547 setFPUCondCode(mkexpr(t3
), fpc_cc
);
2550 setFPUCondCode(binop(Iop_Or32
, mkexpr(t0
), mkexpr(t3
)),
2554 setFPUCondCode(binop(Iop_Or32
, mkexpr(t3
), mkexpr(t1
)),
2558 setFPUCondCode(mkexpr(t2
), fpc_cc
);
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 --------------------------
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))),
2593 assign(t0
, binop(Iop_And32
, mkexpr(ccMIPS
), mkU32(0x1)));
2595 assign(t1
, binop(Iop_And32
, binop(Iop_Shr32
, mkexpr(ccMIPS
),
2596 mkU8(0x1)), mkU32(0x1)));
2598 assign(t2
, binop(Iop_And32
, unop(Iop_Not32
, binop(Iop_Shr32
,
2599 mkexpr(ccMIPS
), mkU8(0x2))), mkU32(0x1)));
2601 assign(t3
, binop(Iop_And32
, binop(Iop_Shr32
, mkexpr(ccMIPS
),
2602 mkU8(0x3)), mkU32(0x1)));
2606 setFPUCondCode(mkU32(0), fpc_cc
);
2609 setFPUCondCode(mkexpr(t0
), fpc_cc
);
2612 setFPUCondCode(mkexpr(t1
), fpc_cc
);
2615 setFPUCondCode(binop(Iop_Or32
, mkexpr(t0
), mkexpr(t1
)),
2619 setFPUCondCode(mkexpr(t3
), fpc_cc
);
2622 setFPUCondCode(binop(Iop_Or32
, mkexpr(t0
), mkexpr(t3
)),
2626 setFPUCondCode(binop(Iop_Or32
, mkexpr(t3
), mkexpr(t1
)),
2630 setFPUCondCode(mkexpr(t2
), fpc_cc
);
2633 setFPUCondCode(mkU32(0), fpc_cc
);
2636 setFPUCondCode(mkexpr(t0
), fpc_cc
);
2639 setFPUCondCode(mkexpr(t1
), fpc_cc
);
2642 setFPUCondCode(binop(Iop_Or32
, mkexpr(t0
), mkexpr(t1
)),
2646 setFPUCondCode(mkexpr(t3
), fpc_cc
);
2649 setFPUCondCode(binop(Iop_Or32
, mkexpr(t0
), mkexpr(t3
)),
2653 setFPUCondCode(binop(Iop_Or32
, mkexpr(t3
), mkexpr(t1
)),
2657 setFPUCondCode(mkexpr(t2
), fpc_cc
);
2675 /*********************************************************/
2676 /*--- Branch Instructions for mips64 ---*/
2677 /*********************************************************/
2678 static Bool
dis_instr_branch ( UInt theInstr
, DisResult
* dres
,
2679 Bool(*resteerOkFn
) (void *, Addr
),
2680 void *callback_opaque
, IRStmt
** set
)
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
;
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
);
2697 UChar regLnk
= 31; /* reg 31 is link reg in MIPS */
2699 Addr64 cia
= guest_PC_curr_instr
;
2701 IRExpr
*eConst0
= mkSzImm(ty
, (UInt
) 0);
2702 IRExpr
*eNia
= mkSzImm(ty
, cia
+ 8);
2703 IRExpr
*eCond
= NULL
;
2705 assign(tmpRs
, getIReg(regRs
));
2706 assign(tmpRt
, getIReg(regRt
));
2707 assign(tmpReg0
, getIReg(0));
2709 eCond
= binop(mkSzOp(ty
, Iop_CmpNE8
), mkexpr(tmpReg0
), mkexpr(tmpReg0
));
2714 case 0x00: { /* BLTZ rs, offset */
2715 addrTgt
= mkSzAddr(ty
, cia
+ 4 + (sOffset
<< 2));
2716 IRTemp tmpLtRes
= newTemp(Ity_I1
);
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
)));
2723 eCond
= binop(mkSzOp(ty
, Iop_CmpNE8
), mkexpr(tmpLt
),
2726 jmpKind
= Ijk_Boring
;
2730 case 0x01: { /* BGEZ rs, offset */
2731 IRTemp tmpLtRes
= newTemp(Ity_I1
);
2732 addrTgt
= mkSzAddr(ty
, cia
+ 4 + (sOffset
<< 2));
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
),
2741 jmpKind
= Ijk_Boring
;
2745 case 0x11: { /* BGEZAL rs, offset */
2746 addrTgt
= mkSzAddr(ty
, cia
+ 4 + (sOffset
<< 2));
2747 putIReg(regLnk
, eNia
);
2748 IRTemp tmpLtRes
= newTemp(Ity_I1
);
2750 assign(tmpLtRes
, binop(opSlt
, mkexpr(tmpRs
), eConst0
));
2751 assign(tmpLt
, mode64
? unop(Iop_1Uto64
, mkexpr(tmpLtRes
)) :
2752 unop(Iop_1Uto32
, mkexpr(tmpLtRes
)));
2754 eCond
= binop(mkSzOp(ty
, Iop_CmpEQ8
), mkexpr(tmpLt
),
2761 case 0x10: { /* BLTZAL rs, offset */
2762 IRTemp tmpLtRes
= newTemp(Ity_I1
);
2763 IRTemp tmpRes
= newTemp(ty
);
2765 addrTgt
= mkSzAddr(ty
, cia
+ 4 + (sOffset
<< 2));
2766 putIReg(regLnk
, eNia
);
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
),
2784 *set
= IRStmt_Exit(eCond
, jmpKind
, mkSzConst(ty
, addrTgt
), OFFB_PC
);
2788 /*********************************************************/
2789 /*--- Cavium Specific Instructions ---*/
2790 /*********************************************************/
2792 /* Convenience function to yield to thread scheduler */
2793 static void jump_back(IRExpr
*condition
)
2795 stmt( IRStmt_Exit(condition
,
2797 IRConst_U64( guest_PC_curr_instr
),
2801 /* Based on s390_irgen_load_and_add32. */
2802 static void mips_load_store32(IRTemp op1addr
, IRTemp new_val
,
2803 IRTemp expd
, UChar rd
, Bool putIntoRd
)
2806 IRTemp old_mem
= newTemp(Ity_I32
);
2807 IRType ty
= mode64
? Ity_I64
: Ity_I32
;
2809 cas
= mkIRCAS(IRTemp_INVALID
, old_mem
,
2810 #if defined (_MIPSEL)
2811 Iend_LE
, mkexpr(op1addr
),
2813 Iend_BE
, mkexpr(op1addr
),
2815 NULL
, mkexpr(expd
), /* expected value */
2816 NULL
, mkexpr(new_val
) /* new value */);
2817 stmt(IRStmt_CAS(cas
));
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
)));
2823 putIReg(rd
, mkWidenFrom32(ty
, mkexpr(old_mem
), True
));
2826 /* Based on s390_irgen_load_and_add64. */
2827 static void mips_load_store64(IRTemp op1addr
, IRTemp new_val
,
2828 IRTemp expd
, UChar rd
, Bool putIntoRd
)
2831 IRTemp old_mem
= newTemp(Ity_I64
);
2833 cas
= mkIRCAS(IRTemp_INVALID
, old_mem
,
2834 #if defined (_MIPSEL)
2835 Iend_LE
, mkexpr(op1addr
),
2837 Iend_BE
, mkexpr(op1addr
),
2839 NULL
, mkexpr(expd
), /* expected value */
2840 NULL
, mkexpr(new_val
) /* new value */);
2841 stmt(IRStmt_CAS(cas
));
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
)));
2847 putIReg(rd
, mkexpr(old_mem
));
2850 static Bool
dis_instr_CVM ( UInt theInstr
)
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
);
2869 assign(tmpRs
, getIReg(regRs
));
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
)));
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
,
2891 mkNarrowTo32(ty
, getIReg(regRt
))));
2892 mips_load_store32(addr
, new_val
, old
, 0, False
);
2896 /* Store Atomic Add Doubleword - SAAD; Cavium OCTEON */
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
,
2907 mips_load_store64(addr
, new_val
, old
, 0, False
);
2911 /* LAI, LAID, LAD, LADD, LAS, LASD,
2912 LAC, LACD, LAA, LAAD, LAW, LAWD */
2914 UInt opc3
= get_sa(theInstr
);
2915 IRTemp addr
= newTemp(Ity_I64
);
2917 /* Load Atomic Increment Word - LAI; Cavium OCTEON2 */
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
,
2927 mips_load_store32(addr
, new_val
, old
, regRd
, True
);
2930 /* Load Atomic Increment Doubleword - LAID; Cavium OCTEON2 */
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
,
2940 mips_load_store64(addr
, new_val
, old
, regRd
, True
);
2943 /* Load Atomic Decrement Word - LAD; Cavium OCTEON2 */
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
,
2953 mips_load_store32(addr
, new_val
, old
, regRd
, True
);
2956 /* Load Atomic Decrement Doubleword - LADD; Cavium OCTEON2 */
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
,
2966 mips_load_store64(addr
, new_val
, old
, regRd
, True
);
2969 /* Load Atomic Set Word - LAS; Cavium OCTEON2 */
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
);
2980 /* Load Atomic Set Doubleword - LASD; Cavium OCTEON2 */
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
);
2991 /* Load Atomic Clear Word - LAC; Cavium OCTEON2 */
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
);
3002 /* Load Atomic Clear Doubleword - LACD; Cavium OCTEON2 */
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
);
3013 /* Load Atomic Add Word - LAA; Cavium OCTEON2 */
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
,
3022 mkNarrowTo32(ty
, getIReg(regRt
))));
3023 mips_load_store32(addr
, new_val
, old
, regRd
, True
);
3026 /* Load Atomic Add Doubleword - LAAD; Cavium OCTEON2 */
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
)),
3036 mips_load_store64(addr
, new_val
, old
, regRd
, True
);
3039 /* Load Atomic Swap Word - LAW; Cavium OCTEON2 */
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
);
3050 /* Load Atomic Swap Doubleword - LAWD; Cavium OCTEON2 */
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
);
3062 vex_printf("Unknown laxx instruction, opc3=0x%x\n", opc3
);
3063 vex_printf("Instruction=0x%08x\n", theInstr
);
3069 /* Unsigned Byte Add - BADDU rd, rs, rt; Cavium OCTEON */
3071 DIP("BADDU r%u, r%u, r%u", regRs
, regRt
, regRd
);
3072 IRTemp t0
= newTemp(Ity_I8
);
3074 assign(t0
, binop(Iop_Add8
,
3075 mkNarrowTo8(ty
, getIReg(regRs
)),
3076 mkNarrowTo8(ty
, getIReg(regRt
))));
3079 putIReg(regRd
, binop(mkSzOp(ty
, Iop_And8
),
3080 unop(Iop_8Uto64
, mkexpr(t0
)),
3081 mkSzImm(ty
, 0xFF)));
3083 putIReg(regRd
, binop(mkSzOp(ty
, Iop_And8
),
3084 unop(Iop_8Uto32
, mkexpr(t0
)),
3085 mkSzImm(ty
, 0xFF)));
3089 case 0x2c: { /* Count Ones in a Word - POP; Cavium OCTEON */
3092 IRTemp old
= newTemp(ty
);
3093 IRTemp nyu
= IRTemp_INVALID
;
3094 assign(old
, getIReg(regRs
));
3095 DIP("pop r%u, r%u", regRd
, regRs
);
3097 for (i
= 0; i
< 5; i
++) {
3098 mask
[i
] = newTemp(ty
);
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));
3108 for (i
= 0; i
< 5; i
++) {
3113 mkexpr(old
), mkexpr(mask
[i
])),
3116 mkexpr(old
), mkU8(shift
[i
])),
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
));
3128 for (i
= 0; i
< 5; i
++) {
3133 mkexpr(old
), mkexpr(mask
[i
])),
3136 mkexpr(old
), mkU8(shift
[i
])),
3141 putIReg(regRd
, mkexpr(nyu
));
3145 /* Count Ones in a Doubleword - DPOP; Cavium OCTEON */
3149 IRTemp old
= newTemp(ty
);
3150 IRTemp nyu
= IRTemp_INVALID
;
3151 DIP("dpop r%u, r%u", regRd
, regRs
);
3153 for (i
= 0; i
< 6; i
++) {
3154 mask
[i
] = newTemp(ty
);
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
);
3170 mkexpr(old
), mkexpr(mask
[i
])),
3173 mkexpr(old
), mkU8(shift
[i
])),
3177 putIReg(regRd
, mkexpr(nyu
));
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
));
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
));
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
)));
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
));
3218 case 0x2B: /* 20. SNE rd, rs, rt */
3219 DIP("sne r%u, r%u, r%u", regRd
,regRs
, regRt
);
3221 putIReg(regRd
, unop(Iop_1Uto64
, binop(Iop_CmpNE64
,
3225 putIReg(regRd
,unop(Iop_1Uto32
, binop(Iop_CmpNE32
,
3230 case 0x2A: /* Set Equals - SEQ; Cavium OCTEON */
3231 DIP("seq r%u, r%u, %d", regRd
, regRs
, regRt
);
3233 putIReg(regRd
, unop(Iop_1Uto64
,
3234 binop(Iop_CmpEQ64
, getIReg(regRs
),
3237 putIReg(regRd
, unop(Iop_1Uto32
,
3238 binop(Iop_CmpEQ32
, getIReg(regRs
),
3242 case 0x2E: /* Set Equals Immediate - SEQI; Cavium OCTEON */
3243 DIP("seqi r%u, r%u, %u", regRt
, regRs
, imm
);
3245 putIReg(regRt
, unop(Iop_1Uto64
,
3246 binop(Iop_CmpEQ64
, getIReg(regRs
),
3247 mkU64(extend_s_10to64(imm
)))));
3249 putIReg(regRt
, unop(Iop_1Uto32
,
3250 binop(Iop_CmpEQ32
, getIReg(regRs
),
3251 mkU32(extend_s_10to32(imm
)))));
3254 case 0x2F: /* Set Not Equals Immediate - SNEI; Cavium OCTEON */
3255 DIP("snei r%u, r%u, %u", regRt
, regRs
, imm
);
3257 putIReg(regRt
, unop(Iop_1Uto64
,
3260 mkU64(extend_s_10to64(imm
)))));
3262 putIReg(regRt
, unop(Iop_1Uto32
,
3265 mkU32(extend_s_10to32(imm
)))));
3272 } /* opc1 0x1C ends here*/
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
)),
3284 case 0x04: // LHX rd, index(base)
3285 DIP("lhx r%u, r%u(r%u)", regRd
, regRt
, regRs
);
3286 LOADX_STORE_PATTERN
;
3288 putIReg(regRd
, unop(Iop_16Sto64
, load(Ity_I16
,
3291 putIReg(regRd
, unop(Iop_16Sto32
, load(Ity_I16
,
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
)));
3301 case 0x06: { // LBUX rd, index(base)
3302 DIP("lbux r%u, r%u(r%u)", regRd
, regRt
, regRs
);
3303 LOADX_STORE_PATTERN
;
3305 putIReg(regRd
, unop(Iop_8Uto64
, load(Ity_I8
,
3308 putIReg(regRd
, unop(Iop_8Uto32
, load(Ity_I8
,
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
)),
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
;
3324 unop(Iop_16Uto64
, load(Ity_I16
, mkexpr(t1
))));
3327 unop(Iop_16Uto32
, load(Ity_I16
, mkexpr(t1
))));
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
;
3335 unop(Iop_8Sto64
, load(Ity_I8
, mkexpr(t1
))));
3338 unop(Iop_8Sto32
, load(Ity_I8
, mkexpr(t1
))));
3342 vex_printf("\nUnhandled LX instruction opc3 = %x\n",
3348 } /* opc1 = 0x1F & opc2 = 0xA (LX) ends here*/
3350 } /* opc1 = 0x1F ends here*/
3353 } /* main opc1 switch ends here */
3357 /*------------------------------------------------------------*/
3358 /*--- Disassemble a single DSP ASE instruction ---*/
3359 /*------------------------------------------------------------*/
3361 static UInt
disDSPInstr_MIPS_WRK ( UInt cins
)
3363 IRTemp t0
, t1
= 0, t2
, t3
, t4
, t5
, t6
, t7
, t8
, t9
, t10
, t11
, t12
, t13
, t14
,
3365 UInt opcode
, rs
, rt
, rd
, sa
, function
, ac
, ac_mfhilo
, rddsp_mask
,
3366 wrdsp_mask
, dsp_imm
, shift
;
3368 opcode
= get_opcode(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
);
3382 case 0x00: { /* Special */
3384 case 0x10: { /* MFHI */
3385 DIP("mfhi ac%u r%u", ac_mfhilo
, rd
);
3386 putIReg(rd
, unop(Iop_64HIto32
, getAcc(ac_mfhilo
)));
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
)));
3398 case 0x12: { /* MFLO */
3399 DIP("mflo ac%u r%u", ac_mfhilo
, rd
);
3400 putIReg(rd
, unop(Iop_64to32
, getAcc(ac_mfhilo
)));
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
)));
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
));
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
,
3427 putAcc(ac
, mkexpr(t1
));
3433 case 0x1C: { /* Special2 */
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
);
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
)));
3445 putAcc(ac
, mkexpr(t3
));
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
);
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
)));
3458 putAcc(ac
, mkexpr(t3
));
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
);
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
)));
3471 putAcc(ac
, mkexpr(t3
));
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
);
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
)));
3484 putAcc(ac
, mkexpr(t3
));
3490 case 0x1F: { /* Special3 */
3492 case 0x12: { /* ABSQ_S.PH */
3494 case 0x1: { /* ABSQ_S.QB */
3495 DIP("absq_s.qb r%u, r%u", rd
, rt
);
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
);
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
,
3530 /* t3 holds abs(t0). */
3531 assign(t3
, IRExpr_ITE(mkexpr(t1
),
3533 IRExpr_ITE(mkexpr(t2
),
3540 /* Absolute value of bits 15-8. */
3541 /* t4 - input byte. */
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
,
3555 /* t3 holds abs(t4). */
3556 assign(t7
, IRExpr_ITE(mkexpr(t5
),
3558 IRExpr_ITE(mkexpr(t6
),
3565 /* Absolute value of bits 23-15. */
3566 /* t8 - input byte. */
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
,
3580 /* t3 holds abs(t8). */
3581 assign(t11
, IRExpr_ITE(mkexpr(t9
),
3583 IRExpr_ITE(mkexpr(t10
),
3590 /* Absolute value of bits 31-24. */
3591 /* t12 - input byte. */
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
,
3605 /* t15 holds abs(t12). */
3606 assign(t15
, IRExpr_ITE(mkexpr(t13
),
3608 IRExpr_ITE(mkexpr(t14
),
3615 /* t16 holds !0 if any of input bytes is 0x80 or 0
3621 unop(Iop_1Sto32
, mkexpr(t13
)),
3622 unop(Iop_1Sto32
, mkexpr(t9
))),
3623 unop(Iop_1Sto32
, mkexpr(t5
))),
3624 unop(Iop_1Sto32
, mkexpr(t1
))));
3626 putDSPControl(IRExpr_ITE(binop(Iop_CmpEQ32
,
3632 mkU32(0x00100000))));
3634 /* t17 = t15|t11|t7|t3 */
3637 binop(Iop_8HLto16
, mkexpr(t15
), mkexpr(t11
)),
3638 binop(Iop_8HLto16
, mkexpr(t7
), mkexpr(t3
))));
3640 putIReg(rd
, mkexpr(t17
));
3643 case 0x2: { /* REPL.QB */
3644 DIP("repl.qb r%u, %u", rd
, dsp_imm
);
3647 putIReg(rd
, mkU32((dsp_imm
<< 24) | (dsp_imm
<< 16) |
3648 (dsp_imm
<< 8) | (dsp_imm
)));
3651 case 0x3: { /* REPLV.QB */
3652 DIP("replv.qb r%u, r%u", rd
, rt
);
3654 t0
= newTemp(Ity_I8
);
3656 assign(t0
, unop(Iop_32to8
,
3657 binop(Iop_And32
, getIReg(rt
), mkU32(0xff))));
3660 binop(Iop_8HLto16
, mkexpr(t0
), mkexpr(t0
)),
3661 binop(Iop_8HLto16
, mkexpr(t0
), mkexpr(t0
))));
3664 case 0x4: { /* PRECEQU.PH.QBL */
3665 DIP("precequ.ph.qbl r%u, r%u", rd
, rt
);
3668 putIReg(rd
, binop(Iop_Or32
,
3681 case 0x5: { /* PRECEQU.PH.QBR */
3682 DIP("precequ.ph.qbr r%u, r%u", rd
, rt
);
3685 putIReg(rd
, binop(Iop_Or32
,
3698 case 0x6: { /* PRECEQU.PH.QBLA */
3699 DIP("precequ.ph.qbla r%u, r%u", rd
, rt
);
3702 putIReg(rd
, binop(Iop_Or32
,
3715 case 0x7: { /* PRECEQU.PH.QBRA */
3716 DIP("precequ.ph.qbra r%u, r%u", rd
, rt
);
3719 putIReg(rd
, binop(Iop_Or32
,
3732 case 0x9: { /* ABSQ_S.PH */
3733 DIP("absq_s.ph r%u, r%u", rd
, rt
);
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
);
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
,
3759 /* t3 holds abs(t0). */
3760 assign(t3
, IRExpr_ITE(mkexpr(t1
),
3762 IRExpr_ITE(mkexpr(t2
),
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
,
3782 /* t7 holds abs(t4). */
3783 assign(t7
, IRExpr_ITE(mkexpr(t5
),
3785 IRExpr_ITE(mkexpr(t6
),
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
))));
3797 putDSPControl(IRExpr_ITE(binop(Iop_CmpEQ32
,
3803 mkU32(0x00100000))));
3806 assign(t9
, binop(Iop_16HLto32
, mkexpr(t7
), mkexpr(t3
)));
3808 putIReg(rd
, mkexpr(t9
));
3811 case 0xA: { /* REPL.PH */
3812 DIP("repl.ph r%u, %u", rd
, dsp_imm
);
3814 UShort immediate
= extend_s_10to16(dsp_imm
);
3816 putIReg(rd
, mkU32(immediate
<< 16 | immediate
));
3819 case 0xB: { /* REPLV.PH */
3820 DIP("replv.ph r%u, r%u", rd
, rt
);
3823 putIReg(rd
, binop(Iop_16HLto32
,
3824 unop(Iop_32to16
, getIReg(rt
)),
3825 unop(Iop_32to16
, getIReg(rt
))));
3828 case 0xC: { /* PRECEQ.W.PHL */
3829 DIP("preceq.w.phl r%u, r%u", rd
, rt
);
3831 putIReg(rd
, binop(Iop_And32
,
3833 mkU32(0xffff0000)));
3836 case 0xD: { /* PRECEQ.W.PHR */
3837 DIP("preceq.w.phr r%u, r%u", rd
, rt
);
3839 putIReg(rd
, binop(Iop_16HLto32
,
3840 unop(Iop_32to16
, getIReg(rt
)),
3844 case 0x11: { /* ABSQ_S.W */
3845 DIP("absq_s.w r%u, r%u", rd
, rt
);
3847 t0
= newTemp(Ity_I1
);
3848 t1
= newTemp(Ity_I1
);
3849 t2
= newTemp(Ity_I32
);
3852 binop(Iop_CmpEQ32
, getIReg(rt
), mkU32(0x80000000)));
3854 putDSPControl(IRExpr_ITE(mkexpr(t0
),
3860 assign(t1
, binop(Iop_CmpLT32S
, getIReg(rt
), mkU32(0x0)));
3862 assign(t2
, IRExpr_ITE(mkexpr(t0
),
3864 IRExpr_ITE(mkexpr(t1
),
3870 putIReg(rd
, mkexpr(t2
));
3873 case 0x1B: { /* BITREV */
3874 DIP("bitrev r%u, r%u", rd
, rt
);
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
);
3885 assign(t1
, binop(Iop_Or32
,
3896 assign(t2
, binop(Iop_Or32
,
3907 assign(t3
, binop(Iop_Or32
,
3918 assign(t4
, binop(Iop_Or32
,
3929 assign(t5
, binop(Iop_Or32
,
3936 putIReg(rd
, binop(Iop_Shr32
,
3941 case 0x1C: { /* PRECEU.PH.QBL */
3942 DIP("preceu.ph.qbl r%u, r%u", rd
, rt
);
3945 putIReg(rd
, binop(Iop_Or32
,
3958 case 0x1E: { /* PRECEU.PH.QBLA */
3959 DIP("preceu.ph.qbla r%u, r%u", rd
, rt
);
3962 putIReg(rd
, binop(Iop_Or32
,
3975 case 0x1D: { /* PRECEU.PH.QBR */
3976 DIP("preceu.ph.qbr r%u, r%u", rd
, rt
);
3979 putIReg(rd
, binop(Iop_Or32
,
3987 mkU32(0x000000ff))));
3990 case 0x1F: { /* PRECEU.PH.QBRA */
3991 DIP("preceu.ph.qbra r%u, r%u", rd
, rt
);
3994 putIReg(rd
, binop(Iop_Or32
,
4000 mkU32(0x000000ff))));
4006 break; /* end of ABSQ_S.PH */
4008 case 0x38: { /* EXTR.W */
4010 case 0x0: { /* EXTR.W */
4011 DIP("extr.w r%u, ac%u, %u", rt
, ac
, rs
);
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
);
4029 assign(t0
, getAcc(ac
));
4031 assign(t1
, mkexpr(t0
));
4033 assign(t1
, binop(Iop_Sar64
, mkexpr(t0
), mkU8(rs
)));
4035 /* Check if bits 63..31 of the result in t1 aren't 0. */
4036 assign(t3
, binop(Iop_CmpNE32
,
4040 assign(t4
, binop(Iop_CmpNE32
,
4046 /* Check if bits 63..31 of the result in t1 aren't
4048 assign(t5
, binop(Iop_CmpNE32
,
4051 mkU32(0xffffffff)));
4052 assign(t6
, binop(Iop_CmpNE32
,
4057 mkU32(0x80000000)));
4058 /* If bits 63..31 aren't 0 nor 0x1ffffffff, set DSP
4059 control register. */
4060 assign(t7
, binop(Iop_And32
,
4062 unop(Iop_1Sto32
, mkexpr(t3
)),
4063 unop(Iop_1Sto32
, mkexpr(t4
))),
4065 unop(Iop_1Sto32
, mkexpr(t5
)),
4066 unop(Iop_1Sto32
, mkexpr(t6
)))));
4067 putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32
,
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
4081 assign(t8
, mkU64(0x0ULL
));
4083 assign(t8
, binop(Iop_And64
,
4089 assign(t9
, binop(Iop_Add64
, mkexpr(t1
), mkexpr(t8
)));
4091 /* Repeat previous steps for the rounded value. */
4092 assign(t10
, binop(Iop_CmpNE32
,
4096 assign(t11
, binop(Iop_CmpNE32
,
4103 assign(t12
, binop(Iop_CmpNE32
,
4106 mkU32(0xffffffff)));
4107 assign(t13
, binop(Iop_CmpNE32
,
4112 mkU32(0x80000000)));
4114 assign(t14
, binop(Iop_And32
,
4116 unop(Iop_1Sto32
, mkexpr(t10
)),
4117 unop(Iop_1Sto32
, mkexpr(t11
))),
4119 unop(Iop_1Sto32
, mkexpr(t12
)),
4120 unop(Iop_1Sto32
, mkexpr(t13
)))));
4121 putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32
,
4129 putIReg(rt
, unop(Iop_64to32
, mkexpr(t0
)));
4131 putIReg(rt
, unop(Iop_64to32
, mkexpr(t1
)));
4135 case 0x1: { /* EXTRV.W */
4136 DIP("extrv.w r%u, ac%u, r%u", rt
, ac
, rs
);
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
);
4155 assign(t15
, unop(Iop_32to8
,
4159 assign(t0
, getAcc(ac
));
4160 assign(t1
, binop(Iop_Sar64
, mkexpr(t0
), mkexpr(t15
)));
4161 putIReg(rt
, IRExpr_ITE(binop(Iop_CmpEQ32
,
4165 unop(Iop_64to32
, mkexpr(t0
)),
4166 unop(Iop_64to32
, mkexpr(t1
))));
4168 /* Check if bits 63..31 of the result in t1 aren't 0. */
4169 assign(t3
, binop(Iop_CmpNE32
,
4173 assign(t4
, binop(Iop_CmpNE32
,
4179 /* Check if bits 63..31 of the result in t1 aren't
4181 assign(t5
, binop(Iop_CmpNE32
,
4184 mkU32(0xffffffff)));
4185 assign(t6
, binop(Iop_CmpNE32
,
4190 mkU32(0x80000000)));
4191 /* If bits 63..31 aren't 0 nor 0x1ffffffff, set DSP
4192 control register. */
4193 assign(t7
, binop(Iop_And32
,
4195 unop(Iop_1Sto32
, mkexpr(t3
)),
4196 unop(Iop_1Sto32
, mkexpr(t4
))),
4198 unop(Iop_1Sto32
, mkexpr(t5
)),
4199 unop(Iop_1Sto32
, mkexpr(t6
)))));
4200 putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32
,
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
4214 IRExpr_ITE(binop(Iop_CmpEQ32
,
4229 assign(t9
, binop(Iop_Add64
, mkexpr(t1
), mkexpr(t8
)));
4231 /* Repeat previous steps for the rounded value. */
4232 assign(t10
, binop(Iop_CmpNE32
,
4236 assign(t11
, binop(Iop_CmpNE32
,
4243 assign(t12
, binop(Iop_CmpNE32
,
4246 mkU32(0xffffffff)));
4247 assign(t13
, binop(Iop_CmpNE32
,
4252 mkU32(0x80000000)));
4254 assign(t14
, binop(Iop_And32
,
4256 unop(Iop_1Sto32
, mkexpr(t10
)),
4257 unop(Iop_1Sto32
, mkexpr(t11
))),
4259 unop(Iop_1Sto32
, mkexpr(t12
)),
4260 unop(Iop_1Sto32
, mkexpr(t13
)))));
4261 putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32
,
4270 case 0x2: { /* EXTP */
4271 DIP("extp r%u, ac%u, %u", rt
, ac
, rs
);
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
);
4282 assign(t0
, getAcc(ac
));
4283 /* Extract pos field of DSPControl register. */
4284 assign(t1
, binop(Iop_And32
, getDSPControl(), mkU32(0x3f)));
4286 /* Check if (pos - size) >= 0 [size <= pos]
4288 put 1 to EFI field of DSPControl register
4290 extract bits from acc and put 0 to EFI field of
4292 assign(t2
, binop(Iop_CmpLT32U
, mkexpr(t1
), mkU32(rs
)));
4294 putDSPControl(IRExpr_ITE(mkexpr(t2
),
4302 mkU32(0xffffbfff))));
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)));
4312 IRExpr_ITE(mkexpr(t3
),
4315 mkexpr(t1
), mkU32(rs
))),
4318 mkU32(63), mkexpr(t1
)))));
4320 assign(t5
, IRExpr_ITE(mkexpr(t3
),
4322 mkexpr(t0
), mkexpr(t4
)),
4324 mkexpr(t0
), mkexpr(t4
))));
4326 /* t6 holds a mask for bit extraction */
4328 IRExpr_ITE(mkexpr(t3
),
4331 mkU64(0xffffffffffffffffULL
),
4335 mkU64(0xffffffffffffffffULL
),
4338 assign(t7
, IRExpr_ITE(mkexpr(t3
),
4350 putIReg(rt
, mkexpr(t7
));
4353 case 0x3: { /* EXTPV */
4354 DIP("extpv r%u, ac%u, r%u", rt
, ac
, rs
);
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
);
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)));
4371 /* Check if (pos - size) >= 0 [size <= pos]
4373 put 1 to EFI field of DSPControl register
4375 extract bits from acc and put 0 to EFI field of
4377 assign(t2
, binop(Iop_CmpLT32U
, mkexpr(t1
), mkexpr(t8
)));
4379 putDSPControl(IRExpr_ITE(mkexpr(t2
),
4387 mkU32(0xffffbfff))));
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)
4395 assign(t3
, binop(Iop_CmpLE32U
, mkexpr(t1
), mkU32(31)));
4398 IRExpr_ITE(mkexpr(t3
),
4401 mkexpr(t1
), mkexpr(t8
))),
4404 mkU32(63), mkexpr(t1
)))));
4406 assign(t5
, IRExpr_ITE(mkexpr(t3
),
4408 mkexpr(t0
), mkexpr(t4
)),
4410 mkexpr(t0
), mkexpr(t4
))));
4412 /* t6 holds a mask for bit extraction. */
4414 IRExpr_ITE(mkexpr(t3
),
4417 mkU64(0xffffffffffffffffULL
),
4424 mkU64(0xffffffffffffffffULL
),
4430 assign(t7
, IRExpr_ITE(mkexpr(t3
),
4445 putIReg(rt
, mkexpr(t7
));
4448 case 0x4: { /* EXTR_R.W */
4449 DIP("extr_r.w r%u, ac%u, %u", rt
, ac
, rs
);
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
);
4469 assign(t0
, getAcc(ac
));
4470 assign(t16
, binop(Iop_CmpEQ32
,
4473 assign(t1
, IRExpr_ITE(mkexpr(t16
),
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
4483 assign(t15
, binop(Iop_Shr64
,
4493 IRExpr_ITE(mkexpr(t16
),
4497 mkU64(0x0000000000000001ULL
))));
4498 assign(t9
, binop(Iop_Add64
, mkexpr(t1
), mkexpr(t8
)));
4499 putIReg(rt
, unop(Iop_64to32
, mkexpr(t9
)));
4501 /* Check if bits 63..31 of the result in t1 aren't 0. */
4502 assign(t3
, binop(Iop_CmpNE32
,
4506 assign(t4
, binop(Iop_CmpNE32
,
4513 /* Check if bits 63..31 of the result in t1 aren't
4515 assign(t5
, binop(Iop_CmpNE32
,
4518 mkU32(0xffffffff)));
4519 assign(t6
, binop(Iop_CmpNE32
,
4524 mkU32(0x80000000)));
4525 /* If bits 63..31 aren't 0 nor 0x1ffffffff, set DSP
4526 control register. */
4527 assign(t7
, binop(Iop_And32
,
4529 unop(Iop_1Sto32
, mkexpr(t3
)),
4530 unop(Iop_1Sto32
, mkexpr(t4
))),
4532 unop(Iop_1Sto32
, mkexpr(t5
)),
4533 unop(Iop_1Sto32
, mkexpr(t6
)))));
4534 putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32
,
4542 /* Repeat previous steps for the rounded value. */
4543 assign(t10
, binop(Iop_CmpNE32
,
4547 assign(t11
, binop(Iop_CmpNE32
,
4554 assign(t12
, binop(Iop_CmpNE32
,
4557 mkU32(0xffffffff)));
4558 assign(t13
, binop(Iop_CmpNE32
,
4563 mkU32(0x80000000)));
4565 assign(t14
, binop(Iop_And32
,
4567 unop(Iop_1Sto32
, mkexpr(t10
)),
4568 unop(Iop_1Sto32
, mkexpr(t11
))),
4570 unop(Iop_1Sto32
, mkexpr(t12
)),
4571 unop(Iop_1Sto32
, mkexpr(t13
)))));
4572 putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32
,
4581 case 0x5: { /* EXTRV_R.W */
4582 DIP("extrv_r.w r%u, ac%u, r%u", rt
, ac
, rs
);
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
);
4601 assign(t15
, unop(Iop_32to8
,
4605 assign(t0
, getAcc(ac
));
4606 assign(t1
, binop(Iop_Sar64
, mkexpr(t0
), mkexpr(t15
)));
4608 /* Check if bits 63..31 of the result in t1 aren't 0. */
4609 assign(t3
, binop(Iop_CmpNE32
,
4613 assign(t4
, binop(Iop_CmpNE32
,
4619 /* Check if bits 63..31 of the result in t1 aren't
4621 assign(t5
, binop(Iop_CmpNE32
,
4624 mkU32(0xffffffff)));
4625 assign(t6
, binop(Iop_CmpNE32
,
4630 mkU32(0x80000000)));
4631 /* If bits 63..31 aren't 0 nor 0x1ffffffff, set DSP
4632 control register. */
4633 assign(t7
, binop(Iop_And32
,
4635 unop(Iop_1Sto32
, mkexpr(t3
)),
4636 unop(Iop_1Sto32
, mkexpr(t4
))),
4638 unop(Iop_1Sto32
, mkexpr(t5
)),
4639 unop(Iop_1Sto32
, mkexpr(t6
)))));
4640 putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32
,
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
4654 IRExpr_ITE(binop(Iop_CmpEQ32
,
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
)));
4673 /* Repeat previous steps for the rounded value. */
4674 assign(t10
, binop(Iop_CmpNE32
,
4678 assign(t11
, binop(Iop_CmpNE32
,
4685 assign(t12
, binop(Iop_CmpNE32
,
4688 mkU32(0xffffffff)));
4689 assign(t13
, binop(Iop_CmpNE32
,
4694 mkU32(0x80000000)));
4696 assign(t14
, binop(Iop_And32
,
4698 unop(Iop_1Sto32
, mkexpr(t10
)),
4699 unop(Iop_1Sto32
, mkexpr(t11
))),
4701 unop(Iop_1Sto32
, mkexpr(t12
)),
4702 unop(Iop_1Sto32
, mkexpr(t13
)))));
4703 putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32
,
4712 case 0x6: { /* EXTR_RS.W */
4713 DIP("extr_rs.w r%u, ac%u, %u", rt
, ac
, rs
);
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
);
4732 assign(t0
, getAcc(ac
));
4734 assign(t1
, mkexpr(t0
));
4736 assign(t1
, binop(Iop_Sar64
, mkexpr(t0
), mkU8(rs
)));
4739 /* Check if bits 63..31 of the result in t1 aren't 0. */
4740 assign(t3
, binop(Iop_CmpNE32
,
4744 assign(t4
, binop(Iop_CmpNE32
,
4750 /* Check if bits 63..31 of the result in t1 aren't
4752 assign(t5
, binop(Iop_CmpNE32
,
4755 mkU32(0xffffffff)));
4756 assign(t6
, binop(Iop_CmpNE32
,
4761 mkU32(0x80000000)));
4762 /* If bits 63..31 aren't 0 nor 0x1ffffffff, set DSP
4763 control register. */
4764 assign(t7
, binop(Iop_And32
,
4766 unop(Iop_1Sto32
, mkexpr(t3
)),
4767 unop(Iop_1Sto32
, mkexpr(t4
))),
4769 unop(Iop_1Sto32
, mkexpr(t5
)),
4770 unop(Iop_1Sto32
, mkexpr(t6
)))));
4771 putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32
,
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
4785 assign(t8
, mkU64(0x0ULL
));
4787 assign(t8
, binop(Iop_And64
,
4794 assign(t9
, binop(Iop_Add64
, mkexpr(t1
), mkexpr(t8
)));
4796 /* Repeat previous steps for the rounded value. */
4797 assign(t10
, binop(Iop_CmpNE32
,
4801 assign(t11
, binop(Iop_CmpNE32
,
4808 assign(t12
, binop(Iop_CmpNE32
,
4811 mkU32(0xffffffff)));
4812 assign(t13
, binop(Iop_CmpNE32
,
4817 mkU32(0x80000000)));
4819 assign(t14
, binop(Iop_And32
,
4821 unop(Iop_1Sto32
, mkexpr(t10
)),
4822 unop(Iop_1Sto32
, mkexpr(t11
))),
4824 unop(Iop_1Sto32
, mkexpr(t12
)),
4825 unop(Iop_1Sto32
, mkexpr(t13
)))));
4826 putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32
,
4834 assign(t16
, binop(Iop_And32
,
4837 mkU32(0x80000000)));
4838 putIReg(rt
, IRExpr_ITE(binop(Iop_CmpNE32
,
4841 IRExpr_ITE(binop(Iop_CmpEQ32
,
4846 unop(Iop_64to32
, mkexpr(t9
))));
4849 case 0x7: { /* EXTRV_RS.W */
4850 DIP("extrv_rs.w r%u, ac%u, r%u", rt
, ac
, rs
);
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
);
4871 assign(t15
, binop(Iop_And32
,
4874 assign(t17
, binop(Iop_CmpEQ32
,
4877 assign(t0
, getAcc(ac
));
4878 assign(t1
, IRExpr_ITE(mkexpr(t17
),
4885 /* Check if bits 63..31 of the result in t1 aren't 0. */
4886 assign(t3
, binop(Iop_CmpNE32
,
4890 assign(t4
, binop(Iop_CmpNE32
,
4896 /* Check if bits 63..31 of the result in t1 aren't
4898 assign(t5
, binop(Iop_CmpNE32
,
4901 mkU32(0xffffffff)));
4902 assign(t6
, binop(Iop_CmpNE32
,
4907 mkU32(0x80000000)));
4908 /* If bits 63..31 aren't 0 nor 0x1ffffffff, set DSP
4909 control register. */
4910 assign(t7
, binop(Iop_And32
,
4912 unop(Iop_1Sto32
, mkexpr(t3
)),
4913 unop(Iop_1Sto32
, mkexpr(t4
))),
4915 unop(Iop_1Sto32
, mkexpr(t5
)),
4916 unop(Iop_1Sto32
, mkexpr(t6
)))));
4917 putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32
,
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
4931 IRExpr_ITE(mkexpr(t17
),
4942 assign(t9
, binop(Iop_Add64
, mkexpr(t1
), mkexpr(t8
)));
4944 /* Repeat previous steps for the rounded value. */
4945 assign(t10
, binop(Iop_CmpNE32
,
4949 assign(t11
, binop(Iop_CmpNE32
,
4956 assign(t12
, binop(Iop_CmpNE32
,
4959 mkU32(0xffffffff)));
4960 assign(t13
, binop(Iop_CmpNE32
,
4965 mkU32(0x80000000)));
4967 assign(t14
, binop(Iop_And32
,
4969 unop(Iop_1Sto32
, mkexpr(t10
)),
4970 unop(Iop_1Sto32
, mkexpr(t11
))),
4972 unop(Iop_1Sto32
, mkexpr(t12
)),
4973 unop(Iop_1Sto32
, mkexpr(t13
)))));
4974 putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32
,
4982 assign(t16
, binop(Iop_And32
,
4985 mkU32(0x80000000)));
4986 putIReg(rt
, IRExpr_ITE(binop(Iop_CmpNE32
,
4989 IRExpr_ITE(binop(Iop_CmpEQ32
,
4994 unop(Iop_64to32
, mkexpr(t9
))));
4997 case 0xA: { /* EXTPDP */
4998 DIP("extpdp r%u, ac%u, %u", rt
, ac
, rs
);
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
);
5010 assign(t0
, getAcc(ac
));
5011 /* Extract pos field of DSPControl register. */
5012 assign(t1
, binop(Iop_And32
, getDSPControl(), mkU32(0x3f)));
5014 /* Check if (pos - size) >= 0 [size <= pos]
5016 put 1 to EFI field of DSPControl register
5018 extract bits from acc and put 0 to EFI field of
5020 assign(t2
, binop(Iop_CmpLT32U
, mkexpr(t1
), mkU32(rs
)));
5022 assign(t8
, binop(Iop_Or32
,
5033 putDSPControl(IRExpr_ITE(mkexpr(t2
),
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.
5047 assign(t3
, binop(Iop_CmpLE32U
, mkexpr(t1
), mkU32(31)));
5050 IRExpr_ITE(mkexpr(t3
),
5053 mkexpr(t1
), mkU32(rs
))),
5056 mkU32(63), mkexpr(t1
)))));
5058 assign(t5
, IRExpr_ITE(mkexpr(t3
),
5060 mkexpr(t0
), mkexpr(t4
)),
5062 mkexpr(t0
), mkexpr(t4
))));
5064 /* t6 holds a mask for bit extraction. */
5066 IRExpr_ITE(mkexpr(t3
),
5069 mkU64(0xffffffffffffffffULL
),
5073 mkU64(0xffffffffffffffffULL
),
5076 assign(t7
, IRExpr_ITE(mkexpr(t3
),
5088 putIReg(rt
, mkexpr(t7
));
5091 case 0xB: { /* EXTPDPV */
5092 DIP("extpdpv r%u, ac%u, r%u", rt
, ac
, rs
);
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
);
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)));
5110 /* Check if (pos - size) >= 0 [size <= pos]
5112 put 1 to EFI field of DSPControl register
5114 extract bits from acc and put 0 to EFI field of
5116 assign(t2
, binop(Iop_CmpLT32U
, mkexpr(t1
), mkexpr(t8
)));
5118 assign(t9
, binop(Iop_Or32
,
5131 putDSPControl(IRExpr_ITE(mkexpr(t2
),
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.
5145 assign(t3
, binop(Iop_CmpLE32U
, mkexpr(t1
), mkU32(31)));
5148 IRExpr_ITE(mkexpr(t3
),
5151 mkexpr(t1
), mkexpr(t8
))),
5154 mkU32(63), mkexpr(t1
)))));
5156 assign(t5
, IRExpr_ITE(mkexpr(t3
),
5158 mkexpr(t0
), mkexpr(t4
)),
5160 mkexpr(t0
), mkexpr(t4
))));
5162 /* t6 holds a mask for bit extraction. */
5164 IRExpr_ITE(mkexpr(t3
),
5167 mkU64(0xffffffffffffffffULL
),
5174 mkU64(0xffffffffffffffffULL
),
5180 assign(t7
, IRExpr_ITE(mkexpr(t3
),
5195 putIReg(rt
, mkexpr(t7
));
5198 case 0xE: { /* EXTR_S.H */
5199 DIP("extr_s.h r%u, ac%u, %u", rt
, ac
, rs
);
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
);
5211 assign(t0
, getAcc(ac
));
5213 assign(t1
, binop(Iop_Sar64
, mkexpr(t0
), mkU8(rs
)));
5215 assign(t2
, binop(Iop_Or32
,
5216 getDSPControl(), mkU32(0x00800000)));
5218 assign(t9
, binop(Iop_And32
,
5221 mkU32(0x80000000)));
5222 putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32
,
5227 mkU32(0x80000000))),
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
,
5237 mkU64(0x0000000000007fffULL
)));
5238 assign(t4
, binop(Iop_And32
,
5246 mkU32(0x7fffffff)))),
5259 putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32
,
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
),
5273 assign(t7
, binop(Iop_And32
,
5281 mkU32(0x7fffffff)))),
5294 putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32
,
5301 putIReg(rt
, IRExpr_ITE(binop(Iop_CmpNE32
,
5305 IRExpr_ITE(binop(Iop_CmpNE32
,
5313 case 0xF: { /* EXTRV_S.H */
5314 DIP("extrv_s.h r%u, ac%u, %u", rt
, ac
, rs
);
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
);
5326 assign(t0
, getAcc(ac
));
5328 assign(t1
, binop(Iop_Sar64
,
5335 assign(t2
, binop(Iop_Or32
,
5336 getDSPControl(), mkU32(0x00800000)));
5338 assign(t9
, binop(Iop_And32
,
5341 mkU32(0x80000000)));
5342 putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32
,
5347 mkU32(0x80000000))),
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
,
5357 mkU64(0x0000000000007fffULL
)));
5358 assign(t4
, binop(Iop_And32
,
5366 mkU32(0x7fffffff)))),
5379 putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32
,
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
),
5393 assign(t7
, binop(Iop_And32
,
5401 mkU32(0x7fffffff)))),
5414 putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32
,
5421 putIReg(rt
, IRExpr_ITE(binop(Iop_CmpNE32
,
5425 IRExpr_ITE(binop(Iop_CmpNE32
,
5433 case 0x12: { /* RDDSP*/
5434 DIP("rddsp r%u, mask 0x%x", rd
, rddsp_mask
);
5437 putIReg(rd
, mkU32(0x0));
5439 if ((rddsp_mask
& 0x1) == 0x1) {
5440 /* Read pos field (bits 5-0) of DSPControl register. */
5441 putIReg(rd
, binop(Iop_Or32
,
5445 mkU32(0x0000003F))));
5448 if ((rddsp_mask
& 0x2) == 0x2) {
5449 /* Read scount field (bits 12-7) of DSPControl
5451 putIReg(rd
, binop(Iop_Or32
,
5455 mkU32(0x00001F80))));
5458 if ((rddsp_mask
& 0x4) == 0x4) {
5459 /* Read C field (bit 13) of DSPControl register. */
5460 putIReg(rd
, binop(Iop_Or32
,
5464 mkU32(0x00002000))));
5467 if ((rddsp_mask
& 0x8) == 0x8) {
5468 /* Read outflag field (bit s 23-16) of DSPControl
5470 putIReg(rd
, binop(Iop_Or32
,
5474 mkU32(0x00FF0000))));
5477 if ((rddsp_mask
& 0x10) == 0x10) {
5478 /* Read ccond field (bits 31-24) of DSPControl
5480 putIReg(rd
, binop(Iop_Or32
,
5484 mkU32(0xFF000000))));
5487 if ((rddsp_mask
& 0x20) == 0x20) {
5488 /* Read EFI field (bit 14) of DSPControl register. */
5489 putIReg(rd
, binop(Iop_Or32
,
5493 mkU32(0x00004000))));
5496 if ((rddsp_mask
& 0x3f) == 0x3f) {
5497 /* Read all fields of DSPControl register. */
5498 putIReg(rd
, getDSPControl());
5502 case 0x13: { /* WRDSP */
5503 DIP("wrdsp r%u, mask 0x%x", rs
, wrdsp_mask
);
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
?
5513 mkU32(0xffff7fbf)) :
5516 mkU32(0x0fff7fbf)));
5518 if ((wrdsp_mask
& 0x1) == 0x1) {
5519 /* Put bits 5-0 of rs to DSPControl register pos
5521 putDSPControl(binop(Iop_Or32
,
5527 mkU32(0x0000003F))));
5530 if ((wrdsp_mask
& 0x2) == 0x2) {
5531 /* Put bits 12-7 of rs to DSPControl scount field. */
5532 putDSPControl(binop(Iop_Or32
,
5538 mkU32(0x00001F80))));
5541 if ((wrdsp_mask
& 0x4) == 0x4) {
5542 /* Put bit 13 of rs to DSPControl register C
5544 putDSPControl(binop(Iop_Or32
,
5550 mkU32(0x00002000))));
5553 if ((wrdsp_mask
& 0x8) == 0x8) {
5554 /* Put bits 23-16 of rs to DSPControl reg outflag
5556 putDSPControl(binop(Iop_Or32
,
5562 mkU32(0x00FF0000))));
5565 if ((wrdsp_mask
& 0x10) == 0x10) {
5566 /* Put bits 31-24 of rs to DSPControl reg ccond
5568 putDSPControl(binop(Iop_Or32
,
5574 mode64
? mkU32(0xFF000000)
5575 : mkU32(0x0F000000))
5580 if ((wrdsp_mask
& 0x20) == 0x20) {
5581 /* Put bit 14 of rs to DSPControl register EFI
5583 putDSPControl(binop(Iop_Or32
,
5589 mkU32(0x00004000))));
5594 case 0x1A: { /* SHILO */
5595 DIP("shilo ac%u, %u", ac
, shift
);
5597 t0
= newTemp(Ity_I64
);
5598 t1
= newTemp(Ity_I64
);
5600 assign(t0
, getAcc(ac
));
5602 putAcc(ac
, mkexpr(t0
));
5604 if (0x20 == (shift
& 0x3f)) {
5605 putAcc(ac
, binop(Iop_32HLto64
,
5606 unop(Iop_64to32
, mkexpr(t0
)),
5608 } else if (0x20 == (shift
& 0x20)) {
5609 assign(t1
, binop(Iop_Shl64
,
5617 putAcc(ac
, mkexpr(t1
));
5619 assign(t1
, binop(Iop_Shr64
, mkexpr(t0
), mkU8(shift
)));
5621 putAcc(ac
, mkexpr(t1
));
5625 case 0x1B: { /* SHILOV */
5626 DIP("shilov ac%u, r%u", ac
, rs
);
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
);
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
,
5644 assign(t4
, binop(Iop_Shr64
,
5650 IRExpr_ITE(mkexpr(t2
),
5652 unop(Iop_64to32
, mkexpr(t0
)),
5654 IRExpr_ITE(binop(Iop_CmpEQ32
,
5663 case 0x1F: { /* MTHLIP */
5664 DIP("mthlip r%u, ac%u", rs
, ac
);
5666 t0
= newTemp(Ity_I64
);
5667 t1
= newTemp(Ity_I32
);
5668 t2
= newTemp(Ity_I32
);
5669 t3
= newTemp(Ity_I1
);
5671 assign(t0
, getAcc(ac
));
5672 putAcc(ac
, binop(Iop_32HLto64
,
5673 unop(Iop_64to32
, mkexpr(t0
)),
5675 assign(t1
, binop(Iop_And32
, getDSPControl(), mkU32(0x3f)));
5676 putDSPControl(IRExpr_ITE(binop(Iop_CmpLE32U
,
5685 mkU32(0xffffffc0))),
5692 mkU32(0xffffffc0)))));
5698 break; /* end of EXTR.W */
5700 case 0xA: { /* LX */
5702 case 0x0: { /* LWX */
5703 DIP("lwx r%u, r%u(r%u)", rd
, rt
, rs
);
5705 t0
= newTemp(Ity_I32
);
5707 assign(t0
, binop(Iop_Add32
, getIReg(rt
), getIReg(rs
)));
5709 putIReg(rd
, load(Ity_I32
, mkexpr(t0
)));
5712 case 0x4: { /* LHX */
5713 DIP("lhx r%u, r%u(r%u)", rd
, rt
, rs
);
5715 t0
= newTemp(Ity_I32
);
5717 assign(t0
, binop(Iop_Add32
, getIReg(rt
), getIReg(rs
)));
5719 putIReg(rd
, unop(Iop_16Sto32
, load(Ity_I16
, mkexpr(t0
))));
5722 case 0x6: { /* LBUX */
5723 DIP("lbux r%u, r%u(r%u)", rd
, rt
, rs
);
5725 t0
= newTemp(Ity_I32
);
5727 assign(t0
, binop(Iop_Add32
, getIReg(rt
), getIReg(rs
)));
5729 putIReg(rd
, unop(Iop_8Uto32
, load(Ity_I8
, mkexpr(t0
))));
5735 break; /* end of LX */
5737 case 0xC: { /* INSV */
5739 case 0x0: { /* INSV */
5740 DIP("insv r%u, r%u", rt
, rs
);
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
);
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
,
5763 assign(t2
, unop(Iop_32to8
,
5768 /* 32-(pos+size) most significant bits of rt. */
5769 assign(t6
, binop(Iop_Shl32
,
5775 assign(t3
, unop(Iop_32to8
,
5779 /* Pos least significant bits of rt. */
5780 assign(t7
, binop(Iop_Shr32
,
5786 /* Size least significant bits of rs,
5787 shifted to appropriate position. */
5788 assign(t8
, binop(Iop_Shl32
,
5799 putIReg(rt
, IRExpr_ITE(binop(Iop_CmpEQ32
,
5802 IRExpr_ITE(binop(Iop_CmpEQ32
,
5809 IRExpr_ITE(binop(Iop_CmpEQ32
,
5826 break; /* enf of INSV */
5828 case 0x10: { /* ADDU.QB */
5830 case 0x00: { /* ADDU.QB */
5831 DIP("addu.qb r%u, r%u, r%u", rd
, rs
, rt
);
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
);
5843 /* Add rightmost bytes of rs and rt. */
5848 unop(Iop_32to16
, getIReg(rs
)))),
5851 unop(Iop_32to16
, getIReg(rt
))))));
5852 /* t1 will be 1 if there is overflow, 0 otherwise. */
5853 assign(t1
, binop(Iop_CmpEQ32
,
5857 mkU32(0x00000100)));
5859 /* Add bits 15-8 of rs and rt. */
5864 unop(Iop_32to16
, getIReg(rs
)))),
5867 unop(Iop_32to16
, getIReg(rt
))))));
5868 /* t3 will be 1 if there is overflow, 0 otherwise. */
5869 assign(t3
, binop(Iop_CmpEQ32
,
5873 mkU32(0x00000100)));
5875 /* Add bits 15-8 of rs and rt. */
5880 unop(Iop_32HIto16
, getIReg(rs
)))),
5883 unop(Iop_32HIto16
, getIReg(rt
))))));
5884 /* t5 will be 1 if there is overflow, 0 otherwise. */
5885 assign(t5
, binop(Iop_CmpEQ32
,
5889 mkU32(0x00000100)));
5891 /* Add bits 15-8 of rs and rt. */
5896 unop(Iop_32HIto16
, getIReg(rs
)))),
5899 unop(Iop_32HIto16
, getIReg(rt
))))));
5900 /* t7 will be 1 if there is overflow, 0 otherwise. */
5901 assign(t7
, binop(Iop_CmpEQ32
,
5905 mkU32(0x00000100)));
5911 unop(Iop_1Sto32
, mkexpr(t7
)),
5912 unop(Iop_1Sto32
, mkexpr(t5
))),
5913 unop(Iop_1Sto32
, mkexpr(t3
))),
5914 unop(Iop_1Sto32
, mkexpr(t1
))));
5916 putDSPControl(IRExpr_ITE(binop(Iop_CmpEQ32
,
5922 mkU32(0x00100000))));
5924 putIReg(rd
, binop(Iop_16HLto32
,
5926 unop(Iop_32to8
, mkexpr(t6
)),
5927 unop(Iop_32to8
, mkexpr(t4
))),
5929 unop(Iop_32to8
, mkexpr(t2
)),
5930 unop(Iop_32to8
, mkexpr(t0
)))));
5933 case 0x1: { /* SUBU.QB */
5934 DIP("subu.qb r%u, r%u, r%u", rd
, rs
, rt
);
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
);
5946 /* Subtract rightmost bytes of rs and rt. */
5951 unop(Iop_32to16
, getIReg(rs
)))),
5954 unop(Iop_32to16
, getIReg(rt
))))));
5955 /* t1 will be 1 if there is overflow, 0 otherwise. */
5956 assign(t1
, binop(Iop_CmpEQ32
,
5960 mkU32(0x00000100)));
5962 /* Subtract bits 15-8 of rs and rt. */
5967 unop(Iop_32to16
, getIReg(rs
)))),
5970 unop(Iop_32to16
, getIReg(rt
))))));
5971 /* t3 will be 1 if there is overflow, 0 otherwise. */
5972 assign(t3
, binop(Iop_CmpEQ32
,
5976 mkU32(0x00000100)));
5978 /* Subtract bits 15-8 of rs and rt. */
5983 unop(Iop_32HIto16
, getIReg(rs
)))),
5986 unop(Iop_32HIto16
, getIReg(rt
))))));
5987 /* t5 will be 1 if there is overflow, 0 otherwise. */
5988 assign(t5
, binop(Iop_CmpEQ32
,
5992 mkU32(0x00000100)));
5994 /* Subtract bits 15-8 of rs and rt. */
5999 unop(Iop_32HIto16
, getIReg(rs
)))),
6002 unop(Iop_32HIto16
, getIReg(rt
))))));
6003 /* t7 will be 1 if there is overflow, 0 otherwise. */
6004 assign(t7
, binop(Iop_CmpEQ32
,
6008 mkU32(0x00000100)));
6010 assign(t8
, 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
))));
6018 putDSPControl(IRExpr_ITE(binop(Iop_CmpEQ32
,
6024 mkU32(0x00100000))));
6026 putIReg(rd
, binop(Iop_16HLto32
,
6028 unop(Iop_32to8
, mkexpr(t6
)),
6029 unop(Iop_32to8
, mkexpr(t4
))),
6031 unop(Iop_32to8
, mkexpr(t2
)),
6032 unop(Iop_32to8
, mkexpr(t0
)))));
6035 case 0x04: { /* ADDU_S.QB */
6036 DIP("addu_s.qb r%u, r%u, r%u", rd
, rs
, rt
);
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
);
6052 /* Add rightmost bytes of rs and rt. */
6057 unop(Iop_32to16
, getIReg(rs
)))),
6060 unop(Iop_32to16
, getIReg(rt
))))));
6061 /* t1 will be 1 if there is overflow, 0 otherwise. */
6062 assign(t1
, binop(Iop_CmpEQ32
,
6066 mkU32(0x00000100)));
6067 /* Saturate if necessary. */
6068 assign(t2
, IRExpr_ITE(mkexpr(t1
),
6070 unop(Iop_32to8
, mkexpr(t0
))));
6072 /* Add bits 15-8 of rs and rt. */
6077 unop(Iop_32to16
, getIReg(rs
)))),
6080 unop(Iop_32to16
, getIReg(rt
))))));
6081 /* t4 will be 1 if there is overflow, 0 otherwise. */
6082 assign(t4
, binop(Iop_CmpEQ32
,
6086 mkU32(0x00000100)));
6087 /* Saturate if necessary. */
6088 assign(t5
, IRExpr_ITE(mkexpr(t4
),
6090 unop(Iop_32to8
, mkexpr(t3
))));
6092 /* Add bits 15-8 of rs and rt. */
6097 unop(Iop_32HIto16
, getIReg(rs
)))),
6100 unop(Iop_32HIto16
, getIReg(rt
))))));
6101 /* t7 will be 1 if there is overflow, 0 otherwise. */
6102 assign(t7
, binop(Iop_CmpEQ32
,
6106 mkU32(0x00000100)));
6107 /* Saturate if necessary. */
6108 assign(t8
, IRExpr_ITE(mkexpr(t7
),
6110 unop(Iop_32to8
, mkexpr(t6
))));
6112 /* Add bits 15-8 of rs and rt. */
6117 unop(Iop_32HIto16
, getIReg(rs
)))),
6120 unop(Iop_32HIto16
, getIReg(rt
))))));
6121 /* t10 will be 1 if there is overflow, 0 otherwise. */
6122 assign(t10
, binop(Iop_CmpEQ32
,
6126 mkU32(0x00000100)));
6127 /* Saturate if necessary. */
6128 assign(t11
, IRExpr_ITE(mkexpr(t10
),
6130 unop(Iop_32to8
, mkexpr(t9
))));
6136 unop(Iop_1Sto32
, mkexpr(t10
)),
6137 unop(Iop_1Sto32
, mkexpr(t7
))),
6138 unop(Iop_1Sto32
, mkexpr(t4
))),
6139 unop(Iop_1Sto32
, mkexpr(t1
))));
6141 putDSPControl(IRExpr_ITE(binop(Iop_CmpEQ32
,
6147 mkU32(0x00100000))));
6151 binop(Iop_8HLto16
, mkexpr(t11
), mkexpr(t8
)),
6152 binop(Iop_8HLto16
, mkexpr(t5
), mkexpr(t2
))));
6155 case 0x05: { /* SUBU_S.QB */
6156 DIP("subu_s.qb r%u, r%u, r%u", rd
, rs
, rt
);
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
);
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
)));
6173 /* Subtract each byte of rs and rt. */
6178 unop(Iop_32to16
, getIReg(rs
)))),
6181 unop(Iop_32to16
, getIReg(rt
))))));
6186 unop(Iop_32to16
, getIReg(rs
)))),
6189 unop(Iop_32to16
, getIReg(rt
))))));
6194 unop(Iop_32HIto16
, getIReg(rs
)))),
6197 unop(Iop_32HIto16
, getIReg(rt
))))));
6202 unop(Iop_32HIto16
, getIReg(rs
)))),
6205 unop(Iop_32HIto16
, getIReg(rt
))))));
6207 /* Put 1 to bit 20 in DSPControl if there is underflow
6209 assign(t2
, binop(Iop_CmpEQ32
,
6213 mkU32(0x00000100)));
6214 putDSPControl(IRExpr_ITE(mkexpr(t2
),
6219 assign(t3
, binop(Iop_CmpEQ32
,
6223 mkU32(0x00000100)));
6224 putDSPControl(IRExpr_ITE(mkexpr(t3
),
6229 assign(t4
, binop(Iop_CmpEQ32
,
6233 mkU32(0x00000100)));
6234 putDSPControl(IRExpr_ITE(mkexpr(t4
),
6239 assign(t5
, binop(Iop_CmpEQ32
,
6243 mkU32(0x00000100)));
6244 putDSPControl(IRExpr_ITE(mkexpr(t5
),
6249 putIReg(rd
, mkexpr(t1
));
6252 case 0x6: { /* MULEU_S.PH.QBL */
6253 DIP("muleu_s.ph.qbl r%u, r%u, r%u", rd
, rs
, rt
);
6255 t0
= newTemp(Ity_I32
);
6256 t1
= newTemp(Ity_I32
);
6257 t2
= newTemp(Ity_I1
);
6258 t3
= newTemp(Ity_I1
);
6268 unop(Iop_32HIto16
, getIReg(rt
))))));
6277 unop(Iop_32to16
, getIReg(rt
))))));
6279 assign(t2
, binop(Iop_CmpNE32
,
6283 mkU32(0x03ff0000))));
6284 assign(t3
, binop(Iop_CmpNE32
,
6288 mkU32(0x03ff0000))));
6289 putDSPControl(IRExpr_ITE(mkexpr(t2
),
6293 IRExpr_ITE(mkexpr(t3
),
6300 IRExpr_ITE(mkexpr(t2
),
6302 unop(Iop_32to16
, mkexpr(t0
))),
6303 IRExpr_ITE(mkexpr(t3
),
6305 unop(Iop_32to16
, mkexpr(t1
)))));
6308 case 0x7: { /* MULEU_S.PH.QBR */
6309 DIP("muleu_s.ph.qbr r%u, r%u, r%u", rd
, rs
, rt
);
6311 t0
= newTemp(Ity_I32
);
6312 t1
= newTemp(Ity_I32
);
6313 t2
= newTemp(Ity_I1
);
6314 t3
= newTemp(Ity_I1
);
6316 assign(t0
, unop(Iop_64to32
,
6325 assign(t1
, unop(Iop_64to32
,
6335 assign(t2
, binop(Iop_CmpNE32
,
6339 mkU32(0x03ff0000))));
6340 assign(t3
, binop(Iop_CmpNE32
,
6344 mkU32(0x03ff0000))));
6345 putDSPControl(IRExpr_ITE(mkexpr(t2
),
6349 IRExpr_ITE(mkexpr(t3
),
6354 putIReg(rd
, binop(Iop_16HLto32
,
6355 IRExpr_ITE(mkexpr(t2
),
6359 IRExpr_ITE(mkexpr(t3
),
6365 case 0x08: { /* ADDU.PH */
6366 DIP("addu.ph r%u, r%u, r%u", rd
, rs
, rt
);
6368 t0
= newTemp(Ity_I32
);
6369 t1
= newTemp(Ity_I1
);
6370 t2
= newTemp(Ity_I32
);
6371 t3
= newTemp(Ity_I1
);
6373 /* Add lower halves. */
6374 assign(t0
, binop(Iop_Add32
,
6376 unop(Iop_32to16
, getIReg(rs
))),
6378 unop(Iop_32to16
, getIReg(rt
)))));
6380 /* Detect overflow. */
6381 assign(t1
, binop(Iop_CmpLT32U
,
6383 unop(Iop_32to16
, mkexpr(t0
))),
6385 unop(Iop_32to16
, getIReg(rs
)))));
6387 putDSPControl(IRExpr_ITE(mkexpr(t1
),
6393 /* Add higher halves. */
6394 assign(t2
, binop(Iop_Add32
,
6396 unop(Iop_32HIto16
, getIReg(rs
))),
6398 unop(Iop_32HIto16
, getIReg(rt
)))));
6400 /* Detect overflow. */
6401 assign(t3
, binop(Iop_CmpLT32U
,
6403 unop(Iop_32to16
, mkexpr(t2
))),
6408 putDSPControl(IRExpr_ITE(mkexpr(t3
),
6414 putIReg(rd
, binop(Iop_16HLto32
,
6415 unop(Iop_32to16
, mkexpr(t2
)),
6416 unop(Iop_32to16
, mkexpr(t0
))));
6419 case 0x9: { /* SUBU.PH */
6420 DIP("subu.ph r%u, r%u, r%u", rd
, rs
, rt
);
6422 t0
= newTemp(Ity_I32
);
6423 t1
= newTemp(Ity_I1
);
6424 t2
= newTemp(Ity_I32
);
6425 t3
= newTemp(Ity_I1
);
6427 /* Substract lower halves. */
6428 assign(t0
, binop(Iop_Sub32
,
6430 unop(Iop_32to16
, getIReg(rs
))),
6432 unop(Iop_32to16
, getIReg(rt
)))));
6434 /* Detect underflow. */
6435 assign(t1
, binop(Iop_CmpNE32
,
6441 putDSPControl(IRExpr_ITE(mkexpr(t1
),
6447 /* Subtract higher halves. */
6448 assign(t2
, binop(Iop_Sub32
,
6450 unop(Iop_32HIto16
, getIReg(rs
))),
6452 unop(Iop_32HIto16
, getIReg(rt
)))));
6454 /* Detect underflow. */
6455 assign(t3
, binop(Iop_CmpNE32
,
6461 putDSPControl(IRExpr_ITE(mkexpr(t3
),
6467 putIReg(rd
, binop(Iop_16HLto32
,
6468 unop(Iop_32to16
, mkexpr(t2
)),
6469 unop(Iop_32to16
, mkexpr(t0
))));
6472 case 0xA: { /* ADDQ.PH */
6473 DIP("addq.ph r%u, r%u, r%u", rd
, rs
, rt
);
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
);
6482 /* Add lower halves. */
6483 assign(t0
, binop(Iop_Add32
,
6485 unop(Iop_32to16
, getIReg(rs
))),
6487 unop(Iop_32to16
, getIReg(rt
)))));
6489 /* Bit 16 of the result. */
6490 assign(t6
, binop(Iop_And32
,
6492 unop(Iop_32HIto16
, mkexpr(t0
))),
6494 /* Detect overflow. */
6495 assign(t1
, binop(Iop_CmpNE32
,
6503 putDSPControl(IRExpr_ITE(mkexpr(t1
),
6509 /* Add higher halves. */
6510 assign(t2
, binop(Iop_Add32
,
6512 unop(Iop_32HIto16
, getIReg(rs
))),
6514 unop(Iop_32HIto16
, getIReg(rt
)))));
6516 /* Bit 16 of the result. */
6517 assign(t7
, binop(Iop_And32
,
6519 unop(Iop_32HIto16
, mkexpr(t2
))),
6521 /* Detect overflow. */
6522 assign(t3
, binop(Iop_CmpNE32
,
6530 putDSPControl(IRExpr_ITE(mkexpr(t3
),
6536 putIReg(rd
, binop(Iop_16HLto32
,
6537 unop(Iop_32to16
, mkexpr(t2
)),
6538 unop(Iop_32to16
, mkexpr(t0
))));
6541 case 0xB: { /* SUBQ.PH */
6542 DIP("subq.ph r%u, r%u, r%u", rd
, rs
, rt
);
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
);
6551 /* Subtract lower halves. */
6552 assign(t0
, binop(Iop_Sub32
,
6554 unop(Iop_32to16
, getIReg(rs
))),
6556 unop(Iop_32to16
, getIReg(rt
)))));
6558 /* Bit 16 of the result. */
6559 assign(t6
, binop(Iop_And32
,
6561 unop(Iop_32HIto16
, mkexpr(t0
))),
6563 /* Compare the signs of input value and the result. */
6564 assign(t1
, binop(Iop_CmpNE32
,
6572 putDSPControl(IRExpr_ITE(mkexpr(t1
),
6578 /* Subtract higher halves. */
6579 assign(t2
, binop(Iop_Sub32
,
6581 unop(Iop_32HIto16
, getIReg(rs
))),
6583 unop(Iop_32HIto16
, getIReg(rt
)))));
6585 /* Bit 16 of the result. */
6586 assign(t7
, binop(Iop_And32
,
6588 unop(Iop_32HIto16
, mkexpr(t2
))),
6590 /* Compare the signs of input value and the result. */
6591 assign(t3
, binop(Iop_CmpNE32
,
6599 putDSPControl(IRExpr_ITE(mkexpr(t3
),
6605 putIReg(rd
, binop(Iop_16HLto32
,
6606 unop(Iop_32to16
, mkexpr(t2
)),
6607 unop(Iop_32to16
, mkexpr(t0
))));
6610 case 0xC: { /* ADDU_S.PH */
6611 DIP("addu_s.ph r%u, r%u, r%u", rd
, rs
, rt
);
6613 t0
= newTemp(Ity_I32
);
6614 t1
= newTemp(Ity_I1
);
6615 t2
= newTemp(Ity_I32
);
6616 t3
= newTemp(Ity_I1
);
6618 /* Add lower halves. */
6619 assign(t0
, binop(Iop_Add32
,
6621 unop(Iop_32to16
, getIReg(rs
))),
6623 unop(Iop_32to16
, getIReg(rt
)))));
6625 /* Detect overflow. */
6626 assign(t1
, binop(Iop_CmpLT32U
,
6628 unop(Iop_32to16
, mkexpr(t0
))),
6630 unop(Iop_32to16
, getIReg(rs
)))));
6632 putDSPControl(IRExpr_ITE(mkexpr(t1
),
6638 /* Add higher halves. */
6639 assign(t2
, binop(Iop_Add32
,
6641 unop(Iop_32HIto16
, getIReg(rs
))),
6643 unop(Iop_32HIto16
, getIReg(rt
)))));
6645 /* Detect overflow. */
6646 assign(t3
, binop(Iop_CmpLT32U
,
6648 unop(Iop_32to16
, mkexpr(t2
))),
6650 unop(Iop_32HIto16
, getIReg(rs
)))));
6652 putDSPControl(IRExpr_ITE(mkexpr(t3
),
6658 putIReg(rd
, binop(Iop_16HLto32
,
6659 IRExpr_ITE(mkexpr(t3
),
6663 IRExpr_ITE(mkexpr(t1
),
6669 case 0xD: { /* SUBU_S.PH */
6670 DIP("subu_s.ph r%u, r%u, r%u", rd
, rs
, rt
);
6672 t0
= newTemp(Ity_I32
);
6673 t1
= newTemp(Ity_I1
);
6674 t2
= newTemp(Ity_I32
);
6675 t3
= newTemp(Ity_I1
);
6677 /* Subtract lower halves. */
6678 assign(t0
, binop(Iop_Sub32
,
6680 unop(Iop_32to16
, getIReg(rs
))),
6682 unop(Iop_32to16
, getIReg(rt
)))));
6684 /* Detect underflow. */
6685 assign(t1
, binop(Iop_CmpNE32
,
6687 mkexpr(t0
), mkU32(0x00010000)),
6690 putDSPControl(IRExpr_ITE(mkexpr(t1
),
6696 /* Subtract higher halves. */
6697 assign(t2
, binop(Iop_Sub32
,
6699 unop(Iop_32HIto16
, getIReg(rs
))),
6701 unop(Iop_32HIto16
, getIReg(rt
)))));
6703 /* Detect underflow. */
6704 assign(t3
, binop(Iop_CmpNE32
,
6706 mkexpr(t2
), mkU32(0x00010000)),
6709 putDSPControl(IRExpr_ITE(mkexpr(t3
),
6717 IRExpr_ITE(mkexpr(t3
),
6719 unop(Iop_32to16
, mkexpr(t2
))),
6720 IRExpr_ITE(mkexpr(t1
),
6722 unop(Iop_32to16
, mkexpr(t0
)))));
6725 case 0xE: { /* ADDQ_S.PH */
6726 DIP("addq_s.ph r%u r%u, r%u", rd
, rs
, rt
);
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
);
6737 /* Add lower halves. */
6738 assign(t0
, binop(Iop_Add32
,
6740 unop(Iop_32to16
, getIReg(rs
))),
6742 unop(Iop_32to16
, getIReg(rt
)))));
6744 /* Bit 16 of the result. */
6745 assign(t6
, binop(Iop_And32
,
6747 unop(Iop_32HIto16
, mkexpr(t0
))),
6749 /* Detect overflow. */
6750 assign(t1
, binop(Iop_CmpNE32
,
6758 putDSPControl(IRExpr_ITE(mkexpr(t1
),
6763 /* Saturate if needed. */
6764 assign(t4
, IRExpr_ITE(mkexpr(t1
),
6765 IRExpr_ITE(binop(Iop_CmpEQ32
,
6770 unop(Iop_32to16
, mkexpr(t0
))));
6772 /* Add higher halves. */
6773 assign(t2
, binop(Iop_Add32
,
6775 unop(Iop_32HIto16
, getIReg(rs
))),
6777 unop(Iop_32HIto16
, getIReg(rt
)))));
6779 /* Bit 16 of the result. */
6780 assign(t7
, binop(Iop_And32
,
6782 unop(Iop_32HIto16
, mkexpr(t2
))),
6784 /* Detect overflow. */
6785 assign(t3
, binop(Iop_CmpNE32
,
6793 putDSPControl(IRExpr_ITE(mkexpr(t3
),
6798 /* Saturate if needed. */
6799 assign(t5
, IRExpr_ITE(mkexpr(t3
),
6800 IRExpr_ITE(binop(Iop_CmpEQ32
,
6805 unop(Iop_32to16
, mkexpr(t2
))));
6807 putIReg(rd
, binop(Iop_16HLto32
, mkexpr(t5
), mkexpr(t4
)));
6810 case 0xF: { /* SUBQ_S.PH */
6811 DIP("subq_s.ph r%u r%u, r%u", rd
, rs
, rt
);
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
);
6822 /* Subtract lower halves. */
6823 assign(t0
, binop(Iop_Sub32
,
6825 unop(Iop_32to16
, getIReg(rs
))),
6827 unop(Iop_32to16
, getIReg(rt
)))));
6829 /* Bit 16 of the result. */
6830 assign(t6
, binop(Iop_And32
,
6832 unop(Iop_32HIto16
, mkexpr(t0
))),
6834 /* Detect overflow or underflow. */
6835 assign(t1
, binop(Iop_CmpNE32
,
6843 putDSPControl(IRExpr_ITE(mkexpr(t1
),
6848 /* Saturate if needed. */
6849 assign(t4
, IRExpr_ITE(mkexpr(t1
),
6850 IRExpr_ITE(binop(Iop_CmpEQ32
,
6855 unop(Iop_32to16
, mkexpr(t0
))));
6857 /* Subtract higher halves. */
6858 assign(t2
, binop(Iop_Sub32
,
6860 unop(Iop_32HIto16
, getIReg(rs
))),
6862 unop(Iop_32HIto16
, getIReg(rt
)))));
6864 /* Bit 16 of the result. */
6865 assign(t7
, binop(Iop_And32
,
6867 unop(Iop_32HIto16
, mkexpr(t2
))),
6869 /* Detect overflow or underflow. */
6870 assign(t3
, binop(Iop_CmpNE32
,
6878 putDSPControl(IRExpr_ITE(mkexpr(t3
),
6883 /* Saturate if needed. */
6884 assign(t5
, IRExpr_ITE(mkexpr(t3
),
6885 IRExpr_ITE(binop(Iop_CmpEQ32
,
6890 unop(Iop_32to16
, mkexpr(t2
))));
6892 putIReg(rd
, binop(Iop_16HLto32
, mkexpr(t5
), mkexpr(t4
)));
6895 case 0x10: { /* ADDSC */
6896 DIP("addsc r%u, r%u, r%u", rd
, rs
, rt
);
6898 t0
= newTemp(Ity_I64
);
6899 t1
= newTemp(Ity_I1
);
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
))));
6907 assign(t1
, binop(Iop_CmpEQ32
,
6909 unop(Iop_64HIto32
, mkexpr(t0
)),
6912 putDSPControl(IRExpr_ITE(mkexpr(t1
),
6918 mkU32(0xffffdfff))));
6920 putIReg(rd
, unop(Iop_64to32
, mkexpr(t0
)));
6923 case 0x11: { /* ADDWC */
6924 DIP("addwc r%u, r%u, r%u", rd
, rs
, rt
);
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
);
6932 /* Get carry bit from DSPControl register. */
6933 assign(t0
, binop(Iop_Shr32
,
6938 assign(t1
, binop(Iop_Add64
,
6939 unop(Iop_32Sto64
, getIReg(rs
)),
6945 /* Extract bits 32 and 31. */
6946 assign(t2
, binop(Iop_And32
,
6947 unop(Iop_64HIto32
, mkexpr(t1
)),
6949 assign(t3
, binop(Iop_Shr32
,
6951 unop(Iop_64to32
, mkexpr(t1
)),
6954 assign(t4
, binop(Iop_CmpNE32
, mkexpr(t2
), mkexpr(t3
)));
6956 putDSPControl(IRExpr_ITE(mkexpr(t4
),
6961 putIReg(rd
, unop(Iop_64to32
, mkexpr(t1
)));
6964 case 0x12: { /* MODSUB */
6965 DIP("modsub r%u, r%u, r%u", rd
, rs
, rt
);
6967 t0
= newTemp(Ity_I32
);
6968 t1
= newTemp(Ity_I32
);
6969 t2
= newTemp(Ity_I32
);
6975 unop(Iop_32to16
, getIReg(rt
)))));
6977 /* lastindex_15..0 */
6982 unop(Iop_32HIto16
, getIReg(rt
))),
6984 unop(Iop_32to16
, getIReg(rt
))))));
6987 IRExpr_ITE(binop(Iop_CmpEQ32
,
6992 getIReg(rs
), mkexpr(t0
))));
6993 putIReg(rd
, mkexpr(t2
));
6996 case 0x14: { /* RADDU.W.QB */
6997 DIP("raddu.w.qb r%u, r%u", rd
, rs
);
6999 putIReg(rd
, binop(Iop_Add32
,
7020 case 0x16: { /* ADDQ_S.W */
7021 DIP("addq_s.w r%u, r%u, r%u", rd
, rs
, rt
);
7023 t0
= newTemp(Ity_I64
);
7024 t1
= newTemp(Ity_I1
);
7025 t2
= newTemp(Ity_I32
);
7026 t3
= newTemp(Ity_I32
);
7028 assign(t0
, binop(Iop_Add64
,
7029 unop(Iop_32Sto64
, getIReg(rs
)),
7030 unop(Iop_32Sto64
, getIReg(rt
))));
7032 assign(t3
, binop(Iop_And32
,
7033 unop(Iop_64HIto32
, mkexpr(t0
)),
7035 assign(t1
, binop(Iop_CmpNE32
,
7038 unop(Iop_64to32
, mkexpr(t0
)),
7043 putDSPControl(IRExpr_ITE(mkexpr(t1
),
7049 putIReg(rd
, IRExpr_ITE(mkexpr(t1
),
7050 IRExpr_ITE(binop(Iop_CmpEQ32
,
7055 unop(Iop_64to32
, mkexpr(t0
))));
7058 case 0x17: { /* SUBQ_S.W */
7059 DIP("subq_s.w r%u, r%u, r%u", rd
, rs
, rt
);
7061 t0
= newTemp(Ity_I64
);
7062 t1
= newTemp(Ity_I1
);
7063 t2
= newTemp(Ity_I32
);
7064 t3
= newTemp(Ity_I32
);
7066 assign(t0
, binop(Iop_Sub64
,
7067 unop(Iop_32Sto64
, getIReg(rs
)),
7068 unop(Iop_32Sto64
, getIReg(rt
))));
7070 assign(t3
, binop(Iop_And32
,
7071 unop(Iop_64HIto32
, mkexpr(t0
)),
7073 assign(t1
, binop(Iop_CmpNE32
,
7076 unop(Iop_64to32
, mkexpr(t0
)),
7081 putDSPControl(IRExpr_ITE(mkexpr(t1
),
7087 putIReg(rd
, IRExpr_ITE(mkexpr(t1
),
7088 IRExpr_ITE(binop(Iop_CmpEQ32
,
7093 unop(Iop_64to32
, mkexpr(t0
))));
7096 case 0x1C: { /* MULEQ_S.W.PHL */
7097 DIP("muleq_s.w.phl r%u, r%u, r%u", rd
, rs
, rt
);
7099 t0
= newTemp(Ity_I32
);
7100 t1
= newTemp(Ity_I1
);
7101 t2
= newTemp(Ity_I1
);
7102 t3
= newTemp(Ity_I32
);
7108 unop(Iop_32HIto16
, getIReg(rt
))),
7110 unop(Iop_32HIto16
, getIReg(rs
)))),
7112 assign(t1
, binop(Iop_CmpEQ32
,
7116 mkU32(0x80000000)));
7117 assign(t2
, binop(Iop_CmpEQ32
,
7121 mkU32(0x80000000)));
7122 assign(t3
, IRExpr_ITE(mkexpr(t1
),
7123 IRExpr_ITE(mkexpr(t2
),
7129 putDSPControl(mkexpr(t3
));
7131 putIReg(rd
, IRExpr_ITE(mkexpr(t1
),
7132 IRExpr_ITE(mkexpr(t2
),
7138 case 0x1D: { /* MULEQ_S.W.PHR */
7139 DIP("muleq_s.w.phr r%u, r%u, r%u", rd
, rs
, rt
);
7141 t0
= newTemp(Ity_I32
);
7142 t1
= newTemp(Ity_I1
);
7143 t2
= newTemp(Ity_I1
);
7149 unop(Iop_32to16
, getIReg(rt
))),
7151 unop(Iop_32to16
, getIReg(rs
)))),
7153 assign(t1
, binop(Iop_CmpEQ32
,
7158 assign(t2
, binop(Iop_CmpEQ32
,
7163 putDSPControl(IRExpr_ITE(mkexpr(t1
),
7164 IRExpr_ITE(mkexpr(t2
),
7171 putIReg(rd
, IRExpr_ITE(mkexpr(t1
),
7172 IRExpr_ITE(mkexpr(t2
),
7178 case 0x1E: { /* MULQ_S.PH */
7179 DIP("mulq_s.ph r%u, r%u, r%u", rd
, rs
, rt
);
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
);
7191 unop(Iop_16Sto32
, unop(Iop_32to16
, getIReg(rs
))));
7193 unop(Iop_16Sto32
, unop(Iop_32to16
, getIReg(rt
))));
7196 unop(Iop_16Sto32
, unop(Iop_32HIto16
, getIReg(rs
))));
7198 unop(Iop_16Sto32
, unop(Iop_32HIto16
, getIReg(rt
))));
7200 assign(t0
, binop(Iop_And32
,
7213 assign(t1
, binop(Iop_And32
,
7227 putDSPControl(IRExpr_ITE(binop(Iop_CmpEQ32
,
7237 assign(t2
, unop(Iop_32HIto16
,
7244 assign(t3
, unop(Iop_32HIto16
,
7251 putIReg(rd
, binop(Iop_16HLto32
,
7252 IRExpr_ITE(binop(Iop_CmpEQ32
,
7257 IRExpr_ITE(binop(Iop_CmpEQ32
,
7264 case 0x1F: { /* MULQ_RS.PH */
7265 DIP("mulq_rs.ph r%u, r%u, r%u", rd
, rs
, rt
);
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
);
7276 /* Multiply and round lower halfwords. */
7277 assign(t0
, binop(Iop_Add32
,
7287 mkU32(0x00008000)));
7288 assign(t1
, binop(Iop_CmpEQ32
,
7290 getIReg(rt
), mkU32(0xffff)),
7292 assign(t2
, binop(Iop_CmpEQ32
,
7294 getIReg(rs
), mkU32(0xffff)),
7296 putDSPControl(IRExpr_ITE(mkexpr(t1
),
7297 IRExpr_ITE(mkexpr(t2
),
7304 assign(t3
, IRExpr_ITE(mkexpr(t1
),
7305 IRExpr_ITE(mkexpr(t2
),
7309 unop(Iop_32HIto16
, mkexpr(t0
))));
7311 /* Multiply and round higher halfwords. */
7312 assign(t4
, binop(Iop_Add32
,
7322 mkU32(0x00008000)));
7323 assign(t5
, binop(Iop_CmpEQ32
,
7327 mkU32(0x80000000)));
7328 assign(t6
, binop(Iop_CmpEQ32
,
7332 mkU32(0x80000000)));
7333 putDSPControl(IRExpr_ITE(mkexpr(t5
),
7334 IRExpr_ITE(mkexpr(t6
),
7340 assign(t7
, IRExpr_ITE(mkexpr(t5
),
7341 IRExpr_ITE(mkexpr(t6
),
7345 unop(Iop_32HIto16
, mkexpr(t4
))));
7347 putIReg(rd
, binop(Iop_16HLto32
, mkexpr(t7
), mkexpr(t3
)));
7353 break; /* end of ADDU.QB */
7355 case 0x11: { /* CMPU.EQ.QB */
7357 case 0x0: { /* CMPU.EQ.QB */
7358 DIP("cmpu.eq.qb r%u, r%u", rs
, rt
);
7360 t1
= newTemp(Ity_I1
);
7361 t2
= newTemp(Ity_I1
);
7362 t3
= newTemp(Ity_I1
);
7363 t4
= newTemp(Ity_I1
);
7367 binop(Iop_And32
, getIReg(rs
), mkU32(0xff)),
7368 binop(Iop_And32
, getIReg(rt
), mkU32(0xff))));
7369 putDSPControl(IRExpr_ITE(mkexpr(t1
),
7375 mkU32(0xfeffffff))));
7377 assign(t2
, binop(Iop_CmpEQ32
,
7386 putDSPControl(IRExpr_ITE(mkexpr(t2
),
7392 mkU32(0xfdffffff))));
7394 assign(t3
, binop(Iop_CmpEQ32
,
7403 putDSPControl(IRExpr_ITE(mkexpr(t3
),
7409 mkU32(0xfbffffff))));
7411 assign(t4
, binop(Iop_CmpEQ32
,
7420 putDSPControl(IRExpr_ITE(mkexpr(t4
),
7426 mkU32(0xf7ffffff))));
7429 case 0x1: { /* CMPU.LT.QB */
7430 DIP("cmpu.lt.qb r%u, r%u", rs
, rt
);
7432 t1
= newTemp(Ity_I1
);
7433 t2
= newTemp(Ity_I1
);
7434 t3
= newTemp(Ity_I1
);
7435 t4
= newTemp(Ity_I1
);
7437 assign(t1
, binop(Iop_CmpLT32U
,
7446 putDSPControl(IRExpr_ITE(mkexpr(t1
),
7452 mkU32(0xfeffffff))));
7454 assign(t2
, binop(Iop_CmpLT32U
,
7463 putDSPControl(IRExpr_ITE(mkexpr(t2
),
7469 mkU32(0xfdffffff))));
7471 assign(t3
, binop(Iop_CmpLT32U
,
7480 putDSPControl(IRExpr_ITE(mkexpr(t3
),
7486 mkU32(0xfbffffff))));
7488 assign(t4
, binop(Iop_CmpLT32U
,
7497 putDSPControl(IRExpr_ITE(mkexpr(t4
),
7503 mkU32(0xf7ffffff))));
7506 case 0x2: { /* CMPU.LE.QB */
7507 DIP("cmpu.le.qb r%u, r%u", rs
, rt
);
7509 t1
= newTemp(Ity_I1
);
7510 t2
= newTemp(Ity_I1
);
7511 t3
= newTemp(Ity_I1
);
7512 t4
= newTemp(Ity_I1
);
7514 assign(t1
, binop(Iop_CmpLE32U
,
7523 putDSPControl(IRExpr_ITE(mkexpr(t1
),
7529 mkU32(0xfeffffff))));
7531 assign(t2
, binop(Iop_CmpLE32U
,
7540 putDSPControl(IRExpr_ITE(mkexpr(t2
),
7546 mkU32(0xfdffffff))));
7548 assign(t3
, binop(Iop_CmpLE32U
,
7557 putDSPControl(IRExpr_ITE(mkexpr(t3
),
7563 mkU32(0xfbffffff))));
7565 assign(t4
, binop(Iop_CmpLE32U
,
7574 putDSPControl(IRExpr_ITE(mkexpr(t4
),
7580 mkU32(0xf7ffffff))));
7583 case 0x3: { /* PICK.QB */
7584 DIP("pick.qb r%u, r%u, r%u", rd
, rs
, rt
);
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
);
7592 assign(t0
, getDSPControl());
7593 assign(t1
, IRExpr_ITE(binop(Iop_CmpNE32
,
7604 assign(t2
, IRExpr_ITE(binop(Iop_CmpNE32
,
7610 unop(Iop_32to16
, getIReg(rs
))),
7614 assign(t3
, IRExpr_ITE(binop(Iop_CmpNE32
,
7625 assign(t4
, IRExpr_ITE(binop(Iop_CmpNE32
,
7638 binop(Iop_8HLto16
, mkexpr(t4
), mkexpr(t3
)),
7639 binop(Iop_8HLto16
, mkexpr(t2
), mkexpr(t1
))));
7642 case 0x4: { /* CMPGU.EQ.QB */
7643 DIP("cmpgu.eq.qb r%u, r%u, r%u", rd
, rs
, rt
);
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
);
7654 assign(t1
, binop(Iop_CmpEQ32
,
7657 unop(Iop_32to16
, getIReg(rs
)))),
7662 assign(t5
, IRExpr_ITE(mkexpr(t1
),
7663 mkU32(0x00000001), mkU32(0)));
7665 assign(t2
, binop(Iop_CmpEQ32
,
7668 unop(Iop_32to16
, getIReg(rs
)))),
7673 assign(t6
, IRExpr_ITE(mkexpr(t2
),
7674 mkU32(0x00000002), mkU32(0)));
7676 assign(t3
, binop(Iop_CmpEQ32
,
7685 assign(t7
, IRExpr_ITE(mkexpr(t3
),
7686 mkU32(0x00000004), mkU32(0)));
7688 assign(t4
, binop(Iop_CmpEQ32
,
7697 assign(t8
, IRExpr_ITE(mkexpr(t4
),
7698 mkU32(0x00000008), mkU32(0)));
7700 putIReg(rd
, binop(Iop_Or32
,
7703 mkexpr(t5
), mkexpr(t6
)),
7708 case 0x5: { /* CMPGU.LT.QB */
7709 DIP("cmpgu.lt.qb r%u, r%u, r%u", rd
, rs
, rt
);
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
);
7720 assign(t1
, binop(Iop_CmpLT32U
,
7723 unop(Iop_32to16
, getIReg(rs
)))),
7728 assign(t5
, IRExpr_ITE(mkexpr(t1
),
7729 mkU32(0x00000001), mkU32(0)));
7731 assign(t2
, binop(Iop_CmpLT32U
,
7734 unop(Iop_32to16
, getIReg(rs
)))),
7739 assign(t6
, IRExpr_ITE(mkexpr(t2
),
7740 mkU32(0x00000002), mkU32(0)));
7742 assign(t3
, binop(Iop_CmpLT32U
,
7751 assign(t7
, IRExpr_ITE(mkexpr(t3
),
7752 mkU32(0x00000004), mkU32(0)));
7754 assign(t4
, binop(Iop_CmpLT32U
,
7763 assign(t8
, IRExpr_ITE(mkexpr(t4
),
7764 mkU32(0x00000008), mkU32(0)));
7765 putIReg(rd
, binop(Iop_Or32
,
7768 mkexpr(t5
), mkexpr(t6
)),
7773 case 0x6: { /* CMPGU.LE.QB */
7774 DIP("cmpgu.le.qb r%u, r%u, r%u", rd
, rs
, rt
);
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
);
7785 assign(t1
, binop(Iop_CmpLE32U
,
7788 unop(Iop_32to16
, getIReg(rs
)))),
7793 assign(t5
, IRExpr_ITE(mkexpr(t1
),
7794 mkU32(0x00000001), mkU32(0)));
7796 assign(t2
, binop(Iop_CmpLE32U
,
7799 unop(Iop_32to16
, getIReg(rs
)))),
7804 assign(t6
, IRExpr_ITE(mkexpr(t2
),
7805 mkU32(0x00000002), mkU32(0)));
7807 assign(t3
, binop(Iop_CmpLE32U
,
7816 assign(t7
, IRExpr_ITE(mkexpr(t3
),
7817 mkU32(0x00000004), mkU32(0)));
7819 assign(t4
, binop(Iop_CmpLE32U
,
7828 assign(t8
, IRExpr_ITE(mkexpr(t4
),
7829 mkU32(0x00000008), mkU32(0)));
7830 putIReg(rd
, binop(Iop_Or32
,
7833 mkexpr(t5
), mkexpr(t6
)),
7838 case 0x8: { /* CMP.EQ.PH */
7839 DIP("cmp.eq.ph r%u, r%u", rs
, rt
);
7841 t1
= newTemp(Ity_I1
);
7842 t2
= newTemp(Ity_I1
);
7844 assign(t1
, binop(Iop_CmpEQ16
,
7845 unop(Iop_32to16
, getIReg(rs
)),
7846 unop(Iop_32to16
, getIReg(rt
))));
7847 putDSPControl(IRExpr_ITE(mkexpr(t1
),
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
),
7863 mkU32(0xfdffffff))));
7866 case 0x9: { /* CMP.LT.PH */
7867 DIP("cmp.lt.ph r%u, r%u", rs
, rt
);
7869 t1
= newTemp(Ity_I1
);
7870 t2
= newTemp(Ity_I1
);
7872 assign(t1
, binop(Iop_CmpLT32S
,
7874 unop(Iop_32to16
, getIReg(rs
))),
7876 unop(Iop_32to16
, getIReg(rt
)))));
7877 putDSPControl(IRExpr_ITE(mkexpr(t1
),
7883 mkU32(0xfeffffff))));
7885 assign(t2
, binop(Iop_CmpLT32S
,
7887 unop(Iop_32HIto16
, getIReg(rs
))),
7889 unop(Iop_32HIto16
, getIReg(rt
)))));
7890 putDSPControl(IRExpr_ITE(mkexpr(t2
),
7896 mkU32(0xfdffffff))));
7899 case 0xA: { /* CMP.LE.PH */
7900 DIP("cmp.le.ph r%u, r%u", rs
, rt
);
7902 t1
= newTemp(Ity_I1
);
7903 t2
= newTemp(Ity_I1
);
7905 assign(t1
, binop(Iop_CmpLE32S
,
7907 unop(Iop_32to16
, getIReg(rs
))),
7909 unop(Iop_32to16
, getIReg(rt
)))));
7910 putDSPControl(IRExpr_ITE(mkexpr(t1
),
7916 mkU32(0xfeffffff))));
7918 assign(t2
, binop(Iop_CmpLE32S
,
7920 unop(Iop_32HIto16
, getIReg(rs
))),
7922 unop(Iop_32HIto16
, getIReg(rt
)))));
7923 putDSPControl(IRExpr_ITE(mkexpr(t2
),
7929 mkU32(0xfdffffff))));
7932 case 0xB: { /* PICK.PH */
7933 DIP("pick.qb r%u, r%u, r%u", rd
, rs
, rt
);
7935 t0
= newTemp(Ity_I32
);
7936 t1
= newTemp(Ity_I16
);
7937 t2
= newTemp(Ity_I16
);
7939 assign(t0
, getDSPControl());
7941 assign(t1
, IRExpr_ITE(binop(Iop_CmpNE32
,
7946 unop(Iop_32to16
, getIReg(rs
)),
7947 unop(Iop_32to16
, getIReg(rt
))));
7949 assign(t2
, IRExpr_ITE(binop(Iop_CmpNE32
,
7954 unop(Iop_32HIto16
, getIReg(rs
)),
7955 unop(Iop_32HIto16
, getIReg(rt
))));
7957 putIReg(rd
, binop(Iop_16HLto32
, mkexpr(t2
), mkexpr(t1
)));
7960 case 0xC: { /* PRECRQ.QB.PH */
7961 DIP("precrq.qb.ph r%u, r%u, %u", rd
, rs
, rt
);
7967 unop(Iop_32HIto16
, getIReg(rs
))),
7969 unop(Iop_32to16
, getIReg(rs
)))),
7972 unop(Iop_32HIto16
, getIReg(rt
))),
7974 unop(Iop_32to16
, getIReg(rt
))))));
7977 case 0xD: { /* PRECR.QB.PH */
7978 DIP("precr.qb.ph r%u, r%u, r%u", rd
, rs
, rt
);
7985 unop(Iop_32HIto16
, getIReg(rs
))),
7987 unop(Iop_32to16
, getIReg(rs
)))),
7990 unop(Iop_32HIto16
, getIReg(rt
))),
7992 unop(Iop_32to16
, getIReg(rt
))))));
7995 case 0xF: { /* PRECRQU_S.QB.PH */
7996 DIP("precrqu_s.qb.ph r%u, r%u, %u", rd
, rs
, rt
);
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
);
8015 assign(t4
, IRExpr_ITE(binop(Iop_CmpLT32U
,
8028 assign(t0
, IRExpr_ITE(binop(Iop_CmpEQ32
,
8037 assign(t5
, binop(Iop_And32
,
8041 mkU32(0x00008000)));
8042 assign(t6
, binop(Iop_CmpLT32U
,
8049 putDSPControl(IRExpr_ITE(binop(Iop_CmpEQ32
,
8052 IRExpr_ITE(mkexpr(t6
),
8060 mkU32(0x00400000))));
8062 assign(t7
, IRExpr_ITE(binop(Iop_CmpLT32U
,
8075 assign(t1
, IRExpr_ITE(binop(Iop_CmpEQ32
,
8084 assign(t8
, binop(Iop_CmpEQ32
,
8091 assign(t9
, IRExpr_ITE(binop(Iop_CmpLT32U
,
8102 putDSPControl(IRExpr_ITE(mkexpr(t8
),
8106 mkU32(0x00400000))));
8108 assign(t10
, IRExpr_ITE(binop(Iop_CmpLT32U
,
8121 assign(t2
, IRExpr_ITE(binop(Iop_CmpEQ32
,
8130 assign(t11
, binop(Iop_CmpEQ32
,
8137 assign(t12
, IRExpr_ITE(binop(Iop_CmpLT32U
,
8148 putDSPControl(IRExpr_ITE(mkexpr(t11
),
8152 mkU32(0x00400000))));
8154 assign(t13
, IRExpr_ITE(binop(Iop_CmpLT32U
,
8167 assign(t3
, IRExpr_ITE(binop(Iop_CmpEQ32
,
8176 assign(t14
, binop(Iop_CmpEQ32
,
8183 assign(t15
, IRExpr_ITE(binop(Iop_CmpLT32U
,
8194 putDSPControl(IRExpr_ITE(mkexpr(t14
),
8198 mkU32(0x00400000))));
8200 putIReg(rd
, binop(Iop_16HLto32
,
8202 mkexpr(t1
), mkexpr(t0
)),
8204 mkexpr(t3
), mkexpr(t2
))));
8207 case 0x14: { /* PRECRQ.PH.W */
8208 DIP("precrq.ph.w r%u, r%u, %u", rd
, rs
, rt
);
8210 putIReg(rd
, binop(Iop_16HLto32
,
8211 unop(Iop_32HIto16
, getIReg(rs
)),
8212 unop(Iop_32HIto16
, getIReg(rt
))));
8215 case 0x15: { /* PRECRQ_RS.PH.W */
8216 DIP("precrq_rs.ph.w r%u, r%u, %u", rd
, rs
, rt
);
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
);
8225 assign(t0
, binop(Iop_Add64
,
8233 mkU64(0x0000000000008000ULL
)));
8234 assign(t1
, binop(Iop_CmpNE32
,
8236 unop(Iop_64HIto32
, mkexpr(t0
)),
8240 unop(Iop_64to32
, mkexpr(t0
)),
8243 assign(t2
, IRExpr_ITE(mkexpr(t1
),
8245 unop(Iop_64to32
, mkexpr(t0
))));
8246 putDSPControl(IRExpr_ITE(mkexpr(t1
),
8251 assign(t3
, binop(Iop_Add64
,
8259 mkU64(0x0000000000008000ULL
)));
8260 assign(t4
, binop(Iop_CmpNE32
,
8262 unop(Iop_64HIto32
, mkexpr(t3
)),
8266 unop(Iop_64to32
, mkexpr(t3
)),
8269 assign(t5
, IRExpr_ITE(mkexpr(t4
),
8271 unop(Iop_64to32
, mkexpr(t3
))));
8272 putDSPControl(IRExpr_ITE(mkexpr(t4
),
8277 putIReg(rd
, binop(Iop_16HLto32
,
8278 unop(Iop_32HIto16
, mkexpr(t2
)),
8279 unop(Iop_32HIto16
, mkexpr(t5
))));
8282 case 0x1E: { /* PRECR_SRA.PH.W */
8283 DIP("precr_sra.ph.w r%u, r%u, %u", rt
, rs
, rd
);
8287 putIReg(rt
, binop(Iop_16HLto32
,
8288 unop(Iop_32to16
, getIReg(rt
)),
8289 unop(Iop_32to16
, getIReg(rs
))));
8291 putIReg(rt
, binop(Iop_16HLto32
,
8292 unop(Iop_32to16
, binop(Iop_Sar32
,
8295 unop(Iop_32to16
, binop(Iop_Sar32
,
8301 case 0x1F: { /* PRECR_SRA_R.PH.W */
8302 DIP("precr_sra_r.ph.w r%u, r%u, %u", rt
, rs
, rd
);
8305 t0
= newTemp(Ity_I32
);
8306 t1
= newTemp(Ity_I32
);
8309 putIReg(rt
, binop(Iop_16HLto32
,
8310 unop(Iop_32to16
, getIReg(rt
)),
8311 unop(Iop_32to16
, getIReg(rs
))));
8313 assign(t0
, binop(Iop_Shr32
,
8320 assign(t1
, binop(Iop_Shr32
,
8327 putIReg(rt
, binop(Iop_16HLto32
,
8328 unop(Iop_32to16
, mkexpr(t0
)),
8329 unop(Iop_32to16
, mkexpr(t1
))));
8333 case 0xE: { /* PACKRL.PH */
8334 DIP("packrl.ph r%u, r%u, r%u", rd
, rs
, rt
);
8337 putIReg(rd
, binop(Iop_16HLto32
,
8338 unop(Iop_32to16
, getIReg(rs
)),
8339 unop(Iop_32HIto16
, getIReg(rt
))));
8342 case 0x18: { /* CMPGDU.EQ.QB */
8343 DIP("cmpgdu.eq.qb r%u, r%u, r%u", rd
, rs
, rt
);
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
);
8358 unop(Iop_32to16
, getIReg(rs
)))),
8361 unop(Iop_32to16
, getIReg(rt
))))));
8362 assign(t5
, IRExpr_ITE(mkexpr(t1
),
8363 mkU32(0x00000001), mkU32(0)));
8364 putDSPControl(IRExpr_ITE(mkexpr(t1
),
8370 mkU32(0xfeffffff))));
8372 assign(t2
, binop(Iop_CmpEQ32
,
8375 unop(Iop_32to16
, getIReg(rs
)))),
8380 assign(t6
, IRExpr_ITE(mkexpr(t2
),
8381 mkU32(0x00000002), mkU32(0)));
8382 putDSPControl(IRExpr_ITE(mkexpr(t2
),
8388 mkU32(0xfdffffff))));
8390 assign(t3
, binop(Iop_CmpEQ32
,
8399 assign(t7
, IRExpr_ITE(mkexpr(t3
),
8400 mkU32(0x00000004), mkU32(0)));
8401 putDSPControl(IRExpr_ITE(mkexpr(t3
),
8407 mkU32(0xfbffffff))));
8409 assign(t4
, binop(Iop_CmpEQ32
,
8418 assign(t8
, IRExpr_ITE(mkexpr(t4
),
8419 mkU32(0x00000008), mkU32(0)));
8420 putDSPControl(IRExpr_ITE(mkexpr(t4
),
8426 mkU32(0xf7ffffff))));
8428 putIReg(rd
, binop(Iop_Or32
,
8431 mkexpr(t5
), mkexpr(t6
)),
8436 case 0x19: { /* CMPGDU.LT.QB */
8437 DIP("cmpgdu.lt.qb r%u, r%u, r%u", rd
, rs
, rt
);
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
);
8448 assign(t1
, binop(Iop_CmpLT32U
,
8451 unop(Iop_32to16
, getIReg(rs
)))),
8456 assign(t5
, IRExpr_ITE(mkexpr(t1
),
8457 mkU32(0x00000001), mkU32(0)));
8458 putDSPControl(IRExpr_ITE(mkexpr(t1
),
8464 mkU32(0xfeffffff))));
8466 assign(t2
, binop(Iop_CmpLT32U
,
8469 unop(Iop_32to16
, getIReg(rs
)))),
8474 assign(t6
, IRExpr_ITE(mkexpr(t2
),
8475 mkU32(0x00000002), mkU32(0)));
8476 putDSPControl(IRExpr_ITE(mkexpr(t2
),
8482 mkU32(0xfdffffff))));
8484 assign(t3
, binop(Iop_CmpLT32U
,
8493 assign(t7
, IRExpr_ITE(mkexpr(t3
),
8494 mkU32(0x00000004), mkU32(0)));
8495 putDSPControl(IRExpr_ITE(mkexpr(t3
),
8501 mkU32(0xfbffffff))));
8503 assign(t4
, binop(Iop_CmpLT32U
,
8512 assign(t8
, IRExpr_ITE(mkexpr(t4
),
8513 mkU32(0x00000008), mkU32(0)));
8514 putDSPControl(IRExpr_ITE(mkexpr(t4
),
8520 mkU32(0xf7ffffff))));
8522 putIReg(rd
, binop(Iop_Or32
,
8525 mkexpr(t5
), mkexpr(t6
)),
8530 case 0x1A: { /* CMPGDU.LE.QB */
8531 DIP("cmpgdu.le.qb r%u, r%u, r%u", rd
, rs
, rt
);
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
);
8542 assign(t1
, binop(Iop_CmpLE32U
,
8545 unop(Iop_32to16
, getIReg(rs
)))),
8550 assign(t5
, IRExpr_ITE(mkexpr(t1
),
8553 putDSPControl(IRExpr_ITE(mkexpr(t1
),
8559 mkU32(0xfeffffff))));
8561 assign(t2
, binop(Iop_CmpLE32U
,
8564 unop(Iop_32to16
, getIReg(rs
)))),
8569 assign(t6
, IRExpr_ITE(mkexpr(t2
),
8570 mkU32(0x00000002), mkU32(0)));
8571 putDSPControl(IRExpr_ITE(mkexpr(t2
),
8577 mkU32(0xfdffffff))));
8579 assign(t3
, binop(Iop_CmpLE32U
,
8588 assign(t7
, IRExpr_ITE(mkexpr(t3
),
8589 mkU32(0x00000004), mkU32(0)));
8590 putDSPControl(IRExpr_ITE(mkexpr(t3
),
8596 mkU32(0xfbffffff))));
8598 assign(t4
, binop(Iop_CmpLE32U
,
8607 assign(t8
, IRExpr_ITE(mkexpr(t4
),
8608 mkU32(0x00000008), mkU32(0)));
8609 putDSPControl(IRExpr_ITE(mkexpr(t4
),
8615 mkU32(0xf7ffffff))));
8617 putIReg(rd
, binop(Iop_Or32
,
8620 mkexpr(t5
), mkexpr(t6
)),
8628 break; /* end of CMPU.EQ.QB */
8630 case 0x13: { /* SHLL.QB */
8632 case 0x0: { /* SHLL.QB */
8633 DIP("shll.qb r%u, r%u, %u", rd
, rt
, rs
);
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
);
8648 putIReg(rd
, getIReg(rt
));
8650 /* Shift bits 7..0 and 23..16. */
8651 assign(t0
, binop(Iop_Shl32
,
8656 assign(t1
, binop(Iop_CmpNE32
,
8660 mkU32(0x00000000)));
8661 assign(t2
, binop(Iop_CmpNE32
,
8665 mkU32(0xff000000)));
8666 assign(t7
, binop(Iop_CmpNE32
,
8670 mkU32(0x00000000)));
8671 assign(t8
, binop(Iop_CmpNE32
,
8676 /* Shift bits 15..8 and 31..24. */
8677 assign(t3
, binop(Iop_Shl32
,
8684 assign(t4
, binop(Iop_CmpNE32
,
8688 mkU32(0x00000000)));
8689 assign(t5
, binop(Iop_CmpNE32
,
8693 mkU32(0xff000000)));
8694 assign(t9
, binop(Iop_CmpNE32
,
8698 mkU32(0x00000000)));
8699 assign(t10
, binop(Iop_CmpNE32
,
8703 mkU32(0x0000ff00)));
8705 assign(t6
, binop(Iop_Or32
,
8729 putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32
,
8736 putIReg(rd
, binop(Iop_Or32
,
8744 mkU32(0x00ff00ff))));
8748 case 0x3: { /* SHRL.QB */
8749 DIP("shrl.qb r%u, r%u, %u", rd
, rt
, rs
);
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
);
8761 assign(t9
, binop(Iop_And32
, getIReg(rs
), mkU32(0x7)));
8762 assign(t0
, unop(Iop_8Uto32
,
8764 unop(Iop_32to16
, getIReg(rt
)))));
8765 assign(t1
, unop(Iop_32to8
,
8768 unop(Iop_32to8
, mkexpr(t9
)))));
8770 assign(t2
, unop(Iop_8Uto32
,
8772 unop(Iop_32to16
, getIReg(rt
)))));
8773 assign(t3
, unop(Iop_32to8
,
8776 unop(Iop_32to8
, mkexpr(t9
)))));
8778 assign(t4
, unop(Iop_8Uto32
,
8780 unop(Iop_32HIto16
, getIReg(rt
)))));
8781 assign(t5
, unop(Iop_32to8
,
8784 unop(Iop_32to8
, mkexpr(t9
)))));
8786 assign(t6
, unop(Iop_8Uto32
,
8788 unop(Iop_32HIto16
, getIReg(rt
)))));
8789 assign(t7
, unop(Iop_32to8
,
8792 unop(Iop_32to8
, mkexpr(t9
)))));
8793 putIReg(rd
, IRExpr_ITE(binop(Iop_CmpEQ32
,
8806 case 0x2: { /* SHLLV.QB */
8807 DIP("shllv.qb r%u, r%u, r%u", rd
, rt
, rs
);
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
);
8822 assign(t11
, unop(Iop_32to8
,
8826 /* Shift bits 7..0 and 23..16. */
8827 assign(t0
, binop(Iop_Shl32
,
8832 assign(t1
, binop(Iop_CmpNE32
,
8836 mkU32(0x00000000)));
8837 assign(t2
, binop(Iop_CmpNE32
,
8841 mkU32(0xff000000)));
8842 assign(t7
, binop(Iop_CmpNE32
,
8846 mkU32(0x00000000)));
8847 assign(t8
, binop(Iop_CmpNE32
,
8852 /* Shift bits 15..8 and 31..24. */
8853 assign(t3
, binop(Iop_Shl32
,
8860 assign(t4
, binop(Iop_CmpNE32
,
8864 mkU32(0x00000000)));
8865 assign(t5
, binop(Iop_CmpNE32
,
8869 mkU32(0xff000000)));
8870 assign(t9
, binop(Iop_CmpNE32
,
8874 mkU32(0x00000000)));
8875 assign(t10
, binop(Iop_CmpNE32
,
8879 mkU32(0x0000ff00)));
8881 assign(t6
, binop(Iop_Or32
,
8905 putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32
,
8912 putIReg(rd
, IRExpr_ITE(binop(Iop_CmpEQ32
,
8913 unop(Iop_8Uto32
, mkexpr(t11
)),
8924 mkU32(0x00ff00ff)))));
8927 case 0x1: { /* SHRLV.QB */
8928 DIP("shrlv.qb r%u, r%u, r%u", rd
, rt
, rs
);
8930 t0
= newTemp(Ity_I8
);
8931 t1
= newTemp(Ity_I8
);
8932 t2
= newTemp(Ity_I8
);
8933 t3
= newTemp(Ity_I8
);
8935 assign(t0
, unop(Iop_32to8
,
8938 unop(Iop_32to8
, getIReg(rt
))),
8940 assign(t1
, unop(Iop_32to8
,
8947 assign(t2
, unop(Iop_32to8
,
8954 assign(t3
, unop(Iop_32to8
,
8963 binop(Iop_8HLto16
, mkexpr(t3
), mkexpr(t2
)),
8964 binop(Iop_8HLto16
, mkexpr(t1
), mkexpr(t0
))));
8967 case 0x4: { /* SHRA.QB */
8968 DIP("shra.qb r%u, r%u, %u", rd
, rt
, rs
);
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
);
8983 /* ========== GPR[rt]_31..24 ========== */
8987 unop(Iop_32HIto16
, getIReg(rt
)))));
8989 binop(Iop_Shr32
, mkexpr(t1
), mkU8(rs
)));
8995 IRExpr_ITE(binop(Iop_CmpEQ32
,
9003 binop(Iop_Sub8
, mkU8(0x8), mkU8(rs
)))));
9005 /* ========== GPR[rt]_23..16 ========== */
9009 unop(Iop_32HIto16
, getIReg(rt
)))));
9010 assign(t5
, binop(Iop_Shr32
, mkexpr(t4
), mkU8(rs
)));
9016 IRExpr_ITE(binop(Iop_CmpEQ32
,
9024 binop(Iop_Sub8
, mkU8(0x8), mkU8(rs
)))));
9026 /* ========== GPR[rt]_15..8 ========== */
9030 unop(Iop_32to16
, getIReg(rt
)))));
9031 assign(t8
, binop(Iop_Shr32
, mkexpr(t7
), mkU8(rs
)));
9037 IRExpr_ITE(binop(Iop_CmpEQ32
,
9045 binop(Iop_Sub8
, mkU8(0x8), mkU8(rs
)))));
9047 /* ========== GPR[rt]_7..0 ========== */
9051 unop(Iop_32to16
, getIReg(rt
)))));
9052 assign(t11
, binop(Iop_Shr32
, mkexpr(t10
), mkU8(rs
)));
9058 IRExpr_ITE(binop(Iop_CmpEQ32
,
9066 binop(Iop_Sub8
, mkU8(0x8), mkU8(rs
)))));
9071 unop(Iop_32to8
, mkexpr(t0
)),
9072 unop(Iop_32to8
, mkexpr(t3
))),
9074 unop(Iop_32to8
, mkexpr(t6
)),
9075 unop(Iop_32to8
, mkexpr(t9
)))));
9078 case 0x5: { /* SHRA_R.QB */
9079 DIP("shra_r.qb r%u, r%u, %u", rd
, rt
, rs
);
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
);
9091 putIReg(rd
, getIReg(rt
));
9093 assign(t0
, unop(Iop_8Sto32
,
9095 unop(Iop_32to16
, getIReg(rt
)))));
9096 assign(t1
, unop(Iop_32to8
,
9105 assign(t2
, unop(Iop_8Sto32
,
9107 unop(Iop_32to16
, getIReg(rt
)))));
9108 assign(t3
, unop(Iop_32to8
,
9117 assign(t4
, unop(Iop_8Sto32
,
9119 unop(Iop_32HIto16
, getIReg(rt
)))));
9120 assign(t5
, unop(Iop_32to8
,
9129 assign(t6
, unop(Iop_8Sto32
,
9131 unop(Iop_32HIto16
, getIReg(rt
)))));
9132 assign(t7
, unop(Iop_32to8
,
9140 putIReg(rd
, binop(Iop_16HLto32
,
9142 mkexpr(t7
), mkexpr(t5
)),
9144 mkexpr(t3
), mkexpr(t1
))));
9148 case 0x6: { /* SHRAV.QB */
9149 DIP("shrav.qb r%u, r%u, %u", rd
, rt
, rs
);
9152 t0
= newTemp(Ity_I32
);
9153 t1
= newTemp(Ity_I32
);
9154 t2
= newTemp(Ity_I32
);
9156 t3
= newTemp(Ity_I32
);
9157 t4
= newTemp(Ity_I32
);
9158 t5
= newTemp(Ity_I32
);
9160 t6
= newTemp(Ity_I32
);
9161 t7
= newTemp(Ity_I32
);
9162 t8
= newTemp(Ity_I32
);
9164 t9
= newTemp(Ity_I32
);
9165 t10
= newTemp(Ity_I32
);
9166 t11
= newTemp(Ity_I32
);
9168 /* ========== GPR[rt]_31..24 ========== */
9172 unop(Iop_32HIto16
, getIReg(rt
)))));
9176 unop(Iop_32to8
, binop(Iop_And32
,
9184 IRExpr_ITE(binop(Iop_CmpEQ32
,
9194 unop(Iop_32to8
, binop(Iop_And32
,
9199 /* ========== GPR[rt]_23..16 ========== */
9203 unop(Iop_32HIto16
, getIReg(rt
)))));
9207 unop(Iop_32to8
, binop(Iop_And32
,
9215 IRExpr_ITE(binop(Iop_CmpEQ32
,
9225 unop(Iop_32to8
, binop(Iop_And32
,
9230 /* ========== GPR[rt]_15..8 ========== */
9234 unop(Iop_32to16
, getIReg(rt
)))));
9238 unop(Iop_32to8
, binop(Iop_And32
,
9246 IRExpr_ITE(binop(Iop_CmpEQ32
,
9256 unop(Iop_32to8
, binop(Iop_And32
,
9261 /* ========== GPR[rt]_7..0 ========== */
9265 unop(Iop_32to16
, getIReg(rt
)))));
9269 unop(Iop_32to8
, binop(Iop_And32
,
9277 IRExpr_ITE(binop(Iop_CmpEQ32
,
9287 unop(Iop_32to8
, binop(Iop_And32
,
9296 IRExpr_ITE(binop(Iop_CmpEQ32
,
9305 IRExpr_ITE(binop(Iop_CmpEQ32
,
9315 IRExpr_ITE(binop(Iop_CmpEQ32
,
9324 IRExpr_ITE(binop(Iop_CmpEQ32
,
9334 case 0x7: { /* SHRAV_R.QB */
9335 DIP("shrav_r.qb r%u, r%u, r%u", rd
, rt
, rs
);
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
);
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
,
9353 unop(Iop_32to16
, getIReg(rt
)))));
9354 assign(t1
, unop(Iop_32to8
,
9364 assign(t2
, unop(Iop_8Sto32
,
9366 unop(Iop_32to16
, getIReg(rt
)))));
9367 assign(t3
, unop(Iop_32to8
,
9374 unop(Iop_32to8
, mkexpr(t9
)))));
9376 assign(t4
, unop(Iop_8Sto32
,
9378 unop(Iop_32HIto16
, getIReg(rt
)))));
9379 assign(t5
, unop(Iop_32to8
,
9386 unop(Iop_32to8
, mkexpr(t9
)))));
9388 assign(t6
, unop(Iop_8Sto32
,
9390 unop(Iop_32HIto16
, getIReg(rt
)))));
9391 assign(t7
, unop(Iop_32to8
,
9398 unop(Iop_32to8
, mkexpr(t9
)))));
9399 putIReg(rd
, IRExpr_ITE(binop(Iop_CmpEQ32
,
9412 case 0x8: { /* SHLL.PH */
9413 DIP("shll.ph r%u, r%u, %u", rd
, rt
, rs
);
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
);
9425 putIReg(rd
, getIReg(rt
));
9427 /* Shift lower 16 bits. */
9428 assign(t0
, binop(Iop_Shl32
,
9430 unop(Iop_32to16
, getIReg(rt
))),
9433 assign(t1
, unop(Iop_1Uto32
,
9439 assign(t2
, unop(Iop_1Uto32
,
9444 mkU32(0xffffffff))));
9445 assign(t3
, binop(Iop_And32
,
9448 putDSPControl(IRExpr_ITE(binop(Iop_CmpEQ32
,
9455 putDSPControl(IRExpr_ITE(binop(Iop_CmpEQ32
,
9467 /* Shift higher 16 bits. */
9468 assign(t4
, binop(Iop_Shl32
,
9470 unop(Iop_32HIto16
, getIReg(rt
))),
9473 assign(t5
, unop(Iop_1Uto32
,
9479 assign(t6
, unop(Iop_1Uto32
,
9484 mkU32(0xffffffff))));
9485 assign(t7
, binop(Iop_And32
,
9488 putDSPControl(IRExpr_ITE(binop(Iop_CmpEQ32
,
9495 putDSPControl(IRExpr_ITE(binop(Iop_CmpEQ32
,
9502 putDSPControl(IRExpr_ITE(binop(Iop_CmpEQ32
,
9516 putIReg(rd
, binop(Iop_16HLto32
,
9517 unop(Iop_32to16
, mkexpr(t4
)),
9518 unop(Iop_32to16
, mkexpr(t0
))));
9522 case 0x9: { /* SHRA.PH */
9523 DIP("shra.ph r%u, r%u, %u", rd
, rt
, rs
);
9525 t0
= newTemp(Ity_I32
);
9526 t1
= newTemp(Ity_I32
);
9528 putIReg(rd
, getIReg(rt
));
9530 assign(t0
, binop(Iop_Sar32
,
9532 unop(Iop_32to16
, getIReg(rt
))),
9534 assign(t1
, binop(Iop_Sar32
,
9536 unop(Iop_32HIto16
, getIReg(rt
))),
9538 putIReg(rd
, binop(Iop_16HLto32
,
9539 unop(Iop_32to16
, mkexpr(t1
)),
9540 unop(Iop_32to16
, mkexpr(t0
))));
9544 case 0xA: { /* SHLLV.PH */
9545 DIP("shllv.ph r%u, r%u, r%u", rd
, rt
, rs
);
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
);
9561 assign(t0
, binop(Iop_And32
, getIReg(rs
), mkU32(0x0f)));
9563 /* Shift lower 16 bits. */
9564 assign(t2
, binop(Iop_Shl32
,
9566 unop(Iop_32to16
, getIReg(rt
))),
9567 unop(Iop_32to8
, mkexpr(t0
))));
9569 assign(t3
, binop(Iop_CmpNE32
,
9571 unop(Iop_32HIto16
, mkexpr(t2
))),
9572 mkU32(0x00000000)));
9573 assign(t4
, binop(Iop_CmpNE32
,
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
,
9585 assign(t12
, binop(Iop_CmpEQ32
,
9593 putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32
,
9599 IRExpr_ITE(mkexpr(t12
),
9605 /* Shift higher 16 bits. */
9606 assign(t6
, binop(Iop_Shl32
,
9608 unop(Iop_32HIto16
, getIReg(rt
))),
9609 unop(Iop_32to8
, mkexpr(t0
))));
9611 assign(t7
, binop(Iop_CmpNE32
,
9613 unop(Iop_32HIto16
, mkexpr(t6
))),
9614 mkU32(0x00000000)));
9615 assign(t8
, binop(Iop_CmpNE32
,
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
))));
9623 assign(t9
, binop(Iop_Shr32
,
9628 assign(t13
, binop(Iop_CmpEQ32
,
9636 putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32
,
9642 IRExpr_ITE(mkexpr(t13
),
9649 putIReg(rd
, binop(Iop_16HLto32
,
9650 unop(Iop_32to16
, mkexpr(t6
)),
9651 unop(Iop_32to16
, mkexpr(t2
))));
9654 case 0xB: { /* SHRAV.PH */
9655 DIP("shrav.ph r%u, r%u, r%u", rd
, rt
, rs
);
9657 t0
= newTemp(Ity_I32
);
9658 t1
= newTemp(Ity_I1
);
9659 t2
= newTemp(Ity_I32
);
9660 t3
= newTemp(Ity_I32
);
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
,
9666 unop(Iop_32to16
, getIReg(rt
))),
9667 unop(Iop_32to8
, mkexpr(t0
))));
9668 assign(t3
, binop(Iop_Sar32
,
9670 unop(Iop_32HIto16
, getIReg(rt
))),
9671 unop(Iop_32to8
, mkexpr(t0
))));
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
)))));
9682 case 0xC: { /* SHLL_S.PH */
9683 DIP("shll_s.ph r%u, r%u, %u", rd
, rt
, rs
);
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
);
9702 putIReg(rd
, getIReg(rt
));
9704 /* Shift lower 16 bits. */
9705 assign(t0
, binop(Iop_Shl32
,
9707 unop(Iop_32to16
, getIReg(rt
))),
9710 assign(t1
, unop(Iop_1Uto32
,
9716 assign(t2
, unop(Iop_1Uto32
,
9721 mkU32(0xffffffff))));
9722 assign(t3
, binop(Iop_And32
,
9725 putDSPControl(IRExpr_ITE(binop(Iop_CmpEQ32
,
9732 putDSPControl(IRExpr_ITE(binop(Iop_CmpEQ32
,
9745 IRExpr_ITE(binop(Iop_CmpEQ32
,
9748 IRExpr_ITE(binop(Iop_CmpEQ32
,
9757 mkU32(0x0000ffff))));
9759 IRExpr_ITE(binop(Iop_CmpEQ32
,
9765 mkU32(0x00008000))),
9767 IRExpr_ITE(binop(Iop_CmpEQ32
,
9773 mkU32(0x00008000))));
9774 /* Shift higher 16 bits. */
9775 assign(t4
, binop(Iop_Shl32
,
9777 unop(Iop_32HIto16
, getIReg(rt
))),
9780 assign(t5
, unop(Iop_1Uto32
,
9786 assign(t6
, unop(Iop_1Uto32
,
9791 mkU32(0xffffffff))));
9792 assign(t7
, binop(Iop_And32
,
9795 putDSPControl(IRExpr_ITE(binop(Iop_CmpEQ32
,
9802 putDSPControl(IRExpr_ITE(binop(Iop_CmpEQ32
,
9809 assign(t12
, binop(Iop_Shl32
,
9814 putDSPControl(IRExpr_ITE(binop(Iop_CmpEQ32
,
9823 assign(t13
, IRExpr_ITE(binop(Iop_CmpEQ32
,
9829 mkU32(0x80000000)));
9831 IRExpr_ITE(binop(Iop_CmpEQ32
,
9840 assign(t14
, IRExpr_ITE(binop(Iop_CmpEQ32
,
9846 mkU32(0x80000000)));
9848 IRExpr_ITE(binop(Iop_CmpEQ32
,
9859 putIReg(rd
, binop(Iop_Or32
,
9865 case 0xD: { /* SHRA_R.PH */
9866 DIP("shra.ph r%u, r%u, %u", rd
, rt
, rs
);
9868 t0
= newTemp(Ity_I32
);
9869 t1
= newTemp(Ity_I32
);
9871 putIReg(rd
, getIReg(rt
));
9873 assign(t0
, binop(Iop_Sar32
,
9882 assign(t1
, binop(Iop_Sar32
,
9891 putIReg(rd
, binop(Iop_16HLto32
,
9892 unop(Iop_32to16
, mkexpr(t1
)),
9893 unop(Iop_32to16
, mkexpr(t0
))));
9897 case 0xE: { /* SHLLV_S.PH */
9898 DIP("shllv_s.ph r%u, r%u, r%u", rd
, rt
, rs
);
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
);
9918 assign(t0
, binop(Iop_And32
, getIReg(rs
), mkU32(0x0f)));
9920 /* Shift lower 16 bits. */
9921 assign(t2
, binop(Iop_Shl32
,
9923 unop(Iop_32to16
, getIReg(rt
))),
9924 unop(Iop_32to8
, mkexpr(t0
))));
9926 assign(t3
, binop(Iop_CmpNE32
,
9928 unop(Iop_32HIto16
, mkexpr(t2
))),
9929 mkU32(0x00000000)));
9930 assign(t4
, binop(Iop_CmpNE32
,
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
,
9942 assign(t12
, binop(Iop_CmpEQ32
,
9950 putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32
,
9956 IRExpr_ITE(mkexpr(t12
),
9962 assign(t14
, IRExpr_ITE(binop(Iop_CmpNE32
,
9967 assign(t15
, IRExpr_ITE(binop(Iop_CmpNE32
,
9971 IRExpr_ITE(mkexpr(t12
),
9975 /* Shift higher 16 bits. */
9976 assign(t6
, binop(Iop_Shl32
,
9978 unop(Iop_32HIto16
, getIReg(rt
))),
9979 unop(Iop_32to8
, mkexpr(t0
))));
9981 assign(t7
, binop(Iop_CmpNE32
,
9983 unop(Iop_32HIto16
, mkexpr(t6
))),
9984 mkU32(0x00000000)));
9985 assign(t8
, binop(Iop_CmpNE32
,
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
))));
9993 assign(t9
, binop(Iop_Shr32
,
9998 assign(t13
, binop(Iop_CmpEQ32
,
10003 mkU32(0x00008000)),
10006 putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32
,
10012 IRExpr_ITE(mkexpr(t13
),
10019 assign(t16
, IRExpr_ITE(binop(Iop_CmpNE32
,
10024 assign(t17
, IRExpr_ITE(binop(Iop_CmpNE32
,
10028 IRExpr_ITE(mkexpr(t13
),
10033 putIReg(rd
, binop(Iop_16HLto32
, mkexpr(t17
), mkexpr(t15
)));
10036 case 0xF: { /* SHRAV_R.PH */
10037 DIP("shrav_r.ph r%u, r%u, r%u", rd
, rt
, rs
);
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
);
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))));
10050 assign(t3
, binop(Iop_Sar32
,
10053 unop(Iop_32to16
, getIReg(rt
))),
10057 unop(Iop_32to8
, mkexpr(t0
))));
10058 assign(t4
, binop(Iop_Sar32
,
10066 unop(Iop_32to8
, mkexpr(t0
))));
10068 putIReg(rd
, binop(Iop_16HLto32
,
10069 IRExpr_ITE(mkexpr(t1
),
10074 IRExpr_ITE(mkexpr(t1
),
10075 unop(Iop_32to16
, getIReg(rt
)),
10080 case 0x14: { /* SHLL_S.W */
10081 DIP("shll_s.w r%u, r%u, %u", rd
, rt
, rs
);
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
);
10091 putIReg(rd
, getIReg(rt
));
10093 /* t0-bits that will be discarded, sign extended to
10095 assign(t0
, binop(Iop_Sar32
,
10103 assign(t1
, IRExpr_ITE(binop(Iop_CmpEQ32
,
10106 mkU32(0x80000000)),
10109 mkU32(0x80000000)));
10111 assign(t2
, binop(Iop_Shl32
, getIReg(rt
), mkU8(rs
)));
10112 assign(t3
, IRExpr_ITE(binop(Iop_CmpEQ32
,
10115 mkU32(0x80000000)),
10118 mkU32(0x80000000))),
10122 assign(t4
, IRExpr_ITE(binop(Iop_CmpNE32
,
10125 IRExpr_ITE(binop(Iop_CmpNE32
,
10132 assign(t5
, IRExpr_ITE(binop(Iop_CmpNE32
,
10134 mkU32(0xffffffff)),
10139 putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32
,
10144 putDSPControl(IRExpr_ITE(binop(Iop_CmpEQ32
,
10147 mkU32(0x80000000)),
10155 mkU32(0x400000))));
10156 putIReg(rd
, mkexpr(t4
));
10160 case 0x15: { /* SHRA_R.W */
10161 DIP("shra_r.w r%u, r%u, %u", rd
, rt
, rs
);
10164 putIReg(rd
, getIReg(rt
));
10166 putIReg(rd
, binop(Iop_Add32
,
10168 getIReg(rt
), mkU8(rs
)),
10179 case 0x16: { /* SHLLV_S.W */
10180 DIP("shllv_s.w r%u, r%u, r%u", rd
, rt
, rs
);
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
);
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)));
10196 /* t2 = sign of the input value. */
10197 assign(t2
, binop(Iop_Shr32
,
10200 mkU32(0x80000000)),
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
,
10219 mkU32(0x80000000)),
10223 unop(Iop_64to32
, mkexpr(t3
)),
10224 mkU32(0x80000000)),
10227 putDSPControl(IRExpr_ITE(unop(Iop_32to1
, mkexpr(t6
)),
10231 IRExpr_ITE(mkexpr(t7
),
10238 assign(t8
, IRExpr_ITE(unop(Iop_32to1
,
10241 mkU32(0x7fffffff)));
10242 putIReg(rd
, IRExpr_ITE(unop(Iop_32to1
, mkexpr(t6
)),
10243 IRExpr_ITE(unop(Iop_32to1
,
10246 mkU32(0x7fffffff)),
10247 IRExpr_ITE(mkexpr(t7
),
10253 case 0x17: { /* SHRAV_R.W */
10254 DIP("shrav_r.w r%u, r%u, r%u", rd
, rt
, rs
);
10256 t0
= newTemp(Ity_I32
);
10257 t1
= newTemp(Ity_I1
);
10258 t2
= newTemp(Ity_I8
);
10259 t3
= newTemp(Ity_I32
);
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))));
10266 putIReg(rd
, IRExpr_ITE(mkexpr(t1
),
10277 case 0x19: { /* SHRL.PH */
10278 DIP("shrl.ph r%u, r%u, %u", rd
, rt
, rs
);
10280 t0
= newTemp(Ity_I32
);
10281 t1
= newTemp(Ity_I32
);
10282 assign(t0
, binop(Iop_Shr32
,
10284 unop(Iop_32to16
, getIReg(rt
))),
10286 assign(t1
, binop(Iop_Shr32
,
10288 unop(Iop_32HIto16
, getIReg(rt
))),
10290 putIReg(rd
, binop(Iop_16HLto32
,
10291 unop(Iop_32to16
, mkexpr(t1
)),
10292 unop(Iop_32to16
, mkexpr(t0
))));
10295 case 0x1B: { /* SHRLV.PH */
10296 DIP("shrlv.ph r%u, r%u, r%u", rd
, rt
, rs
);
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
);
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)));
10310 assign(t2
, binop(Iop_Shr32
,
10312 unop(Iop_32to16
, getIReg(rt
))),
10313 unop(Iop_32to8
, mkexpr(t0
))));
10314 assign(t3
, binop(Iop_Shr32
,
10316 unop(Iop_32HIto16
, getIReg(rt
))),
10317 unop(Iop_32to8
, mkexpr(t0
))));
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
)));
10331 break; /* end of SHLL.QB */
10333 case 0x18: { /* ADDUH.QB/MUL.PH */
10335 case 0x00: { /* ADDUH.QB */
10336 DIP("adduh.qb r%u, r%u, r%u", rd
, rs
, rt
);
10338 t0
= newTemp(Ity_I32
);
10340 assign(t0
, binop(Iop_HAdd8Ux4
, getIReg(rs
), getIReg(rt
)));
10342 putIReg(rd
, mkexpr(t0
));
10345 case 0x1: { /* SUBUH.QB */
10346 DIP("subuh.qb r%u, r%u, r%u", rd
, rs
, rt
);
10348 t0
= newTemp(Ity_I32
);
10350 assign(t0
, binop(Iop_HSub8Ux4
, getIReg(rs
), getIReg(rt
)));
10352 putIReg(rd
, mkexpr(t0
));
10355 case 0x02: { /* ADDUH_R.QB */
10356 DIP("adduh_r.qb r%u, r%u, r%u", rd
, rs
, rt
);
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
);
10371 /* Extract input bytes, add values, add 1 and half the
10373 assign(t0
, unop(Iop_8Uto32
,
10375 unop(Iop_32to16
, getIReg(rs
)))));
10376 assign(t1
, unop(Iop_8Uto32
,
10378 unop(Iop_32to16
, getIReg(rt
)))));
10379 assign(t2
, unop(Iop_16to8
,
10386 mkU32(0x00000001)),
10389 assign(t3
, unop(Iop_8Uto32
,
10391 unop(Iop_32to16
, getIReg(rs
)))));
10392 assign(t4
, unop(Iop_8Uto32
,
10394 unop(Iop_32to16
, getIReg(rt
)))));
10395 assign(t5
, unop(Iop_16to8
,
10402 mkU32(0x00000001)),
10405 assign(t6
, unop(Iop_8Uto32
,
10407 unop(Iop_32HIto16
, getIReg(rs
)))));
10408 assign(t7
, unop(Iop_8Uto32
,
10410 unop(Iop_32HIto16
, getIReg(rt
)))));
10411 assign(t8
, unop(Iop_16to8
,
10418 mkU32(0x00000001)),
10421 assign(t9
, unop(Iop_8Uto32
,
10423 unop(Iop_32HIto16
, getIReg(rs
)))));
10424 assign(t10
, unop(Iop_8Uto32
,
10426 unop(Iop_32HIto16
, getIReg(rt
)))));
10427 assign(t11
, unop(Iop_16to8
,
10434 mkU32(0x00000001)),
10437 putIReg(rd
, binop(Iop_16HLto32
,
10439 mkexpr(t11
), mkexpr(t8
)),
10441 mkexpr(t5
), mkexpr(t2
))));
10444 case 0x3: { /* SUBUH_R.QB */
10445 DIP("subuh_r.qb r%u, r%u, r%u", rd
, rs
, rt
);
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
);
10460 /* Extract each byte of rs and rt. */
10461 assign(t1
, unop(Iop_8Uto32
,
10463 unop(Iop_32to16
, getIReg(rs
)))));
10464 assign(t2
, unop(Iop_8Uto32
,
10466 unop(Iop_32to16
, getIReg(rs
)))));
10467 assign(t3
, unop(Iop_8Uto32
,
10469 unop(Iop_32HIto16
, getIReg(rs
)))));
10470 assign(t4
, unop(Iop_8Uto32
,
10472 unop(Iop_32HIto16
, getIReg(rs
)))));
10474 assign(t5
, unop(Iop_8Uto32
,
10476 unop(Iop_32to16
, getIReg(rt
)))));
10477 assign(t6
, unop(Iop_8Uto32
,
10479 unop(Iop_32to16
, getIReg(rt
)))));
10480 assign(t7
, unop(Iop_8Uto32
,
10482 unop(Iop_32HIto16
, getIReg(rt
)))));
10483 assign(t8
, unop(Iop_8Uto32
,
10485 unop(Iop_32HIto16
, getIReg(rt
)))));
10487 /* Add 1 to each resulting byte and half the results. */
10488 assign(t9
, unop(Iop_16to8
,
10495 mkU32(0x00000001)),
10497 assign(t10
, unop(Iop_16to8
,
10504 mkU32(0x00000001)),
10506 assign(t11
, unop(Iop_16to8
,
10513 mkU32(0x00000001)),
10515 assign(t12
, unop(Iop_16to8
,
10522 mkU32(0x00000001)),
10525 putIReg(rd
, binop(Iop_16HLto32
,
10527 mkexpr(t12
), mkexpr(t11
)),
10529 mkexpr(t10
), mkexpr(t9
))));
10532 case 0x8: { /* ADDQH.PH */
10533 DIP("addqh.ph r%u, r%u, r%u", rd
, rs
, rt
);
10535 t0
= newTemp(Ity_I32
);
10536 t1
= newTemp(Ity_I16
);
10537 t2
= newTemp(Ity_I32
);
10538 t3
= newTemp(Ity_I16
);
10540 /* Add lower halfs of rs and rt
10541 and right shift the result by 1. */
10542 assign(t0
, binop(Iop_Add32
,
10544 unop(Iop_32to16
, getIReg(rs
))),
10546 unop(Iop_32to16
, getIReg(rt
)))));
10547 assign(t1
, unop(Iop_32to16
,
10551 mkU32(0x0001fffe)),
10553 /* Add higher halfs of rs and rt
10554 and right shift the result by 1. */
10555 assign(t2
, binop(Iop_Add32
,
10557 unop(Iop_32HIto16
, getIReg(rs
))),
10559 unop(Iop_32HIto16
, getIReg(rt
)))));
10560 assign(t3
, unop(Iop_32to16
,
10564 mkU32(0x0001fffe)),
10566 putIReg(rd
, binop(Iop_16HLto32
, mkexpr(t3
), mkexpr(t1
)));
10569 case 0x9: { /* SUBQH.PH */
10570 DIP("subqh.ph r%u, r%u, r%u", rd
, rs
, rt
);
10573 putIReg(rd
, binop(Iop_HSub16Sx2
,
10574 getIReg(rs
), getIReg(rt
)));
10577 case 0xA: {/* ADDQH_R.PH */
10578 DIP("addqh_r.ph r%u, r%u, r%u", rd
, rs
, rt
);
10580 t0
= newTemp(Ity_I32
);
10581 t1
= newTemp(Ity_I16
);
10582 t2
= newTemp(Ity_I32
);
10583 t3
= newTemp(Ity_I16
);
10585 /* Add lower halfs of rs and rt, add 1
10586 and right shift the result by 1. */
10587 assign(t0
, binop(Iop_Add32
,
10589 unop(Iop_32to16
, getIReg(rs
))),
10591 unop(Iop_32to16
, getIReg(rt
)))));
10592 assign(t1
, unop(Iop_32to16
,
10598 mkU32(0x0001fffe)),
10600 /* Add higher halfs of rs and rt, add 1
10601 and right shift the result by 1. */
10602 assign(t2
, binop(Iop_Add32
,
10604 unop(Iop_32HIto16
, getIReg(rs
))),
10606 unop(Iop_32HIto16
, getIReg(rt
)))));
10607 assign(t3
, unop(Iop_32to16
,
10613 mkU32(0x0001fffe)),
10616 putIReg(rd
, binop(Iop_16HLto32
, mkexpr(t3
), mkexpr(t1
)));
10619 case 0xB: { /* SUBQH_R.PH */
10620 DIP("subqh_r.ph r%u, r%u, r%u", rd
, rs
, rt
);
10622 t0
= newTemp(Ity_I32
);
10623 t1
= newTemp(Ity_I16
);
10624 t2
= newTemp(Ity_I32
);
10625 t3
= newTemp(Ity_I16
);
10627 /* Sub lower halfs of rs and rt, add 1
10628 and right shift the result by 1. */
10629 assign(t0
, binop(Iop_Sub32
,
10631 unop(Iop_32to16
, getIReg(rs
))),
10633 unop(Iop_32to16
, getIReg(rt
)))));
10634 assign(t1
, unop(Iop_32to16
,
10640 mkU32(0x0001fffe)),
10642 /* Sub higher halfs of rs and rt, add 1
10643 and right shift the result by 1. */
10644 assign(t2
, binop(Iop_Sub32
,
10646 unop(Iop_32HIto16
, getIReg(rs
))),
10648 unop(Iop_32HIto16
, getIReg(rt
)))));
10649 assign(t3
, unop(Iop_32to16
,
10655 mkU32(0x0001fffe)),
10658 putIReg(rd
, binop(Iop_16HLto32
, mkexpr(t3
), mkexpr(t1
)));
10661 case 0xC: { /* MUL.PH */
10662 DIP("mul.ph r%u, r%u, r%u", rd
, rs
, rt
);
10664 t0
= newTemp(Ity_I32
);
10665 t1
= newTemp(Ity_I32
);
10666 t2
= newTemp(Ity_I32
);
10671 unop(Iop_32HIto16
, getIReg(rs
))),
10673 unop(Iop_32HIto16
, getIReg(rt
)))));
10674 /* DSP Control flag. */
10675 putDSPControl(IRExpr_ITE(unop(Iop_Not1
,
10676 binop(Iop_CmpLE32S
,
10681 mkU32(0x00200000)),
10682 IRExpr_ITE(binop(Iop_CmpLT32S
,
10690 getDSPControl())));
10695 unop(Iop_32to16
, getIReg(rs
))),
10697 unop(Iop_32to16
, getIReg(rt
)))));
10698 /* DSP Control flag. */
10699 putDSPControl(IRExpr_ITE(unop(Iop_Not1
,
10700 binop(Iop_CmpLE32S
,
10705 mkU32(0x00200000)),
10706 IRExpr_ITE(binop(Iop_CmpLT32S
,
10714 getDSPControl())));
10716 assign(t2
, binop(Iop_16HLto32
,
10717 unop(Iop_32to16
, mkexpr(t0
)),
10718 unop(Iop_32to16
, mkexpr(t1
))));
10719 putIReg(rd
, mkexpr(t2
));
10722 case 0xE: { /* MUL_S.PH */
10723 DIP("mul_s.ph r%u r%u, r%u", rd
, rs
, rt
);
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
);
10732 /* t0 - signed intermediate result. */
10736 unop(Iop_32HIto16
, getIReg(rs
))),
10738 unop(Iop_32HIto16
, getIReg(rt
)))));
10741 IRExpr_ITE(unop(Iop_Not1
,
10742 binop(Iop_CmpLE32S
,
10746 IRExpr_ITE(binop(Iop_CmpLT32S
,
10748 mkU32(0xFFFF8000)),
10752 /* DSP Control flag. */
10753 putDSPControl(IRExpr_ITE(unop(Iop_Not1
,
10754 binop(Iop_CmpLE32S
,
10759 mkU32(0x00200000)),
10760 IRExpr_ITE(binop(Iop_CmpLT32S
,
10768 getDSPControl())));
10770 /* t2 - signed intermediate result. */
10771 assign(t2
, binop(Iop_Mul32
,
10773 unop(Iop_32to16
, getIReg(rs
))),
10775 unop(Iop_32to16
, getIReg(rt
)))));
10777 assign(t3
, IRExpr_ITE(unop(Iop_Not1
,
10778 binop(Iop_CmpLE32S
,
10782 IRExpr_ITE(binop(Iop_CmpLT32S
,
10784 mkU32(0xFFFF8000)),
10788 /* DSP Control flag. */
10789 putDSPControl(IRExpr_ITE(unop(Iop_Not1
,
10790 binop(Iop_CmpLE32S
,
10795 mkU32(0x00200000)),
10796 IRExpr_ITE(binop(Iop_CmpLT32S
,
10804 getDSPControl())));
10806 assign(t4
, binop(Iop_16HLto32
,
10807 unop(Iop_32to16
, mkexpr(t1
)),
10808 unop(Iop_32to16
, mkexpr(t3
))));
10809 putIReg(rd
, mkexpr(t4
));
10812 case 0x10: { /* ADDQH.W */
10813 DIP("addqh.w r%u, r%u, r%u", rd
, rs
, rt
);
10815 t0
= newTemp(Ity_I64
);
10816 t1
= newTemp(Ity_I64
);
10818 assign(t0
, binop(Iop_Add64
,
10819 unop(Iop_32Sto64
, getIReg(rs
)),
10820 unop(Iop_32Sto64
, getIReg(rt
))));
10821 assign(t1
, binop(Iop_And64
,
10823 mkU64(0x00000001fffffffeULL
)));
10824 putIReg(rd
, unop(Iop_64to32
,
10825 binop(Iop_Shr64
, mkexpr(t1
), mkU8(0x1))));
10828 case 0x11: { /* SUBQH.W */
10829 DIP("subqh.w r%u, r%u, r%u", rd
, rs
, rt
);
10831 t0
= newTemp(Ity_I64
);
10832 t1
= newTemp(Ity_I64
);
10834 assign(t0
, binop(Iop_Sub64
,
10835 unop(Iop_32Sto64
, getIReg(rs
)),
10836 unop(Iop_32Sto64
, getIReg(rt
))));
10837 assign(t1
, binop(Iop_And64
,
10839 mkU64(0x00000001fffffffeULL
)));
10840 putIReg(rd
, unop(Iop_64to32
,
10841 binop(Iop_Shr64
, mkexpr(t1
), mkU8(0x1))));
10844 case 0x12: { /* ADDQH_R.W */
10845 DIP("addqh_r.w r%u, r%u, r%u", rd
, rs
, rt
);
10847 t0
= newTemp(Ity_I64
);
10848 t1
= newTemp(Ity_I64
);
10849 t2
= newTemp(Ity_I64
);
10851 assign(t0
, binop(Iop_Add64
,
10852 unop(Iop_32Sto64
, getIReg(rs
)),
10853 unop(Iop_32Sto64
, getIReg(rt
))));
10854 assign(t1
, binop(Iop_Add64
,
10856 mkU64(0x0000000000000001ULL
)));
10857 assign(t2
, binop(Iop_And64
,
10859 mkU64(0x00000001fffffffeULL
)));
10860 putIReg(rd
, unop(Iop_64to32
,
10861 binop(Iop_Shr64
, mkexpr(t2
), mkU8(0x1))));
10864 case 0x13: { /* SUBQH_R.W */
10865 DIP("subqh_r.w r%u, r%u, r%u", rd
, rs
, rt
);
10867 t0
= newTemp(Ity_I64
);
10868 t1
= newTemp(Ity_I64
);
10869 t2
= newTemp(Ity_I64
);
10871 assign(t0
, binop(Iop_Sub64
,
10872 unop(Iop_32Sto64
, getIReg(rs
)),
10873 unop(Iop_32Sto64
, getIReg(rt
))));
10874 assign(t1
, binop(Iop_Add64
,
10876 mkU64(0x0000000000000001ULL
)));
10877 assign(t2
, binop(Iop_And64
,
10879 mkU64(0x00000001fffffffeULL
)));
10880 putIReg(rd
, unop(Iop_64to32
,
10881 binop(Iop_Shr64
, mkexpr(t2
), mkU8(0x1))));
10884 case 0x16: { /* MULQ_S.W */
10885 DIP("mulq_s.w r%u, r%u, r%u", rd
, rs
, rt
);
10887 t0
= newTemp(Ity_I64
);
10888 t1
= newTemp(Ity_I1
);
10889 t2
= newTemp(Ity_I1
);
10891 assign(t0
, binop(Iop_Shl64
,
10893 getIReg(rt
), getIReg(rs
)),
10895 assign(t1
, binop(Iop_CmpEQ32
,
10896 getIReg(rt
), mkU32(0x80000000)));
10897 assign(t2
, binop(Iop_CmpEQ32
,
10898 getIReg(rs
), mkU32(0x80000000)));
10900 putDSPControl(IRExpr_ITE(mkexpr(t1
),
10901 IRExpr_ITE(mkexpr(t2
),
10908 putIReg(rd
, IRExpr_ITE(mkexpr(t1
),
10909 IRExpr_ITE(mkexpr(t2
),
10913 unop(Iop_64HIto32
, mkexpr(t0
))));
10916 case 0x17: { /* MULQ_RS.W */
10917 DIP("mulq_rs.w r%u, r%u, r%u", rd
, rs
, rt
);
10919 t0
= newTemp(Ity_I64
);
10920 t1
= newTemp(Ity_I1
);
10921 t2
= newTemp(Ity_I1
);
10923 assign(t0
, binop(Iop_Add64
,
10929 mkU64(0x0000000080000000ULL
)));
10931 binop(Iop_CmpEQ32
, getIReg(rt
), mkU32(0x80000000)));
10933 binop(Iop_CmpEQ32
, getIReg(rs
), mkU32(0x80000000)));
10934 putDSPControl(IRExpr_ITE(mkexpr(t1
),
10935 IRExpr_ITE(mkexpr(t2
),
10942 putIReg(rd
, IRExpr_ITE(mkexpr(t1
),
10943 IRExpr_ITE(mkexpr(t2
),
10947 unop(Iop_64HIto32
, mkexpr(t0
))));
10953 break; /* end of ADDUH.QB/MUL.PH */
10955 case 0x30: { /* DPAQ.W.PH */
10957 case 0x0: { /* DPA.W.PH */
10958 DIP("dpa.w.ph ac%u, r%u, r%u", ac
, rs
, rt
);
10961 t0
= newTemp(Ity_I64
);
10962 t1
= newTemp(Ity_I64
);
10963 t2
= newTemp(Ity_I64
);
10969 unop(Iop_32HIto16
, getIReg(rs
))),
10971 unop(Iop_32HIto16
, getIReg(rt
))))));
10976 unop(Iop_32to16
, getIReg(rs
))),
10978 unop(Iop_32to16
, getIReg(rt
))))));
10982 binop(Iop_Add64
, mkexpr(t0
), mkexpr(t1
))));
10983 putAcc(ac
, mkexpr(t2
));
10986 case 0x1: { /* DPS.W.PH */
10987 DIP("dps.w.ph ac%u, r%u, r%u", ac
, rs
, rt
);
10990 t0
= newTemp(Ity_I64
);
10991 t1
= newTemp(Ity_I64
);
10992 t2
= newTemp(Ity_I64
);
10998 unop(Iop_32HIto16
, getIReg(rs
))),
11000 unop(Iop_32HIto16
, getIReg(rt
))))));
11005 unop(Iop_32to16
, getIReg(rs
))),
11007 unop(Iop_32to16
, getIReg(rt
))))));
11011 binop(Iop_Add64
, mkexpr(t0
), mkexpr(t1
))));
11012 putAcc(ac
, mkexpr(t2
));
11015 case 0x2: { /* MULSA.W.PH */
11016 DIP("mulsa.w.ph ac%u, r%u, r%u", ac
, rs
, rt
);
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
);
11024 assign(t4
, getAcc(ac
));
11025 assign(t0
, binop(Iop_Mul32
,
11027 unop(Iop_32to16
, getIReg(rt
))),
11029 unop(Iop_32to16
, getIReg(rs
)))));
11030 assign(t1
, binop(Iop_Mul32
,
11032 unop(Iop_32HIto16
, getIReg(rt
))),
11034 unop(Iop_32HIto16
, getIReg(rs
)))));
11035 assign(t2
, binop(Iop_Sub32
, mkexpr(t1
), mkexpr(t0
)));
11036 putAcc(ac
, binop(Iop_Add64
,
11038 unop(Iop_32Sto64
, mkexpr(t2
))));
11041 case 0x3: { /* DPAU.H.QBL */
11042 DIP("dpau.h.qbl ac%u, r%u, r%u", ac
, rs
, rt
);
11044 t0
= newTemp(Ity_I32
);
11045 t1
= newTemp(Ity_I32
);
11046 t2
= newTemp(Ity_I64
);
11047 t3
= newTemp(Ity_I64
);
11053 unop(Iop_32HIto16
, getIReg(rs
)))),
11056 unop(Iop_32HIto16
, getIReg(rt
))))));
11061 unop(Iop_32HIto16
, getIReg(rs
)))),
11064 unop(Iop_32HIto16
, getIReg(rt
))))));
11071 binop(Iop_Add64
, getAcc(ac
), mkexpr(t2
)));
11072 putAcc(ac
, mkexpr(t3
));
11075 case 0x4: { /* DPAQ_S.W.PH */
11076 DIP("dpaq_s.w.ph ac%u, r%u, r%u", ac
, rs
, rt
);
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
);
11089 assign(t0
, getAcc(ac
));
11091 assign(t1
, binop(Iop_Shl64
,
11100 assign(t2
, binop(Iop_CmpEQ32
,
11102 unop(Iop_32HIto16
, getIReg(rs
))),
11103 mkU32(0x00008000)));
11104 assign(t3
, binop(Iop_CmpEQ32
,
11106 unop(Iop_32HIto16
, getIReg(rt
))),
11107 mkU32(0x00008000)));
11109 IRExpr_ITE(mkexpr(t2
),
11110 IRExpr_ITE(mkexpr(t3
),
11111 mkU64(0x000000007fffffffULL
),
11115 putDSPControl(IRExpr_ITE(mkexpr(t2
),
11116 IRExpr_ITE(mkexpr(t3
),
11127 assign(t5
, binop(Iop_Shl64
,
11130 unop(Iop_32to16
, getIReg(rs
))),
11132 unop(Iop_32to16
, getIReg(rt
)))
11135 assign(t6
, binop(Iop_CmpEQ32
,
11137 unop(Iop_32to16
, getIReg(rs
))),
11138 mkU32(0x00008000)));
11139 assign(t7
, binop(Iop_CmpEQ32
,
11141 unop(Iop_32to16
, getIReg(rt
))),
11142 mkU32(0x00008000)));
11144 IRExpr_ITE(mkexpr(t6
),
11145 IRExpr_ITE(mkexpr(t7
),
11146 mkU64(0x000000007fffffffULL
),
11150 putDSPControl(IRExpr_ITE(mkexpr(t6
),
11151 IRExpr_ITE(mkexpr(t7
),
11162 assign(t9
, binop(Iop_Add64
,
11163 binop(Iop_Add64
, mkexpr(t4
), mkexpr(t8
)),
11165 putAcc(ac
, mkexpr(t9
));
11168 case 0x5: { /* DPSQ_S.W.PH */
11169 DIP("dpsq_s.w.ph ac%u r%u, r%u", ac
, rs
, rt
);
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
);
11182 assign(t0
, getAcc(ac
));
11184 assign(t1
, binop(Iop_Shl64
,
11193 assign(t2
, binop(Iop_CmpEQ32
,
11195 unop(Iop_32HIto16
, getIReg(rs
))),
11196 mkU32(0x00008000)));
11197 assign(t3
, binop(Iop_CmpEQ32
,
11199 unop(Iop_32HIto16
, getIReg(rt
))),
11200 mkU32(0x00008000)));
11202 IRExpr_ITE(mkexpr(t2
),
11203 IRExpr_ITE(mkexpr(t3
),
11204 mkU64(0x000000007fffffffULL
),
11208 putDSPControl(IRExpr_ITE(mkexpr(t2
),
11209 IRExpr_ITE(mkexpr(t3
),
11224 unop(Iop_32to16
, getIReg(rs
))),
11226 unop(Iop_32to16
, getIReg(rt
)))),
11228 assign(t6
, binop(Iop_CmpEQ32
,
11230 unop(Iop_32to16
, getIReg(rs
))),
11231 mkU32(0x00008000)));
11232 assign(t7
, binop(Iop_CmpEQ32
,
11234 unop(Iop_32to16
, getIReg(rt
))),
11235 mkU32(0x00008000)));
11237 IRExpr_ITE(mkexpr(t6
),
11238 IRExpr_ITE(mkexpr(t7
),
11239 mkU64(0x000000007fffffffULL
),
11243 putDSPControl(IRExpr_ITE(mkexpr(t6
),
11244 IRExpr_ITE(mkexpr(t7
),
11258 binop(Iop_Add64
, mkexpr(t4
), mkexpr(t8
))));
11259 putAcc(ac
, mkexpr(t9
));
11262 case 0x6: { /* MULSAQ_S.W.PH */
11263 DIP("mulsaq_s.w.ph ac%u r%u, r%u", ac
, rs
, rt
);
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
);
11277 assign(t0
, unop(Iop_16Sto32
,
11278 unop(Iop_32HIto16
, getIReg(rs
))));
11279 assign(t1
, unop(Iop_16Sto32
,
11280 unop(Iop_32HIto16
, getIReg(rt
))));
11282 assign(t8
, binop(Iop_And32
,
11295 /* DSPControl_outflag:16+acc <- 1 */
11296 putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32
,
11308 IRExpr_ITE(binop(Iop_CmpNE32
,
11309 mkexpr(t8
), mkU32(0x0)),
11313 mkexpr(t0
), mkexpr(t1
)),
11316 assign(t3
, unop(Iop_16Sto32
,
11317 unop(Iop_32to16
, getIReg(rs
))));
11318 assign(t4
, unop(Iop_16Sto32
,
11319 unop(Iop_32to16
, getIReg(rt
))));
11321 assign(t9
, binop(Iop_And32
,
11334 /* DSPControl_outflag:16+acc <- 1 */
11335 putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32
,
11346 IRExpr_ITE(binop(Iop_CmpNE32
,
11358 unop(Iop_32Sto64
, mkexpr(t2
)),
11359 unop(Iop_32Sto64
, mkexpr(t5
))));
11361 assign(t7
, binop(Iop_Add64
, getAcc(ac
), mkexpr(t6
)));
11363 putAcc(ac
, mkexpr(t7
));
11366 case 0x7: { /* DPAU.H.QBR */
11367 DIP("dpau.h.qbr ac%u, r%u, r%u", ac
, rs
, rt
);
11369 t0
= newTemp(Ity_I32
);
11370 t1
= newTemp(Ity_I32
);
11371 t2
= newTemp(Ity_I64
);
11372 t3
= newTemp(Ity_I64
);
11378 unop(Iop_32to16
, getIReg(rs
)))),
11381 unop(Iop_32to16
, getIReg(rt
))))));
11386 unop(Iop_32to16
, getIReg(rs
)))),
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
));
11396 case 0x8: { /* DPAX.W.PH */
11397 DIP("dpax.w.ph ac%u, r%u, r%u", ac
, rs
, rt
);
11399 t0
= newTemp(Ity_I64
);
11400 t1
= newTemp(Ity_I64
);
11401 t2
= newTemp(Ity_I64
);
11407 unop(Iop_32HIto16
, getIReg(rs
))),
11409 unop(Iop_32to16
, getIReg(rt
))))));
11414 unop(Iop_32to16
, getIReg(rs
))),
11416 unop(Iop_32HIto16
, getIReg(rt
))))));
11420 binop(Iop_Add64
, mkexpr(t0
), mkexpr(t1
))));
11421 putAcc(ac
, mkexpr(t2
));
11424 case 0x9: { /* DPSX.W.PH */
11425 DIP("dpsx.w.ph ac%u r%u, r%u", ac
, rs
, rt
);
11428 t0
= newTemp(Ity_I64
);
11429 t1
= newTemp(Ity_I64
);
11430 t2
= newTemp(Ity_I64
);
11436 unop(Iop_32HIto16
, getIReg(rs
))),
11438 unop(Iop_32to16
, getIReg(rt
))))));
11443 unop(Iop_32to16
, getIReg(rs
))),
11445 unop(Iop_32HIto16
, getIReg(rt
))))));
11449 binop(Iop_Add64
, mkexpr(t0
), mkexpr(t1
))));
11450 putAcc(ac
, mkexpr(t2
));
11453 case 0xB: { /* DPSU.H.QBL */
11454 DIP("dpsu.h.qbl ac%u, r%u, r%u", ac
, rs
, rt
);
11457 t0
= newTemp(Ity_I32
);
11458 t1
= newTemp(Ity_I32
);
11459 t2
= newTemp(Ity_I64
);
11460 t3
= newTemp(Ity_I64
);
11466 unop(Iop_32HIto16
, getIReg(rs
)))),
11469 unop(Iop_32HIto16
, getIReg(rt
))))));
11474 unop(Iop_32HIto16
, getIReg(rs
)))),
11477 unop(Iop_32HIto16
, getIReg(rt
))))));
11480 binop(Iop_Add32
, mkexpr(t0
), mkexpr(t1
))));
11482 binop(Iop_Sub64
, getAcc(ac
), mkexpr(t2
)));
11483 putAcc(ac
, mkexpr(t3
));
11486 case 0xC: { /* DPAQ_SA.L.W */
11487 DIP("dpaq_sa.l.w ac%u, r%u, r%u", ac
, rs
, rt
);
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
);
11500 assign(t0
, getAcc(ac
));
11502 assign(t1
, binop(Iop_Shl64
,
11504 getIReg(rs
), getIReg(rt
)),
11507 assign(t2
, binop(Iop_CmpEQ32
,
11509 mkU32(0x80000000)));
11510 assign(t3
, binop(Iop_CmpEQ32
,
11512 mkU32(0x80000000)));
11515 IRExpr_ITE(mkexpr(t2
),
11516 IRExpr_ITE(mkexpr(t3
),
11517 mkU64(0x7fffffffffffffffULL
),
11521 putDSPControl(IRExpr_ITE(mkexpr(t2
),
11522 IRExpr_ITE(mkexpr(t3
),
11533 assign(t5
, binop(Iop_Add64
,
11535 unop(Iop_64to32
, mkexpr(t0
))),
11537 unop(Iop_64to32
, mkexpr(t4
)))));
11542 unop(Iop_64HIto32
, mkexpr(t0
))),
11544 unop(Iop_64HIto32
, mkexpr(t4
)))),
11547 unop(Iop_64HIto32
, mkexpr(t5
)),
11549 assign(t7
, binop(Iop_32HLto64
,
11550 unop(Iop_64to32
, mkexpr(t6
)),
11551 unop(Iop_64to32
, mkexpr(t5
))));
11552 assign(t8
, binop(Iop_CmpEQ32
,
11555 unop(Iop_64to32
, mkexpr(t6
)),
11556 mkU32(0x80000000)),
11559 unop(Iop_64HIto32
, mkexpr(t6
)),
11560 mkU32(0x00000001))));
11561 assign(t9
, binop(Iop_CmpEQ32
,
11565 mkU32(0x00000001)),
11567 putDSPControl(IRExpr_ITE(mkexpr(t8
),
11575 IRExpr_ITE(mkexpr(t8
),
11577 IRExpr_ITE(mkexpr(t9
),
11578 mkU64(0x8000000000000000ULL
),
11579 mkU64(0x7fffffffffffffffULL
)))
11583 case 0xD: { /* DPSQ_SA.L.W */
11584 DIP("dpsq_sa.l.w ac%u, r%u, r%u", ac
, rs
, rt
);
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
);
11597 assign(t0
, getAcc(ac
));
11599 assign(t1
, binop(Iop_Shl64
,
11601 getIReg(rs
), getIReg(rt
)),
11604 assign(t2
, binop(Iop_CmpEQ32
,
11606 mkU32(0x80000000)));
11607 assign(t3
, binop(Iop_CmpEQ32
,
11609 mkU32(0x80000000)));
11612 IRExpr_ITE(mkexpr(t2
),
11613 IRExpr_ITE(mkexpr(t3
),
11614 mkU64(0x7fffffffffffffffULL
),
11618 putDSPControl(IRExpr_ITE(mkexpr(t2
),
11619 IRExpr_ITE(mkexpr(t3
),
11630 assign(t5
, binop(Iop_Sub64
,
11632 unop(Iop_64to32
, mkexpr(t0
))),
11634 unop(Iop_64to32
, mkexpr(t4
)))));
11635 assign(t6
, binop(Iop_Sub64
,
11638 unop(Iop_64HIto32
, mkexpr(t0
))
11642 binop(Iop_CmpLT32U
,
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
,
11655 unop(Iop_64to32
, mkexpr(t6
)),
11656 mkU32(0x80000000)),
11659 unop(Iop_64HIto32
, mkexpr(t6
)),
11660 mkU32(0x00000001))));
11661 assign(t9
, binop(Iop_CmpEQ32
,
11663 unop(Iop_64HIto32
, mkexpr(t6
)),
11664 mkU32(0x00000001)),
11666 putDSPControl(IRExpr_ITE(mkexpr(t8
),
11674 IRExpr_ITE(mkexpr(t8
),
11676 IRExpr_ITE(mkexpr(t9
),
11677 mkU64(0x8000000000000000ULL
),
11678 mkU64(0x7fffffffffffffffULL
)))
11682 case 0xF: { /* DPSU.H.QBR */
11683 DIP("dpsu.h.qbr ac%u r%u, r%u", ac
, rs
, rt
);
11686 t0
= newTemp(Ity_I32
);
11687 t1
= newTemp(Ity_I32
);
11688 t2
= newTemp(Ity_I64
);
11689 t3
= newTemp(Ity_I64
);
11695 unop(Iop_32to16
, getIReg(rs
)))),
11698 unop(Iop_32to16
, getIReg(rt
))))));
11703 unop(Iop_32to16
, getIReg(rs
)))),
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
));
11714 case 0x10: { /* MAQ_SA.W.PHL */
11715 DIP("maq_sa.w.phl ac%u, r%u, r%u", ac
, rs
, rt
);
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
);
11726 assign(t0
, getAcc(ac
));
11727 assign(t1
, unop(Iop_32Sto64
,
11738 /* If both input arguments are equal 0x8000, saturate
11739 intermediate product and write to DSPControl register.
11741 assign(t2
, binop(Iop_CmpEQ32
,
11743 unop(Iop_32HIto16
, getIReg(rs
))),
11744 mkU32(0x00008000)));
11745 assign(t3
, binop(Iop_CmpEQ32
,
11747 unop(Iop_32HIto16
, getIReg(rt
))),
11748 mkU32(0x00008000)));
11751 IRExpr_ITE(mkexpr(t2
),
11752 IRExpr_ITE(mkexpr(t3
),
11753 mkU64(0x000000007fffffffULL
),
11757 putDSPControl(IRExpr_ITE(mkexpr(t2
),
11758 IRExpr_ITE(mkexpr(t3
),
11768 /* Add intermediate product and value in the
11770 assign(t5
, binop(Iop_Add64
, mkexpr(t0
), mkexpr(t4
)));
11772 /* Compare bits 31 and 32 of the value in t5. */
11773 assign(t6
, binop(Iop_CmpEQ32
,
11776 unop(Iop_64to32
, mkexpr(t5
)),
11777 mkU32(0x80000000)),
11780 unop(Iop_64HIto32
, mkexpr(t5
)),
11782 putDSPControl(IRExpr_ITE(mkexpr(t6
),
11790 IRExpr_ITE(mkexpr(t6
),
11792 IRExpr_ITE(binop(Iop_CmpEQ32
,
11798 mkU64(0x000000007fffffffULL
),
11799 mkU64(0xffffffff80000000ULL
)))
11801 putAcc(ac
, mkexpr(t7
));
11804 case 0x12: { /* MAQ_SA.W.PHR */
11805 DIP("maq_sa.w.phr ac%u, r%u, r%u", ac
, rs
, rt
);
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
);
11816 assign(t0
, getAcc(ac
));
11817 assign(t1
, unop(Iop_32Sto64
,
11828 /* If both input arguments are equal 0x8000, saturate
11829 intermediate product and write to DSPControl
11831 assign(t2
, binop(Iop_CmpEQ32
,
11833 unop(Iop_32to16
, getIReg(rs
))),
11834 mkU32(0x00008000)));
11835 assign(t3
, binop(Iop_CmpEQ32
,
11837 unop(Iop_32to16
, getIReg(rt
))),
11838 mkU32(0x00008000)));
11841 IRExpr_ITE(mkexpr(t2
),
11842 IRExpr_ITE(mkexpr(t3
),
11843 mkU64(0x000000007fffffffULL
),
11847 putDSPControl(IRExpr_ITE(mkexpr(t2
),
11848 IRExpr_ITE(mkexpr(t3
),
11858 /* Add intermediate product and value in the
11860 assign(t5
, binop(Iop_Add64
, mkexpr(t0
), mkexpr(t4
)));
11862 /* Compare bits 31 and 32 of the value in t5. */
11863 assign(t6
, binop(Iop_CmpEQ32
,
11866 unop(Iop_64to32
, mkexpr(t5
)),
11867 mkU32(0x80000000)),
11870 unop(Iop_64HIto32
, mkexpr(t5
)),
11872 putDSPControl(IRExpr_ITE(mkexpr(t6
),
11880 IRExpr_ITE(mkexpr(t6
),
11882 IRExpr_ITE(binop(Iop_CmpEQ32
,
11888 mkU64(0x000000007fffffffULL
),
11889 mkU64(0xffffffff80000000ULL
)))
11891 putAcc(ac
, mkexpr(t7
));
11894 case 0x14: { /* MAQ_S.W.PHL */
11895 DIP("maq_s.w.phl ac%u, r%u, r%u", ac
, rs
, rt
);
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
);
11904 assign(t5
, getAcc(ac
));
11906 assign(t0
, unop(Iop_16Sto32
,
11907 unop(Iop_32HIto16
, getIReg(rs
))));
11908 assign(t1
, unop(Iop_16Sto32
,
11909 unop(Iop_32HIto16
, getIReg(rt
))));
11911 assign(t2
, binop(Iop_And32
,
11925 assign(t3
, binop(Iop_CmpEQ32
, mkexpr(t2
), mkU32(0x0)));
11927 putDSPControl(IRExpr_ITE(mkexpr(t3
),
11935 assign(t4
, unop(Iop_64to32
,
11937 mkexpr(t0
), mkexpr(t1
))));
11938 putAcc(ac
, IRExpr_ITE(mkexpr(t3
),
11948 mkU32(0x7fffffff)))));
11951 case 0x16: { /* MAQ_S.W.PHR */
11952 DIP("maq_s.w.phr ac%u, r%u, r%u", ac
, rs
, rt
);
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
);
11961 assign(t5
, getAcc(ac
));
11963 assign(t0
, unop(Iop_16Sto32
,
11964 unop(Iop_32to16
, getIReg(rs
))));
11965 assign(t1
, unop(Iop_16Sto32
,
11966 unop(Iop_32to16
, getIReg(rt
))));
11968 assign(t2
, binop(Iop_And32
,
11982 assign(t3
, binop(Iop_CmpEQ32
, mkexpr(t2
), mkU32(0x0)));
11984 putDSPControl(IRExpr_ITE(mkexpr(t3
),
11992 assign(t4
, unop(Iop_64to32
,
11994 mkexpr(t0
), mkexpr(t1
))));
11995 putAcc(ac
, IRExpr_ITE(mkexpr(t3
),
12005 mkU32(0x7fffffff)))));
12008 case 0x18: { /* DPAQX_S.W.PH */
12009 DIP("dpaqx_s.w.ph ac%u, r%u, r%u", ac
, rs
, rt
);
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
);
12022 assign(t0
, getAcc(ac
));
12024 assign(t1
, binop(Iop_Shl64
,
12033 assign(t2
, binop(Iop_CmpEQ32
,
12035 unop(Iop_32HIto16
, getIReg(rs
))),
12036 mkU32(0x00008000)));
12037 assign(t3
, binop(Iop_CmpEQ32
,
12039 unop(Iop_32to16
, getIReg(rt
))),
12040 mkU32(0x00008000)));
12042 IRExpr_ITE(mkexpr(t2
),
12043 IRExpr_ITE(mkexpr(t3
),
12044 mkU64(0x000000007fffffffULL
),
12048 putDSPControl(IRExpr_ITE(mkexpr(t2
),
12049 IRExpr_ITE(mkexpr(t3
),
12058 assign(t5
, binop(Iop_Shl64
,
12067 assign(t6
, binop(Iop_CmpEQ32
,
12069 unop(Iop_32to16
, getIReg(rs
))),
12070 mkU32(0x00008000)));
12071 assign(t7
, binop(Iop_CmpEQ32
,
12073 unop(Iop_32HIto16
, getIReg(rt
))),
12074 mkU32(0x00008000)));
12076 IRExpr_ITE(mkexpr(t6
),
12077 IRExpr_ITE(mkexpr(t7
),
12078 mkU64(0x000000007fffffffULL
),
12082 putDSPControl(IRExpr_ITE(mkexpr(t6
),
12083 IRExpr_ITE(mkexpr(t7
),
12094 assign(t9
, binop(Iop_Add64
,
12095 binop(Iop_Add64
, mkexpr(t4
), mkexpr(t8
)),
12097 putAcc(ac
, mkexpr(t9
));
12100 case 0x19: { /* DPSQX_S.W.PH */
12101 DIP("dpsqx_s.w.ph ac%u, r%u, r%u", ac
, rs
, rt
);
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
);
12114 assign(t0
, getAcc(ac
));
12116 assign(t1
, binop(Iop_Shl64
,
12125 assign(t2
, binop(Iop_CmpEQ32
,
12127 unop(Iop_32HIto16
, getIReg(rs
))),
12128 mkU32(0x00008000)));
12129 assign(t3
, binop(Iop_CmpEQ32
,
12131 unop(Iop_32to16
, getIReg(rt
))),
12132 mkU32(0x00008000)));
12134 IRExpr_ITE(mkexpr(t2
),
12135 IRExpr_ITE(mkexpr(t3
),
12136 mkU64(0x000000007fffffffULL
),
12140 putDSPControl(IRExpr_ITE(mkexpr(t2
),
12141 IRExpr_ITE(mkexpr(t3
),
12152 assign(t5
, binop(Iop_Shl64
,
12161 assign(t6
, binop(Iop_CmpEQ32
,
12163 unop(Iop_32to16
, getIReg(rs
))),
12164 mkU32(0x00008000)));
12165 assign(t7
, binop(Iop_CmpEQ32
,
12167 unop(Iop_32HIto16
, getIReg(rt
))),
12168 mkU32(0x00008000)));
12170 IRExpr_ITE(mkexpr(t6
),
12171 IRExpr_ITE(mkexpr(t7
),
12172 mkU64(0x000000007fffffffULL
),
12176 putDSPControl(IRExpr_ITE(mkexpr(t6
),
12177 IRExpr_ITE(mkexpr(t7
),
12188 assign(t9
, binop(Iop_Sub64
,
12190 binop(Iop_Add64
, mkexpr(t4
), mkexpr(t8
))));
12191 putAcc(ac
, mkexpr(t9
));
12194 case 0x1A: { /* DPAQX_SA.W.PH */
12195 DIP("dpaqx_sa.w.ph ac%u, r%u, r%u", ac
, rs
, rt
);
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
);
12209 assign(t0
, getAcc(ac
));
12210 /* Calculate the first cross dot product and saturate if
12212 assign(t1
, unop(Iop_32Sto64
,
12223 /* If both input arguments are equal 0x8000, saturate
12224 intermediate product and write to DSPControl
12226 assign(t2
, binop(Iop_CmpEQ32
,
12228 unop(Iop_32HIto16
, getIReg(rs
))),
12229 mkU32(0x00008000)));
12230 assign(t3
, binop(Iop_CmpEQ32
,
12232 unop(Iop_32to16
, getIReg(rt
))),
12233 mkU32(0x00008000)));
12235 assign(t4
, IRExpr_ITE(binop(Iop_CmpNE32
,
12242 mkU64(0x000000007fffffffULL
),
12245 putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32
,
12258 /* Calculate second cross dot product and saturate if
12260 assign(t5
, unop(Iop_32Sto64
,
12271 /* If both input arguments are equal 0x8000, saturate
12272 intermediate product and write to DSPControl
12274 assign(t6
, binop(Iop_CmpEQ32
,
12276 unop(Iop_32to16
, getIReg(rs
))),
12277 mkU32(0x00008000)));
12278 assign(t7
, binop(Iop_CmpEQ32
,
12280 unop(Iop_32HIto16
, getIReg(rt
))),
12281 mkU32(0x00008000)));
12283 assign(t8
, IRExpr_ITE(binop(Iop_CmpNE32
,
12290 mkU64(0x000000007fffffffULL
),
12293 putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32
,
12306 /* Subtract intermediate products from value in the
12311 binop(Iop_Add64
, mkexpr(t8
), mkexpr(t4
))));
12314 IRExpr_ITE(binop(Iop_CmpEQ32
,
12318 mkU32(0x80000000)),
12320 IRExpr_ITE(binop(Iop_CmpNE32
,
12326 mkU64(0x000000007fffffffULL
),
12328 IRExpr_ITE(binop(Iop_CmpNE32
,
12333 mkU32(0xffffffff)),
12334 mkU64(0xffffffff80000000ULL
),
12336 assign(t10
, IRExpr_ITE(binop(Iop_CmpEQ32
,
12347 putDSPControl(IRExpr_ITE(binop(Iop_CmpEQ32
,
12360 case 0x1B: { /* DPSQX_SA.W.PH */
12361 DIP("dpsqx_sa.w.ph ac%u, r%u, r%u", ac
, rs
, rt
);
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
);
12375 assign(t0
, getAcc(ac
));
12376 /* Calculate the first cross dot product and saturate if
12378 assign(t1
, unop(Iop_32Sto64
,
12389 /* If both input arguments are equal 0x8000, saturate
12390 intermediate product and write to DSPControl
12392 assign(t2
, binop(Iop_CmpEQ32
,
12394 unop(Iop_32HIto16
, getIReg(rs
))),
12395 mkU32(0x00008000)));
12396 assign(t3
, binop(Iop_CmpEQ32
,
12398 unop(Iop_32to16
, getIReg(rt
))),
12399 mkU32(0x00008000)));
12401 assign(t4
, IRExpr_ITE(binop(Iop_CmpNE32
,
12408 mkU64(0x000000007fffffffULL
),
12411 putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32
,
12424 /* Calculate second cross dot product and saturate if
12426 assign(t5
, unop(Iop_32Sto64
,
12437 /* If both input arguments are equal 0x8000, saturate
12438 intermediate product and write to DSPControl
12440 assign(t6
, binop(Iop_CmpEQ32
,
12442 unop(Iop_32to16
, getIReg(rs
))),
12443 mkU32(0x00008000)));
12444 assign(t7
, binop(Iop_CmpEQ32
,
12446 unop(Iop_32HIto16
, getIReg(rt
))),
12447 mkU32(0x00008000)));
12449 assign(t8
, IRExpr_ITE(binop(Iop_CmpNE32
,
12456 mkU64(0x000000007fffffffULL
),
12459 putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32
,
12472 /* Subtract intermediate products from value in the
12477 binop(Iop_Add64
, mkexpr(t8
), mkexpr(t4
))));
12480 IRExpr_ITE(binop(Iop_CmpEQ32
,
12484 mkU32(0x80000000)),
12486 IRExpr_ITE(binop(Iop_CmpNE32
,
12492 mkU64(0x000000007fffffffULL
),
12494 IRExpr_ITE(binop(Iop_CmpNE32
,
12499 mkU32(0xffffffff)),
12500 mkU64(0xffffffff80000000ULL
),
12502 assign(t10
, IRExpr_ITE(binop(Iop_CmpEQ32
,
12513 putDSPControl(IRExpr_ITE(binop(Iop_CmpEQ32
,
12529 break; /* end of DPAQ.W.PH */
12531 case 0x31: { /* APPEND */
12533 case 0x0: { /* APPEND */
12534 DIP("append r%u, r%u, %u", rt
, rs
, rd
);
12536 t1
= newTemp(Ity_I32
);
12537 t2
= newTemp(Ity_I32
);
12538 t3
= newTemp(Ity_I32
);
12540 assign(t1
, binop(Iop_Shl32
, getIReg(rt
), mkU8(rd
)));
12543 putIReg(rt
, binop(Iop_Or32
,
12547 mkU32(0x7fffffff))));
12548 } else if (1 == rd
) {
12553 getIReg(rs
), mkU32(0x1))));
12558 mkU32(0xffffffff), mkU8(rd
))));
12560 putIReg(rt
, binop(Iop_Or32
,
12563 getIReg(rs
), mkexpr(t2
))));
12567 case 0x1: { /* PREPEND */
12568 DIP("prepend r%u, r%u, %u", rt
, rs
, rd
);
12570 t1
= newTemp(Ity_I32
);
12571 t2
= newTemp(Ity_I32
);
12572 t3
= newTemp(Ity_I32
);
12575 assign(t1
, binop(Iop_Shr32
, getIReg(rt
), mkU8(rd
)));
12578 putIReg(rt
, binop(Iop_Or32
,
12583 mkU32(0x7fffffff)),
12585 } else if (1 == rd
) {
12586 putIReg(rt
, binop(Iop_Or32
,
12594 assign(t2
, binop(Iop_Add32
, mkU32(rd
), mkU32(0x1)));
12596 assign(t3
, unop(Iop_Not32
,
12599 unop(Iop_32to8
, mkexpr(t2
)))));
12601 putIReg(rt
, binop(Iop_Or32
,
12612 case 0x10: { /* BALIGN */
12613 DIP("balign r%u, r%u, %u", rt
, rs
, rd
);
12615 t1
= newTemp(Ity_I32
);
12616 t2
= newTemp(Ity_I32
);
12617 t3
= newTemp(Ity_I32
);
12619 if ((2 != rd
) && (0 != rd
)) {
12620 assign(t1
, binop(Iop_Shl32
,
12622 mkU32(rd
), mkU32(0x3)),
12624 assign(t2
, binop(Iop_Shl32
,
12626 unop(Iop_32to8
, mkexpr(t1
))));
12627 assign(t3
, binop(Iop_Shr32
,
12637 putIReg(rt
, binop(Iop_Or32
, mkexpr(t2
), mkexpr(t3
)));
12644 break; /* end of APPEND */
12657 static Int
msa_I8_logical(UInt cins
, UChar wd
, UChar ws
) {
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
);
12670 tmp
|= (tmp
<< 56) | (tmp
<< 48) | (tmp
<< 40) |
12671 (tmp
<< 32) | (tmp
<< 24) | (tmp
<< 16) |
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
)));
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
);
12684 tmp
|= (tmp
<< 56) | (tmp
<< 48) | (tmp
<< 40) |
12685 (tmp
<< 32) | (tmp
<< 24) | (tmp
<< 16) |
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
)));
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
);
12698 tmp
|= (tmp
<< 56) | (tmp
<< 48) | (tmp
<< 40) |
12699 (tmp
<< 32) | (tmp
<< 24) | (tmp
<< 16) |
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
))));
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
);
12713 tmp
|= (tmp
<< 56) | (tmp
<< 48) | (tmp
<< 40) |
12714 (tmp
<< 32) | (tmp
<< 24) | (tmp
<< 16) |
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
)));
12729 static Int
msa_I8_branch(UInt cins
, UChar wd
, UChar ws
) {
12730 IRTemp t1
, t2
, t3
, t4
;
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
);
12744 tmp
|= (tmp
<< 56) | (tmp
<< 48) | (tmp
<< 40) |
12745 (tmp
<< 32) | (tmp
<< 24) | (tmp
<< 16) |
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
));
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
);
12763 tmp
|= (tmp
<< 56) | (tmp
<< 48) | (tmp
<< 40) |
12764 (tmp
<< 32) | (tmp
<< 24) | (tmp
<< 16) |
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
));
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
);
12782 tmp
|= (tmp
<< 56) | (tmp
<< 48) | (tmp
<< 40) |
12783 (tmp
<< 32) | (tmp
<< 24) | (tmp
<< 16) |
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
));
12801 static Int
msa_I8_shift(UInt cins
, UChar wd
, UChar ws
) {
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
));
12818 for (i
= 0; i
< 16; i
++) {
12819 tmp
[i
] = newTemp(Ity_I8
);
12821 binop(Iop_GetElem8x16
, mkexpr(t2
),
12823 ((i8
>> (i
% 4) * 2) & 0x03))));
12826 putWReg(wd
, binop(Iop_64HLtoV128
,
12827 binop(Iop_32HLto64
,
12828 binop(Iop_16HLto32
,
12835 binop(Iop_16HLto32
,
12842 binop(Iop_32HLto64
,
12843 binop(Iop_16HLto32
,
12850 binop(Iop_16HLto32
,
12856 mkexpr(tmp
[0]))))));
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
));
12869 for (i
= 0; i
< 8; i
++) {
12870 tmp
[i
] = newTemp(Ity_I16
);
12872 binop(Iop_GetElem16x8
, mkexpr(t2
),
12874 ((i8
>> (i
% 4) * 2) & 0x03))));
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])))));
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
));
12900 for (i
= 0; i
< 4; i
++) {
12901 tmp
[i
] = newTemp(Ity_I32
);
12903 binop(Iop_GetElem32x4
, mkexpr(t2
),
12905 ((i8
>> (i
% 4) * 2) & 0x03))));
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]))));
12923 static Int
msa_I5_06(UInt cins
, UChar wd
, UChar ws
) { /* I5 (0x06) */
12928 operation
= (cins
& 0x03800000) >> 23;
12929 df
= (cins
& 0x00600000) >> 21;
12930 wt
= (cins
& 0x001F0000) >> 16;
12932 switch (operation
) {
12933 case 0x00: { /* ADDVI */
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) |
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
));
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
));
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
));
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
));
12994 case 0x01: { /* SUBVI */
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) |
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
));
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
));
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
));
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
));
13055 case 0x02: { /* MAXI_S */
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) |
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
));
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
));
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;
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
));
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;
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
));
13124 case 0x03: { /* MAXI_U */
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) |
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
));
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
));
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
));
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
));
13185 case 0x04: { /* MINI_S */
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) |
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
));
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
));
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;
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
));
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;
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
));
13254 case 0x05: { /* MINI_U */
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) |
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
));
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
));
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
));
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
));
13323 static Int
msa_I5_07(UInt cins
, UChar wd
, UChar ws
) { /* I5 (0x07) / I10 */
13328 operation
= (cins
& 0x03800000) >> 23;
13329 df
= (cins
& 0x00600000) >> 21;
13330 i5
= (cins
& 0x001F0000) >> 16;
13332 switch (operation
) {
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) |
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
));
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
));
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;
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
));
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;
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
));
13402 case 0x02: { /* CLTI_S.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) |
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
));
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
));
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;
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
));
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;
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
));
13474 case 0x03: { /* CLTI_U.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) |
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
));
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
));
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
));
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
));
13535 case 0x04: { /* CLEI_S.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) |
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
));
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
));
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;
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
));
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;
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
));
13621 case 0x05: { /* CLEI_U.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) |
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
));
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
));
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
));
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
));
13698 case 0x06: { /* LDI.df */
13701 s10
= (cins
& 0x001FF800) >> 11;
13703 case 0x00: /* LDI.B */
13704 DIP("LDI.B w%d, %d", wd
, s10
);
13706 tmp
= tmp
| (tmp
<< 8) | (tmp
<< 16) | (tmp
<< 24)
13707 | (tmp
<< 32) | (tmp
<< 40) | (tmp
<< 48) |
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);
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);
13723 case 0x03: /* LDI.D */
13724 DIP("LDI.D w%d, %d", wd
, s10
);
13725 tmp
= extend_s_10to64(s10
);
13732 putWReg(wd
, binop(Iop_64HLtoV128
, mkU64(tmp
), mkU64(tmp
)));
13743 static Int
msa_BIT_09(UInt cins
, UChar wd
, UChar ws
) { /* BIT (0x09) */
13748 operation
= (cins
& 0x03800000) >> 23;
13749 df
= (cins
& 0x007F0000) >> 16;
13751 if ((df
& 0x70) == 0x70) { // 111mmmm; b
13754 } else if ((df
& 0x60) == 0x60) { // 110mmmm; h
13757 } else if ((df
& 0x40) == 0x40) { // 10mmmmm; w
13760 } else if ((df
& 0x00) == 0x00) { // 0mmmmmm; d
13765 switch (operation
) {
13766 case 0x00: { /* SLLI.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
)));
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
)));
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
)));
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
)));
13796 case 0x01: { /* SRAI.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
)));
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
)));
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
)));
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
)));
13826 case 0x02: { /* SRLI.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
)));
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
)));
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
)));
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
)));
13856 case 0x03: { /* BCLRI.df */
13857 t1
= newTemp(Ity_V128
);
13858 t2
= newTemp(Ity_V128
);
13859 t3
= newTemp(Ity_V128
);
13861 assign(t1
, getWReg(ws
));
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) |
13869 assign(t2
, binop(Iop_ShlN8x16
,
13870 binop(Iop_64HLtoV128
,
13871 mkU64(tmp
), mkU64(tmp
)),mkU8(m
)));
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
)));
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
)));
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
)));
13902 assign(t3
, binop(Iop_AndV128
,
13903 mkexpr(t1
), unop(Iop_NotV128
, mkexpr(t2
))));
13904 putWReg(wd
, mkexpr(t3
));
13908 case 0x04: { /* BSETI */
13909 t1
= newTemp(Ity_V128
);
13910 t2
= newTemp(Ity_V128
);
13911 t3
= newTemp(Ity_V128
);
13913 assign(t1
, getWReg(ws
));
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) |
13921 assign(t2
, binop(Iop_ShlN8x16
,
13922 binop(Iop_64HLtoV128
,
13923 mkU64(tmp
), mkU64(tmp
)), mkU8(m
)));
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
)));
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
)));
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
)));
13954 assign(t3
, binop(Iop_OrV128
, mkexpr(t1
), mkexpr(t2
)));
13955 putWReg(wd
, mkexpr(t3
));
13959 case 0x05: { /* BNEGI.df */
13960 t1
= newTemp(Ity_V128
);
13961 t2
= newTemp(Ity_V128
);
13962 t3
= newTemp(Ity_V128
);
13964 assign(t1
, getWReg(ws
));
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) |
13972 assign(t2
, binop(Iop_ShlN8x16
,
13973 binop(Iop_64HLtoV128
,
13974 mkU64(tmp
), mkU64(tmp
)), mkU8(m
)));
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
)));
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
)));
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
)));
14005 assign(t3
, binop(Iop_XorV128
, mkexpr(t1
), mkexpr(t2
)));
14006 putWReg(wd
, mkexpr(t3
));
14010 case 0x06: { /* BINSLI.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
)));
14023 unop(Iop_NotV128
, mkexpr(t1
)), getWReg(wd
)));
14026 mkexpr(t1
), getWReg(ws
)));
14029 mkexpr(t2
), mkexpr(t3
)));
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
;
14040 binop(Iop_SarN16x8
,
14041 binop(Iop_64HLtoV128
,
14042 mkU64(tmp
), mkU64(tmp
)), mkU8(m
)));
14045 unop(Iop_NotV128
, mkexpr(t1
)), getWReg(wd
)));
14048 mkexpr(t1
), getWReg(ws
)));
14051 mkexpr(t2
), mkexpr(t3
)));
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
;
14062 binop(Iop_SarN32x4
,
14063 binop(Iop_64HLtoV128
,
14064 mkU64(tmp
), mkU64(tmp
)), mkU8(m
)));
14067 unop(Iop_NotV128
, mkexpr(t1
)), getWReg(wd
)));
14070 mkexpr(t1
), getWReg(ws
)));
14073 mkexpr(t2
), mkexpr(t3
)));
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
;
14084 binop(Iop_SarN64x2
,
14085 binop(Iop_64HLtoV128
,
14086 mkU64(tmp
), mkU64(tmp
)), mkU8(m
)));
14089 unop(Iop_NotV128
, mkexpr(t1
)), getWReg(wd
)));
14092 mkexpr(t1
), getWReg(ws
)));
14095 mkexpr(t2
), mkexpr(t3
)));
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
;
14115 binop(Iop_ShlN8x16
,
14116 binop(Iop_64HLtoV128
,
14117 mkU64(tmp
), mkU64(tmp
)), mkU8(m
)));
14120 unop(Iop_NotV128
, mkexpr(t1
)), getWReg(ws
)));
14123 mkexpr(t1
), getWReg(wd
)));
14126 mkexpr(t2
), mkexpr(t3
)));
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
;
14137 binop(Iop_ShlN16x8
,
14138 binop(Iop_64HLtoV128
,
14139 mkU64(tmp
), mkU64(tmp
)),
14143 unop(Iop_NotV128
, mkexpr(t1
)),
14147 mkexpr(t1
), getWReg(wd
)));
14150 mkexpr(t2
), mkexpr(t3
)));
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
;
14161 binop(Iop_ShlN32x4
,
14162 binop(Iop_64HLtoV128
,
14163 mkU64(tmp
), mkU64(tmp
)),
14167 unop(Iop_NotV128
, mkexpr(t1
)),
14171 mkexpr(t1
), getWReg(wd
)));
14174 mkexpr(t2
), mkexpr(t3
)));
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
);
14185 binop(Iop_ShlN64x2
,
14186 binop(Iop_64HLtoV128
,
14187 mkU64(tmp
), mkU64(tmp
)),
14191 unop(Iop_NotV128
, mkexpr(t1
)),
14195 mkexpr(t1
), getWReg(wd
)));
14198 mkexpr(t2
), mkexpr(t3
)));
14216 static Int
msa_BIT_0A(UInt cins
, UChar wd
, UChar ws
) { /* BIT (0x0A) */
14221 operation
= (cins
& 0x03800000) >> 23;
14222 df
= (cins
& 0x007F0000) >> 16;
14224 if ((df
& 0x70) == 0x70) { // 111mmmm; b
14227 } else if ((df
& 0x60) == 0x60) { // 110mmmm; h
14230 } else if ((df
& 0x40) == 0x40) { // 10mmmmm; w
14233 } else if ((df
& 0x00) == 0x00) { // 0mmmmmm; d
14238 switch (operation
) {
14239 case 0x00: { /* SAT_S.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)));
14247 putWReg(wd
, mkexpr(t1
));
14249 t2
= newTemp(Ity_V128
);
14251 binop(Iop_SarN8x16
, getWReg(ws
), mkU8(m
)));
14256 binop(Iop_CmpEQ8x16
,
14260 binop(Iop_ShlN8x16
,
14261 binop(Iop_CmpGT8Sx16
,
14265 binop(Iop_ShrN8x16
,
14266 binop(Iop_CmpGT8Sx16
,
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)));
14281 putWReg(wd
, mkexpr(t1
));
14283 t2
= newTemp(Ity_V128
);
14285 binop(Iop_SarN16x8
,
14292 binop(Iop_CmpEQ16x8
,
14296 binop(Iop_ShlN16x8
,
14297 binop(Iop_CmpGT16Sx8
,
14301 binop(Iop_ShrN16x8
,
14302 binop(Iop_CmpGT16Sx8
,
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)));
14317 putWReg(wd
, mkexpr(t1
));
14319 t2
= newTemp(Ity_V128
);
14321 binop(Iop_SarN32x4
,
14328 binop(Iop_CmpEQ32x4
,
14332 binop(Iop_ShlN32x4
,
14333 binop(Iop_CmpGT32Sx4
,
14337 binop(Iop_ShrN32x4
,
14338 binop(Iop_CmpGT32Sx4
,
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)));
14353 putWReg(wd
, mkexpr(t1
));
14355 t2
= newTemp(Ity_V128
);
14357 binop(Iop_SarN64x2
,
14364 binop(Iop_CmpEQ64x2
,
14368 binop(Iop_ShlN64x2
,
14369 binop(Iop_CmpGT64Sx2
,
14373 binop(Iop_ShrN64x2
,
14374 binop(Iop_CmpGT64Sx2
,
14387 case 0x01: { /* SAT_U.df */
14389 case 0x00: { /* SAT_U.B */
14390 DIP("SAT_U.B w%d, w%d, %d", wd
, ws
, m
);
14393 putWReg(wd
, getWReg(ws
));
14395 t1
= newTemp(Ity_V128
);
14397 binop(Iop_CmpEQ8x16
,
14398 binop(Iop_ShrN8x16
,
14401 binop(Iop_64HLtoV128
,
14402 mkU64(0), mkU64(0))));
14408 binop(Iop_ShrN8x16
,
14417 case 0x01: { /* SAT_U.H */
14418 DIP("SAT_U.H w%d, w%d, %d", wd
, ws
, m
);
14421 putWReg(wd
, getWReg(ws
));
14423 t1
= newTemp(Ity_V128
);
14425 binop(Iop_CmpEQ16x8
,
14426 binop(Iop_ShrN16x8
,
14429 binop(Iop_64HLtoV128
,
14430 mkU64(0), mkU64(0))));
14436 binop(Iop_ShrN16x8
,
14445 case 0x02: { /* SAT_U.W */
14446 DIP("SAT_U.W w%d, w%d, %d", wd
, ws
, m
);
14449 putWReg(wd
, getWReg(ws
));
14451 t1
= newTemp(Ity_V128
);
14453 binop(Iop_CmpEQ32x4
,
14454 binop(Iop_ShrN32x4
,
14457 binop(Iop_64HLtoV128
,
14458 mkU64(0), mkU64(0))));
14464 binop(Iop_ShrN32x4
,
14473 case 0x03: { /* SAT_U.D */
14474 DIP("SAT_U.D w%d, w%d, %d", wd
, ws
, m
);
14477 putWReg(wd
, getWReg(ws
));
14479 t1
= newTemp(Ity_V128
);
14481 binop(Iop_CmpEQ64x2
,
14482 binop(Iop_ShrN64x2
,
14485 binop(Iop_64HLtoV128
,
14486 mkU64(0), mkU64(0))));
14492 binop(Iop_ShrN64x2
,
14505 case 0x02: { /* SRARI.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
);
14512 binop(Iop_SarN8x16
,
14516 binop(Iop_ShrN8x16
,
14517 binop(Iop_ShlN8x16
,
14522 if (m
) putWReg(wd
, binop(Iop_Add8x16
,
14525 else putWReg(wd
, mkexpr(t1
));
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
);
14535 binop(Iop_SarN16x8
,
14539 binop(Iop_ShrN16x8
,
14540 binop(Iop_ShlN16x8
,
14548 mkexpr(t1
), mkexpr(t2
)));
14549 else putWReg(wd
, mkexpr(t1
));
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
);
14559 binop(Iop_SarN32x4
,
14563 binop(Iop_ShrN32x4
,
14564 binop(Iop_ShlN32x4
,
14572 mkexpr(t1
), mkexpr(t2
)));
14573 else putWReg(wd
, mkexpr(t1
));
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
);
14583 binop(Iop_SarN64x2
,
14587 binop(Iop_ShrN64x2
,
14588 binop(Iop_ShlN64x2
,
14596 mkexpr(t1
), mkexpr(t2
)));
14597 else putWReg(wd
, mkexpr(t1
));
14606 case 0x03: { /* SRLRI.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
);
14613 binop(Iop_ShrN8x16
,
14617 binop(Iop_ShrN8x16
,
14618 binop(Iop_ShlN8x16
,
14626 mkexpr(t1
), mkexpr(t2
)));
14627 else putWReg(wd
, mkexpr(t1
));
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
);
14637 binop(Iop_ShrN16x8
,
14641 binop(Iop_ShrN16x8
,
14642 binop(Iop_ShlN16x8
,
14650 mkexpr(t1
), mkexpr(t2
)));
14651 else putWReg(wd
, mkexpr(t1
));
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
);
14661 binop(Iop_ShrN32x4
,
14665 binop(Iop_ShrN32x4
,
14666 binop(Iop_ShlN32x4
,
14674 mkexpr(t1
), mkexpr(t2
)));
14675 else putWReg(wd
, mkexpr(t1
));
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
);
14685 binop(Iop_ShrN64x2
,
14689 binop(Iop_ShrN64x2
,
14690 binop(Iop_ShlN64x2
,
14698 mkexpr(t1
), mkexpr(t2
)));
14699 else putWReg(wd
, mkexpr(t1
));
14715 static Int
msa_3R_0D(UInt cins
, UChar wd
, UChar ws
) { /* 3R (0x0D) */
14720 operation
= (cins
& 0x03800000) >> 23;
14721 df
= (cins
& 0x00600000) >> 21;
14722 wt
= (cins
& 0x001F0000) >> 16;
14724 switch (operation
) {
14725 case 0x00: { /* SLL.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
));
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
));
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
));
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
));
14782 case 0x01: { /* SRA.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
));
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
));
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
));
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
));
14839 case 0x02: { /* SRL.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
));
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
));
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
));
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
));
14896 case 0x03: { /* BCLR.df */
14897 t1
= newTemp(Ity_V128
);
14898 t2
= newTemp(Ity_V128
);
14899 t3
= newTemp(Ity_V128
);
14901 assign(t1
, getWReg(ws
));
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) |
14909 assign(t2
, binop(Iop_Shl8x16
,
14910 binop(Iop_64HLtoV128
,
14911 mkU64(tmp
), mkU64(tmp
)),
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);
14921 binop(Iop_64HLtoV128
,
14922 mkU64(tmp
), mkU64(tmp
)),
14927 case 0x02: { /* BCLR.W */
14928 DIP("BCLR.W w%d, w%d, w%d", wd
, ws
, wt
);
14929 tmp
|= (tmp
<< 32);
14932 binop(Iop_64HLtoV128
,
14933 mkU64(tmp
), mkU64(tmp
)),
14938 case 0x03: { /* BCLR.D */
14939 DIP("BCLR.D w%d, w%d, w%d", wd
, ws
, wt
);
14942 binop(Iop_64HLtoV128
,
14943 mkU64(tmp
), mkU64(tmp
)),
14951 mkexpr(t1
), unop(Iop_NotV128
, mkexpr(t2
))));
14952 putWReg(wd
, mkexpr(t3
));
14956 case 0x04: { /* BSET.df */
14957 t1
= newTemp(Ity_V128
);
14958 t2
= newTemp(Ity_V128
);
14959 t3
= newTemp(Ity_V128
);
14961 assign(t1
, getWReg(ws
));
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) |
14971 binop(Iop_64HLtoV128
,
14972 mkU64(tmp
), mkU64(tmp
)),
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);
14982 binop(Iop_64HLtoV128
,
14983 mkU64(tmp
), mkU64(tmp
)),
14988 case 0x02: { /* BSET.W */
14989 DIP("BSET.W w%d, w%d, w%d", wd
, ws
, wt
);
14990 tmp
|= (tmp
<< 32);
14993 binop(Iop_64HLtoV128
,
14994 mkU64(tmp
), mkU64(tmp
)),
14999 case 0x03: { /* BSET.D */
15000 DIP("BSET.D w%d, w%d, w%d", wd
, ws
, wt
);
15003 binop(Iop_64HLtoV128
,
15004 mkU64(tmp
), mkU64(tmp
)),
15010 assign(t3
, binop(Iop_OrV128
, mkexpr(t1
), mkexpr(t2
)));
15011 putWReg(wd
, mkexpr(t3
));
15015 case 0x05: { /* BNEG.df */
15016 t1
= newTemp(Ity_V128
);
15017 t2
= newTemp(Ity_V128
);
15018 t3
= newTemp(Ity_V128
);
15020 assign(t1
, getWReg(ws
));
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) |
15030 binop(Iop_64HLtoV128
,
15031 mkU64(tmp
), mkU64(tmp
)),
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);
15041 binop(Iop_64HLtoV128
,
15042 mkU64(tmp
), mkU64(tmp
)),
15047 case 0x02: { /* BNEG.W */
15048 DIP("BNEG.W w%d, w%d, w%d", wd
, ws
, wt
);
15049 tmp
|= (tmp
<< 32);
15052 binop(Iop_64HLtoV128
,
15053 mkU64(tmp
), mkU64(tmp
)),
15058 case 0x03: { /* BNEG.D */
15059 DIP("BNEG.D w%d, w%d, w%d", wd
, ws
, wt
);
15062 binop(Iop_64HLtoV128
,
15063 mkU64(tmp
), mkU64(tmp
)),
15069 assign(t3
, binop(Iop_XorV128
, mkexpr(t1
), mkexpr(t2
)));
15070 putWReg(wd
, mkexpr(t3
));
15074 case 0x06: { /* BINSL.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
;
15084 binop(Iop_64HLtoV128
,
15085 mkU64(tmp
), mkU64(tmp
)),
15089 unop(Iop_NotV128
, mkexpr(t1
)),
15093 mkexpr(t1
), getWReg(ws
)));
15096 mkexpr(t2
), mkexpr(t3
)));
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
;
15108 binop(Iop_64HLtoV128
,
15109 mkU64(tmp
), mkU64(tmp
)),
15113 unop(Iop_NotV128
, mkexpr(t1
)),
15117 mkexpr(t1
), getWReg(ws
)));
15120 mkexpr(t2
), mkexpr(t3
)));
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
;
15132 binop(Iop_64HLtoV128
,
15133 mkU64(tmp
), mkU64(tmp
)),
15137 unop(Iop_NotV128
, mkexpr(t1
)),
15141 mkexpr(t1
), getWReg(ws
)));
15144 mkexpr(t2
), mkexpr(t3
)));
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
;
15156 binop(Iop_64HLtoV128
,
15157 mkU64(tmp
), mkU64(tmp
)),
15161 unop(Iop_NotV128
, mkexpr(t1
)),
15165 mkexpr(t1
), getWReg(ws
)));
15168 mkexpr(t2
), mkexpr(t3
)));
15179 case 0x07: { /* BINSR.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
;
15189 binop(Iop_64HLtoV128
,
15190 mkU64(tmp
), mkU64(tmp
)),
15194 unop(Iop_NotV128
, mkexpr(t1
)),
15198 mkexpr(t1
), getWReg(wd
)));
15201 mkexpr(t2
), mkexpr(t3
)));
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
;
15213 binop(Iop_64HLtoV128
,
15214 mkU64(tmp
), mkU64(tmp
)),
15218 unop(Iop_NotV128
, mkexpr(t1
)),
15222 mkexpr(t1
), getWReg(wd
)));
15225 mkexpr(t2
), mkexpr(t3
)));
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
;
15237 binop(Iop_64HLtoV128
,
15238 mkU64(tmp
), mkU64(tmp
)),
15242 unop(Iop_NotV128
, mkexpr(t1
)),
15246 mkexpr(t1
), getWReg(wd
)));
15249 mkexpr(t2
), mkexpr(t3
)));
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
);
15261 binop(Iop_64HLtoV128
,
15262 mkU64(tmp
), mkU64(tmp
)),
15266 unop(Iop_NotV128
, mkexpr(t1
)),
15270 mkexpr(t1
), getWReg(wd
)));
15273 mkexpr(t2
), mkexpr(t3
)));
15291 static Int
msa_3R_0E(UInt cins
, UChar wd
, UChar ws
) { /* 3R (0x0E) */
15292 IRTemp t1
, t2
, t3
, t4
;
15296 operation
= (cins
& 0x03800000) >> 23;
15297 df
= (cins
& 0x00600000) >> 21;
15298 wt
= (cins
& 0x001F0000) >> 16;
15300 switch (operation
) {
15301 case 0x00: { /* ADDV.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
));
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
));
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
));
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
));
15358 case 0x01: { /* SUBV.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
));
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
));
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
));
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
));
15415 case 0x02: { /* MAX_S.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
));
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
));
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
));
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
));
15472 case 0x03: { /* MAX_U.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
));
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
));
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
));
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
));
15529 case 0x04: { /* MIN_S.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
));
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
));
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
));
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
));
15586 case 0x05: { /* MIN_U.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
));
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
));
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
));
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
));
15643 case 0x06: { /* MAX_A.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
,
15659 unop(Iop_NotV128
, mkexpr(t4
)),
15661 putWReg(wd
, mkexpr(t3
));
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
,
15679 unop(Iop_NotV128
, mkexpr(t4
)),
15681 putWReg(wd
, mkexpr(t3
));
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
,
15699 unop(Iop_NotV128
, mkexpr(t4
)),
15701 putWReg(wd
, mkexpr(t3
));
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
,
15719 unop(Iop_NotV128
, mkexpr(t4
)),
15721 putWReg(wd
, mkexpr(t3
));
15732 case 0x07: { /* MIN_A.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
,
15752 unop(Iop_NotV128
, mkexpr(t4
)),
15754 putWReg(wd
, mkexpr(t3
));
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
,
15776 unop(Iop_NotV128
, mkexpr(t4
)),
15778 putWReg(wd
, mkexpr(t3
));
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
,
15800 unop(Iop_NotV128
, mkexpr(t4
)),
15802 putWReg(wd
, mkexpr(t3
));
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
,
15824 unop(Iop_NotV128
, mkexpr(t4
)),
15826 putWReg(wd
, mkexpr(t3
));
15844 static Int
msa_3R_0F(UInt cins
, UChar wd
, UChar ws
) { /* 3R (0x0F) */
15849 operation
= (cins
& 0x03800000) >> 23;
15850 df
= (cins
& 0x00600000) >> 21;
15851 wt
= (cins
& 0x001F0000) >> 16;
15853 switch (operation
) {
15854 case 0x00: { /* CEQ.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
));
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
));
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
));
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
));
15911 case 0x02: { /* CLT_S.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
));
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
));
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
));
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
));
15968 case 0x03: { /* CLT_U.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
));
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
));
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
));
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
));
16025 case 0x04: { /* CLE_S.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
));
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
));
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
));
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
));
16098 case 0x05: { /* CLE_U.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
));
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
));
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
));
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
));
16157 binop(Iop_CmpGT64Ux2
,
16158 mkexpr(t2
), mkexpr(t1
)),
16159 binop(Iop_CmpEQ64x2
,
16160 mkexpr(t1
), mkexpr(t2
))));
16161 putWReg(wd
, mkexpr(t3
));
16179 static Int
msa_3R_10(UInt cins
, UChar wd
, UChar ws
) { /* 3R (0x10) */
16180 IRTemp t1
, t2
, t3
, t4
;
16184 operation
= (cins
& 0x03800000) >> 23;
16185 df
= (cins
& 0x00600000) >> 21;
16186 wt
= (cins
& 0x001F0000) >> 16;
16188 switch (operation
) {
16189 case 0x00: { /* ADD_A.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
));
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
));
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
));
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
));
16246 case 0x01: { /* ADDS_A.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
,
16261 assign(t4
, binop(Iop_SarN8x16
,
16266 putWReg(wd
, binop(Iop_QAdd8Sx16
,
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
,
16301 assign(t4
, binop(Iop_SarN16x8
,
16306 putWReg(wd
, binop(Iop_QAdd16Sx8
,
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
,
16341 assign(t4
, binop(Iop_SarN32x4
,
16346 putWReg(wd
, binop(Iop_QAdd32Sx4
,
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
,
16381 assign(t4
, binop(Iop_SarN64x2
,
16387 binop(Iop_QAdd64Sx2
,
16416 case 0x02: { /* ADDS_S.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
));
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
));
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
));
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
));
16473 case 0x03: { /* ADDS_U.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
));
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
));
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
));
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
));
16530 case 0x04: { /* AVE_S.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
,
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
,
16552 putWReg(wd
, mkexpr(t3
));
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
));
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
,
16577 putWReg(wd
, mkexpr(t3
));
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
,
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
,
16601 putWReg(wd
, mkexpr(t3
));
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
,
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
,
16625 putWReg(wd
, mkexpr(t3
));
16636 case 0x05: { /* AVE_U.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
,
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
,
16658 putWReg(wd
, mkexpr(t3
));
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
,
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
,
16682 putWReg(wd
, mkexpr(t3
));
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
,
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
,
16706 putWReg(wd
, mkexpr(t3
));
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
,
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
,
16730 putWReg(wd
, mkexpr(t3
));
16741 case 0x06: { /* AVER_S.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
));
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
));
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
));
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
,
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
,
16799 putWReg(wd
, mkexpr(t3
));
16810 case 0x07: { /* AVER_U.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
));
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
));
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
));
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
,
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
,
16868 putWReg(wd
, mkexpr(t3
));
16886 static Int
msa_3R_11(UInt cins
, UChar wd
, UChar ws
) { /* 3R (0x11) */
16891 operation
= (cins
& 0x03800000) >> 23;
16892 df
= (cins
& 0x00600000) >> 21;
16893 wt
= (cins
& 0x001F0000) >> 16;
16895 switch (operation
) {
16896 case 0x00: { /* SUBS_S.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
));
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
));
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
));
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
));
16953 case 0x01: { /* SUBS_U.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
));
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
));
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
));
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
));
17010 case 0x02: { /* SUBSUS_U.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
,
17023 binop(Iop_CmpEQ8x16
,
17029 mkexpr(t3
), mkexpr(t2
)),
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)));
17047 binop(Iop_CmpGT16Ux8
,
17050 binop(Iop_CmpEQ16x8
,
17056 mkexpr(t3
), mkexpr(t2
)),
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)));
17074 binop(Iop_CmpGT32Ux4
,
17077 binop(Iop_CmpEQ32x4
,
17083 mkexpr(t3
), mkexpr(t2
)),
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)));
17101 binop(Iop_CmpGT64Ux2
,
17104 binop(Iop_CmpEQ64x2
,
17110 mkexpr(t3
), mkexpr(t2
)),
17126 case 0x03: { /* SUBSUU_S.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
)));
17135 binop(Iop_SarN8x16
,
17136 binop (Iop_AndV128
,
17146 binop(Iop_SarN8x16
,
17147 getWReg(ws
), mkU8(7)),
17156 binop(Iop_ShlN8x16
,
17157 mkexpr(t2
), mkU8(7)),
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
)));
17169 binop(Iop_SarN16x8
,
17170 binop (Iop_AndV128
,
17180 binop(Iop_SarN16x8
,
17191 binop(Iop_ShlN16x8
,
17192 mkexpr(t2
), mkU8(15)),
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
)));
17204 binop(Iop_SarN32x4
,
17205 binop (Iop_AndV128
,
17215 binop(Iop_SarN32x4
,
17226 binop(Iop_ShlN32x4
,
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
)));
17240 binop(Iop_SarN64x2
,
17241 binop (Iop_AndV128
,
17251 binop(Iop_SarN64x2
,
17262 binop(Iop_ShlN64x2
,
17263 mkexpr(t2
), mkU8(63)),
17275 case 0x04: { /* ASUB_S.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
)));
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
)));
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
)));
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
)));
17424 case 0x05: { /* ASUB_U.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
));
17434 binop(Iop_SarN8x16
,
17436 mkexpr(t1
), mkexpr(t2
)),
17441 unop(Iop_NotV128
, mkexpr(t3
)),
17446 binop(Iop_AndV128
, mkexpr(t3
),
17448 binop(Iop_Max8Ux16
,
17451 binop(Iop_Min8Ux16
,
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
));
17465 binop(Iop_SarN16x8
,
17467 mkexpr(t1
), mkexpr(t2
)),
17481 binop(Iop_Max16Ux8
,
17484 binop(Iop_Min16Ux8
,
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
));
17498 binop(Iop_SarN32x4
,
17500 mkexpr(t1
), mkexpr(t2
)),
17505 unop(Iop_NotV128
, mkexpr(t3
)),
17513 binop(Iop_Max32Ux4
,
17516 binop(Iop_Min32Ux4
,
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
));
17530 binop(Iop_SarN64x2
,
17532 mkexpr(t1
), mkexpr(t2
)),
17537 unop(Iop_NotV128
, mkexpr(t3
)),
17545 binop(Iop_Max64Ux2
,
17548 binop(Iop_Min64Ux2
,
17568 static Int
msa_3R_12(UInt cins
, UChar wd
, UChar ws
) { /* 3R (0x12) */
17569 IRTemp t1
, t2
, t3
, t4
, t5
, t6
;
17573 operation
= (cins
& 0x03800000) >> 23;
17574 df
= (cins
& 0x00600000) >> 21;
17575 wt
= (cins
& 0x001F0000) >> 16;
17577 switch (operation
) {
17578 case 0x00: { /* MULV.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
)));
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
)));
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
)));
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
));
17605 binop(Iop_64HLtoV128
,
17607 unop(Iop_V128HIto64
,
17609 unop(Iop_V128HIto64
,
17626 case 0x01: { /* MADDV.df */
17628 case 0x00: { /* MADDV.B */
17629 DIP("MADDV.B w%d, w%d, w%d", wd
, ws
, wt
);
17639 case 0x01: { /* MADDV.H */
17640 DIP("MADDV.H w%d, w%d, w%d", wd
, ws
, wt
);
17650 case 0x02: { /* MADDV.W */
17651 DIP("MADDV.W w%d, w%d, w%d", wd
, ws
, wt
);
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
));
17670 binop(Iop_64HLtoV128
,
17672 unop(Iop_V128HIto64
,
17674 unop(Iop_V128HIto64
,
17691 case 0x02: { /* MSUBV.df */
17693 case 0x00: { /* MSUBV.B */
17694 DIP("MSUBV.B w%d, w%d, w%d", wd
, ws
, wt
);
17704 case 0x01: { /* MSUBV.H */
17705 DIP("MSUBV.H w%d, w%d, w%d", wd
, ws
, wt
);
17715 case 0x02: { /* MSUBV.W */
17716 DIP("MSUBV.W w%d, w%d, w%d", wd
, ws
, wt
);
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
));
17735 binop(Iop_64HLtoV128
,
17737 unop(Iop_V128HIto64
,
17739 unop(Iop_V128HIto64
,
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
));
17763 case 0x00: { /* DIV_S.B */
17764 DIP("DIV_S.B w%d, w%d, w%d", wd
, ws
, wt
);
17768 for (i
= 0; i
< 16; i
++) {
17769 tmp
[i
] = newTemp(Ity_I32
);
17776 binop(Iop_GetElem8x16
,
17780 binop(Iop_GetElem8x16
,
17783 mkU8((i
& 3) << 3)));
17787 binop(Iop_64HLtoV128
,
17788 binop(Iop_32HLto64
,
17795 mkexpr(tmp
[12])))),
17802 mkexpr(tmp
[8]))))),
17803 binop(Iop_32HLto64
,
17817 mkexpr(tmp
[0]))))))
17822 case 0x01: { /* DIV_S.H */
17823 DIP("DIV_S.H w%d, w%d, w%d", wd
, ws
, wt
);
17827 for (i
= 0; i
< 8; i
++) {
17828 tmp
[i
] = newTemp(Ity_I32
);
17835 binop(Iop_GetElem16x8
,
17839 binop(Iop_GetElem16x8
,
17842 mkU8((i
& 1) << 4)));
17846 binop(Iop_64HLtoV128
,
17847 binop(Iop_32HLto64
,
17854 binop(Iop_32HLto64
,
17860 mkexpr(tmp
[0])))));
17864 case 0x02: { /* DIV_S.W */
17865 DIP("DIV_S.W w%d, w%d, w%d", wd
, ws
, wt
);
17869 for (i
= 0; i
< 4; i
++) {
17870 tmp
[i
] = newTemp(Ity_I32
);
17873 binop(Iop_GetElem32x4
,
17874 mkexpr(t1
), mkU8(i
)),
17875 binop(Iop_GetElem32x4
,
17876 mkexpr(t2
), mkU8(i
))));
17880 binop(Iop_64HLtoV128
, \
17881 binop(Iop_32HLto64
,
17884 binop(Iop_32HLto64
,
17890 case 0x03: { /* DIV_S.D */
17891 DIP("DIV_S.D w%d, w%d, w%d", wd
, ws
, wt
);
17893 binop(Iop_64HLtoV128
,
17895 unop(Iop_V128HIto64
,
17897 unop(Iop_V128HIto64
,
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
));
17921 case 0x00: { /* DIV_U.B */
17922 DIP("DIV_U.B w%d, w%d, w%d", wd
, ws
, wt
);
17926 for (i
= 0; i
< 16; i
++) {
17927 tmp
[i
] = newTemp(Ity_I32
);
17934 binop(Iop_GetElem8x16
,
17938 binop(Iop_GetElem8x16
,
17941 mkU8((i
& 3) << 3)));
17945 binop(Iop_64HLtoV128
,
17946 binop(Iop_32HLto64
,
17953 mkexpr(tmp
[12])))),
17960 mkexpr(tmp
[8]))))),
17961 binop(Iop_32HLto64
,
17975 mkexpr(tmp
[0]))))))
17980 case 0x01: { /* DIV_U.H */
17981 DIP("DIV_U.H w%d, w%d, w%d", wd
, ws
, wt
);
17985 for (i
= 0; i
< 8; i
++) {
17986 tmp
[i
] = newTemp(Ity_I32
);
17993 binop(Iop_GetElem16x8
,
17997 binop(Iop_GetElem16x8
,
18000 mkU8((i
& 1) << 4)));
18004 binop(Iop_64HLtoV128
,
18005 binop(Iop_32HLto64
,
18012 binop(Iop_32HLto64
,
18018 mkexpr(tmp
[0])))));
18022 case 0x02: { /* DIV_U.W */
18023 DIP("DIV_U.W w%d, w%d, w%d", wd
, ws
, wt
);
18027 for (i
= 0; i
< 4; i
++) {
18028 tmp
[i
] = newTemp(Ity_I32
);
18031 binop(Iop_GetElem32x4
,
18032 mkexpr(t1
), mkU8(i
)),
18033 binop(Iop_GetElem32x4
,
18034 mkexpr(t2
), mkU8(i
))));
18038 binop(Iop_64HLtoV128
,
18039 binop(Iop_32HLto64
,
18042 binop(Iop_32HLto64
,
18048 case 0x03: { /* DIV_U.D */
18049 DIP("DIV_U.D w%d, w%d, w%d", wd
, ws
, wt
);
18051 binop(Iop_64HLtoV128
,
18053 unop(Iop_V128HIto64
,
18055 unop(Iop_V128HIto64
,
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
));
18079 case 0x00: { /* MOD_S.B */
18080 DIP("MOD_S.B w%d, w%d, w%d", wd
, ws
, wt
);
18084 for (i
= 0; i
< 16; i
++) {
18085 tmp
[i
] = newTemp(Ity_I32
);
18091 binop(Iop_DivModS32to32
,
18093 binop(Iop_GetElem8x16
,
18097 binop(Iop_GetElem8x16
,
18100 mkU8((i
& 3) << 3)));
18104 binop(Iop_64HLtoV128
,
18105 binop(Iop_32HLto64
,
18112 mkexpr(tmp
[12])))),
18119 mkexpr(tmp
[8]))))),
18120 binop(Iop_32HLto64
,
18134 mkexpr(tmp
[0])))))));
18138 case 0x01: { /* MOD_S.H */
18139 DIP("MOD_S.H w%d, w%d, w%d", wd
, ws
, wt
);
18143 for (i
= 0; i
< 8; i
++) {
18144 tmp
[i
] = newTemp(Ity_I32
);
18150 binop(Iop_DivModS32to32
,
18152 binop(Iop_GetElem16x8
,
18156 binop(Iop_GetElem16x8
,
18159 mkU8((i
& 1) << 4)));
18163 binop(Iop_64HLtoV128
,
18164 binop(Iop_32HLto64
,
18171 binop(Iop_32HLto64
,
18177 mkexpr(tmp
[0])))));
18181 case 0x02: { /* MOD_S.W */
18182 DIP("MOD_S.W w%d, w%d, w%d", wd
, ws
, wt
);
18186 for (i
= 0; i
< 4; i
++) {
18187 tmp
[i
] = newTemp(Ity_I32
);
18190 binop(Iop_DivModS32to32
,
18191 binop(Iop_GetElem32x4
,
18194 binop(Iop_GetElem32x4
,
18200 binop(Iop_64HLtoV128
,
18201 binop(Iop_32HLto64
,
18204 binop(Iop_32HLto64
,
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
)));
18221 binop(Iop_64HLtoV128
,
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
));
18253 case 0x00: { /* MOD_U.B */
18254 DIP("MOD_U.B w%d, w%d, w%d", wd
, ws
, wt
);
18258 for (i
= 0; i
< 16; i
++) {
18259 tmp
[i
] = newTemp(Ity_I32
);
18265 binop(Iop_DivModU32to32
,
18267 binop(Iop_GetElem8x16
,
18271 binop(Iop_GetElem8x16
,
18274 mkU8((i
& 3) << 3)));
18278 binop(Iop_64HLtoV128
,
18279 binop(Iop_32HLto64
,
18286 mkexpr(tmp
[12])))),
18293 mkexpr(tmp
[8]))))),
18294 binop(Iop_32HLto64
,
18308 mkexpr(tmp
[0])))))));
18312 case 0x01: { /* MOD_U.H */
18313 DIP("MOD_U.H w%d, w%d, w%d", wd
, ws
, wt
);
18317 for (i
= 0; i
< 8; i
++) {
18318 tmp
[i
] = newTemp(Ity_I32
);
18324 binop(Iop_DivModU32to32
,
18326 binop(Iop_GetElem16x8
,
18330 binop(Iop_GetElem16x8
,
18333 mkU8((i
& 1) << 4)));
18337 binop(Iop_64HLtoV128
,
18338 binop(Iop_32HLto64
,
18345 binop(Iop_32HLto64
,
18351 mkexpr(tmp
[0])))));
18355 case 0x02: { /* MOD_U.W */
18356 DIP("MOD_U.W w%d, w%d, w%d", wd
, ws
, wt
);
18360 for (i
= 0; i
< 4; i
++) {
18361 tmp
[i
] = newTemp(Ity_I32
);
18364 binop(Iop_DivModU32to32
,
18365 binop(Iop_GetElem32x4
,
18368 binop(Iop_GetElem32x4
,
18374 binop(Iop_64HLtoV128
,
18375 binop(Iop_32HLto64
,
18378 binop(Iop_32HLto64
,
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
)));
18395 binop(Iop_64HLtoV128
,
18427 static Int
msa_3R_13(UInt cins
, UChar wd
, UChar ws
) { /* 3R (0x13) */
18432 operation
= (cins
& 0x03800000) >> 23;
18433 df
= (cins
& 0x00600000) >> 21;
18434 wt
= (cins
& 0x001F0000) >> 16;
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
));
18444 case 0x01: { /* DOTP_S.H */
18445 DIP("DOTP_S.H w%d, w%d, w%d", wd
, ws
, wt
);
18449 for (i
= 0; i
< 8; i
++) {
18450 tmp
[i
] = newTemp(Ity_I16
);
18454 binop(Iop_GetElem8x16
,
18457 binop(Iop_GetElem8x16
,
18461 binop(Iop_GetElem8x16
,
18464 binop(Iop_GetElem8x16
,
18466 mkU8(2 * i
+ 1)))));
18470 binop(Iop_64HLtoV128
,
18471 binop(Iop_32HLto64
,
18472 binop(Iop_16HLto32
,
18475 binop(Iop_16HLto32
,
18478 binop(Iop_32HLto64
,
18479 binop(Iop_16HLto32
,
18482 binop(Iop_16HLto32
,
18484 mkexpr(tmp
[0])))));
18488 case 0x02: { /* DOTP_S.W */
18489 DIP("DOTP_S.W w%d, w%d, w%d", wd
, ws
, wt
);
18493 for (i
= 0; i
< 4; i
++) {
18494 tmp
[i
] = newTemp(Ity_I32
);
18498 binop(Iop_GetElem16x8
,
18501 binop(Iop_GetElem16x8
,
18505 binop(Iop_GetElem16x8
,
18508 binop(Iop_GetElem16x8
,
18510 mkU8(2 * i
+ 1)))));
18514 binop(Iop_64HLtoV128
,
18515 binop(Iop_32HLto64
,
18518 binop(Iop_32HLto64
,
18524 case 0x03: { /* DOTP_S.D */
18525 DIP("DOTP_S.D w%d, w%d, w%d", wd
, ws
, wt
);
18529 for (i
= 0; i
< 2; i
++) {
18530 tmp
[i
] = newTemp(Ity_I64
);
18534 binop(Iop_GetElem32x4
,
18537 binop(Iop_GetElem32x4
,
18541 binop(Iop_GetElem32x4
,
18544 binop(Iop_GetElem32x4
,
18546 mkU8(2 * i
+ 1)))));
18550 binop(Iop_64HLtoV128
,
18551 mkexpr(tmp
[1]), mkexpr(tmp
[0])));
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
));
18569 case 0x01: { /* DOTP_U.H */
18570 DIP("DOTP_U.H w%d, w%d, w%d", wd
, ws
, wt
);
18574 for (i
= 0; i
< 8; i
++) {
18575 tmp
[i
] = newTemp(Ity_I16
);
18579 binop(Iop_GetElem8x16
,
18582 binop(Iop_GetElem8x16
,
18586 binop(Iop_GetElem8x16
,
18589 binop(Iop_GetElem8x16
,
18591 mkU8(2 * i
+ 1)))));
18595 binop(Iop_64HLtoV128
,
18596 binop(Iop_32HLto64
,
18597 binop(Iop_16HLto32
,
18600 binop(Iop_16HLto32
,
18603 binop(Iop_32HLto64
,
18604 binop(Iop_16HLto32
,
18607 binop(Iop_16HLto32
,
18609 mkexpr(tmp
[0])))));
18613 case 0x02: { /* DOTP_U.W */
18614 DIP("DOTP_U.W w%d, w%d, w%d", wd
, ws
, wt
);
18618 for (i
= 0; i
< 4; i
++) {
18619 tmp
[i
] = newTemp(Ity_I32
);
18623 binop(Iop_GetElem16x8
,
18626 binop(Iop_GetElem16x8
,
18630 binop(Iop_GetElem16x8
,
18633 binop(Iop_GetElem16x8
,
18635 mkU8(2 * i
+ 1)))));
18639 binop(Iop_64HLtoV128
,
18640 binop(Iop_32HLto64
,
18643 binop(Iop_32HLto64
,
18649 case 0x03: { /* DOTP_U.D */
18650 DIP("DOTP_U.D w%d, w%d, w%d", wd
, ws
, wt
);
18654 for (i
= 0; i
< 2; i
++) {
18655 tmp
[i
] = newTemp(Ity_I64
);
18659 binop(Iop_GetElem32x4
,
18662 binop(Iop_GetElem32x4
,
18666 binop(Iop_GetElem32x4
,
18669 binop(Iop_GetElem32x4
,
18671 mkU8(2 * i
+ 1)))));
18675 binop(Iop_64HLtoV128
,
18676 mkexpr(tmp
[1]), mkexpr(tmp
[0])));
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
));
18694 case 0x01: { /* DPADD_S.H */
18695 DIP("DPADD_S.H w%d, w%d, w%d", wd
, ws
, wt
);
18699 for (i
= 0; i
< 8; i
++) {
18700 tmp
[i
] = newTemp(Ity_I16
);
18704 binop(Iop_GetElem8x16
,
18707 binop(Iop_GetElem8x16
,
18711 binop(Iop_GetElem8x16
,
18714 binop(Iop_GetElem8x16
,
18716 mkU8(2 * i
+ 1)))));
18722 binop(Iop_64HLtoV128
,
18723 binop(Iop_32HLto64
,
18724 binop(Iop_16HLto32
,
18727 binop(Iop_16HLto32
,
18730 binop(Iop_32HLto64
,
18731 binop(Iop_16HLto32
,
18734 binop(Iop_16HLto32
,
18736 mkexpr(tmp
[0]))))));
18740 case 0x02: { /* DPADD_S.W */
18741 DIP("DPADD_S.W w%d, w%d, w%d", wd
, ws
, wt
);
18745 for (i
= 0; i
< 4; i
++) {
18746 tmp
[i
] = newTemp(Ity_I32
);
18750 binop(Iop_GetElem16x8
,
18753 binop(Iop_GetElem16x8
,
18757 binop(Iop_GetElem16x8
,
18760 binop(Iop_GetElem16x8
,
18762 mkU8(2 * i
+ 1)))));
18768 binop(Iop_64HLtoV128
,
18769 binop(Iop_32HLto64
,
18772 binop(Iop_32HLto64
,
18774 mkexpr(tmp
[0])))));
18778 case 0x03: { /* DPADD_S.D */
18779 DIP("DPADD_S.D w%d, w%d, w%d", wd
, ws
, wt
);
18783 for (i
= 0; i
< 2; i
++) {
18784 tmp
[i
] = newTemp(Ity_I64
);
18788 binop(Iop_GetElem32x4
,
18791 binop(Iop_GetElem32x4
,
18795 binop(Iop_GetElem32x4
,
18798 binop(Iop_GetElem32x4
,
18800 mkU8(2 * i
+ 1)))));
18806 binop(Iop_64HLtoV128
,
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
));
18826 case 0x01: { /* DPADD_U.H */
18827 DIP("DPADD_U.H w%d, w%d, w%d", wd
, ws
, wt
);
18831 for (i
= 0; i
< 8; i
++) {
18832 tmp
[i
] = newTemp(Ity_I16
);
18836 binop(Iop_GetElem8x16
,
18839 binop(Iop_GetElem8x16
,
18843 binop(Iop_GetElem8x16
,
18846 binop(Iop_GetElem8x16
,
18848 mkU8(2 * i
+ 1)))));
18854 binop(Iop_64HLtoV128
,
18855 binop(Iop_32HLto64
,
18856 binop(Iop_16HLto32
,
18859 binop(Iop_16HLto32
,
18862 binop(Iop_32HLto64
,
18863 binop(Iop_16HLto32
,
18866 binop(Iop_16HLto32
,
18868 mkexpr(tmp
[0]))))));
18872 case 0x02: { /* DPADD_U.W */
18873 DIP("DPADD_U.W w%d, w%d, w%d", wd
, ws
, wt
);
18877 for (i
= 0; i
< 4; i
++) {
18878 tmp
[i
] = newTemp(Ity_I32
);
18882 binop(Iop_GetElem16x8
,
18885 binop(Iop_GetElem16x8
,
18889 binop(Iop_GetElem16x8
,
18892 binop(Iop_GetElem16x8
,
18894 mkU8(2 * i
+ 1)))));
18900 binop(Iop_64HLtoV128
,
18901 binop(Iop_32HLto64
,
18904 binop(Iop_32HLto64
,
18906 mkexpr(tmp
[0])))));
18910 case 0x03: { /* DPADD_U.D */
18911 DIP("DPADD_U.D w%d, w%d, w%d", wd
, ws
, wt
);
18915 for (i
= 0; i
< 2; i
++) {
18916 tmp
[i
] = newTemp(Ity_I64
);
18920 binop(Iop_GetElem32x4
,
18923 binop(Iop_GetElem32x4
,
18927 binop(Iop_GetElem32x4
,
18930 binop(Iop_GetElem32x4
,
18932 mkU8(2 * i
+ 1)))));
18938 binop(Iop_64HLtoV128
,
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
));
18958 case 0x01: { /* DPSUB_S.H */
18959 DIP("DPSUB_S.H w%d, w%d, w%d", wd
, ws
, wt
);
18963 for (i
= 0; i
< 8; i
++) {
18964 tmp
[i
] = newTemp(Ity_I16
);
18968 binop(Iop_GetElem8x16
,
18971 binop(Iop_GetElem8x16
,
18975 binop(Iop_GetElem8x16
,
18978 binop(Iop_GetElem8x16
,
18980 mkU8(2 * i
+ 1)))));
18986 binop(Iop_64HLtoV128
,
18987 binop(Iop_32HLto64
,
18988 binop(Iop_16HLto32
,
18991 binop(Iop_16HLto32
,
18994 binop(Iop_32HLto64
,
18995 binop(Iop_16HLto32
,
18998 binop(Iop_16HLto32
,
19000 mkexpr(tmp
[0]))))));
19004 case 0x02: { /* DPSUB_S.W */
19005 DIP("DPSUB_S.W w%d, w%d, w%d", wd
, ws
, wt
);
19009 for (i
= 0; i
< 4; i
++) {
19010 tmp
[i
] = newTemp(Ity_I32
);
19014 binop(Iop_GetElem16x8
,
19017 binop(Iop_GetElem16x8
,
19021 binop(Iop_GetElem16x8
,
19024 binop(Iop_GetElem16x8
,
19026 mkU8(2 * i
+ 1)))));
19032 binop(Iop_64HLtoV128
,
19033 binop(Iop_32HLto64
,
19036 binop(Iop_32HLto64
,
19038 mkexpr(tmp
[0])))));
19042 case 0x03: { /* DPSUB_S.D */
19043 DIP("DPSUB_S.D w%d, w%d, w%d", wd
, ws
, wt
);
19047 for (i
= 0; i
< 2; i
++) {
19048 tmp
[i
] = newTemp(Ity_I64
);
19052 binop(Iop_GetElem32x4
,
19055 binop(Iop_GetElem32x4
,
19059 binop(Iop_GetElem32x4
,
19062 binop(Iop_GetElem32x4
,
19064 mkU8(2 * i
+ 1)))));
19070 binop(Iop_64HLtoV128
,
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
));
19090 case 0x01: { /* DPSUB_U.H */
19091 DIP("DPSUB_U.H w%d, w%d, w%d", wd
, ws
, wt
);
19095 for (i
= 0; i
< 8; i
++) {
19096 tmp
[i
] = newTemp(Ity_I16
);
19100 binop(Iop_GetElem8x16
,
19103 binop(Iop_GetElem8x16
,
19107 binop(Iop_GetElem8x16
,
19110 binop(Iop_GetElem8x16
,
19112 mkU8(2 * i
+ 1)))));
19118 binop(Iop_64HLtoV128
,
19119 binop(Iop_32HLto64
,
19120 binop(Iop_16HLto32
,
19123 binop(Iop_16HLto32
,
19126 binop(Iop_32HLto64
,
19127 binop(Iop_16HLto32
,
19130 binop(Iop_16HLto32
,
19132 mkexpr(tmp
[0]))))));
19136 case 0x02: { /* DPSUB_U.W */
19137 DIP("DPSUB_U.W w%d, w%d, w%d", wd
, ws
, wt
);
19141 for (i
= 0; i
< 4; i
++) {
19142 tmp
[i
] = newTemp(Ity_I32
);
19146 binop(Iop_GetElem16x8
,
19149 binop(Iop_GetElem16x8
,
19153 binop(Iop_GetElem16x8
,
19156 binop(Iop_GetElem16x8
,
19158 mkU8(2 * i
+ 1)))));
19164 binop(Iop_64HLtoV128
,
19165 binop(Iop_32HLto64
,
19168 binop(Iop_32HLto64
,
19170 mkexpr(tmp
[0])))));
19174 case 0x03: { /* DPSUB_U.D */
19175 DIP("DPSUB_U.D w%d, w%d, w%d", wd
, ws
, wt
);
19179 for (i
= 0; i
< 2; i
++) {
19180 tmp
[i
] = newTemp(Ity_I64
);
19184 binop(Iop_GetElem32x4
,
19187 binop(Iop_GetElem32x4
,
19191 binop(Iop_GetElem32x4
,
19194 binop(Iop_GetElem32x4
,
19196 mkU8(2 * i
+ 1)))));
19202 binop(Iop_64HLtoV128
,
19222 static Int
msa_3R_14(UInt cins
, UChar wd
, UChar ws
) { /* 3R (0x14) */
19223 IRTemp t1
, t2
, t3
, t4
;
19228 operation
= (cins
& 0x03800000) >> 23;
19229 df
= (cins
& 0x00600000) >> 21;
19230 wt
= (cins
& 0x001F0000) >> 16;
19231 ty
= mode64
? Ity_I64
: Ity_I32
;
19233 switch (operation
) {
19234 case 0x00: { /* SLD.df */
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
);
19251 unop(Iop_32to8
, mkexpr(t1
))));
19261 mkexpr(t2
), mkexpr(t3
)));
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
);
19279 binop(Iop_32HLto64
, mkU32(0), mkexpr(t1
)));
19283 binop(Iop_64HLtoV128
,
19284 mkexpr(t2
), mkexpr(t2
))));
19289 binop(Iop_64HLtoV128
,
19292 binop(Iop_64HLtoV128
,
19300 mkexpr(t1
), mkU32(0)),
19302 binop(Iop_64HLtoV128
,
19303 mkU64(0), mkU64(0)))));
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
);
19321 binop(Iop_32HLto64
,
19322 mkexpr(t1
), mkexpr(t1
)));
19326 binop(Iop_64HLtoV128
,
19327 mkexpr(t2
), mkexpr(t2
))));
19332 binop(Iop_64HLtoV128
,
19333 mkU64(0x2000000020ul
),
19334 mkU64(0x2000000020ul
)),
19335 binop(Iop_64HLtoV128
,
19343 mkexpr(t1
), mkU32(0)),
19345 binop(Iop_64HLtoV128
,
19346 mkU64(0), mkU64(0)))));
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
);
19364 binop(Iop_32HLto64
,
19368 mkexpr(t1
), mkU8(16))),
19372 mkexpr(t1
), mkU8(16)))));
19376 binop(Iop_64HLtoV128
,
19377 mkexpr(t2
), mkexpr(t2
))));
19382 binop(Iop_64HLtoV128
,
19383 mkU64(0x10001000100010ul
),
19384 mkU64(0x10001000100010ul
)),
19385 binop(Iop_64HLtoV128
,
19393 mkexpr(t1
), mkU32(0)),
19395 binop(Iop_64HLtoV128
,
19396 mkU64(0), mkU64(0)))));
19404 case 0x01: { /* SPLAT.df */
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
));
19414 mkNarrowTo32(ty
, getIReg(wt
)));
19417 for (i
= 0; i
< 16; i
++) {
19418 tmp
[i
] = newTemp(Ity_I8
);
19420 binop(Iop_GetElem8x16
,
19422 unop(Iop_32to8
, mkexpr(t2
))));
19426 binop(Iop_64HLtoV128
,
19427 binop(Iop_32HLto64
,
19428 binop(Iop_16HLto32
,
19435 binop(Iop_16HLto32
,
19442 binop(Iop_32HLto64
,
19443 binop(Iop_16HLto32
,
19450 binop(Iop_16HLto32
,
19456 mkexpr(tmp
[0]))))));
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
));
19466 mkNarrowTo32(ty
, getIReg(wt
)));
19469 for (i
= 0; i
< 8; i
++) {
19470 tmp
[i
] = newTemp(Ity_I16
);
19472 binop(Iop_GetElem16x8
,
19474 unop(Iop_32to8
, mkexpr(t2
))));
19478 binop(Iop_64HLtoV128
,
19479 binop(Iop_32HLto64
,
19480 binop(Iop_16HLto32
,
19483 binop(Iop_16HLto32
,
19486 binop(Iop_32HLto64
,
19487 binop(Iop_16HLto32
,
19490 binop(Iop_16HLto32
,
19492 mkexpr(tmp
[0])))));
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
));
19502 mkNarrowTo32(ty
, getIReg(wt
)));
19505 for (i
= 0; i
< 4; i
++) {
19506 tmp
[i
] = newTemp(Ity_I32
);
19508 binop(Iop_GetElem32x4
,
19510 unop(Iop_32to8
, mkexpr(t2
))));
19514 binop(Iop_64HLtoV128
,
19515 binop(Iop_32HLto64
,
19518 binop(Iop_32HLto64
,
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
));
19530 mkNarrowTo32(ty
, getIReg(wt
)));
19533 for (i
= 0; i
< 2; i
++) {
19534 tmp
[i
] = newTemp(Ity_I64
);
19536 binop(Iop_GetElem64x2
,
19538 unop(Iop_32to8
, mkexpr(t2
))));
19542 binop(Iop_64HLtoV128
,
19543 mkexpr(tmp
[1]), mkexpr(tmp
[0])));
19551 case 0x02: { /* PCKEV.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
));
19561 binop(Iop_PackEvenLanes8x16
,
19562 mkexpr(t1
), mkexpr(t2
)));
19563 putWReg(wd
, mkexpr(t3
));
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
));
19575 binop(Iop_PackEvenLanes16x8
,
19576 mkexpr(t1
), mkexpr(t2
)));
19577 putWReg(wd
, mkexpr(t3
));
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
));
19589 binop(Iop_PackEvenLanes32x4
,
19590 mkexpr(t1
), mkexpr(t2
)));
19591 putWReg(wd
, mkexpr(t3
));
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
));
19603 binop(Iop_InterleaveLO64x2
,
19604 mkexpr(t1
), mkexpr(t2
)));
19605 putWReg(wd
, mkexpr(t3
));
19616 case 0x03: { /* PCKOD.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
));
19626 binop(Iop_PackOddLanes8x16
,
19627 mkexpr(t1
), mkexpr(t2
)));
19628 putWReg(wd
, mkexpr(t3
));
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
));
19640 binop(Iop_PackOddLanes16x8
,
19641 mkexpr(t1
), mkexpr(t2
)));
19642 putWReg(wd
, mkexpr(t3
));
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
));
19654 binop(Iop_PackOddLanes32x4
,
19655 mkexpr(t1
), mkexpr(t2
)));
19656 putWReg(wd
, mkexpr(t3
));
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
));
19668 binop(Iop_InterleaveHI64x2
,
19669 mkexpr(t1
), mkexpr(t2
)));
19670 putWReg(wd
, mkexpr(t3
));
19681 case 0x04: { /* ILVL.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
));
19691 binop(Iop_InterleaveHI8x16
,
19692 mkexpr(t1
), mkexpr(t2
)));
19693 putWReg(wd
, mkexpr(t3
));
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
));
19705 binop(Iop_InterleaveHI16x8
,
19706 mkexpr(t1
), mkexpr(t2
)));
19707 putWReg(wd
, mkexpr(t3
));
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
));
19719 binop(Iop_InterleaveHI32x4
,
19720 mkexpr(t1
), mkexpr(t2
)));
19721 putWReg(wd
, mkexpr(t3
));
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
));
19733 binop(Iop_InterleaveHI64x2
,
19734 mkexpr(t1
), mkexpr(t2
)));
19735 putWReg(wd
, mkexpr(t3
));
19746 case 0x05: { /* ILVR.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
));
19756 binop(Iop_InterleaveLO8x16
,
19757 mkexpr(t1
), mkexpr(t2
)));
19758 putWReg(wd
, mkexpr(t3
));
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
));
19770 binop(Iop_InterleaveLO16x8
,
19771 mkexpr(t1
), mkexpr(t2
)));
19772 putWReg(wd
, mkexpr(t3
));
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
));
19784 binop(Iop_InterleaveLO32x4
,
19785 mkexpr(t1
), mkexpr(t2
)));
19786 putWReg(wd
, mkexpr(t3
));
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
));
19798 binop(Iop_InterleaveLO64x2
,
19799 mkexpr(t1
), mkexpr(t2
)));
19800 putWReg(wd
, mkexpr(t3
));
19808 case 0x06: { /* ILVEV.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
));
19818 binop(Iop_InterleaveEvenLanes8x16
,
19819 mkexpr(t1
), mkexpr(t2
)));
19820 putWReg(wd
, mkexpr(t3
));
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
));
19832 binop(Iop_InterleaveEvenLanes16x8
,
19833 mkexpr(t1
), mkexpr(t2
)));
19834 putWReg(wd
, mkexpr(t3
));
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
));
19846 binop(Iop_InterleaveEvenLanes32x4
,
19847 mkexpr(t1
), mkexpr(t2
)));
19848 putWReg(wd
, mkexpr(t3
));
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
));
19860 binop(Iop_InterleaveLO64x2
,
19861 mkexpr(t1
), mkexpr(t2
)));
19862 putWReg(wd
, mkexpr(t3
));
19873 case 0x07: { /* ILVOD.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
));
19883 binop(Iop_InterleaveOddLanes8x16
,
19884 mkexpr(t1
), mkexpr(t2
)));
19885 putWReg(wd
, mkexpr(t3
));
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
));
19897 binop(Iop_InterleaveOddLanes16x8
,
19898 mkexpr(t1
), mkexpr(t2
)));
19899 putWReg(wd
, mkexpr(t3
));
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
));
19911 binop(Iop_InterleaveOddLanes32x4
,
19912 mkexpr(t1
), mkexpr(t2
)));
19913 putWReg(wd
, mkexpr(t3
));
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
));
19925 binop(Iop_InterleaveHI64x2
,
19926 mkexpr(t1
), mkexpr(t2
)));
19927 putWReg(wd
, mkexpr(t3
));
19945 static Int
msa_3R_15(UInt cins
, UChar wd
, UChar ws
) { /* 3R (0x15) */
19946 IRTemp t1
, t2
, t3
, t4
;
19950 operation
= (cins
& 0x03800000) >> 23;
19951 df
= (cins
& 0x00600000) >> 21;
19952 wt
= (cins
& 0x001F0000) >> 16;
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
));
19964 case 0x00: { /* VSHF.B */
19965 DIP("VSHF.B w%d, w%d, w%d", wd
, ws
, wt
);
19969 for (i
= 0; i
< 16; i
++) {
19970 tmp
[i
] = newTemp(Ity_I8
);
19975 binop(Iop_GetElem8x16
,
19983 binop(Iop_GetElem8x16
,
19988 binop(Iop_GetElem8x16
,
19990 binop(Iop_GetElem8x16
,
19993 binop(Iop_GetElem8x16
,
19995 binop(Iop_GetElem8x16
,
20002 binop(Iop_64HLtoV128
,
20003 binop(Iop_32HLto64
,
20004 binop(Iop_16HLto32
,
20011 binop(Iop_16HLto32
,
20018 binop(Iop_32HLto64
,
20019 binop(Iop_16HLto32
,
20026 binop(Iop_16HLto32
,
20032 mkexpr(tmp
[0]))))));
20036 case 0x01: { /* VSHF.H */
20037 DIP("VSHF.H w%d, w%d, w%d", wd
, ws
, wt
);
20041 for (i
= 0; i
< 8; i
++) {
20042 tmp
[i
] = newTemp(Ity_I16
);
20047 binop(Iop_GetElem16x8
,
20055 binop(Iop_GetElem16x8
,
20060 binop(Iop_GetElem16x8
,
20063 binop(Iop_GetElem16x8
,
20066 binop(Iop_GetElem16x8
,
20069 binop(Iop_GetElem16x8
,
20076 binop(Iop_64HLtoV128
,
20077 binop(Iop_32HLto64
,
20078 binop(Iop_16HLto32
,
20081 binop(Iop_16HLto32
,
20084 binop(Iop_32HLto64
,
20085 binop(Iop_16HLto32
,
20088 binop(Iop_16HLto32
,
20090 mkexpr(tmp
[0])))));
20094 case 0x02: { /* VSHF.W */
20095 DIP("VSHF.W w%d, w%d, w%d", wd
, ws
, wt
);
20099 for (i
= 0; i
< 4; i
++) {
20100 tmp
[i
] = newTemp(Ity_I32
);
20105 binop(Iop_GetElem32x4
,
20113 binop(Iop_GetElem32x4
,
20118 binop(Iop_GetElem32x4
,
20121 binop(Iop_GetElem32x4
,
20124 binop(Iop_GetElem32x4
,
20127 binop(Iop_GetElem32x4
,
20134 binop(Iop_64HLtoV128
,
20135 binop(Iop_32HLto64
,
20138 binop(Iop_32HLto64
,
20144 case 0x03: { /* VSHF.D */
20145 DIP("VSHF.D w%d, w%d, w%d", wd
, ws
, wt
);
20149 for (i
= 0; i
< 2; i
++) {
20150 tmp
[i
] = newTemp(Ity_I64
);
20155 binop(Iop_GetElem64x2
,
20163 binop(Iop_GetElem64x2
,
20168 binop(Iop_GetElem64x2
,
20171 binop(Iop_GetElem64x2
,
20174 binop(Iop_GetElem64x2
,
20177 binop(Iop_GetElem64x2
,
20184 binop(Iop_64HLtoV128
,
20185 mkexpr(tmp
[1]), mkexpr(tmp
[0])));
20196 case 0x01: { /* SRAR.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
);
20210 binop(Iop_64HLtoV128
,
20211 mkU64(0x808080808080808ull
),
20212 mkU64(0x808080808080808ull
)),
20216 binop(Iop_CmpEQ8x16
,
20217 binop(Iop_ShlN8x16
,
20220 binop(Iop_64HLtoV128
,
20221 mkU64(0), mkU64(0)))));
20223 binop(Iop_ShrN8x16
,
20232 mkexpr(t1
), mkexpr(t3
)));
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
);
20248 binop(Iop_64HLtoV128
,
20249 mkU64(0x10001000100010ul
),
20250 mkU64(0x10001000100010ul
)),
20254 binop(Iop_CmpEQ16x8
,
20255 binop(Iop_ShlN16x8
,
20258 binop(Iop_64HLtoV128
,
20259 mkU64(0), mkU64(0)))));
20261 binop(Iop_ShrN16x8
,
20270 mkexpr(t1
), mkexpr(t3
)));
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
20286 binop(Iop_64HLtoV128
,
20287 mkU64(0x2000000020ul
),
20288 mkU64(0x2000000020ul
)),
20292 binop(Iop_CmpEQ32x4
,
20293 binop(Iop_ShlN32x4
,
20296 binop(Iop_64HLtoV128
,
20297 mkU64(0), mkU64(0)))));
20299 binop(Iop_ShrN32x4
,
20308 mkexpr(t1
), mkexpr(t3
)));
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
);
20324 binop(Iop_64HLtoV128
,
20325 mkU64(64ul), mkU64(64ul)),
20329 binop(Iop_CmpEQ64x2
,
20330 binop(Iop_ShlN64x2
,
20333 binop(Iop_64HLtoV128
,
20334 mkU64(0), mkU64(0)))));
20336 binop(Iop_ShrN64x2
,
20345 mkexpr(t1
), mkexpr(t3
)));
20356 case 0x02: { /* SRLR.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
);
20370 binop(Iop_64HLtoV128
,
20371 mkU64(0x808080808080808ull
),
20372 mkU64(0x808080808080808ull
)),
20376 binop(Iop_CmpEQ8x16
,
20377 binop(Iop_ShlN8x16
,
20380 binop(Iop_64HLtoV128
,
20381 mkU64(0), mkU64(0)))));
20383 binop(Iop_ShrN8x16
,
20392 mkexpr(t1
), mkexpr(t3
)));
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
);
20408 binop(Iop_64HLtoV128
,
20409 mkU64(0x10001000100010ul
),
20410 mkU64(0x10001000100010ul
)),
20414 binop(Iop_CmpEQ16x8
,
20415 binop(Iop_ShlN16x8
,
20418 binop(Iop_64HLtoV128
,
20419 mkU64(0), mkU64(0)))));
20421 binop(Iop_ShrN16x8
,
20430 mkexpr(t1
), mkexpr(t3
)));
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
);
20446 binop(Iop_64HLtoV128
,
20447 mkU64(0x2000000020ul
),
20448 mkU64(0x2000000020ul
)),
20452 binop(Iop_CmpEQ32x4
,
20453 binop(Iop_ShlN32x4
,
20456 binop(Iop_64HLtoV128
,
20457 mkU64(0), mkU64(0)))));
20459 binop(Iop_ShrN32x4
,
20468 mkexpr(t1
), mkexpr(t3
)));
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
);
20484 binop(Iop_64HLtoV128
,
20485 mkU64(64ul), mkU64(64ul)),
20489 binop(Iop_CmpEQ64x2
,
20490 binop(Iop_ShlN64x2
,
20493 binop(Iop_64HLtoV128
,
20494 mkU64(0), mkU64(0)))));
20496 binop(Iop_ShrN64x2
,
20505 mkexpr(t1
), mkexpr(t3
)));
20516 case 0x04: { /* HADD_S.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
));
20527 binop(Iop_SarN16x8
,
20528 mkexpr(t1
), mkU8(8)),
20529 binop(Iop_SarN16x8
,
20530 binop(Iop_ShlN16x8
,
20531 mkexpr(t2
), mkU8(8)),
20533 putWReg(wd
, mkexpr(t3
));
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
));
20546 binop(Iop_SarN32x4
,
20547 mkexpr(t1
), mkU8(16)),
20548 binop(Iop_SarN32x4
,
20549 binop(Iop_ShlN32x4
,
20550 mkexpr(t2
), mkU8(16)),
20552 putWReg(wd
, mkexpr(t3
));
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
));
20565 binop(Iop_SarN64x2
,
20566 mkexpr(t1
), mkU8(32)),
20567 binop(Iop_SarN64x2
,
20568 binop(Iop_ShlN64x2
,
20569 mkexpr(t2
), mkU8(32)),
20571 putWReg(wd
, mkexpr(t3
));
20582 case 0x05: { /* HADD_U.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
));
20593 binop(Iop_ShrN16x8
,
20594 mkexpr(t1
), mkU8(8)),
20595 binop(Iop_ShrN16x8
,
20596 binop(Iop_ShlN16x8
,
20597 mkexpr(t2
), mkU8(8)),
20599 putWReg(wd
, mkexpr(t3
));
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
));
20612 binop(Iop_ShrN32x4
,
20613 mkexpr(t1
), mkU8(16)),
20614 binop(Iop_ShrN32x4
,
20615 binop(Iop_ShlN32x4
,
20616 mkexpr(t2
), mkU8(16)),
20618 putWReg(wd
, mkexpr(t3
));
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
));
20631 binop(Iop_ShrN64x2
,
20632 mkexpr(t1
), mkU8(32)),
20633 binop(Iop_ShrN64x2
,
20634 binop(Iop_ShlN64x2
,
20635 mkexpr(t2
), mkU8(32)),
20637 putWReg(wd
, mkexpr(t3
));
20648 case 0x06: { /* HSUB_S.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
));
20659 binop(Iop_SarN16x8
,
20660 mkexpr(t1
), mkU8(8)),
20661 binop(Iop_SarN16x8
,
20662 binop(Iop_ShlN16x8
,
20663 mkexpr(t2
), mkU8(8)),
20665 putWReg(wd
, mkexpr(t3
));
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
));
20678 binop(Iop_SarN32x4
,
20679 mkexpr(t1
), mkU8(16)),
20680 binop(Iop_SarN32x4
,
20681 binop(Iop_ShlN32x4
,
20682 mkexpr(t2
), mkU8(16)),
20684 putWReg(wd
, mkexpr(t3
));
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
));
20697 binop(Iop_SarN64x2
,
20698 mkexpr(t1
), mkU8(32)),
20699 binop(Iop_SarN64x2
,
20700 binop(Iop_ShlN64x2
,
20701 mkexpr(t2
), mkU8(32)),
20703 putWReg(wd
, mkexpr(t3
));
20714 case 0x07: { /* HSUB_U.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
));
20725 binop(Iop_ShrN16x8
,
20726 mkexpr(t1
), mkU8(8)),
20727 binop(Iop_ShrN16x8
,
20728 binop(Iop_ShlN16x8
,
20729 mkexpr(t2
), mkU8(8)),
20731 putWReg(wd
, mkexpr(t3
));
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
));
20744 binop(Iop_ShrN32x4
,
20745 mkexpr(t1
), mkU8(16)),
20746 binop(Iop_ShrN32x4
,
20747 binop(Iop_ShlN32x4
,
20748 mkexpr(t2
), mkU8(16)),
20750 putWReg(wd
, mkexpr(t3
));
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
));
20763 binop(Iop_ShrN64x2
,
20764 mkexpr(t1
), mkU8(32)),
20765 binop(Iop_ShrN64x2
,
20766 binop(Iop_ShlN64x2
,
20767 mkexpr(t2
), mkU8(32)),
20769 putWReg(wd
, mkexpr(t3
));
20787 static Int
msa_3R_1A(UInt cins
, UChar wd
, UChar ws
) { /* 3R (0x1A) */
20791 operation
= (cins
& 0x03C00000) >> 22;
20792 df
= (cins
& 0x00200000) >> 21;
20793 wt
= (cins
& 0x001F0000) >> 16;
20795 switch (operation
) {
20796 case 0x00: { /* FCAF.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)));
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)));
20819 case 0x01: { /* FCUN.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
,
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
,
20846 case 0x02: { /* FCEQ.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
,
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
,
20873 case 0x03: { /* FCUEQ.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);
20880 binop(Iop_CmpEQ32Fx4
,
20883 binop(Iop_CmpUN32Fx4
,
20889 case 0x01: { /* FCUEQ.D */
20890 DIP("FCUEQ.D w%d, w%d, w%d", wd
, ws
, wt
);
20891 calculateMSACSR(ws
, wt
, FCUEQD
, 2);
20894 binop(Iop_CmpEQ64Fx2
,
20897 binop(Iop_CmpUN64Fx2
,
20910 case 0x04: { /* FCLT.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);
20916 binop(Iop_CmpLT32Fx4
,
20922 case 0x01: { /* FCLT.D */
20923 DIP("FCLT.D w%d, w%d, w%d", wd
, ws
, wt
);
20924 calculateMSACSR(ws
, wt
, FCLTD
, 2);
20926 binop(Iop_CmpLT64Fx2
,
20939 case 0x05: { /* FCULT.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);
20946 binop(Iop_CmpLT32Fx4
,
20949 binop(Iop_CmpUN32Fx4
,
20955 case 0x01: { /* FCULT.D */
20956 DIP("FCULT.D w%d, w%d, w%d", wd
, ws
, wt
);
20957 calculateMSACSR(ws
, wt
, FCULTD
, 2);
20960 binop(Iop_CmpLT64Fx2
,
20963 binop(Iop_CmpUN64Fx2
,
20976 case 0x06: { /* FCLE.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);
20982 binop(Iop_CmpLE32Fx4
,
20988 case 0x01: { /* FCLE.D */
20989 DIP("FCLE.D w%d, w%d, w%d", wd
, ws
, wt
);
20990 calculateMSACSR(ws
, wt
, FCLED
, 2);
20992 binop(Iop_CmpLE64Fx2
,
21005 case 0x07: { /* FCULE.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);
21012 binop(Iop_CmpLE32Fx4
,
21015 binop(Iop_CmpUN32Fx4
,
21021 case 0x01: { /* FCULE.D */
21022 DIP("FCULE.D w%d, w%d, w%d", wd
, ws
, wt
);
21023 calculateMSACSR(ws
, wt
, FCULED
, 2);
21026 binop(Iop_CmpLE64Fx2
,
21029 binop(Iop_CmpUN64Fx2
,
21042 case 0x08: { /* FSAF.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);
21048 binop(Iop_64HLtoV128
,
21049 mkU64(0ul), mkU64(0ul)));
21053 case 0x01: { /* FSAF.D */
21054 DIP("FSAF.D w%d, w%d, w%d", wd
, ws
, wt
);
21055 calculateMSACSR(ws
, wt
, FSAFD
, 2);
21057 binop(Iop_64HLtoV128
,
21058 mkU64(0ul), mkU64(0ul)));
21069 case 0x09: { /* FSUN.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);
21075 binop(Iop_CmpUN32Fx4
,
21081 case 0x01: { /* FSUN.D */
21082 DIP("FSUN.D w%d, w%d, w%d", wd
, ws
, wt
);
21083 calculateMSACSR(ws
, wt
, FSUND
, 2);
21085 binop(Iop_CmpUN64Fx2
,
21098 case 0x0A: { /* FSEQ.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);
21104 binop(Iop_CmpEQ32Fx4
,
21110 case 0x01: { /* FSEQ.D */
21111 DIP("FSEQ.D w%d, w%d, w%d", wd
, ws
, wt
);
21112 calculateMSACSR(ws
, wt
, FSEQD
, 2);
21114 binop(Iop_CmpEQ64Fx2
,
21127 case 0x0B: { /* FSUEQ.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);
21134 binop(Iop_CmpEQ32Fx4
,
21137 binop(Iop_CmpUN32Fx4
,
21143 case 0x01: { /* FSUEQ.D */
21144 DIP("FSUEQ.D w%d, w%d, w%d", wd
, ws
, wt
);
21145 calculateMSACSR(ws
, wt
, FSUEQD
, 2);
21148 binop(Iop_CmpEQ64Fx2
,
21151 binop(Iop_CmpUN64Fx2
,
21164 case 0x0C: { /* FSLT.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);
21170 binop(Iop_CmpLT32Fx4
,
21176 case 0x01: { /* FSLT.D */
21177 DIP("FSLT.D w%d, w%d, w%d", wd
, ws
, wt
);
21178 calculateMSACSR(ws
, wt
, FSLTD
, 2);
21180 binop(Iop_CmpLT64Fx2
,
21193 case 0x0D: { /* FSULT.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);
21200 binop(Iop_CmpLT32Fx4
,
21203 binop(Iop_CmpUN32Fx4
,
21209 case 0x01: { /* FSULT.D */
21210 DIP("FSULT.D w%d, w%d, w%d", wd
, ws
, wt
);
21211 calculateMSACSR(ws
, wt
, FSULTD
, 2);
21214 binop(Iop_CmpLT64Fx2
,
21217 binop(Iop_CmpUN64Fx2
,
21230 case 0x0E: { /* FSLE.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);
21236 binop(Iop_CmpLE32Fx4
,
21242 case 0x01: { /* FSLE.D */
21243 DIP("FSLE.D w%d, w%d, w%d", wd
, ws
, wt
);
21244 calculateMSACSR(ws
, wt
, FSLED
, 2);
21246 binop(Iop_CmpLE64Fx2
,
21259 case 0x0F: { /* FSULE.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);
21266 binop(Iop_CmpLE32Fx4
,
21269 binop(Iop_CmpUN32Fx4
,
21275 case 0x01: { /* FSULE.D */
21276 DIP("FSULE.D w%d, w%d, w%d", wd
, ws
, wt
);
21277 calculateMSACSR(ws
, wt
, FSULED
, 2);
21280 binop(Iop_CmpLE64Fx2
,
21283 binop(Iop_CmpUN64Fx2
,
21303 static Int
msa_3R_1B(UInt cins
, UChar wd
, UChar ws
) { /* 3R (0x1B) */
21304 IRTemp t1
, t2
, t3
, t4
;
21308 operation
= (cins
& 0x03C00000) >> 22;
21309 df
= (cins
& 0x00200000) >> 21;
21310 wt
= (cins
& 0x001F0000) >> 16;
21312 switch (operation
) {
21313 case 0x00: { /* FADD.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();
21320 triop(Iop_Add32Fx4
, rm
,
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();
21331 triop(Iop_Add64Fx2
, rm
,
21344 case 0x01: { /* FSUB.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();
21351 triop(Iop_Sub32Fx4
, rm
,
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();
21362 triop(Iop_Sub64Fx2
, rm
,
21375 case 0x02: { /* FMUL.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();
21382 triop(Iop_Mul32Fx4
, rm
,
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();
21393 triop(Iop_Mul64Fx2
, rm
,
21406 case 0x03: { /* FDIV.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();
21413 triop(Iop_Div32Fx4
, rm
,
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();
21424 triop(Iop_Div64Fx2
, rm
,
21437 case 0x04: { /* FMADD.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();
21446 for (i
= 0; i
< 4; i
++) {
21447 tmp
[i
] = newTemp(Ity_F32
);
21449 qop(Iop_MAddF32
, rm
,
21450 unop(Iop_ReinterpI32asF32
,
21451 binop(Iop_GetElem32x4
,
21454 unop(Iop_ReinterpI32asF32
,
21455 binop(Iop_GetElem32x4
,
21458 unop(Iop_ReinterpI32asF32
,
21459 binop(Iop_GetElem32x4
,
21465 binop(Iop_64HLtoV128
,
21466 binop(Iop_32HLto64
,
21467 unop(Iop_ReinterpF32asI32
,
21469 unop(Iop_ReinterpF32asI32
,
21471 binop(Iop_32HLto64
,
21472 unop(Iop_ReinterpF32asI32
,
21474 unop(Iop_ReinterpF32asI32
,
21475 mkexpr(tmp
[0])))));
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();
21486 for (i
= 0; i
< 2; i
++) {
21487 tmp
[i
] = newTemp(Ity_F64
);
21489 qop(Iop_MAddF64
, rm
,
21490 unop(Iop_ReinterpI64asF64
,
21491 binop(Iop_GetElem64x2
,
21494 unop(Iop_ReinterpI64asF64
,
21495 binop(Iop_GetElem64x2
,
21498 unop(Iop_ReinterpI64asF64
,
21499 binop(Iop_GetElem64x2
,
21505 binop(Iop_64HLtoV128
,
21506 unop(Iop_ReinterpF64asI64
,
21508 unop(Iop_ReinterpF64asI64
,
21520 case 0x05: { /* FMSUB.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();
21529 for (i
= 0; i
< 4; i
++) {
21530 tmp
[i
] = newTemp(Ity_F32
);
21532 qop(Iop_MSubF32
, rm
,
21533 unop(Iop_ReinterpI32asF32
,
21534 binop(Iop_GetElem32x4
,
21537 unop(Iop_ReinterpI32asF32
,
21538 binop(Iop_GetElem32x4
,
21541 unop(Iop_ReinterpI32asF32
,
21542 binop(Iop_GetElem32x4
,
21548 binop(Iop_64HLtoV128
,
21549 binop(Iop_32HLto64
,
21550 unop(Iop_ReinterpF32asI32
,
21552 unop(Iop_ReinterpF32asI32
,
21554 binop(Iop_32HLto64
,
21555 unop(Iop_ReinterpF32asI32
,
21557 unop(Iop_ReinterpF32asI32
,
21558 mkexpr(tmp
[0])))));
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();
21569 for (i
= 0; i
< 2; i
++) {
21570 tmp
[i
] = newTemp(Ity_F64
);
21572 qop(Iop_MSubF64
, rm
,
21573 unop(Iop_ReinterpI64asF64
,
21574 binop(Iop_GetElem64x2
,
21577 unop(Iop_ReinterpI64asF64
,
21578 binop(Iop_GetElem64x2
,
21581 unop(Iop_ReinterpI64asF64
,
21582 binop(Iop_GetElem64x2
,
21588 binop(Iop_64HLtoV128
,
21589 unop(Iop_ReinterpF64asI64
,
21591 unop(Iop_ReinterpF64asI64
,
21603 case 0x07: { /* FEXP2.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();
21610 triop(Iop_Scale2_32Fx4
, rm
,
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();
21621 triop(Iop_Scale2_64Fx2
, rm
,
21634 case 0x08: { /* FEXDO.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
);
21642 unop(Iop_F32toF16x4_DEP
,
21645 unop(Iop_F32toF16x4_DEP
,
21648 binop(Iop_64HLtoV128
,
21649 mkexpr(t1
), mkexpr(t2
)));
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();
21662 unop(Iop_ReinterpF32asI32
,
21663 binop(Iop_F64toF32
, rm
,
21664 unop(Iop_ReinterpI64asF64
,
21668 unop(Iop_ReinterpF32asI32
,
21669 binop(Iop_F64toF32
, rm
,
21670 unop(Iop_ReinterpI64asF64
,
21671 unop(Iop_V128HIto64
,
21674 unop(Iop_ReinterpF32asI32
,
21675 binop(Iop_F64toF32
, rm
,
21676 unop(Iop_ReinterpI64asF64
,
21680 unop(Iop_ReinterpF32asI32
,
21681 binop(Iop_F64toF32
, rm
,
21682 unop(Iop_ReinterpI64asF64
,
21683 unop(Iop_V128HIto64
,
21686 binop(Iop_64HLtoV128
,
21687 binop(Iop_32HLto64
,
21688 mkexpr(t2
), mkexpr(t1
)),
21689 binop(Iop_32HLto64
,
21690 mkexpr(t4
), mkexpr(t3
))));
21701 case 0x0A: { /* FTQ.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();
21708 triop(Iop_F32x4_2toQ16x8
, rm
,
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();
21719 triop(Iop_F64x2_2toQ32x4
, rm
,
21732 case 0x0C: { /* FMIN.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);
21738 binop(Iop_Min32Fx4
,
21744 case 0x01: { /* FMIN.D */
21745 DIP("FMIN.D w%d, w%d, w%d", wd
, ws
, wt
);
21746 calculateMSACSR(ws
, wt
, FMINW
, 2);
21748 binop(Iop_Min64Fx2
,
21761 case 0x0D: { /* FMIN_A.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
);
21773 binop(Iop_64HLtoV128
,
21774 mkU64(0x7FFFFFFF7FFFFFFF),
21775 mkU64(0x7FFFFFFF7FFFFFFF))));
21779 binop(Iop_64HLtoV128
,
21780 mkU64(0x7FFFFFFF7FFFFFFF),
21781 mkU64(0x7FFFFFFF7FFFFFFF))));
21783 binop(Iop_Min32Fx4
,
21784 mkexpr(t2
), mkexpr(t1
)));
21789 binop(Iop_CmpUN32Fx4
,
21794 binop(Iop_CmpEQ32Fx4
,
21803 binop(Iop_CmpUN32Fx4
,
21806 binop(Iop_CmpLT32Fx4
,
21812 binop(Iop_CmpUN32Fx4
,
21815 binop(Iop_CmpLT32Fx4
,
21819 binop(Iop_64HLtoV128
,
21820 mkU64(0x8000000080000000),
21821 mkU64(0x8000000080000000))));
21824 mkexpr(t3
), mkexpr(t4
)));
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
);
21838 binop(Iop_64HLtoV128
,
21839 mkU64(0x7FFFFFFFFFFFFFFF),
21840 mkU64(0x7FFFFFFFFFFFFFFF))));
21844 binop(Iop_64HLtoV128
,
21845 mkU64(0x7FFFFFFFFFFFFFFF),
21846 mkU64(0x7FFFFFFFFFFFFFFF))));
21848 binop(Iop_Min64Fx2
,
21849 mkexpr(t2
), mkexpr(t1
)));
21854 binop(Iop_CmpUN64Fx2
,
21859 binop(Iop_CmpEQ64Fx2
,
21868 binop(Iop_CmpUN64Fx2
,
21871 binop(Iop_CmpLT64Fx2
,
21877 binop(Iop_CmpUN64Fx2
,
21880 binop(Iop_CmpLT64Fx2
,
21884 binop(Iop_64HLtoV128
,
21885 mkU64(0x8000000000000000),
21886 mkU64(0x8000000000000000))));
21889 mkexpr(t3
), mkexpr(t4
)));
21900 case 0x0E: { /* FMAX.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);
21906 binop(Iop_Max32Fx4
,
21912 case 0x01: { /* FMAX.D */
21913 DIP("FMAX.D w%d, w%d, w%d", wd
, ws
, wt
);
21914 calculateMSACSR(ws
, wt
, FMAXW
, 2);
21916 binop(Iop_Max64Fx2
,
21929 case 0x0F: { /* FMAX_A.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
);
21941 binop(Iop_64HLtoV128
,
21942 mkU64(0x7FFFFFFF7FFFFFFF),
21943 mkU64(0x7FFFFFFF7FFFFFFF))));
21947 binop(Iop_64HLtoV128
,
21948 mkU64(0x7FFFFFFF7FFFFFFF),
21949 mkU64(0x7FFFFFFF7FFFFFFF))));
21951 binop(Iop_Max32Fx4
,
21952 mkexpr(t2
), mkexpr(t1
)));
21957 binop(Iop_CmpUN32Fx4
,
21962 binop(Iop_CmpEQ32Fx4
,
21971 binop(Iop_CmpUN32Fx4
,
21974 binop(Iop_CmpLT32Fx4
,
21980 binop(Iop_CmpUN32Fx4
,
21983 binop(Iop_CmpLT32Fx4
,
21987 binop(Iop_64HLtoV128
,
21988 mkU64(0x8000000080000000),
21989 mkU64(0x8000000080000000))));
21992 mkexpr(t3
), mkexpr(t4
)));
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
);
22006 binop(Iop_64HLtoV128
,
22007 mkU64(0x7FFFFFFFFFFFFFFF),
22008 mkU64(0x7FFFFFFFFFFFFFFF))));
22012 binop(Iop_64HLtoV128
,
22013 mkU64(0x7FFFFFFFFFFFFFFF),
22014 mkU64(0x7FFFFFFFFFFFFFFF))));
22016 binop(Iop_Max64Fx2
,
22017 mkexpr(t2
), mkexpr(t1
)));
22022 binop(Iop_CmpUN64Fx2
,
22027 binop(Iop_CmpEQ64Fx2
,
22036 binop(Iop_CmpUN64Fx2
,
22039 binop(Iop_CmpLT64Fx2
,
22045 binop(Iop_CmpUN64Fx2
,
22048 binop(Iop_CmpLT64Fx2
,
22052 binop(Iop_64HLtoV128
,
22053 mkU64(0x8000000000000000),
22054 mkU64(0x8000000000000000))));
22057 mkexpr(t3
), mkexpr(t4
)));
22075 static Int
msa_3R_1C(UInt cins
, UChar wd
, UChar ws
) { /* 3R (0x1C) */
22076 IRTemp t1
, t2
, t3
, t4
, t5
, t6
;
22080 operation
= (cins
& 0x03C00000) >> 22;
22081 df
= (cins
& 0x00200000) >> 21;
22082 wt
= (cins
& 0x001F0000) >> 16;
22084 switch (operation
) {
22085 case 0x01: { /* FCOR.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);
22092 binop(Iop_CmpUN32Fx4
,
22098 case 0x01: { /* FCOR.D */
22099 DIP("FCOR.D w%d, w%d, w%d", wd
, ws
, wt
);
22100 calculateMSACSR(ws
, wt
, FCORD
, 2);
22103 binop(Iop_CmpUN64Fx2
,
22116 case 0x02: { /* FCUNE.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);
22123 binop(Iop_CmpEQ32Fx4
,
22129 case 0x01: { /* FCUNE.D */
22130 DIP("FCUNE.D w%d, w%d, w%d", wd
, ws
, wt
);
22131 calculateMSACSR(ws
, wt
, FCUNED
, 2);
22134 binop(Iop_CmpEQ64Fx2
,
22147 case 0x03: { /* FCNE.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);
22155 binop(Iop_CmpEQ32Fx4
,
22158 binop(Iop_CmpUN32Fx4
,
22164 case 0x01: { /* FCNE.D */
22165 DIP("FCNE.D w%d, w%d, w%d", wd
, ws
, wt
);
22166 calculateMSACSR(ws
, wt
, FCNED
, 2);
22170 binop(Iop_CmpEQ64Fx2
,
22173 binop(Iop_CmpUN64Fx2
,
22186 case 0x04: { /* MUL_Q.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
));
22196 binop(Iop_QDMulHi16Sx8
,
22197 mkexpr(t1
), mkexpr(t2
)));
22198 putWReg(wd
, mkexpr(t3
));
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
));
22210 binop(Iop_QDMulHi32Sx4
,
22211 mkexpr(t1
), mkexpr(t2
)));
22212 putWReg(wd
, mkexpr(t3
));
22223 case 0x05: { /* MADD_Q.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
);
22234 binop(Iop_SarN32x4
,
22235 binop(Iop_InterleaveEvenLanes16x8
,
22240 binop(Iop_SarN32x4
,
22241 getWReg(ws
), mkU8(16)));
22243 binop(Iop_SarN32x4
,
22244 binop(Iop_InterleaveEvenLanes16x8
,
22249 binop(Iop_SarN32x4
,
22250 getWReg(wt
), mkU8(16)));
22253 binop(Iop_ShlN32x4
,
22254 binop(Iop_SarN32x4
,
22255 binop(Iop_InterleaveEvenLanes16x8
,
22261 mkexpr(t1
), mkexpr(t3
))));
22264 binop(Iop_ShlN32x4
,
22265 binop(Iop_SarN32x4
,
22270 mkexpr(t2
), mkexpr(t4
))));
22272 binop(Iop_InterleaveEvenLanes16x8
,
22273 binop(Iop_QandQSarNnarrow32Sto16Sx4
,
22274 mkexpr(t6
), mkU8(15)),
22275 binop(Iop_QandQSarNnarrow32Sto16Sx4
,
22276 mkexpr(t5
), mkU8(15))));
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
);
22289 binop(Iop_SarN64x2
,
22290 binop(Iop_InterleaveEvenLanes32x4
,
22295 binop(Iop_SarN64x2
,
22296 getWReg(ws
), mkU8(32)));
22298 binop(Iop_SarN64x2
,
22299 binop(Iop_InterleaveEvenLanes32x4
,
22304 binop(Iop_SarN64x2
,
22305 getWReg(wt
), mkU8(32)));
22308 binop(Iop_ShlN64x2
,
22309 binop(Iop_SarN64x2
,
22310 binop(Iop_InterleaveEvenLanes32x4
,
22315 binop(Iop_64HLtoV128
,
22317 unop(Iop_V128HIto64
,
22319 unop(Iop_V128HIto64
,
22328 binop(Iop_ShlN64x2
,
22329 binop(Iop_SarN64x2
,
22333 binop(Iop_64HLtoV128
,
22335 unop(Iop_V128HIto64
,
22337 unop(Iop_V128HIto64
,
22345 binop(Iop_InterleaveEvenLanes32x4
,
22346 binop(Iop_QandQSarNnarrow64Sto32Sx2
,
22347 mkexpr(t6
), mkU8(31)),
22348 binop(Iop_QandQSarNnarrow64Sto32Sx2
,
22349 mkexpr(t5
), mkU8(31))));
22360 case 0x06: { /* MSUB_Q.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
);
22371 binop(Iop_SarN32x4
,
22372 binop(Iop_InterleaveEvenLanes16x8
,
22377 binop(Iop_SarN32x4
,
22378 getWReg(ws
), mkU8(16)));
22380 binop(Iop_SarN32x4
,
22381 binop(Iop_InterleaveEvenLanes16x8
,
22386 binop(Iop_SarN32x4
,
22387 getWReg(wt
), mkU8(16)));
22390 binop(Iop_ShlN32x4
,
22391 binop(Iop_SarN32x4
,
22392 binop(Iop_InterleaveEvenLanes16x8
,
22398 mkexpr(t1
), mkexpr(t3
))));
22401 binop(Iop_ShlN32x4
,
22402 binop(Iop_SarN32x4
,
22407 mkexpr(t2
), mkexpr(t4
))));
22409 binop(Iop_InterleaveEvenLanes16x8
,
22410 binop(Iop_QandQSarNnarrow32Sto16Sx4
,
22411 mkexpr(t6
), mkU8(15)),
22412 binop(Iop_QandQSarNnarrow32Sto16Sx4
,
22413 mkexpr(t5
), mkU8(15))));
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
);
22426 binop(Iop_SarN64x2
,
22427 binop(Iop_InterleaveEvenLanes32x4
,
22432 binop(Iop_SarN64x2
,
22433 getWReg(ws
), mkU8(32)));
22435 binop(Iop_SarN64x2
,
22436 binop(Iop_InterleaveEvenLanes32x4
,
22441 binop(Iop_SarN64x2
,
22442 getWReg(wt
), mkU8(32)));
22445 binop(Iop_ShlN64x2
,
22446 binop(Iop_SarN64x2
,
22447 binop(Iop_InterleaveEvenLanes32x4
,
22452 binop(Iop_64HLtoV128
,
22454 unop(Iop_V128HIto64
,
22456 unop(Iop_V128HIto64
,
22465 binop(Iop_ShlN64x2
,
22466 binop(Iop_SarN64x2
,
22470 binop(Iop_64HLtoV128
,
22472 unop(Iop_V128HIto64
,
22474 unop(Iop_V128HIto64
,
22482 binop(Iop_InterleaveEvenLanes32x4
,
22483 binop(Iop_QandQSarNnarrow64Sto32Sx2
,
22484 mkexpr(t6
), mkU8(31)),
22485 binop(Iop_QandQSarNnarrow64Sto32Sx2
,
22486 mkexpr(t5
), mkU8(31))));
22497 case 0x09: { /* FSOR.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);
22504 binop(Iop_CmpUN32Fx4
,
22510 case 0x01: { /* FSOR.D */
22511 DIP("FSOR.D w%d, w%d, w%d", wd
, ws
, wt
);
22512 calculateMSACSR(ws
, wt
, FSORD
, 2);
22515 binop(Iop_CmpUN64Fx2
,
22528 case 0x0A: { /* FSUNE.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);
22535 binop(Iop_CmpEQ32Fx4
,
22541 case 0x01: { /* FSUNE.D */
22542 DIP("FSUNE.D w%d, w%d, w%d", wd
, ws
, wt
);
22543 calculateMSACSR(ws
, wt
, FSUNED
, 2);
22546 binop(Iop_CmpEQ64Fx2
,
22559 case 0x0B: { /* FSNE.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);
22567 binop(Iop_CmpEQ32Fx4
,
22570 binop(Iop_CmpUN32Fx4
,
22576 case 0x01: { /* FSNE.D */
22577 DIP("FSNE.D w%d, w%d, w%d", wd
, ws
, wt
);
22578 calculateMSACSR(ws
, wt
, FSNED
, 2);
22582 binop(Iop_CmpEQ64Fx2
,
22585 binop(Iop_CmpUN64Fx2
,
22598 case 0x0C: { /* MULR_Q.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
));
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
));
22633 case 0x0D: { /* MADDR_Q.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
);
22644 binop(Iop_SarN32x4
,
22645 binop(Iop_InterleaveEvenLanes16x8
,
22650 binop(Iop_SarN32x4
,
22651 getWReg(ws
), mkU8(16)));
22653 binop(Iop_SarN32x4
,
22654 binop(Iop_InterleaveEvenLanes16x8
,
22659 binop(Iop_SarN32x4
,
22660 getWReg(wt
), mkU8(16)));
22663 binop(Iop_ShlN32x4
,
22664 binop(Iop_SarN32x4
,
22665 binop(Iop_InterleaveEvenLanes16x8
,
22671 mkexpr(t1
), mkexpr(t3
))));
22674 binop(Iop_ShlN32x4
,
22675 binop(Iop_SarN32x4
,
22680 mkexpr(t2
), mkexpr(t4
))));
22682 binop(Iop_InterleaveEvenLanes16x8
,
22683 binop(Iop_QandQRSarNnarrow32Sto16Sx4
,
22684 mkexpr(t6
), mkU8(15)),
22685 binop(Iop_QandQRSarNnarrow32Sto16Sx4
,
22686 mkexpr(t5
), mkU8(15))));
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
);
22699 binop(Iop_SarN64x2
,
22700 binop(Iop_InterleaveEvenLanes32x4
,
22705 binop(Iop_SarN64x2
,
22706 getWReg(ws
), mkU8(32)));
22708 binop(Iop_SarN64x2
,
22709 binop(Iop_InterleaveEvenLanes32x4
,
22714 binop(Iop_SarN64x2
,
22715 getWReg(wt
), mkU8(32)));
22718 binop(Iop_ShlN64x2
,
22719 binop(Iop_SarN64x2
,
22720 binop(Iop_InterleaveEvenLanes32x4
,
22725 binop(Iop_64HLtoV128
,
22727 unop(Iop_V128HIto64
,
22729 unop(Iop_V128HIto64
,
22738 binop(Iop_ShlN64x2
,
22739 binop(Iop_SarN64x2
,
22743 binop(Iop_64HLtoV128
,
22745 unop(Iop_V128HIto64
,
22747 unop(Iop_V128HIto64
,
22755 binop(Iop_InterleaveEvenLanes32x4
,
22756 binop(Iop_QandQRSarNnarrow64Sto32Sx2
,
22757 mkexpr(t6
), mkU8(31)),
22758 binop(Iop_QandQRSarNnarrow64Sto32Sx2
,
22759 mkexpr(t5
), mkU8(31))));
22770 case 0x0E: { /* MSUBR_Q.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
);
22781 binop(Iop_SarN32x4
,
22782 binop(Iop_InterleaveEvenLanes16x8
,
22787 binop(Iop_SarN32x4
,
22788 getWReg(ws
), mkU8(16)));
22790 binop(Iop_SarN32x4
,
22791 binop(Iop_InterleaveEvenLanes16x8
,
22796 binop(Iop_SarN32x4
,
22797 getWReg(wt
), mkU8(16)));
22800 binop(Iop_ShlN32x4
,
22801 binop(Iop_SarN32x4
,
22802 binop(Iop_InterleaveEvenLanes16x8
,
22808 mkexpr(t1
), mkexpr(t3
))));
22811 binop(Iop_ShlN32x4
,
22812 binop(Iop_SarN32x4
,
22817 mkexpr(t2
), mkexpr(t4
))));
22819 binop(Iop_InterleaveEvenLanes16x8
,
22820 binop(Iop_QandQRSarNnarrow32Sto16Sx4
,
22821 mkexpr(t6
), mkU8(15)),
22822 binop(Iop_QandQRSarNnarrow32Sto16Sx4
,
22823 mkexpr(t5
), mkU8(15))));
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
);
22836 binop(Iop_SarN64x2
,
22837 binop(Iop_InterleaveEvenLanes32x4
,
22842 binop(Iop_SarN64x2
,
22843 getWReg(ws
), mkU8(32)));
22845 binop(Iop_SarN64x2
,
22846 binop(Iop_InterleaveEvenLanes32x4
,
22851 binop(Iop_SarN64x2
,
22852 getWReg(wt
), mkU8(32)));
22855 binop(Iop_ShlN64x2
,
22856 binop(Iop_SarN64x2
,
22857 binop(Iop_InterleaveEvenLanes32x4
,
22862 binop(Iop_64HLtoV128
,
22864 unop(Iop_V128HIto64
,
22866 unop(Iop_V128HIto64
,
22875 binop(Iop_ShlN64x2
,
22876 binop(Iop_SarN64x2
,
22880 binop(Iop_64HLtoV128
,
22882 unop(Iop_V128HIto64
,
22884 unop(Iop_V128HIto64
,
22892 binop(Iop_InterleaveEvenLanes32x4
,
22893 binop(Iop_QandQRSarNnarrow64Sto32Sx2
,
22894 mkexpr(t6
), mkU8(31)),
22895 binop(Iop_QandQRSarNnarrow64Sto32Sx2
,
22896 mkexpr(t5
), mkU8(31))));
22914 static Int
msa_ELM(UInt cins
, UChar wd
, UChar ws
) { /* ELM (0x19) */
22915 IRTemp t1
, t2
, t3
, t4
, t5
;
22920 operation
= (cins
& 0x03C00000) >> 22;
22921 ty
= mode64
? Ity_I64
: Ity_I32
;
22923 switch ((cins
& 0x03FF0000) >> 16) {
22924 case 0x07E: /* CFCMSA */
22925 DIP("CFCMSA r%d, c%d", wd
, ws
);
22928 case 0: { /* MSAIR */
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
,
22938 /* d->nFxState = 0; */
22939 stmt(IRStmt_Dirty(d
));
22941 mkWidenFrom32(ty
, mkexpr(t1
), True
));
22945 case 1: /* MSACSR */
22947 mkWidenFrom32(ty
, getMSACSR(), True
));
22952 mkWidenFrom32(ty
, mkU32(0), False
));
22958 case 0x03E: /* CTCMSA */
22959 DIP("CTCMSA r%d, c%d", ws
, wd
);
22961 if (wd
== 1) { /* MSACSR */
22963 binop(Iop_And32
, mkNarrowTo32(ty
, getIReg(ws
)),
22964 mkU32(0x1FFFFFF)));
22969 case 0x0BE: /* MOVE.V */
22970 DIP("MOVE.V w%d, w%d", ws
, wd
);
22971 putWReg(wd
, getWReg(ws
));
22975 df
= (cins
& 0x003F0000) >> 16;
22976 if ((df
& 0x38) == 0x38) { // 11100n; dw
22979 } else if ((df
& 0x30) == 0x30) { // 1100nn; w
22982 } else if ((df
& 0x20) == 0x20) { // 100nnn; hw
22985 } else if ((df
& 0x00) == 0x00) { // 00nnnn; b
22990 switch (operation
) {
22991 case 0x00: /* SLDI.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
);
23005 (16 - n
) << 3 : 0)));
23007 binop(Iop_OrV128
, mkexpr(t1
), mkexpr(t2
)));
23010 case 0x20: /* SLDI.H */
23011 DIP("SLDI.H w%d, w%d[%d]", wd
, ws
, n
);
23014 putWReg(wd
, getWReg(ws
));
23016 t1
= newTemp(Ity_V128
);
23017 t2
= newTemp(Ity_V128
);
23019 binop(Iop_ShrN64x2
,
23023 binop(Iop_ShlN64x2
,
23025 mkU8((8 - n
) << 3)));
23034 case 0x30: /* SLDI.W */
23035 DIP("SLDI.W w%d, w%d[%d]", wd
, ws
, n
);
23038 putWReg(wd
, getWReg(ws
));
23040 t1
= newTemp(Ity_V128
);
23041 t2
= newTemp(Ity_V128
);
23043 binop(Iop_ShrN32x4
,
23047 binop(Iop_ShlN32x4
,
23049 mkU8((4 - n
) << 3)));
23058 case 0x38: /* SLDI.D */
23059 DIP("SLDI.D w%d, w%d[%d]", wd
, ws
, n
);
23062 putWReg(wd
, getWReg(ws
));
23064 t1
= newTemp(Ity_V128
);
23065 t2
= newTemp(Ity_V128
);
23067 binop(Iop_ShrN16x8
,
23071 binop(Iop_ShlN16x8
,
23073 mkU8((2 - n
) << 3)));
23088 case 0x01: /* SPLATI.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
);
23099 binop(Iop_InterleaveOddLanes8x16
,
23104 binop(Iop_InterleaveEvenLanes8x16
,
23112 binop(Iop_InterleaveOddLanes16x8
,
23113 mkexpr(t1
), mkexpr(t1
)));
23116 binop(Iop_InterleaveEvenLanes16x8
,
23117 mkexpr(t1
), mkexpr(t1
)));
23123 binop(Iop_InterleaveOddLanes32x4
,
23124 mkexpr(t2
), mkexpr(t2
)));
23127 binop(Iop_InterleaveEvenLanes32x4
,
23128 mkexpr(t2
), mkexpr(t2
)));
23134 binop(Iop_InterleaveHI64x2
,
23135 mkexpr(t3
), mkexpr(t3
)));
23138 binop(Iop_InterleaveLO64x2
,
23139 mkexpr(t3
), mkexpr(t3
)));
23141 putWReg(wd
, mkexpr(t4
));
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
);
23153 binop(Iop_InterleaveOddLanes16x8
,
23158 binop(Iop_InterleaveEvenLanes16x8
,
23166 binop(Iop_InterleaveOddLanes32x4
,
23167 mkexpr(t1
), mkexpr(t1
)));
23170 binop(Iop_InterleaveEvenLanes32x4
,
23171 mkexpr(t1
), mkexpr(t1
)));
23177 binop(Iop_InterleaveHI64x2
,
23178 mkexpr(t2
), mkexpr(t2
)));
23181 binop(Iop_InterleaveLO64x2
,
23182 mkexpr(t2
), mkexpr(t2
)));
23184 putWReg(wd
, mkexpr(t3
));
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
));
23197 binop(Iop_InterleaveOddLanes32x4
,
23198 mkexpr(t1
), mkexpr(t1
)));
23201 binop(Iop_InterleaveEvenLanes32x4
,
23202 mkexpr(t1
), mkexpr(t1
)));
23208 binop(Iop_InterleaveHI64x2
,
23209 mkexpr(t2
), mkexpr(t2
)));
23212 binop(Iop_InterleaveLO64x2
,
23213 mkexpr(t2
), mkexpr(t2
)));
23215 putWReg(wd
, mkexpr(t3
));
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
));
23227 binop(Iop_InterleaveHI64x2
,
23228 mkexpr(t1
), mkexpr(t1
)));
23231 binop(Iop_InterleaveLO64x2
,
23232 mkexpr(t1
), mkexpr(t1
)));
23234 putWReg(wd
, mkexpr(t3
));
23243 case 0x02: /* COPY_S.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
);
23324 unop(Iop_V128HIto64
,
23333 unop(Iop_V128HIto64
,
23342 unop(Iop_V128HIto64
,
23351 unop(Iop_V128HIto64
,
23360 unop(Iop_V128HIto64
,
23369 unop(Iop_V128HIto64
,
23378 unop(Iop_V128HIto64
,
23387 unop(Iop_V128HIto64
,
23393 unop(mode64
? Iop_8Sto64
: Iop_8Sto32
,
23397 case 0x20: /* COPY_S.H */
23398 DIP("COPY_S.H r%d, w%d[%d]", wd
, ws
, n
);
23399 t1
= newTemp(Ity_I16
);
23438 unop(Iop_V128HIto64
,
23446 unop(Iop_V128HIto64
,
23454 unop(Iop_V128HIto64
,
23462 unop(Iop_V128HIto64
,
23468 unop(mode64
? Iop_16Sto64
: Iop_16Sto32
,
23472 case 0x30: /* COPY_S.W */
23473 DIP("COPY_S.W r%d, w%d[%d]", wd
, ws
, n
);
23485 t2
= newTemp(Ity_I64
);
23487 unop(Iop_V128to64
, getWReg(ws
)));
23496 t2
= newTemp(Ity_I64
);
23498 unop(Iop_V128HIto64
,
23508 t2
= newTemp(Ity_I64
);
23510 unop(Iop_V128HIto64
,
23525 case 0x38: /* COPY_S.D */
23527 DIP("COPY_S.D r%d, w%d[%d]", wd
, ws
, n
);
23538 unop(Iop_V128HIto64
,
23554 case 0x03: { /* COPY_U.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
);
23638 unop(Iop_V128HIto64
,
23647 unop(Iop_V128HIto64
,
23656 unop(Iop_V128HIto64
,
23665 unop(Iop_V128HIto64
,
23674 unop(Iop_V128HIto64
,
23683 unop(Iop_V128HIto64
,
23692 unop(Iop_V128HIto64
,
23701 unop(Iop_V128HIto64
,
23707 unop(mode64
? Iop_8Uto64
: Iop_8Uto32
,
23711 case 0x20: /* COPY_U.H */
23712 DIP("COPY_U.H r%d, w%d[%d]", wd
, ws
, n
);
23713 t1
= newTemp(Ity_I16
);
23752 unop(Iop_V128HIto64
,
23760 unop(Iop_V128HIto64
,
23768 unop(Iop_V128HIto64
,
23776 unop(Iop_V128HIto64
,
23782 unop(mode64
? Iop_16Uto64
: Iop_16Uto32
,
23786 case 0x30: /* COPY_U.W */
23787 DIP("COPY_U.W r%d, w%d[%d]", wd
, ws
, n
);
23799 t2
= newTemp(Ity_I64
);
23811 t2
= newTemp(Ity_I64
);
23813 unop(Iop_V128HIto64
,
23823 t2
= newTemp(Ity_I64
);
23825 unop(Iop_V128HIto64
,
23847 case 0x04: { /* INSERT.df */
23848 t5
= newTemp(Ity_I64
);
23852 assign(t5
, mode64
? getIReg(ws
) :
23853 unop(Iop_32Uto64
, getIReg(ws
)));
23855 if (df
== 0x38) { /* INSERT.D */
23857 DIP("INSERT.D w%d[%d], r%d", wd
, n
, ws
);
23861 binop(Iop_64HLtoV128
,
23862 unop(Iop_V128HIto64
,
23867 binop(Iop_64HLtoV128
,
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
)));
23885 case 0x00: /* INSERT.B */
23886 DIP("INSERT.B w%d[%d], r%d", wd
, n
, ws
);
23898 case 0x20: /* INSERT.H */
23899 DIP("INSERT.H w%d[%d], r%d", wd
, n
, ws
);
23911 case 0x30: /* INSERT.W */
23912 DIP("INSERT.W w%d[%d], r%d", wd
, n
, ws
);
23921 mask
= 0xFFFFFFFFull
;
23929 t4
= newTemp(Ity_I64
);
23934 t3
= newTemp(Ity_I64
);
23943 binop(Iop_And64
, mkexpr(*src
), mkU64(~mask
)),
23945 binop(Iop_Shl64
, mkexpr(t5
), mkU8(n
)),
23948 binop(Iop_64HLtoV128
, mkexpr(t4
), mkexpr(t3
)));
23952 case 0x05: { /* INSVE.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
));
23963 for (i
= 0; i
< 16; i
++) {
23964 tmp
[i
] = newTemp(Ity_I8
);
23968 binop(Iop_GetElem8x16
,
23969 mkexpr(t2
), mkU8(0x0)));
23972 binop(Iop_GetElem8x16
,
23973 mkexpr(t1
), mkU8(i
)));
23977 binop(Iop_64HLtoV128
,
23978 binop(Iop_32HLto64
,
23979 binop(Iop_16HLto32
,
23986 binop(Iop_16HLto32
,
23993 binop(Iop_32HLto64
,
23994 binop(Iop_16HLto32
,
24001 binop(Iop_16HLto32
,
24007 mkexpr(tmp
[0]))))));
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
));
24020 for (i
= 0; i
< 8; i
++) {
24021 tmp
[i
] = newTemp(Ity_I16
);
24025 binop(Iop_GetElem16x8
,
24026 mkexpr(t2
), mkU8(0x0)));
24029 binop(Iop_GetElem16x8
,
24030 mkexpr(t1
), mkU8(i
)));
24034 binop(Iop_64HLtoV128
,
24035 binop(Iop_32HLto64
,
24036 binop(Iop_16HLto32
,
24039 binop(Iop_16HLto32
,
24042 binop(Iop_32HLto64
,
24043 binop(Iop_16HLto32
,
24046 binop(Iop_16HLto32
,
24048 mkexpr(tmp
[0])))));
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
));
24061 for (i
= 0; i
< 4; i
++) {
24062 tmp
[i
] = newTemp(Ity_I32
);
24066 binop(Iop_GetElem32x4
,
24067 mkexpr(t2
), mkU8(0x0)));
24070 binop(Iop_GetElem32x4
,
24071 mkexpr(t1
), mkU8(i
)));
24075 binop(Iop_64HLtoV128
,
24076 binop(Iop_32HLto64
,
24079 binop(Iop_32HLto64
,
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
));
24094 for (i
= 0; i
< 2; i
++) {
24095 tmp
[i
] = newTemp(Ity_I64
);
24099 binop(Iop_GetElem64x2
,
24100 mkexpr(t2
), mkU8(0x0)));
24103 binop(Iop_GetElem64x2
,
24104 mkexpr(t1
), mkU8(i
)));
24108 binop(Iop_64HLtoV128
,
24109 mkexpr(tmp
[1]), mkexpr(tmp
[0])));
24124 static Int
msa_VEC(UInt cins
, UChar wd
, UChar ws
) { /* VEC */
24129 vassert((cins
& 0x03000000) == 0);
24131 operation
= (cins
& 0x03E00000) >> 21;
24132 wt
= (cins
& 0x001F0000) >> 16;
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
));
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
));
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
));
24168 binop(Iop_OrV128
, mkexpr(t1
), mkexpr(t2
))));
24169 putWReg(wd
, mkexpr(t3
));
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
));
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
);
24192 getWReg(ws
), getWReg(wt
)));
24196 unop(Iop_NotV128
, getWReg(wt
))));
24197 assign(t3
, binop(Iop_OrV128
, mkexpr(t1
), mkexpr(t2
)));
24198 putWReg(wd
, mkexpr(t3
));
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
);
24209 getWReg(wd
), getWReg(wt
)));
24213 unop(Iop_NotV128
, getWReg(wt
))));
24214 assign(t3
, binop(Iop_OrV128
, mkexpr(t1
), mkexpr(t2
)));
24215 putWReg(wd
, mkexpr(t3
));
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
);
24226 getWReg(wd
), getWReg(wt
)));
24230 unop(Iop_NotV128
, getWReg(wd
))));
24231 assign(t3
, binop(Iop_OrV128
, mkexpr(t1
), mkexpr(t2
)));
24232 putWReg(wd
, mkexpr(t3
));
24243 static Int
msa_2R(UInt cins
, UChar wd
, UChar ws
) { /* 2R */
24244 IRTemp t1
, t2
, t3
, t4
;
24249 vassert((cins
& 0x00200000) == 0);
24251 operation
= (cins
& 0x03FC0000) >> 18;
24252 df
= (cins
& 0x00030000) >> 16;
24253 ty
= mode64
? Ity_I64
: Ity_I32
;
24255 switch (operation
) {
24256 case 0xC0: { /* FILL.df */
24257 t1
= newTemp(Ity_I64
);
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
)));
24267 binop(Iop_8HLto16
, mkexpr(t4
), mkexpr(t4
)));
24269 binop(Iop_16HLto32
, mkexpr(t3
), mkexpr(t3
)));
24271 binop(Iop_32HLto64
, mkexpr(t2
), mkexpr(t2
)));
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
)));
24280 binop(Iop_16HLto32
, mkexpr(t3
), mkexpr(t3
)));
24282 binop(Iop_32HLto64
, mkexpr(t2
), mkexpr(t2
)));
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
)));
24290 binop(Iop_32HLto64
, mkexpr(t2
), mkexpr(t2
)));
24293 case 0x03: /* FILL.D */
24295 DIP("FILL.W w%d, r%d", wd
, ws
);
24296 t2
= newTemp(Ity_I32
);
24297 assign(t1
, getIReg(ws
));
24309 binop(Iop_64HLtoV128
, mkexpr(t1
), mkexpr(t1
)));
24313 case 0xC1: { /* PCNT.df */
24315 case 0x00: /* PCNT.B */
24316 DIP("PCNT.B w%d, r%d", wd
, ws
);
24318 unop(Iop_Cnt8x16
, getWReg(ws
)));
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
)));
24330 binop(Iop_64HLtoV128
,
24331 mkU64(0x00FF00FF00FF00FFULL
),
24332 mkU64(0x00FF00FF00FF00FFULL
))),
24334 binop(Iop_ShrN16x8
,
24335 mkexpr(t1
), mkU8(8)),
24336 binop(Iop_64HLtoV128
,
24337 mkU64(0x00FF00FF00FF00FFULL
),
24338 mkU64(0x00FF00FF00FF00FFULL
)))));
24339 putWReg(wd
, mkexpr(t2
));
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
)));
24352 binop(Iop_64HLtoV128
,
24353 mkU64(0x00FF00FF00FF00FFULL
),
24354 mkU64(0x00FF00FF00FF00FFULL
))),
24356 binop(Iop_ShrN32x4
,
24357 mkexpr(t1
), mkU8(8)),
24358 binop(Iop_64HLtoV128
,
24359 mkU64(0x00FF00FF00FF00FFULL
),
24360 mkU64(0x00FF00FF00FF00FFULL
)))));
24365 binop(Iop_64HLtoV128
,
24366 mkU64(0x0000FFFF0000FFFFULL
),
24367 mkU64(0x0000FFFF0000FFFFULL
))),
24369 binop(Iop_ShrN32x4
,
24370 mkexpr(t2
), mkU8(16)),
24371 binop(Iop_64HLtoV128
,
24372 mkU64(0x0000FFFF0000FFFFULL
),
24373 mkU64(0x0000FFFF0000FFFFULL
)))));
24374 putWReg(wd
, mkexpr(t3
));
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
)));
24388 binop(Iop_64HLtoV128
,
24389 mkU64(0x00FF00FF00FF00FFULL
),
24390 mkU64(0x00FF00FF00FF00FFULL
))),
24392 binop(Iop_ShrN64x2
,
24393 mkexpr(t1
), mkU8(8)),
24394 binop(Iop_64HLtoV128
,
24395 mkU64(0x00FF00FF00FF00FFULL
),
24396 mkU64(0x00FF00FF00FF00FFULL
)))));
24401 binop(Iop_64HLtoV128
,
24402 mkU64(0x0000FFFF0000FFFFULL
),
24403 mkU64(0x0000FFFF0000FFFFULL
))),
24405 binop(Iop_ShrN64x2
,
24406 mkexpr(t2
), mkU8(16)),
24407 binop(Iop_64HLtoV128
,
24408 mkU64(0x0000FFFF0000FFFFULL
),
24409 mkU64(0x0000FFFF0000FFFFULL
)))));
24414 binop(Iop_64HLtoV128
,
24415 mkU64(0x00000000FFFFFFFFULL
),
24416 mkU64(0x00000000FFFFFFFFULL
))),
24418 binop(Iop_ShrN64x2
,
24419 mkexpr(t3
), mkU8(32)),
24420 binop(Iop_64HLtoV128
,
24421 mkU64(0x00000000FFFFFFFFULL
),
24422 mkU64(0x00000000FFFFFFFFULL
)))));
24423 putWReg(wd
, mkexpr(t4
));
24433 case 0xC2: { /* NLOC.df */
24435 case 0x00: /* NLOC.B */
24436 DIP("NLOC.B w%d, w%d", wd
, ws
);
24438 unop(Iop_Cls8x16
, getWReg(ws
)));
24441 case 0x01: /* NLOC.H */
24442 DIP("NLOC.H w%d, w%d", wd
, ws
);
24444 unop(Iop_Cls16x8
, getWReg(ws
)));
24447 case 0x02: /* NLOC.W */
24448 DIP("NLOC.W w%d, w%d", wd
, ws
);
24450 unop(Iop_Cls32x4
, getWReg(ws
)));
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
)));
24467 case 0xC3: { /* NLZC.df */
24469 case 0x00: /* NLZC.B */
24470 DIP("NLZC.W w%d, w%d", wd
, ws
);
24472 unop(Iop_Clz8x16
, getWReg(ws
)));
24475 case 0x01: /* NLZC.H */
24476 DIP("NLZC.H w%d, w%d", wd
, ws
);
24478 unop(Iop_Clz16x8
, getWReg(ws
)));
24481 case 0x02: /* NLZC.W */
24482 DIP("NLZC.W w%d, w%d", wd
, ws
);
24484 unop(Iop_Clz32x4
, getWReg(ws
)));
24487 case 0x03: {/* NLZC.D */
24489 unop(Iop_Clz64x2
, getWReg(ws
)));
24507 static Int
msa_2RF(UInt cins
, UChar wd
, UChar ws
) { /* 2RF */
24508 IRTemp t1
, t2
, t3
, t4
, t5
;
24512 operation
= (cins
& 0x03FE0000) >> 17;
24513 df
= (cins
& 0x00010000) >> 16;
24514 wt
= (cins
& 0x001F0000) >> 16;
24516 switch (operation
) {
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
);
24527 case 0x00: { /* FCLASS.W */
24528 DIP("FCLASS.W w%d, w%d", wd
, ws
);
24530 binop(Iop_CmpEQ32x4
,
24533 binop(Iop_64HLtoV128
,
24534 mkU64(0x7F8000007F800000ull
),
24535 mkU64(0x7F8000007F800000ull
))),
24536 binop(Iop_64HLtoV128
,
24537 mkU64(0ull), mkU64(0ull))));
24539 binop(Iop_CmpEQ32x4
,
24542 binop(Iop_64HLtoV128
,
24543 mkU64(0x7F8000007F800000ull
),
24544 mkU64(0x7F8000007F800000ull
))),
24545 binop(Iop_64HLtoV128
,
24546 mkU64(0x7F8000007F800000ull
),
24547 mkU64(0x7F8000007F800000ull
))));
24549 binop(Iop_SarN32x4
,
24550 getWReg(ws
), mkU8(31)));
24552 binop(Iop_CmpEQ32x4
,
24555 binop(Iop_64HLtoV128
,
24556 mkU64(0x0040000000400000ull
),
24557 mkU64(0x0040000000400000ull
))),
24558 binop(Iop_64HLtoV128
,
24559 mkU64(0x0040000000400000ull
),
24560 mkU64(0x0040000000400000ull
))));
24562 binop(Iop_CmpEQ32x4
,
24565 binop(Iop_64HLtoV128
,
24566 mkU64(0x007FFFFF007FFFFFULL
),
24567 mkU64(0x007FFFFF007FFFFFULL
))),
24568 binop(Iop_64HLtoV128
,
24569 mkU64(0ull), mkU64(0ull))));
24577 binop(Iop_64HLtoV128
,
24578 mkU64(0x100000001ull
),
24579 mkU64(0x100000001ull
)))),
24586 binop(Iop_64HLtoV128
,
24587 mkU64(0x800000008ull
),
24588 mkU64(0x800000008ull
))),
24592 binop(Iop_64HLtoV128
,
24593 mkU64(0x400000004ull
),
24594 mkU64(0x400000004ull
))))),
24601 binop(Iop_64HLtoV128
,
24602 mkU64(0x200000002ull
),
24603 mkU64(0x200000002ull
)))))),
24607 binop(Iop_64HLtoV128
,
24608 mkU64(0x200000002ull
),
24609 mkU64(0x200000002ull
))),
24613 binop(Iop_64HLtoV128
,
24614 mkU64(0x600000006ull
),
24615 mkU64(0x600000006ull
))))));
24620 binop(Iop_CmpEQ32x4
,
24622 binop(Iop_64HLtoV128
,
24628 binop(Iop_64HLtoV128
,
24629 mkU64(0x100000001ull
),
24630 mkU64(0x100000001ull
))),
24632 unop(Iop_NotV128
, mkexpr(t3
)),
24633 binop(Iop_64HLtoV128
,
24634 mkU64(0x200000002ull
),
24635 mkU64(0x200000002ull
)))))));
24639 case 0x01: { /* FCLASS.D */
24640 DIP("FCLASS.D w%d, w%d", wd
, ws
);
24642 binop(Iop_CmpEQ64x2
,
24645 binop(Iop_64HLtoV128
,
24646 mkU64(0x7FF0000000000000ull
),
24647 mkU64(0x7FF0000000000000ull
))),
24648 binop(Iop_64HLtoV128
,
24649 mkU64(0ull), mkU64(0ull))));
24651 binop(Iop_CmpEQ64x2
,
24654 binop(Iop_64HLtoV128
,
24655 mkU64(0x7FF0000000000000ull
),
24656 mkU64(0x7FF0000000000000ull
))),
24657 binop(Iop_64HLtoV128
,
24658 mkU64(0x7FF0000000000000ull
),
24659 mkU64(0x7FF0000000000000ull
))));
24661 binop(Iop_SarN64x2
,
24662 getWReg(ws
), mkU8(63)));
24664 binop(Iop_CmpEQ64x2
,
24667 binop(Iop_64HLtoV128
,
24668 mkU64(0x0008000000000000ull
),
24669 mkU64(0x0008000000000000ull
))),
24670 binop(Iop_64HLtoV128
,
24671 mkU64(0x0008000000000000ull
),
24672 mkU64(0x0008000000000000ull
))));
24674 binop(Iop_CmpEQ64x2
,
24677 binop(Iop_64HLtoV128
,
24678 mkU64(0x000FFFFFFFFFFFFFULL
),
24679 mkU64(0x000FFFFFFFFFFFFFULL
))),
24680 binop(Iop_64HLtoV128
,
24681 mkU64(0ull), mkU64(0ull))));
24689 binop(Iop_64HLtoV128
,
24698 binop(Iop_64HLtoV128
,
24704 binop(Iop_64HLtoV128
,
24713 binop(Iop_64HLtoV128
,
24719 binop(Iop_64HLtoV128
,
24725 binop(Iop_64HLtoV128
,
24732 binop(Iop_CmpEQ64x2
,
24734 binop(Iop_64HLtoV128
,
24740 binop(Iop_64HLtoV128
,
24746 binop(Iop_64HLtoV128
,
24759 case 0x191: { /* FTRUNC_S.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_F32toI32Sx4_RZ
, getWReg(ws
)));
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
);
24777 binop(Iop_CmpUN64Fx2
,
24780 binop(Iop_Max64Fx2
,
24782 binop(Iop_64HLtoV128
,
24783 mkU64(0xC3E0000000000000),
24784 mkU64(0xC3E0000000000000)))));
24786 binop(Iop_F64toI64S
, mkU32(0x3),
24787 unop(Iop_ReinterpI64asF64
,
24788 unop(Iop_V128to64
, mkexpr(t3
)))));
24790 binop(Iop_F64toI64S
, mkU32(0x3),
24791 unop(Iop_ReinterpI64asF64
,
24792 unop(Iop_V128HIto64
, mkexpr(t3
)))));
24794 binop(Iop_64HLtoV128
,
24795 mkexpr(t2
), mkexpr(t1
)));
24806 case 0x192: { /* FTRUNC_U.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_F32toI32Ux4_RZ
, getWReg(ws
)));
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
);
24821 binop(Iop_F64toI64U
,
24823 unop(Iop_ReinterpI64asF64
,
24827 binop(Iop_F64toI64U
,
24829 unop(Iop_ReinterpI64asF64
,
24830 unop(Iop_V128HIto64
,
24833 binop(Iop_64HLtoV128
,
24834 mkexpr(t2
), mkexpr(t1
)));
24845 case 0x193: { /* FSQRT.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
)));
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
)));
24870 case 0x194: { /* FRSQRT.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
)));
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
)));
24893 case 0x195: { /* FRCP.df */
24894 switch (df
) { /* FRCP.W */
24896 DIP("FRCP.W w%d, w%d", wd
, ws
);
24897 calculateMSACSR(ws
, wd
, FRCPW
, 1);
24898 putWReg(wd
, unop(Iop_RecipEst32Fx4
, getWReg(ws
)));
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
)));
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
));
24925 case 0x00: { /* FRINT.W */
24926 DIP("FRINT.W w%d, w%d", wd
, ws
);
24927 calculateMSACSR(ws
, wt
, FRINTW
, 1);
24930 binop(Iop_CmpLT32Fx4
,
24932 binop(Iop_64HLtoV128
,
24933 mkU64(0xCF000000CF000000ull
),
24934 mkU64(0xCF000000CF000000ull
))),
24935 binop(Iop_CmpLT32Fx4
,
24936 binop(Iop_64HLtoV128
,
24937 mkU64(0x4F0000004F000000ull
),
24938 mkU64(0x4F0000004F000000ull
)),
24941 binop(Iop_CmpEQ32x4
,
24944 binop(Iop_64HLtoV128
,
24945 mkU64(0x0040000000400000ull
),
24946 mkU64(0x0040000000400000ull
))),
24947 binop(Iop_64HLtoV128
,
24948 mkU64(0x0040000000400000ull
),
24949 mkU64(0x0040000000400000ull
))));
24951 binop(Iop_CmpUN32Fx4
,
24952 mkexpr(t1
), mkexpr(t1
)));
24956 for (i
= 0; i
< 4; i
++) {
24957 tmp
[i
] = newTemp(Ity_I32
);
24959 unop(Iop_ReinterpF32asI32
,
24960 binop(Iop_RoundF32toInt
, rm
,
24961 unop(Iop_ReinterpI32asF32
,
24962 binop(Iop_GetElem32x4
,
24963 mkexpr(t1
), mkU8(i
))))));
24981 binop(Iop_64HLtoV128
,
24982 mkU64(0x7FBFFFFF7FBFFFFF),
24983 mkU64(0x7FBFFFFF7FBFFFFF)))),
24990 binop(Iop_64HLtoV128
,
24991 binop(Iop_32HLto64
,
24994 binop(Iop_32HLto64
,
24999 binop(Iop_64HLtoV128
,
25000 mkU64(0x8000000080000000ull
),
25001 mkU64(0x8000000080000000ull
)))
25006 case 0x01: { /* FRINT.D */
25007 DIP("FRINT.D w%d, w%d", wd
, ws
);
25008 calculateMSACSR(ws
, wt
, FRINTD
, 1);
25011 binop(Iop_CmpLT64Fx2
,
25013 binop(Iop_64HLtoV128
,
25014 mkU64(0xC3E0000000000000ull
),
25015 mkU64(0xC3E0000000000000ull
))),
25016 binop(Iop_CmpLT64Fx2
,
25017 binop(Iop_64HLtoV128
,
25018 mkU64(0x43E0000000000000ull
),
25019 mkU64(0x43E0000000000000ull
)),
25022 binop(Iop_CmpEQ64x2
,
25025 binop(Iop_64HLtoV128
,
25026 mkU64(0x0008000000000000ull
),
25027 mkU64(0x0008000000000000ull
))),
25028 binop(Iop_64HLtoV128
,
25029 mkU64(0x0008000000000000ull
),
25030 mkU64(0x0008000000000000ull
))));
25032 binop(Iop_CmpUN64Fx2
,
25033 mkexpr(t1
), mkexpr(t1
)));
25037 for (i
= 0; i
< 2; i
++) {
25038 tmp
[i
] = newTemp(Ity_I64
);
25040 unop(Iop_ReinterpF64asI64
,
25041 binop(Iop_RoundF64toInt
, rm
,
25042 unop(Iop_ReinterpI64asF64
,
25043 binop(Iop_GetElem64x2
,
25044 mkexpr(t1
), mkU8(i
))))));
25062 binop(Iop_64HLtoV128
,
25063 mkU64(0x7FF7FFFFFFFFFFFF),
25064 mkU64(0x7FF7FFFFFFFFFFFF)))),
25071 binop(Iop_64HLtoV128
,
25076 binop(Iop_64HLtoV128
,
25077 mkU64(0x8000000000000000ull
),
25078 mkU64(0x8000000000000000ull
))
25090 case 0x197: { /* FLOG2.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
)));
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
)));
25114 case 0x198: { /* FEXUPL.df */
25116 case 0x00: { /* FEXUPL.W */
25117 DIP("FEXUPL.W w%d, w%d", wd
, ws
);
25118 calculateMSACSR(ws
, wt
, FEXUPLW
, 1);
25120 unop(Iop_F16toF32x4
,
25121 unop(Iop_V128HIto64
,
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
);
25132 unop(Iop_ReinterpF64asI64
,
25134 unop(Iop_ReinterpI32asF32
,
25136 unop(Iop_V128HIto64
,
25139 unop(Iop_ReinterpF64asI64
,
25141 unop(Iop_ReinterpI32asF32
,
25143 unop(Iop_V128HIto64
,
25146 binop(Iop_64HLtoV128
,
25147 mkexpr(t2
), mkexpr(t1
)));
25158 case 0x199: { /* FEXUPR.df */
25160 case 0x00: { /* FEXUPR.W */
25161 DIP("FEXUPR.W w%d, w%d", wd
, ws
);
25162 calculateMSACSR(ws
, wt
, FEXUPRW
, 1);
25164 unop(Iop_F16toF32x4
,
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
);
25176 unop(Iop_ReinterpF64asI64
,
25178 unop(Iop_ReinterpI32asF32
,
25183 unop(Iop_ReinterpF64asI64
,
25185 unop(Iop_ReinterpI32asF32
,
25190 binop(Iop_64HLtoV128
,
25191 mkexpr(t2
), mkexpr(t1
)));
25202 case 0x19A: { /* FFQL.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();
25212 binop(Iop_SarN32x4
,
25213 binop(Iop_InterleaveHI16x8
,
25218 binop(Iop_32HLto64
,
25219 unop(Iop_ReinterpF32asI32
,
25220 binop(Iop_I32StoF32
, rm
,
25221 binop(Iop_GetElem32x4
,
25224 unop(Iop_ReinterpF32asI32
,
25225 binop(Iop_I32StoF32
, rm
,
25226 binop(Iop_GetElem32x4
,
25230 binop(Iop_32HLto64
,
25231 unop(Iop_ReinterpF32asI32
,
25232 binop(Iop_I32StoF32
, rm
,
25233 binop(Iop_GetElem32x4
,
25236 unop(Iop_ReinterpF32asI32
,
25237 binop(Iop_I32StoF32
, rm
,
25238 binop(Iop_GetElem32x4
,
25242 triop(Iop_Div32Fx4
, rm
,
25243 binop(Iop_64HLtoV128
,
25244 mkexpr(t3
), mkexpr(t2
)),
25245 binop(Iop_64HLtoV128
,
25246 mkU64(0x4700000047000000),
25247 mkU64(0x4700000047000000))));
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();
25259 binop(Iop_SarN64x2
,
25260 binop(Iop_InterleaveHI32x4
,
25265 unop(Iop_ReinterpF64asI64
,
25266 binop(Iop_I64StoF64
, rm
,
25270 unop(Iop_ReinterpF64asI64
,
25271 binop(Iop_I64StoF64
, rm
,
25272 unop(Iop_V128HIto64
,
25275 triop(Iop_Div64Fx2
, rm
,
25276 binop(Iop_64HLtoV128
,
25277 mkexpr(t3
), mkexpr(t2
)),
25278 binop(Iop_64HLtoV128
,
25279 mkU64(0x41E0000000000000),
25280 mkU64(0x41E0000000000000))));
25291 case 0x19B: { /* FFQR.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();
25301 binop(Iop_SarN32x4
,
25302 binop(Iop_InterleaveLO16x8
,
25307 binop(Iop_32HLto64
,
25308 unop(Iop_ReinterpF32asI32
,
25309 binop(Iop_I32StoF32
, rm
,
25310 binop(Iop_GetElem32x4
,
25313 unop(Iop_ReinterpF32asI32
,
25314 binop(Iop_I32StoF32
, rm
,
25315 binop(Iop_GetElem32x4
,
25319 binop(Iop_32HLto64
,
25320 unop(Iop_ReinterpF32asI32
,
25321 binop(Iop_I32StoF32
, rm
,
25322 binop(Iop_GetElem32x4
,
25325 unop(Iop_ReinterpF32asI32
,
25326 binop(Iop_I32StoF32
, rm
,
25327 binop(Iop_GetElem32x4
,
25331 triop(Iop_Div32Fx4
, rm
,
25332 binop(Iop_64HLtoV128
,
25333 mkexpr(t3
), mkexpr(t2
)),
25334 binop(Iop_64HLtoV128
,
25335 mkU64(0x4700000047000000),
25336 mkU64(0x4700000047000000))));
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();
25348 binop(Iop_SarN64x2
,
25349 binop(Iop_InterleaveLO32x4
,
25354 unop(Iop_ReinterpF64asI64
,
25355 binop(Iop_I64StoF64
, rm
,
25359 unop(Iop_ReinterpF64asI64
,
25360 binop(Iop_I64StoF64
, rm
,
25361 unop(Iop_V128HIto64
,
25364 triop(Iop_Div64Fx2
, rm
,
25365 binop(Iop_64HLtoV128
,
25366 mkexpr(t3
), mkexpr(t2
)),
25367 binop(Iop_64HLtoV128
,
25368 mkU64(0x41E0000000000000),
25369 mkU64(0x41E0000000000000))));
25380 case 0x19C: { /* FTINT_S.df */
25381 switch (df
) { /* FTINT_S.W */
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
);
25392 binop(Iop_CmpUN32Fx4
,
25395 binop(Iop_Max32Fx4
,
25397 binop(Iop_64HLtoV128
,
25398 mkU64(0xCF000000CF000000),
25399 mkU64(0xCF000000CF000000)))));
25400 IRExpr
*rm
= get_IR_roundingmode_MSA();
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))))));
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))))));
25422 binop(Iop_64HLtoV128
,
25423 mkexpr(t2
), mkexpr(t1
)));
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
);
25436 binop(Iop_CmpUN64Fx2
,
25439 binop(Iop_Max64Fx2
,
25441 binop(Iop_64HLtoV128
,
25442 mkU64(0xC3E0000000000000),
25443 mkU64(0xC3E0000000000000)))));
25444 IRExpr
*rm
= get_IR_roundingmode_MSA();
25446 binop(Iop_F64toI64S
, rm
,
25447 unop(Iop_ReinterpI64asF64
,
25448 unop(Iop_V128to64
, mkexpr(t3
)))));
25450 binop(Iop_F64toI64S
, rm
,
25451 unop(Iop_ReinterpI64asF64
,
25452 unop(Iop_V128HIto64
, mkexpr(t3
)))));
25454 binop(Iop_64HLtoV128
,
25455 mkexpr(t2
), mkexpr(t1
)));
25466 case 0x19D: {/* FTINT_U.df */
25467 switch (df
) { /* FTINT_U.W */
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();
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))))));
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))))));
25498 binop(Iop_SarN32x4
,
25502 binop(Iop_CmpLT32Fx4
,
25504 binop(Iop_64HLtoV128
,
25505 mkU64(0x4EFFFFFF4EFFFFFF),
25506 mkU64(0x4EFFFFFF4EFFFFFF))));
25512 binop(Iop_64HLtoV128
,
25517 unop(Iop_NotV128
, mkexpr(t4
)),
25518 unop(Iop_F32toI32Ux4_RZ
,
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();
25530 binop(Iop_F64toI64U
, rm
,
25531 unop(Iop_ReinterpI64asF64
,
25535 binop(Iop_F64toI64U
, rm
,
25536 unop(Iop_ReinterpI64asF64
,
25537 unop(Iop_V128HIto64
,
25540 binop(Iop_64HLtoV128
,
25541 mkexpr(t2
), mkexpr(t1
)));
25552 case 0x19E: { /* FFINT_S.df */
25553 t1
= newTemp(Ity_V128
);
25554 assign(t1
, getWReg(ws
));
25555 IRExpr
*rm
= get_IR_roundingmode_MSA();
25558 case 0x00: { /* FFINT_S.W */
25559 DIP("FFINT_S.W w%d, w%d", wd
, ws
);
25560 calculateMSACSR(ws
, wt
, FFINTSW
, 1);
25564 for (i
= 0; i
< 4; i
++) {
25565 tmp
[i
] = newTemp(Ity_F32
);
25567 binop(Iop_I32StoF32
, rm
,
25568 binop(Iop_GetElem32x4
,
25569 mkexpr(t1
), mkU8(i
))));
25573 binop(Iop_64HLtoV128
,
25574 binop(Iop_32HLto64
,
25575 unop(Iop_ReinterpF32asI32
,
25577 unop(Iop_ReinterpF32asI32
,
25579 binop(Iop_32HLto64
,
25580 unop(Iop_ReinterpF32asI32
,
25582 unop(Iop_ReinterpF32asI32
,
25583 mkexpr(tmp
[0])))));
25587 case 0x01: { /* FFINT_S.D */
25588 DIP("FFINT_S.D w%d, w%d", wd
, ws
);
25589 calculateMSACSR(ws
, wt
, FFINTSD
, 1);
25593 for (i
= 0; i
< 2; i
++) {
25594 tmp
[i
] = newTemp(Ity_F64
);
25596 binop(Iop_I64StoF64
, rm
,
25597 binop(Iop_GetElem64x2
,
25598 mkexpr(t1
), mkU8(i
))));
25602 binop(Iop_64HLtoV128
,
25603 unop(Iop_ReinterpF64asI64
,
25605 unop(Iop_ReinterpF64asI64
,
25617 case 0x19F: { /* FFINT_U.df */
25618 IRExpr
*rm
= get_IR_roundingmode_MSA();
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_I32UtoF32x4_DEP
, getWReg(ws
)));
25628 case 0x01: { /* FFINT_U.D */
25629 DIP("FFINT_U.D w%d, w%d",
25631 calculateMSACSR(ws
, wt
,
25633 t1
= newTemp(Ity_I64
);
25634 t2
= newTemp(Ity_I64
);
25636 unop(Iop_ReinterpF64asI64
,
25637 binop(Iop_I64UtoF64
, rm
,
25641 unop(Iop_ReinterpF64asI64
,
25642 binop(Iop_I64UtoF64
, rm
,
25643 unop(Iop_V128HIto64
,
25646 binop(Iop_64HLtoV128
,
25647 mkexpr(t2
), mkexpr(t1
)));
25665 static Int
msa_MI10_load(UInt cins
, UChar wd
, UChar ws
) { /* MI10 (0x20) */
25670 i10
= (cins
& 0x03FF0000) >> 16;
25671 df
= cins
& 0x00000003;
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
)));
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)
25688 unop(Iop_Reverse8sIn16_x8
,
25689 load(Ity_V128
, mkexpr(t1
))));
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)
25701 unop(Iop_Reverse8sIn32_x4
,
25702 load(Ity_V128
, mkexpr(t1
))));
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)
25714 unop(Iop_Reverse8sIn64_x2
,
25715 load(Ity_V128
, mkexpr(t1
))));
25727 static Int
msa_MI10_store(UInt cins
, UChar wd
, UChar ws
) { /* MI10 (0x24) */
25732 df
= cins
& 0x00000003;
25733 i10
= (cins
& 0x03FF0000) >> 16;
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
));
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)
25750 unop(Iop_Reverse8sIn16_x8
, getWReg(wd
)));
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)
25762 unop(Iop_Reverse8sIn32_x4
, getWReg(wd
)));
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)
25774 unop(Iop_Reverse8sIn64_x2
, getWReg(wd
)));
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 /*------------------------------------------------------------*/
25793 static Int
disMSAInstr_MIPS_WRK ( UInt cins
) {
25794 UChar minor_opcode
, wd
, ws
;
25797 vassert((cins
& 0xFC000000) == 0x78000000);
25799 minor_opcode
= (cins
& 0x20) > 0 ? (cins
& 0x3C) : (cins
& 0x3F);
25800 wd
= (cins
& 0x000007C0) >> 6;
25801 ws
= (cins
& 0x0000F800) >> 11;
25803 switch (minor_opcode
) {
25805 return msa_I8_logical(cins
, wd
, ws
);
25808 return msa_I8_branch(cins
, wd
, ws
);
25811 return msa_I8_shift(cins
, wd
, ws
);
25814 return msa_I5_06(cins
, wd
, ws
);
25817 return msa_I5_07(cins
, wd
, ws
);
25820 return msa_BIT_09(cins
, wd
, ws
);
25823 return msa_BIT_0A(cins
, wd
, ws
);
25826 return msa_3R_0D(cins
, wd
, ws
);
25829 return msa_3R_0E(cins
, wd
, ws
);
25832 return msa_3R_0F(cins
, wd
, ws
);
25835 return msa_3R_10(cins
, wd
, ws
);
25838 return msa_3R_11(cins
, wd
, ws
);
25841 return msa_3R_12(cins
, wd
, ws
);
25844 return msa_3R_13(cins
, wd
, ws
);
25847 return msa_3R_14(cins
, wd
, ws
);
25850 return msa_3R_15(cins
, wd
, ws
);
25853 return msa_ELM(cins
, wd
, ws
);
25856 return msa_3R_1A(cins
, wd
, ws
);
25859 return msa_3R_1B(cins
, wd
, ws
);
25862 return msa_3R_1C(cins
, wd
, ws
);
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
);
25870 return msa_2RF(cins
, wd
, ws
);
25873 return msa_MI10_load(cins
, wd
, ws
);
25876 return msa_MI10_store(cins
, wd
, ws
);
25882 /*------------------------------------------------------------*/
25883 /*--- Disassemble a single instruction ---*/
25884 /*------------------------------------------------------------*/
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
25891 static DisResult
disInstr_MIPS_WRK ( Bool(*resteerOkFn
) (/*opaque */void *,
25894 void* callback_opaque
,
25896 const VexArchInfo
* archinfo
,
25897 const VexAbiInfo
* abiinfo
,
25900 IRTemp t0
, t1
= 0, t2
, t3
, t4
, t5
, t6
, t7
;
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 */
25909 static IRExpr
*lastn
= NULL
; /* last jump addr */
25910 static IRStmt
*bstmt
= NULL
; /* branch (Exit) stmt */
25912 /* The running delta */
25913 Int delta
= (Int
) delta64
;
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
;
25919 /* Are we in a delay slot ? */
25920 Bool delay_slot_branch
, likely_delay_slot
, delay_slot_jump
;
25922 /* Set result defaults. */
25923 dres
.whatNext
= Dis_Continue
;
25925 dres
.continueAt
= 0;
25926 dres
.jk_StopHere
= Ijk_INVALID
;
25927 dres
.hint
= Dis_HintNone
;
25929 delay_slot_branch
= likely_delay_slot
= delay_slot_jump
= False
;
25931 const UChar
*code
= guest_code
+ delta
;
25932 cins
= getUInt(code
);
25933 DIP("\t0x%llx:\t0x%08x\t", (Addr64
)guest_PC_curr_instr
, cins
);
25936 if (branch_or_jump(guest_code
+ delta
- 4)) {
25937 if (lastn
== NULL
&& bstmt
== NULL
) {
25940 dres
.whatNext
= Dis_StopHere
;
25941 if (lastn
!= NULL
) {
25942 delay_slot_jump
= True
;
25943 } else if (bstmt
!= NULL
) {
25944 delay_slot_branch
= True
;
25949 if (branch_or_link_likely(guest_code
+ delta
- 4)) {
25950 likely_delay_slot
= True
;
25954 /* Spot "Special" instructions (see comment at top of file). */
25956 /* Spot the 16-byte preamble:
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 )");
25980 putPC(mkU64(guest_PC_curr_instr
+ 20));
25982 putPC(mkU32(guest_PC_curr_instr
+ 20));
25983 dres
.jk_StopHere
= Ijk_ClientReq
;
25984 dres
.whatNext
= Dis_StopHere
;
25986 goto decode_success
;
25987 } else if (getUInt(code
+ 16) == 0x01ce7025 /* or $14, $14, $14 */ ) {
25988 /* $11 = guest_NRADDR */
25989 DIP("$11 = guest_NRADDR");
25993 putIReg(11, IRExpr_Get(offsetof(VexGuestMIPS64State
,
25994 guest_NRADDR
), Ity_I64
));
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");
26003 putIReg(31, mkU64(guest_PC_curr_instr
+ 20));
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 */ ) {
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
);
26019 stmt(IRStmt_Put(offsetof(VexGuestMIPS64State
, guest_CMSTART
),
26020 mkU64(guest_PC_curr_instr
)));
26021 stmt(IRStmt_Put(offsetof(VexGuestMIPS64State
, guest_CMLEN
),
26024 putPC(mkU64(guest_PC_curr_instr
+ 20));
26026 stmt(IRStmt_Put(offsetof(VexGuestMIPS32State
, guest_CMSTART
),
26027 mkU32(guest_PC_curr_instr
)));
26028 stmt(IRStmt_Put(offsetof(VexGuestMIPS32State
, guest_CMLEN
),
26031 putPC(mkU32(guest_PC_curr_instr
+ 20));
26033 dres
.whatNext
= Dis_StopHere
;
26034 dres
.jk_StopHere
= Ijk_InvalICache
;
26037 goto decode_success
;
26040 /* We don't know what it is. Set opc1/opc2 so decode_failure
26041 can print the insn following the Special-insn preamble. */
26043 goto decode_failure
;
26047 opcode
= get_opcode(cins
);
26048 imm
= get_imm(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
;
26066 ac
= get_acNo(cins
);
26070 case 0x03: /* JAL */
26071 DIP("jal 0x%x", instr_index
);
26073 putIReg(31, mkU64(guest_PC_curr_instr
+ 8));
26075 assign(t0
, mkU64((guest_PC_curr_instr
& 0xFFFFFFFFF0000000ULL
) |
26076 (instr_index
<< 2)));
26078 putIReg(31, mkU32(guest_PC_curr_instr
+ 8));
26080 assign(t0
, mkU32((guest_PC_curr_instr
& 0xF0000000) |
26081 (instr_index
<< 2)));
26083 lastn
= mkexpr(t0
);
26086 DIP("j 0x%x", instr_index
);
26089 assign(t0
, mkU64((guest_PC_curr_instr
& 0xFFFFFFFFF0000000ULL
) |
26090 (instr_index
<< 2)));
26092 assign(t0
, mkU32((guest_PC_curr_instr
& 0xF0000000) |
26093 (instr_index
<< 2)));
26094 lastn
= mkexpr(t0
);
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
)) {
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
));
26109 putIReg(rt
, mkWidenFrom32(ty
, unop(Iop_ReinterpF32asI32
,
26110 getFReg(fs
| 1)), True
));
26113 ILLEGAL_INSTRUCTON
;
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
)) {
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
)));
26127 putFReg(fs
| 1, unop(Iop_ReinterpI32asF32
,
26128 mkNarrowTo32(ty
, getIReg(rt
))));
26131 ILLEGAL_INSTRUCTON
;
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
);
26141 assign(t1
, binop(Iop_CmpEQ32
, mkU32(0), mkU32(bc1_cc
)));
26142 assign(t2
, IRExpr_ITE(mkexpr(t1
),
26144 binop(Iop_Shr32
, getFCSR(), mkU8(23)),
26147 binop(Iop_Shr32
, getFCSR(),
26148 mkU8(24 + bc1_cc
)),
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
);
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
);
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
),
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
),
26174 goto decode_failure
;
26175 } else if (fmt
>= 0x1c && has_msa
) { /* BNZ.df */
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)));
26185 case 0x00: { /* BNZ.B */
26186 DIP("BNZ.B w%d, %d", ft
, imm
);
26187 assign(t3
, binop(Iop_CmpEQ8x16
, mkexpr(t1
), mkexpr(t2
)));
26191 case 0x01: { /* BNZ.H */
26192 DIP("BNZ.H w%d, %d", ft
, imm
);
26193 assign(t3
, binop(Iop_CmpEQ16x8
, mkexpr(t1
), mkexpr(t2
)));
26197 case 0x02: { /* BNZ.W */
26198 DIP("BNZ.W w%d, %d", ft
, imm
);
26199 assign(t3
, binop(Iop_CmpEQ32x4
, mkexpr(t1
), mkexpr(t2
)));
26203 case 0x03: { /* BNZ.D */
26204 DIP("BNZ.D w%d, %d", ft
, imm
);
26205 assign(t3
, binop(Iop_CmpEQ64x2
, mkexpr(t1
), mkexpr(t2
)));
26213 unop(Iop_V128to32
, mkexpr(t3
)),
26214 unop(Iop_64HIto32
, unop(Iop_V128to64
, mkexpr(t3
)))),
26217 unop(Iop_V128HIto64
, mkexpr(t3
))),
26219 unop(Iop_V128HIto64
, mkexpr(t3
))))));
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
));
26229 unop(Iop_V128to32
, mkexpr(t1
)),
26230 unop(Iop_64HIto32
, unop(Iop_V128to64
, mkexpr(t1
)))),
26232 unop(Iop_64to32
, unop(Iop_V128HIto64
, mkexpr(t1
))),
26234 unop(Iop_V128HIto64
, mkexpr(t1
))))));
26236 binop(Iop_CmpNE32
, mkexpr(t0
), mkU32(0)), imm
, &bstmt
);
26237 } else if (fmt
>= 0x18 && has_msa
) { /* BZ.df */
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)));
26247 case 0x00: { /* BZ.B */
26248 DIP("BZ.B w%d, %d", ft
, imm
);
26249 assign(t3
, binop(Iop_CmpEQ8x16
, mkexpr(t1
), mkexpr(t2
)));
26253 case 0x01: { /* BZ.H */
26254 DIP("BZ.H w%d, %d", ft
, imm
);
26255 assign(t3
, binop(Iop_CmpEQ16x8
, mkexpr(t1
), mkexpr(t2
)));
26259 case 0x02: { /* BZ.W */
26260 DIP("BZ.W w%d, %d", ft
, imm
);
26261 assign(t3
, binop(Iop_CmpEQ32x4
, mkexpr(t1
), mkexpr(t2
)));
26265 case 0x03: { /* BZ.D */
26266 DIP("BZ.D w%d, %d", ft
, imm
);
26267 assign(t3
, binop(Iop_CmpEQ64x2
, mkexpr(t1
), mkexpr(t2
)));
26275 unop(Iop_V128to32
, mkexpr(t3
)),
26276 unop(Iop_64HIto32
, unop(Iop_V128to64
, mkexpr(t3
)))),
26278 unop(Iop_64to32
, unop(Iop_V128HIto64
, mkexpr(t3
))),
26280 unop(Iop_V128HIto64
, mkexpr(t3
))))));
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
));
26290 unop(Iop_V128to32
, mkexpr(t1
)),
26291 unop(Iop_64HIto32
, unop(Iop_V128to64
, mkexpr(t1
)))),
26293 unop(Iop_64to32
, unop(Iop_V128HIto64
, mkexpr(t1
))),
26295 unop(Iop_V128HIto64
, mkexpr(t1
))))));
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
);
26303 assign(t1
, binop(Iop_CmpEQ64
,
26305 unop(Iop_ReinterpF64asI64
, getDReg(ft
)),
26309 assign(t1
, binop(Iop_CmpEQ32
,
26312 unop(Iop_ReinterpF64asI64
, getDReg(ft
))),
26316 dis_branch(False
, mkexpr(t1
), imm
, &bstmt
);
26318 ILLEGAL_INSTRUCTON
;
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
);
26325 assign(t1
, binop(Iop_CmpNE64
,
26327 unop(Iop_ReinterpF64asI64
, getDReg(ft
)),
26331 assign(t1
, binop(Iop_CmpNE32
,
26334 unop(Iop_ReinterpF64asI64
, getDReg(ft
))),
26338 dis_branch(False
, mkexpr(t1
), imm
, &bstmt
);
26340 ILLEGAL_INSTRUCTON
;
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
) {
26351 signaling
= CMPSAFD
;
26353 assign(t0
, binop(Iop_CmpF64
, getDReg(fs
), getDReg(ft
)));
26354 calculateFCSR(fs
, ft
, signaling
, False
, 2);
26356 binop(Iop_I64StoF64
,
26357 get_IR_roundingmode(), mkU64(0)));
26360 signaling
= CMPSAFD
;
26362 assign(t0
, binop(Iop_CmpF64
, getDReg(fs
), getDReg(ft
)));
26363 calculateFCSR(fs
, ft
, signaling
, False
, 2);
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))));
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);
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
))));
26383 case 0xa: /* SEQ */
26384 signaling
= CMPSAFD
;
26386 assign(t0
, binop(Iop_CmpF64
, getDReg(fs
), getDReg(ft
)));
26387 calculateFCSR(fs
, ft
, signaling
, False
, 2);
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))));
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);
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
))));
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);
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(),
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);
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(),
26441 case 0xC: /* SLT */
26442 signaling
= CMPSAFD
;
26444 assign(t0
, binop(Iop_CmpF64
, getDReg(fs
), getDReg(ft
)));
26445 calculateFCSR(fs
, ft
, signaling
, False
, 2);
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))));
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);
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(),
26470 case 0xE: /* SLE */
26471 signaling
= CMPSAFD
;
26473 assign(t0
, binop(Iop_CmpF64
, getDReg(fs
), getDReg(ft
)));
26474 calculateFCSR(fs
, ft
, signaling
, False
, 2);
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(),
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);
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
))));
26500 comparison
= False
;
26503 if (!VEX_MIPS_CPU_HAS_MIPSR6(archinfo
->hwcaps
)) {
26504 ILLEGAL_INSTRUCTON
;
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
) {
26517 signaling
= CMPSAFS
;
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);
26524 mkWidenFromF32(tyF
,
26525 binop(Iop_I32StoF32
,
26526 get_IR_roundingmode(), mkU32(0))));
26529 signaling
= CMPSAFS
;
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);
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(),
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);
26553 IRExpr_ITE(binop(Iop_CmpEQ32
, mkexpr(t0
), mkU32(0x45)),
26554 mkWidenFromF32(tyF
,
26555 binop(Iop_I32StoF32
,
26556 get_IR_roundingmode(),
26558 mkWidenFromF32(tyF
,
26559 unop(Iop_ReinterpI32asF32
,
26560 mkU32(0xFFFFFFFFU
)))));
26562 case 0xa: /* SEQ */
26563 signaling
= CMPSAFS
;
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);
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(),
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);
26587 IRExpr_ITE(binop(Iop_CmpEQ32
, mkexpr(t0
), mkU32(0x40)),
26588 mkWidenFromF32(tyF
,
26589 binop(Iop_I32StoF32
,
26590 get_IR_roundingmode(),
26592 mkWidenFromF32(tyF
,
26593 unop(Iop_ReinterpI32asF32
,
26594 mkU32(0xFFFFFFFFU
)))));
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);
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(),
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);
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(),
26640 case 0xC: /* SLT */
26641 signaling
= CMPSAFS
;
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);
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(),
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);
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(),
26679 case 0xE: /* SLE */
26680 signaling
= CMPSAFS
;
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);
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(),
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);
26709 IRExpr_ITE(binop(Iop_CmpEQ32
, mkexpr(t0
), mkU32(0x0)),
26710 mkWidenFromF32(tyF
,
26711 binop(Iop_I32StoF32
,
26712 get_IR_roundingmode(),
26714 mkWidenFromF32(tyF
,
26715 unop(Iop_ReinterpI32asF32
,
26716 mkU32(0xFFFFFFFFU
)))));
26719 comparison
= False
;
26722 if (!VEX_MIPS_CPU_HAS_MIPSR6(archinfo
->hwcaps
)) {
26723 ILLEGAL_INSTRUCTON
;
26729 switch (function
) {
26730 case 0x4: { /* SQRT.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
)))));
26738 case 0x11: { /* D */
26739 IRExpr
*rm
= get_IR_roundingmode();
26740 putDReg(fd
, binop(Iop_SqrtF64
, rm
, getDReg(fs
)));
26744 goto decode_failure
;
26748 case 0x5: /* abs.fmt */
26751 DIP("abs.s f%u, f%u", fd
, fs
);
26752 putFReg(fd
, mkWidenFromF32(tyF
, unop(Iop_AbsF32
,
26753 getLoFromF64(tyF
, getFReg(fs
)))));
26756 DIP("abs.d f%u, f%u", fd
, fs
);
26757 putDReg(fd
, unop(Iop_AbsF64
, getDReg(fs
)));
26760 goto decode_failure
;
26762 break; /* case 0x5 */
26764 case 0x02: /* MUL.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
),
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
)))));
26782 goto decode_failure
;
26784 break; /* MUL.fmt */
26786 case 0x03: /* DIV.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
),
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
)))));
26805 goto decode_failure
;
26807 break; /* DIV.fmt */
26809 case 0x01: /* SUB.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
),
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
)))));
26829 goto decode_failure
;
26831 break; /* SUB.fmt */
26833 case 0x06: /* MOV.fmt */
26836 DIP("mov.d f%u, f%u", fd
, fs
);
26838 putDReg(fd
, getDReg(fs
));
26840 putFReg(fd
, getFReg(fs
));
26841 putFReg(fd
+ 1, getFReg(fs
+ 1));
26845 DIP("mov.s f%u, f%u", fd
, fs
);
26846 putFReg(fd
, getFReg(fs
));
26849 goto decode_failure
;
26851 break; /* MOV.fmt */
26853 case 0x7: /* neg.fmt */
26856 DIP("neg.s f%u, f%u", fd
, fs
);
26857 putFReg(fd
, mkWidenFromF32(tyF
, unop(Iop_NegF32
,
26858 getLoFromF64(tyF
, getFReg(fs
)))));
26861 DIP("neg.d f%u, f%u", fd
, fs
);
26862 putDReg(fd
, unop(Iop_NegF64
, getDReg(fs
)));
26865 goto decode_failure
;
26867 break; /* case 0x7 */
26869 case 0x08: /* ROUND.L.fmt */
26872 DIP("round.l.s f%u, f%u", fd
, fs
);
26874 calculateFCSR(fs
, 0, ROUNDLS
, True
, 1);
26875 t0
= newTemp(Ity_I64
);
26877 assign(t0
, binop(Iop_F32toI64S
, mkU32(0x0),
26878 getLoFromF64(Ity_F64
, getFReg(fs
))));
26880 putDReg(fd
, unop(Iop_ReinterpI64asF64
, mkexpr(t0
)));
26882 ILLEGAL_INSTRUCTON
;
26886 DIP("round.l.d f%u, f%u", fd
, fs
);
26888 calculateFCSR(fs
, 0, ROUNDLD
, False
, 1);
26889 putDReg(fd
, unop(Iop_ReinterpI64asF64
,
26890 binop(Iop_F64toI64S
,
26894 ILLEGAL_INSTRUCTON
;
26898 goto decode_failure
;
26901 break; /* ROUND.L.fmt */
26903 case 0x09: /* TRUNC.L.fmt */
26906 DIP("trunc.l.s f%u, f%u", fd
, fs
);
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
))));
26913 putDReg(fd
, unop(Iop_ReinterpI64asF64
, mkexpr(t0
)));
26915 ILLEGAL_INSTRUCTON
;
26919 DIP("trunc.l.d f%u, f%u", fd
, fs
);
26921 calculateFCSR(fs
, 0, TRUNCLD
, False
, 1);
26922 putDReg(fd
, unop(Iop_ReinterpI64asF64
,
26923 binop(Iop_F64toI64S
,
26927 ILLEGAL_INSTRUCTON
;
26931 goto decode_failure
;
26933 break; /* TRUNC.L.fmt */
26935 case 0x15: /* RECIP.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
,
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
)));
26956 goto decode_failure
;
26959 break; /* case 0x15 */
26961 case 0x13: /* MOVN.fmt */
26964 DIP("movn.s f%u, f%u, r%u", fd
, fs
, rt
);
26965 t1
= newTemp(Ity_I1
);
26968 assign(t1
, binop(Iop_CmpNE64
, mkU64(0), getIReg(rt
)));
26970 assign(t1
, binop(Iop_CmpNE32
, mkU32(0), getIReg(rt
)));
26972 putFReg(fd
, IRExpr_ITE(mkexpr(t1
), getFReg(fs
), getFReg(fd
)));
26975 DIP("movn.d f%u, f%u, r%u", fd
, fs
, rt
);
26976 t1
= newTemp(Ity_I1
);
26979 assign(t1
, binop(Iop_CmpNE64
, mkU64(0), getIReg(rt
)));
26981 assign(t1
, binop(Iop_CmpNE32
, mkU32(0), getIReg(rt
)));
26983 putDReg(fd
, IRExpr_ITE(mkexpr(t1
), getDReg(fs
), getDReg(fd
)));
26986 goto decode_failure
;
26988 break; /* MOVN.fmt */
26990 case 0x12: /* MOVZ.fmt */
26993 DIP("movz.s f%u, f%u, r%u", fd
, fs
, rt
);
26994 t1
= newTemp(Ity_I1
);
26997 assign(t1
, binop(Iop_CmpEQ64
, mkU64(0), getIReg(rt
)));
26999 assign(t1
, binop(Iop_CmpEQ32
, mkU32(0), getIReg(rt
)));
27001 putFReg(fd
, IRExpr_ITE(mkexpr(t1
), getFReg(fs
), getFReg(fd
)));
27004 DIP("movz.d f%u, f%u, r%u", fd
, fs
, rt
);
27005 t1
= newTemp(Ity_I1
);
27008 assign(t1
, binop(Iop_CmpEQ64
, mkU64(0), getIReg(rt
)));
27010 assign(t1
, binop(Iop_CmpEQ32
, mkU32(0), getIReg(rt
)));
27012 putDReg(fd
, IRExpr_ITE(mkexpr(t1
), getDReg(fs
), getDReg(fd
)));
27015 goto decode_failure
;
27017 break; /* MOVZ.fmt */
27019 case 0x11: /* MOVT.fmt */
27021 UInt mov_cc
= get_mov_cc(cins
);
27022 switch (fmt
) { /* MOVCF = 010001 */
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
);
27030 assign(t1
, binop(Iop_CmpEQ32
, mkU32(0), mkU32(mov_cc
)));
27031 assign(t2
, IRExpr_ITE(mkexpr(t1
),
27033 binop(Iop_Shr32
, getFCSR(),
27037 binop(Iop_Shr32
, getFCSR(),
27038 mkU8(24 + mov_cc
)),
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
));
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
);
27058 assign(t5
, getFReg(fs
));
27059 assign(t6
, getFReg(fd
));
27061 assign(t5
, unop(Iop_F32toF64
, getFReg(fs
)));
27062 assign(t6
, unop(Iop_F32toF64
, getFReg(fd
)));
27065 assign(t1
, binop(Iop_CmpEQ32
, mkU32(0), mkU32(mov_cc
)));
27066 assign(t2
, IRExpr_ITE(mkexpr(t1
),
27068 binop(Iop_Shr32
, getFCSR(),
27072 binop(Iop_Shr32
, getFCSR(),
27073 mkU8(24 + mov_cc
)),
27077 assign(t3
, binop(Iop_CmpEQ32
, mkU32(1), mkexpr(t2
)));
27078 assign(t4
, IRExpr_ITE(mkexpr(t3
),
27079 mkexpr(t5
), mkexpr(t6
)));
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
))),
27091 putFReg(fd
, unop(Iop_ReinterpI64asF64
, mkexpr(t7
)));
27093 putFReg(fd
, binop(Iop_F64toF32
, get_IR_roundingmode(),
27097 goto decode_failure
;
27099 } else if (tf
== 0) /* movf.fmt */
27101 UInt mov_cc
= get_mov_cc(cins
);
27102 switch (fmt
) /* MOVCF = 010001 */
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
);
27111 assign(t1
, binop(Iop_CmpEQ32
, mkU32(0), mkU32(mov_cc
)));
27112 assign(t2
, IRExpr_ITE(mkexpr(t1
),
27114 binop(Iop_Shr32
, getFCSR(),
27118 binop(Iop_Shr32
, getFCSR(),
27119 mkU8(24 + mov_cc
)),
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
));
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
);
27138 assign(t5
, getFReg(fs
));
27139 assign(t6
, getFReg(fd
));
27141 assign(t5
, unop(Iop_F32toF64
, getFReg(fs
)));
27142 assign(t6
, unop(Iop_F32toF64
, getFReg(fd
)));
27145 assign(t1
, binop(Iop_CmpEQ32
, mkU32(0), mkU32(mov_cc
)));
27146 assign(t2
, IRExpr_ITE(mkexpr(t1
),
27148 binop(Iop_Shr32
, getFCSR(),
27152 binop(Iop_Shr32
, getFCSR(),
27153 mkU8(24 + mov_cc
)),
27157 assign(t3
, binop(Iop_CmpEQ32
, mkU32(0), mkexpr(t2
)));
27158 assign(t4
, IRExpr_ITE(mkexpr(t3
),
27159 mkexpr(t5
), mkexpr(t6
)));
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
))),
27172 putFReg(fd
, unop(Iop_ReinterpI64asF64
, mkexpr(t7
)));
27174 putFReg(fd
, binop(Iop_F64toF32
, get_IR_roundingmode(),
27178 goto decode_failure
;
27182 break; /* MOVT.fmt */
27184 case 0x0: /* add.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
)))));
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
)));
27203 case 0x4: /* MTC1 (Move Word to Floating Point) */
27204 DIP("mtc1 r%u, f%u", rt
, fs
);
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
)));
27211 putFReg(fs
, mkWidenFromF32(tyF
, mkexpr(t1
)));
27213 putFReg(fs
, unop(Iop_ReinterpI32asF32
,
27214 mkNarrowTo32(ty
, getIReg(rt
))));
27217 case 0x5: /* Doubleword Move to Floating Point DMTC1; MIPS64 */
27218 DIP("dmtc1 r%u, f%u", rt
, fs
);
27220 putDReg(fs
, unop(Iop_ReinterpI64asF64
, getIReg(rt
)));
27223 case 0x0: /* MFC1 */
27224 DIP("mfc1 r%u, f%u", rt
, fs
);
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
));
27232 putIReg(rt
, mkWidenFrom32(ty
,
27233 unop(Iop_ReinterpF32asI32
, getFReg(fs
)),
27237 case 0x1: /* Doubleword Move from Floating Point DMFC1;
27239 DIP("dmfc1 r%u, f%u", rt
, fs
);
27240 putIReg(rt
, unop(Iop_ReinterpF64asI64
, getDReg(fs
)));
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
),
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
));
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());
27305 putIReg(rt
, mkWidenFrom32(ty
,
27306 IRExpr_Get(offsetof(VexGuestMIPS32State
,
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
));
27342 goto decode_failure
;
27346 case 0x21: /* CVT.D */
27349 DIP("cvt.d.s f%u, f%u", fd
, fs
);
27350 calculateFCSR(fs
, 0, CVTDS
, True
, 1);
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
)));
27359 assign(t1
, unop(Iop_64to32
, mkexpr(t0
)));
27361 assign(t3
, unop(Iop_ReinterpI32asF32
, mkexpr(t1
)));
27363 putFReg(fd
, unop(Iop_F32toF64
, mkexpr(t3
)));
27365 putDReg(fd
, unop(Iop_F32toF64
, getFReg(fs
)));
27369 DIP("cvt.d.w %u, %u", fd
, fs
);
27370 calculateFCSR(fs
, 0, CVTDW
, True
, 1);
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
)));
27379 assign(t1
, unop(Iop_64to32
, mkexpr(t0
)));
27380 putDReg(fd
,unop(Iop_I32StoF64
, mkexpr(t1
)));
27383 t0
= newTemp(Ity_I32
);
27384 assign(t0
, unop(Iop_ReinterpF32asI32
, getFReg(fs
)));
27385 putDReg(fd
, unop(Iop_I32StoF64
, mkexpr(t0
)));
27389 case 0x15: { /* L */
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
)));
27396 putFReg(fd
, binop(Iop_I64StoF64
,
27397 get_IR_roundingmode(), mkexpr(t0
)));
27400 goto decode_failure
;
27403 goto decode_failure
;
27407 case 0x20: /* cvt.s */
27410 DIP("cvt.s.w %u, %u", fd
, fs
);
27411 calculateFCSR(fs
, 0, CVTSW
, True
, 1);
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
)));
27420 assign(t1
, unop(Iop_64to32
, mkexpr(t0
)));
27421 putFReg(fd
, mkWidenFromF32(tyF
, binop(Iop_I32StoF32
,
27422 get_IR_roundingmode(), mkexpr(t1
))));
27424 t0
= newTemp(Ity_I32
);
27425 assign(t0
, unop(Iop_ReinterpF32asI32
, getFReg(fs
)));
27426 putFReg(fd
, binop(Iop_I32StoF32
, get_IR_roundingmode(),
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(),
27437 putFReg(fd
, mkWidenFromF32(tyF
, mkexpr(t0
)));
27441 DIP("cvt.s.l %u, %u", fd
, fs
);
27443 calculateFCSR(fs
, 0, CVTSL
, False
, 1);
27444 t0
= newTemp(Ity_I64
);
27445 assign(t0
, unop(Iop_ReinterpF64asI64
, getFReg(fs
)));
27447 putFReg(fd
, mkWidenFromF32(tyF
, binop(Iop_I64StoF32
,
27448 get_IR_roundingmode(), mkexpr(t0
))));
27450 ILLEGAL_INSTRUCTON
;
27455 goto decode_failure
;
27459 case 0x24: /* cvt.w */
27462 DIP("cvt.w.s %u, %u", fd
, fs
);
27463 calculateFCSR(fs
, 0, CVTWS
, True
, 1);
27465 mkWidenFromF32(tyF
,
27466 unop(Iop_ReinterpI32asF32
,
27467 binop(Iop_F32toI32S
,
27468 get_IR_roundingmode(),
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(),
27480 assign(t1
, unop(Iop_ReinterpI32asF32
, mkexpr(t0
)));
27481 putFReg(fd
, mkWidenFromF32(tyF
, mkexpr(t1
)));
27485 goto decode_failure
;
27490 case 0x25: /* cvt.l */
27493 DIP("cvt.l.s %u, %u", fd
, fs
);
27495 calculateFCSR(fs
, 0, CVTLS
, True
, 1);
27496 t0
= newTemp(Ity_I64
);
27498 assign(t0
, binop(Iop_F32toI64S
, get_IR_roundingmode(),
27499 getLoFromF64(tyF
, getFReg(fs
))));
27501 putDReg(fd
, unop(Iop_ReinterpI64asF64
, mkexpr(t0
)));
27503 ILLEGAL_INSTRUCTON
;
27507 case 0x11: { /* D */
27508 DIP("cvt.l.d %u, %u", fd
, fs
);
27510 calculateFCSR(fs
, 0, CVTLD
, False
, 1);
27511 putDReg(fd
, unop(Iop_ReinterpI64asF64
,
27512 binop(Iop_F64toI64S
,
27513 get_IR_roundingmode(),
27516 ILLEGAL_INSTRUCTON
;
27522 goto decode_failure
;
27526 case 0x0B: /* FLOOR.L.fmt */
27529 DIP("floor.l.s %u, %u", fd
, fs
);
27531 calculateFCSR(fs
, 0, FLOORLS
, True
, 1);
27532 t0
= newTemp(Ity_I64
);
27534 assign(t0
, binop(Iop_F32toI64S
, mkU32(0x1),
27535 getLoFromF64(tyF
, getFReg(fs
))));
27537 putDReg(fd
, unop(Iop_ReinterpI64asF64
, mkexpr(t0
)));
27539 ILLEGAL_INSTRUCTON
;
27544 DIP("floor.l.d %u, %u", fd
, fs
);
27546 calculateFCSR(fs
, 0, FLOORLD
, False
, 1);
27547 putDReg(fd
, unop(Iop_ReinterpI64asF64
,
27548 binop(Iop_F64toI64S
,
27552 ILLEGAL_INSTRUCTON
;
27556 goto decode_failure
;
27560 case 0x0C: /* ROUND.W.fmt */
27563 DIP("round.w.s f%u, f%u", fd
, fs
);
27564 calculateFCSR(fs
, 0, ROUNDWS
, True
, 1);
27566 mkWidenFromF32(tyF
,
27567 unop(Iop_ReinterpI32asF32
,
27568 binop(Iop_F32toI32S
,
27575 DIP("round.w.d f%u, f%u", fd
, fs
);
27576 calculateFCSR(fs
, 0, ROUNDWD
, False
, 1);
27578 t0
= newTemp(Ity_I32
);
27579 assign(t0
, binop(Iop_F64toI32S
, mkU32(0x0),
27581 putFReg(fd
, mkWidenFromF32(tyF
,
27582 unop(Iop_ReinterpI32asF32
, mkexpr(t0
))));
27584 t0
= newTemp(Ity_I32
);
27586 assign(t0
, binop(Iop_F64toI32S
, mkU32(0x0),
27589 putFReg(fd
, unop(Iop_ReinterpI32asF32
, mkexpr(t0
)));
27593 goto decode_failure
;
27596 break; /* ROUND.W.fmt */
27598 case 0x0F: /* FLOOR.W.fmt */
27601 DIP("floor.w.s f%u, f%u", fd
, fs
);
27602 calculateFCSR(fs
, 0, FLOORWS
, True
, 1);
27604 mkWidenFromF32(tyF
,
27605 unop(Iop_ReinterpI32asF32
,
27606 binop(Iop_F32toI32S
,
27613 DIP("floor.w.d f%u, f%u", fd
, fs
);
27614 calculateFCSR(fs
, 0, FLOORWD
, False
, 1);
27616 t0
= newTemp(Ity_I32
);
27617 assign(t0
, binop(Iop_F64toI32S
, mkU32(0x1),
27619 putFReg(fd
, mkWidenFromF32(tyF
,
27620 unop(Iop_ReinterpI32asF32
, mkexpr(t0
))));
27623 t0
= newTemp(Ity_I32
);
27625 assign(t0
, binop(Iop_F64toI32S
, mkU32(0x1),
27628 putFReg(fd
, unop(Iop_ReinterpI32asF32
, mkexpr(t0
)));
27632 goto decode_failure
;
27635 break; /* FLOOR.W.fmt */
27637 case 0x0D: /* TRUNC.W */
27640 DIP("trunc.w.s %u, %u", fd
, fs
);
27641 calculateFCSR(fs
, 0, TRUNCWS
, True
, 1);
27643 mkWidenFromF32(tyF
,
27644 unop(Iop_ReinterpI32asF32
,
27645 binop(Iop_F32toI32S
,
27651 DIP("trunc.w.d %u, %u", fd
, fs
);
27652 calculateFCSR(fs
, 0, TRUNCWD
, False
, 1);
27654 t0
= newTemp(Ity_I32
);
27656 assign(t0
, binop(Iop_F64toI32S
, mkU32(0x3),
27659 putFReg(fd
, mkWidenFromF32(tyF
,
27660 unop(Iop_ReinterpI32asF32
, mkexpr(t0
))));
27662 t0
= newTemp(Ity_I32
);
27664 assign(t0
, binop(Iop_F64toI32S
, mkU32(0x3),
27667 putFReg(fd
, unop(Iop_ReinterpI32asF32
, mkexpr(t0
)));
27671 goto decode_failure
;
27676 case 0x0E: /* CEIL.W.fmt */
27679 DIP("ceil.w.s %u, %u", fd
, fs
);
27680 calculateFCSR(fs
, 0, CEILWS
, True
, 1);
27682 mkWidenFromF32(tyF
,
27683 unop(Iop_ReinterpI32asF32
,
27684 binop(Iop_F32toI32S
,
27691 DIP("ceil.w.d %u, %u", fd
, fs
);
27692 calculateFCSR(fs
, 0, CEILWD
, False
, 1);
27694 t0
= newTemp(Ity_I32
);
27695 assign(t0
, binop(Iop_F64toI32S
, mkU32(0x2),
27697 putFReg(fd
, unop(Iop_ReinterpI32asF32
, mkexpr(t0
)));
27699 t0
= newTemp(Ity_I32
);
27700 assign(t0
, binop(Iop_F64toI32S
, mkU32(0x2),
27702 putFReg(fd
, mkWidenFromF32(tyF
,
27703 unop(Iop_ReinterpI32asF32
, mkexpr(t0
))));
27708 goto decode_failure
;
27713 case 0x0A: /* CEIL.L.fmt */
27716 DIP("ceil.l.s %u, %u", fd
, fs
);
27718 calculateFCSR(fs
, 0, CEILLS
, True
, 1);
27719 t0
= newTemp(Ity_I64
);
27721 assign(t0
, binop(Iop_F32toI64S
, mkU32(0x2),
27722 getLoFromF64(tyF
, getFReg(fs
))));
27724 putFReg(fd
, unop(Iop_ReinterpI64asF64
, mkexpr(t0
)));
27726 ILLEGAL_INSTRUCTON
;
27731 DIP("ceil.l.d %u, %u", fd
, fs
);
27733 calculateFCSR(fs
, 0, CEILLD
, False
, 1);
27734 putDReg(fd
, unop(Iop_ReinterpI64asF64
,
27735 binop(Iop_F64toI64S
,
27739 ILLEGAL_INSTRUCTON
;
27744 goto decode_failure
;
27749 case 0x16: /* RSQRT.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
,
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
))));
27770 goto decode_failure
;
27775 case 0x18: /* MADDF.fmt */
27776 if (VEX_MIPS_CPU_HAS_MIPSR6(archinfo
->hwcaps
)) {
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
),
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
)));
27799 goto decode_failure
;
27802 ILLEGAL_INSTRUCTON
;
27807 case 0x19: /* MSUBF.fmt */
27808 if (VEX_MIPS_CPU_HAS_MIPSR6(archinfo
->hwcaps
)) {
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
)));
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
)));
27831 goto decode_failure
;
27834 ILLEGAL_INSTRUCTON
;
27839 case 0x1E: /* MAX.fmt */
27840 if (VEX_MIPS_CPU_HAS_MIPSR6(archinfo
->hwcaps
)) {
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
)));
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
,
27855 getLoFromF64(Ity_F64
,
27861 goto decode_failure
;
27864 ILLEGAL_INSTRUCTON
;
27869 case 0x1C: /* MIN.fmt */
27870 if (VEX_MIPS_CPU_HAS_MIPSR6(archinfo
->hwcaps
)) {
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
)));
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
,
27885 getLoFromF64(Ity_F64
,
27890 goto decode_failure
;
27893 ILLEGAL_INSTRUCTON
;
27898 case 0x1F: /* MAXA.fmt */
27899 if (VEX_MIPS_CPU_HAS_MIPSR6(archinfo
->hwcaps
)) {
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
)),
27914 putFReg(fd
, IRExpr_ITE(mkexpr(t4
),
27915 getFReg(fs
), getFReg(ft
)));
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
,
27928 assign(t2
, unop(Iop_AbsF32
, getLoFromF64(Ity_F64
,
27930 assign(t3
, binop(Iop_MaxNumF32
, mkexpr(t1
), mkexpr(t2
)));
27931 assign(t4
, binop(Iop_CmpEQ32
,
27932 binop(Iop_CmpF32
, mkexpr(t3
), mkexpr(t1
)),
27934 putFReg(fd
, IRExpr_ITE(mkexpr(t4
),
27935 getFReg(fs
), getFReg(ft
)));
27940 goto decode_failure
;
27942 /* missing in documentation */
27944 ILLEGAL_INSTRUCTON
;
27948 case 0x1D: /* MINA.fmt */
27949 if (VEX_MIPS_CPU_HAS_MIPSR6(archinfo
->hwcaps
)) {
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
)),
27964 putFReg(fd
, IRExpr_ITE(mkexpr(t4
),
27965 getFReg(fs
), getFReg(ft
)));
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
,
27978 assign(t2
, unop(Iop_AbsF32
, getLoFromF64(Ity_F64
,
27980 assign(t3
, binop(Iop_MinNumF32
, mkexpr(t1
), mkexpr(t2
)));
27981 assign(t4
, binop(Iop_CmpEQ32
,
27982 binop(Iop_CmpF32
, mkexpr(t3
), mkexpr(t1
)),
27984 putFReg(fd
, IRExpr_ITE(mkexpr(t4
),
27985 getFReg(fs
), getFReg(ft
)));
27990 goto decode_failure
;
27993 ILLEGAL_INSTRUCTON
;
27997 case 0x1A: /* RINT.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
)));
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();
28013 mkWidenFromF32(tyF
,
28014 binop(Iop_RoundF32toInt
, rm
,
28021 goto decode_failure
;
28027 case 0x10: /* SEL.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
);
28034 assign(t1
,binop(Iop_CmpNE64
,
28036 unop(Iop_ReinterpF64asI64
,
28041 assign(t1
,binop(Iop_CmpNE32
,
28044 unop(Iop_ReinterpF64asI64
,
28049 putDReg(fd
, IRExpr_ITE(mkexpr(t1
),
28050 getDReg(ft
), getDReg(fs
)));
28053 ILLEGAL_INSTRUCTON
;
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
,
28063 unop(Iop_ReinterpF32asI32
,
28064 getLoFromF64(tyF
, getFReg(fd
))),
28067 putFReg(fd
, IRExpr_ITE( mkexpr(t1
),
28068 getFReg(ft
), getFReg(fs
)));
28072 goto decode_failure
;
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
);
28083 assign(t1
, binop(Iop_CmpNE64
,
28085 unop(Iop_ReinterpF64asI64
,
28090 assign(t1
, binop(Iop_CmpNE32
,
28093 unop(Iop_ReinterpF64asI64
,
28098 putDReg(fd
, IRExpr_ITE( mkexpr(t1
),
28099 binop(Iop_I64StoF64
,
28100 get_IR_roundingmode(),mkU64(0)),
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
,
28110 unop(Iop_ReinterpF32asI32
,
28111 getLoFromF64(tyF
, getFReg(ft
))),
28114 putFReg(fd
, IRExpr_ITE(mkexpr(t1
),
28115 mkWidenFromF32(tyF
,
28116 binop(Iop_I32StoF32
,
28117 get_IR_roundingmode(),
28124 goto decode_failure
;
28127 ILLEGAL_INSTRUCTON
;
28131 case 0x17: /* SELNEZ.fmt */
28132 if (VEX_MIPS_CPU_HAS_MIPSR6(archinfo
->hwcaps
)) {
28134 case 0x11: { /* D */
28135 DIP("selnez.d f%u, f%u, f%u", fd
, fs
, ft
);
28136 t1
= newTemp(Ity_I1
);
28138 assign(t1
, binop(Iop_CmpNE64
,
28140 unop(Iop_ReinterpF64asI64
,
28145 assign(t1
, binop(Iop_CmpNE32
,
28148 unop(Iop_ReinterpF64asI64
,
28153 putDReg(fd
, IRExpr_ITE( mkexpr(t1
),
28155 binop(Iop_I64StoF64
,
28156 get_IR_roundingmode(),
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
,
28166 unop(Iop_ReinterpF32asI32
,
28167 getLoFromF64(tyF
, getFReg(ft
))),
28170 putFReg(fd
, IRExpr_ITE(mkexpr(t1
),
28172 mkWidenFromF32(tyF
,
28173 binop(Iop_I32StoF32
,
28174 get_IR_roundingmode(),
28180 goto decode_failure
;
28183 ILLEGAL_INSTRUCTON
;
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
);
28196 case 0x11: { /* D */
28197 DIP("class.d f%u, f%u", fd
, fs
);
28198 assign(t0
, binop(Iop_CmpEQ32
,
28201 unop(Iop_ReinterpF64asI64
,
28203 mkU32(0x7ff00000)),
28205 assign(t1
, binop(Iop_CmpEQ32
,
28208 unop(Iop_ReinterpF64asI64
,
28210 mkU32(0x7ff00000)),
28211 mkU32(0x7ff00000)));
28212 assign(t2
, binop(Iop_CmpEQ32
,
28215 unop(Iop_ReinterpF64asI64
,
28217 mkU32(0x80000000)),
28218 mkU32(0x80000000)));
28219 assign(t3
, binop(Iop_CmpEQ32
,
28222 unop(Iop_ReinterpF64asI64
,
28224 mkU32(0x00080000)),
28225 mkU32(0x00080000)));
28226 if (mode64
) assign(t4
, binop(Iop_CmpNE64
,
28228 unop(Iop_ReinterpF64asI64
,
28230 mkU64(0x000fffffffffffffULL
)),
28232 else assign(t4
, binop(Iop_CmpNE32
,
28236 unop(Iop_ReinterpF64asI64
,
28238 mkU32(0x000fffff)),
28240 unop(Iop_ReinterpF64asI64
,
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
),
28252 IRExpr_ITE(mkexpr(t2
), mkU8(2), mkU8(6))));
28253 putDReg(fd
, unop(Iop_ReinterpI64asF64
,
28255 IRExpr_ITE(binop(Iop_CmpNE32
,
28256 mkexpr(t5
), mkU32(0)),
28258 IRExpr_ITE(mkexpr(t3
),
28263 case 0x10: { /* S */
28264 DIP("class.s f%u, f%u", fd
, fs
);
28265 assign(t0
, binop(Iop_CmpEQ32
,
28267 unop(Iop_ReinterpF32asI32
,
28268 getLoFromF64(tyF
, getFReg(fs
))),
28269 mkU32(0x7f800000)),
28271 assign(t1
, binop(Iop_CmpEQ32
,
28273 unop(Iop_ReinterpF32asI32
,
28274 getLoFromF64(tyF
, getFReg(fs
))),
28275 mkU32(0x7f800000)),
28276 mkU32(0x7f800000)));
28277 assign(t2
, binop(Iop_CmpEQ32
,
28279 unop(Iop_ReinterpF32asI32
,
28280 getLoFromF64(tyF
, getFReg(fs
))),
28281 mkU32(0x80000000)),
28282 mkU32(0x80000000)));
28283 assign(t3
, binop(Iop_CmpEQ32
,
28285 unop(Iop_ReinterpF32asI32
,
28286 getLoFromF64(tyF
, getFReg(fs
))),
28287 mkU32(0x00400000)),
28288 mkU32(0x00400000)));
28289 assign(t4
, binop(Iop_CmpNE32
,
28291 unop(Iop_ReinterpF32asI32
,
28292 getLoFromF64(tyF
, getFReg(fs
))),
28293 mkU32(0x007fffff)),
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
),
28302 mkU32(0x8)), //zero or subnorm
28304 IRExpr_ITE(mkexpr(t2
), mkU8(2), mkU8(6))));
28305 putDReg(fd
, unop(Iop_ReinterpI64asF64
,
28307 IRExpr_ITE(binop(Iop_CmpNE32
,
28308 mkexpr(t5
), mkU32(0)),
28310 IRExpr_ITE(mkexpr(t3
),
28316 goto decode_failure
;
28319 ILLEGAL_INSTRUCTON
;
28324 if (dis_instr_CCondFmt(cins
))
28326 goto decode_failure
;
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
;
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
)));
28346 putFReg(ft
, load(Ity_F32
, mkexpr(t1
)));
28350 case 0x39: /* SWC1 */
28351 DIP("swc1 f%u, %u(r%u)", ft
, imm
, rs
);
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
)));
28360 LOAD_STORE_PATTERN
;
28361 store(mkexpr(t1
), getFReg(ft
));
28365 case 0x33: /* PREF */
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
)));
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
));
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
));
28389 case 0x20: /* LB */
28390 DIP("lb r%u, %u(r%u)", rt
, imm
, rs
);
28391 LOAD_STORE_PATTERN
;
28393 putIReg(rt
, unop(Iop_8Sto64
, load(Ity_I8
, mkexpr(t1
))));
28395 putIReg(rt
, unop(Iop_8Sto32
, load(Ity_I8
, mkexpr(t1
))));
28398 case 0x24: /* LBU */
28399 DIP("lbu r%u, %u(r%u)", rt
, imm
, rs
);
28400 LOAD_STORE_PATTERN
;
28402 putIReg(rt
, unop(Iop_8Uto64
, load(Ity_I8
, mkexpr(t1
))));
28404 putIReg(rt
, unop(Iop_8Uto32
, load(Ity_I8
, mkexpr(t1
))));
28407 case 0x21: /* LH */
28408 DIP("lh r%u, %u(r%u)", rt
, imm
, rs
);
28409 LOAD_STORE_PATTERN
;
28411 putIReg(rt
, unop(Iop_16Sto64
, load(Ity_I16
, mkexpr(t1
))));
28413 putIReg(rt
, unop(Iop_16Sto32
, load(Ity_I16
, mkexpr(t1
))));
28416 case 0x25: /* LHU */
28417 DIP("lhu r%u, %u(r%u)", rt
, imm
, rs
);
28418 LOAD_STORE_PATTERN
;
28420 putIReg(rt
, unop(Iop_16Uto64
, load(Ity_I16
, mkexpr(t1
))));
28422 putIReg(rt
, unop(Iop_16Uto32
, load(Ity_I16
, mkexpr(t1
))));
28425 case 0x0F: /* LUI */
28428 DIP("lui r%u, imm: 0x%x", rt
, imm
);
28430 putIReg(rt
, mkU64(extend_s_32to64(p
)));
28432 putIReg(rt
, mkU32(p
));
28434 } else if (VEX_MIPS_CPU_HAS_MIPSR6(archinfo
->hwcaps
)) { /* AUI */
28435 DIP("aui r%u, imm: 0x%x", rt
, imm
);
28437 putIReg(rt
, unop(Iop_32Sto64
,
28441 mkU64(extend_s_32to64(imm
<< 16))))));
28443 putIReg(rt
, binop(Iop_Add32
, getIReg(rs
), mkU32(imm
<< 16)));
28446 ILLEGAL_INSTRUCTON
;
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
);
28456 assign(t2
, binop(mode64
? Iop_Add64
: Iop_Add32
, getIReg(rs
),
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
)));
28465 assign(t4
, mkWidenFrom32(Ity_I64
, unop(Iop_ReinterpF32asI32
,
28466 mkexpr(t3
)), True
));
28468 putFReg(fd
, unop(Iop_ReinterpI64asF64
, mkexpr(t4
)));
28470 putFReg(fd
, load(Ity_F32
, mkexpr(t2
)));
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
);
28480 assign(t0
, binop(mode64
? Iop_Add64
: Iop_Add32
, getIReg(rs
),
28482 putDReg(fd
, load(Ity_F64
, mkexpr(t0
)));
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
))
28493 assign(t0
, binop(mode64
? Iop_Add64
: Iop_Add32
,
28494 getIReg(rs
), getIReg(rt
)));
28495 assign(t1
, binop(mode64
? Iop_And64
: Iop_And32
,
28497 mode64
? mkU64(0xfffffffffffffff8ULL
)
28498 : mkU32(0xfffffff8ULL
)));
28499 putFReg(fd
, load(Ity_F64
, mkexpr(t1
)));
28501 ILLEGAL_INSTRUCTON
;
28505 case 0x8: { /* Store Word Indexed from Floating Point - SWXC1 */
28506 DIP("swxc1 f%u, r%u(r%u)", ft
, rt
, rs
);
28508 assign(t0
, binop(mode64
? Iop_Add64
: Iop_Add32
, getIReg(rs
),
28511 store(mkexpr(t0
), getLoFromF64(tyF
, getFReg(fs
)));
28513 store(mkexpr(t0
), getFReg(fs
));
28517 case 0x9: { /* Store Doubleword Indexed from Floating Point - SDXC1 */
28518 DIP("sdxc1 f%u, r%u(r%u)", fs
, rt
, rs
);
28520 assign(t0
, binop(mode64
? Iop_Add64
: Iop_Add32
, getIReg(rs
),
28522 store(mkexpr(t0
), getDReg(fs
));
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
))
28532 assign(t0
, binop(mode64
? Iop_Add64
: Iop_Add32
,
28533 getIReg(rs
), getIReg(rt
)));
28534 assign(t1
, binop(mode64
? Iop_And64
: Iop_And32
,
28536 mode64
? mkU64(0xfffffffffffffff8ULL
)
28537 : mkU32(0xfffffff8ULL
)));
28538 store(mkexpr(t1
), getFReg(fs
));
28540 ILLEGAL_INSTRUCTON
;
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 */
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
),
28564 break; /* MADD.D */
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 */
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 */
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 */
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
),
28601 putDReg(fd
, unop(Iop_NegF64
, mkexpr(t1
)));
28602 break; /* NMADD.D */
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 */
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 */
28626 goto decode_failure
;
28630 case 0x22: /* LWL */
28631 DIP("lwl r%u, %u(r%u)", rt
, imm
, rs
);
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
,
28642 mkU64(extend_s_16to64(imm
)))));
28644 /* t2 = word addr */
28645 /* t4 = addr mod 4 */
28648 /* t3 = word content - shifted */
28649 t3
= newTemp(Ity_I32
);
28650 assign(t3
, binop(Iop_Shl32
,
28651 load(Ity_I32
, mkexpr(t2
)),
28659 /* rt content - adjusted */
28660 t5
= newTemp(Ity_I32
);
28661 assign(t5
, binop(Iop_And32
,
28662 mkNarrowTo32(ty
, getIReg(rt
)),
28665 narrowTo(Ity_I8
, binop(Iop_Mul32
,
28669 putIReg(rt
, mkWidenFrom32(ty
, binop(Iop_Or32
, mkexpr(t5
),
28670 mkexpr(t3
)), True
));
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
)))));
28681 /* t2 = word addr */
28682 /* t4 = addr mod 4 */
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
)),
28691 /* rt content - adjusted */
28692 t5
= newTemp(Ity_I32
);
28693 assign(t5
, binop(Iop_And32
,
28697 narrowTo(Ity_I8
, binop(Iop_Mul32
,
28701 putIReg(rt
, binop(Iop_Or32
, mkexpr(t5
), mkexpr(t3
)));
28705 case 0x26: /* LWR */
28706 DIP("lwr r%u, %u(r%u)", rt
, imm
, rs
);
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
,
28717 mkU64(extend_s_16to64(imm
)))));
28719 /* t2 = word addr */
28720 /* t4 = addr mod 4 */
28723 /* t3 = word content - shifted */
28724 t3
= newTemp(Ity_I32
);
28725 assign(t3
, binop(Iop_Shr32
,
28726 load(Ity_I32
, mkexpr(t2
)),
28728 binop(Iop_Shl32
, mkexpr(t4
), mkU8(0x03)))));
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)))))));
28736 putIReg(rt
, mkWidenFrom32(ty
, binop(Iop_Or32
, mkexpr(t5
),
28737 mkexpr(t3
)), True
));
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
)))));
28749 /* t2 = word addr */
28750 /* t4 = addr mod 4 */
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
),
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)))))));
28765 putIReg(rt
, binop(Iop_Or32
, mkexpr(t5
), mkexpr(t3
)));
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
)));
28775 case 0x2C: { /* SDL rt, offset(base) MIPS64 */
28776 DIP("sdl r%u, %u(r%u)", rt
, imm
, rs
);
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
);
28794 assign(H_byte
, getByteFromReg(rt
, 0));
28796 assign(G_byte
, getByteFromReg(rt
, 1));
28798 assign(F_byte
, getByteFromReg(rt
, 2));
28800 assign(E_byte
, getByteFromReg(rt
, 3));
28802 assign(D_byte
, getByteFromReg(rt
, 4));
28804 assign(C_byte
, getByteFromReg(rt
, 5));
28806 assign(B_byte
, getByteFromReg(rt
, 6));
28808 assign(A_byte
, getByteFromReg(rt
, 7));
28811 t1
= newTemp(Ity_I64
);
28812 assign(t1
, binop(Iop_Add64
, getIReg(rs
), mkU64(extend_s_16to64(imm
))));
28814 /* t2 = word addr */
28815 t2
= newTemp(Ity_I64
);
28816 assign(t2
, binop(Iop_And64
, mkexpr(t1
), mkU64(0xFFFFFFFFFFFFFFF8ULL
)));
28818 /* t3 = addr mod 7 */
28819 t3
= newTemp(Ity_I64
);
28820 assign(t3
, binop(Iop_And64
, mkexpr(t1
), mkU64(0x7)));
28822 #if defined (_MIPSEL)
28823 /* Calculate X_byte position. */
28824 assign(B_pos
, IRExpr_ITE(binop(Iop_CmpLT64U
, mkexpr(t3
), mkU64(0x1)),
28828 assign(C_pos
, IRExpr_ITE(binop(Iop_CmpLT64U
, mkexpr(t3
), mkU64(0x2)),
28832 assign(D_pos
, IRExpr_ITE(binop(Iop_CmpLT64U
, mkexpr(t3
), mkU64(0x3)),
28836 assign(E_pos
, IRExpr_ITE(binop(Iop_CmpLT64U
, mkexpr(t3
), mkU64(0x4)),
28840 assign(F_pos
, IRExpr_ITE(binop(Iop_CmpLT64U
, mkexpr(t3
), mkU64(0x5)),
28844 assign(G_pos
, IRExpr_ITE(binop(Iop_CmpEQ64
, mkexpr(t3
), mkU64(0x7)),
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
));
28858 #else /* _MIPSEB */
28859 /* Calculate X_byte position. */
28860 assign(B_pos
, IRExpr_ITE(binop(Iop_CmpEQ64
, mkexpr(t3
), mkU64(0x7)),
28864 assign(C_pos
, IRExpr_ITE(binop(Iop_CmpLT64U
, mkexpr(t3
), mkU64(0x6)),
28868 assign(D_pos
, IRExpr_ITE(binop(Iop_CmpLT64U
, mkexpr(t3
), mkU64(0x5)),
28872 assign(E_pos
, IRExpr_ITE(binop(Iop_CmpLT64U
, mkexpr(t3
), mkU64(0x4)),
28876 assign(F_pos
, IRExpr_ITE(binop(Iop_CmpLT64U
, mkexpr(t3
), mkU64(0x3)),
28880 assign(G_pos
, IRExpr_ITE(binop(Iop_CmpEQ64
, mkexpr(t3
), mkU64(0x0)),
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
));
28899 /* SDR rt, offset(base) - MIPS64 */
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
);
28918 assign(H_byte
, getByteFromReg(rt
, 0));
28920 assign(G_byte
, getByteFromReg(rt
, 1));
28922 assign(F_byte
, getByteFromReg(rt
, 2));
28924 assign(E_byte
, getByteFromReg(rt
, 3));
28926 assign(D_byte
, getByteFromReg(rt
, 4));
28928 assign(C_byte
, getByteFromReg(rt
, 5));
28930 assign(B_byte
, getByteFromReg(rt
, 6));
28932 assign(A_byte
, getByteFromReg(rt
, 7));
28935 t1
= newTemp(Ity_I64
);
28936 assign(t1
, binop(Iop_Add64
, getIReg(rs
), mkU64(extend_s_16to64(imm
))));
28938 /* t2 = word addr */
28939 t2
= newTemp(Ity_I64
);
28940 assign(t2
, binop(Iop_And64
, mkexpr(t1
), mkU64(0xFFFFFFFFFFFFFFF8ULL
)));
28942 /* t3 = addr mod 7 */
28943 t3
= newTemp(Ity_I64
);
28944 assign(t3
, binop(Iop_And64
, mkexpr(t1
), mkU64(0x7)));
28946 #if defined (_MIPSEL)
28947 /* Calculate X_byte position. */
28948 assign(B_pos
, IRExpr_ITE(binop(Iop_CmpLT64U
, mkU64(0x1), mkexpr(t3
)),
28952 assign(C_pos
, IRExpr_ITE(binop(Iop_CmpLT64U
, mkU64(0x2), mkexpr(t3
)),
28956 assign(D_pos
, IRExpr_ITE(binop(Iop_CmpLT64U
, mkU64(0x3), mkexpr(t3
)),
28960 assign(E_pos
, IRExpr_ITE(binop(Iop_CmpLT64U
, mkU64(0x4), mkexpr(t3
)),
28964 assign(F_pos
, IRExpr_ITE(binop(Iop_CmpLT64U
, mkU64(0x5), mkexpr(t3
)),
28968 assign(G_pos
, IRExpr_ITE(binop(Iop_CmpEQ64
, mkexpr(t3
), mkU64(0x7)),
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
));
28982 #else /* _MIPSEB */
28983 /* Calculate X_byte position. */
28984 assign(B_pos
, IRExpr_ITE(binop(Iop_CmpLT64U
, mkU64(0x5), mkexpr(t3
)),
28988 assign(C_pos
, IRExpr_ITE(binop(Iop_CmpLT64U
, mkU64(0x4), mkexpr(t3
)),
28992 assign(D_pos
, IRExpr_ITE(binop(Iop_CmpLT64U
, mkU64(0x3), mkexpr(t3
)),
28996 assign(E_pos
, IRExpr_ITE(binop(Iop_CmpLT64U
, mkU64(0x2), mkexpr(t3
)),
29000 assign(F_pos
, IRExpr_ITE(binop(Iop_CmpLT64U
, mkU64(0x1), mkexpr(t3
)),
29004 assign(G_pos
, IRExpr_ITE(binop(Iop_CmpEQ64
, mkexpr(t3
), mkU64(0x0)),
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
));
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
)));
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
)));
29033 case 0x2A: /* SWL */
29034 DIP("swl r%u, %u(r%u)", rt
, imm
, rs
);
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
);
29044 assign(H_byte
, getByteFromReg(rt
, 0));
29046 assign(G_byte
, getByteFromReg(rt
, 1));
29048 assign(F_byte
, getByteFromReg(rt
, 2));
29050 assign(E_byte
, getByteFromReg(rt
, 3));
29053 t1
= newTemp(Ity_I64
);
29054 assign(t1
, binop(Iop_Add64
, getIReg(rs
), mkU64(extend_s_16to64(imm
))));
29056 /* t2 = word addr */
29057 t2
= newTemp(Ity_I64
);
29058 assign(t2
, binop(Iop_And64
, mkexpr(t1
), mkU64(0xFFFFFFFFFFFFFFFCULL
)));
29060 /* t3 = addr mod 4 */
29061 t3
= newTemp(Ity_I64
);
29062 assign(t3
, binop(Iop_And64
, mkexpr(t1
), mkU64(0x3)));
29064 #if defined (_MIPSEL)
29065 /* Calculate X_byte position. */
29066 assign(F_pos
, IRExpr_ITE(binop(Iop_CmpEQ64
, mkexpr(t3
), mkU64(0x0)),
29070 assign(G_pos
, IRExpr_ITE(binop(Iop_CmpEQ64
, mkexpr(t3
), mkU64(0x3)),
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
));
29080 #else /* _MIPSEB */
29081 /* Calculate X_byte position. */
29082 assign(F_pos
, IRExpr_ITE(binop(Iop_CmpEQ64
, mkexpr(t3
), mkU64(0x3)),
29086 assign(G_pos
, IRExpr_ITE(binop(Iop_CmpEQ64
, mkexpr(t3
), mkU64(0x0)),
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
));
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
);
29105 assign(H_byte
, getByteFromReg(rt
, 0));
29107 assign(G_byte
, getByteFromReg(rt
, 1));
29109 assign(F_byte
, getByteFromReg(rt
, 2));
29111 assign(E_byte
, getByteFromReg(rt
, 3));
29114 t1
= newTemp(Ity_I32
);
29115 assign(t1
, binop(Iop_Add32
, getIReg(rs
), mkU32(extend_s_16to32(imm
))));
29117 /* t2 = word addr */
29118 t2
= newTemp(Ity_I32
);
29119 assign(t2
, binop(Iop_And32
, mkexpr(t1
), mkU32(0xFFFFFFFCULL
)));
29121 /* t3 = addr mod 4 */
29122 t3
= newTemp(Ity_I32
);
29123 assign(t3
, binop(Iop_And32
, mkexpr(t1
), mkU32(0x3)));
29125 #if defined (_MIPSEL)
29126 /* Calculate X_byte position. */
29127 assign(F_pos
, IRExpr_ITE(binop(Iop_CmpEQ32
, mkexpr(t3
), mkU32(0x0)),
29131 assign(G_pos
, IRExpr_ITE(binop(Iop_CmpEQ32
, mkexpr(t3
), mkU32(0x3)),
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
));
29141 #else /* _MIPSEB */
29142 /* Calculate X_byte position. */
29143 assign(F_pos
, IRExpr_ITE(binop(Iop_CmpEQ32
, mkexpr(t3
), mkU32(0x3)),
29147 assign(G_pos
, IRExpr_ITE(binop(Iop_CmpEQ32
, mkexpr(t3
), mkU32(0x0)),
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
));
29160 case 0x2E: /* SWR */
29161 DIP("swr r%u, %u(r%u)", rt
, imm
, rs
);
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
);
29171 assign(H_byte
, getByteFromReg(rt
, 0));
29173 assign(G_byte
, getByteFromReg(rt
, 1));
29175 assign(F_byte
, getByteFromReg(rt
, 2));
29177 assign(E_byte
, getByteFromReg(rt
, 3));
29180 t1
= newTemp(Ity_I64
);
29181 assign(t1
, binop(Iop_Add64
, getIReg(rs
), mkU64(extend_s_16to64(imm
))));
29183 /* t2 = word addr */
29184 t2
= newTemp(Ity_I64
);
29185 assign(t2
, binop(Iop_And64
, mkexpr(t1
), mkU64(0xFFFFFFFFFFFFFFFCULL
)));
29187 /* t3 = addr mod 4 */
29188 t3
= newTemp(Ity_I64
);
29189 assign(t3
, binop(Iop_And64
, mkexpr(t1
), mkU64(0x3)));
29191 #if defined (_MIPSEL)
29192 /* Calculate X_byte position. */
29193 assign(F_pos
, IRExpr_ITE(binop(Iop_CmpEQ64
, mkexpr(t3
), mkU64(0x0)),
29197 assign(G_pos
, IRExpr_ITE(binop(Iop_CmpEQ64
, mkexpr(t3
), mkU64(0x3)),
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
));
29207 #else /* _MIPSEB */
29208 /* Calculate X_byte position. */
29209 assign(F_pos
, IRExpr_ITE(binop(Iop_CmpEQ64
, mkexpr(t3
), mkU64(0x3)),
29213 assign(G_pos
, IRExpr_ITE(binop(Iop_CmpEQ64
, mkexpr(t3
), mkU64(0x0)),
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
));
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
);
29232 assign(H_byte
, getByteFromReg(rt
, 0));
29234 assign(G_byte
, getByteFromReg(rt
, 1));
29236 assign(F_byte
, getByteFromReg(rt
, 2));
29238 assign(E_byte
, getByteFromReg(rt
, 3));
29241 t1
= newTemp(Ity_I32
);
29242 assign(t1
, binop(Iop_Add32
, getIReg(rs
), mkU32(extend_s_16to32(imm
))));
29244 /* t2 = word addr */
29245 t2
= newTemp(Ity_I32
);
29246 assign(t2
, binop(Iop_And32
, mkexpr(t1
), mkU32(0xFFFFFFFCULL
)));
29248 /* t3 = addr mod 4 */
29249 t3
= newTemp(Ity_I32
);
29250 assign(t3
, binop(Iop_And32
, mkexpr(t1
), mkU32(0x3)));
29252 #if defined (_MIPSEL)
29253 /* Calculate X_byte position. */
29254 assign(F_pos
, IRExpr_ITE(binop(Iop_CmpEQ32
, mkexpr(t3
), mkU32(0x0)),
29258 assign(G_pos
, IRExpr_ITE(binop(Iop_CmpEQ32
, mkexpr(t3
), mkU32(0x3)),
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
));
29268 #else /* _MIPSEB */
29269 /* Calculate X_byte position. */
29270 assign(F_pos
, IRExpr_ITE(binop(Iop_CmpEQ32
, mkexpr(t3
), mkU32(0x3)),
29274 assign(G_pos
, IRExpr_ITE(binop(Iop_CmpEQ32
, mkexpr(t3
), mkU32(0x0)),
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
));
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
))
29301 goto decode_failure
;
29303 goto decode_failure
;
29307 case 0x02: { /* MUL */
29308 DIP("mul r%u, r%u, r%u", rd
, rs
, rt
);
29310 IRTemp tmpRs32
= newTemp(Ity_I32
);
29311 IRTemp tmpRt32
= newTemp(Ity_I32
);
29312 IRTemp tmpRes
= newTemp(Ity_I32
);
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
));
29320 putIReg(rd
, binop(Iop_Mul32
, getIReg(rs
), getIReg(rt
)));
29324 case 0x00: { /* MADD */
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
);
29334 assign(t1
, mkNarrowTo32(ty
, getHI()));
29335 assign(t2
, mkNarrowTo32(ty
, getLO()));
29337 assign(t3
, binop(Iop_MullS32
, mkNarrowTo32(ty
, getIReg(rs
)),
29338 mkNarrowTo32(ty
, getIReg(rt
))));
29340 assign(t4
, binop(Iop_32HLto64
, mkexpr(t1
), mkexpr(t2
)));
29341 assign(t5
, binop(Iop_Add64
, mkexpr(t3
), mkexpr(t4
)));
29343 putHI(mkWidenFrom32(ty
, unop(Iop_64HIto32
, mkexpr(t5
)), True
));
29344 putLO(mkWidenFrom32(ty
, unop(Iop_64to32
, mkexpr(t5
)), True
));
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
;
29355 goto decode_failure_dsp
;
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
);
29366 assign(t1
, getHI());
29367 assign(t2
, getLO());
29369 assign(t3
, binop(Iop_MullS32
, getIReg(rs
), getIReg(rt
)));
29371 assign(t4
, binop(Iop_Add32
, mkexpr(t2
), unop(Iop_64to32
,
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
)));
29378 putHI(binop(Iop_Add32
, mkexpr(t6
), unop(Iop_64HIto32
,
29387 case 0x01: { /* MADDU */
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
);
29397 assign(t1
, mkNarrowTo32(ty
, getHI()));
29398 assign(t2
, mkNarrowTo32(ty
, getLO()));
29400 assign(t3
, binop(Iop_MullU32
, mkNarrowTo32(ty
, getIReg(rs
)),
29401 mkNarrowTo32(ty
, getIReg(rt
))));
29403 assign(t4
, binop(Iop_32HLto64
, mkexpr(t1
), mkexpr(t2
)));
29404 assign(t5
, binop(Iop_Add64
, mkexpr(t3
), mkexpr(t4
)));
29406 putHI(mkWidenFrom32(ty
, unop(Iop_64HIto32
, mkexpr(t5
)), True
));
29407 putLO(mkWidenFrom32(ty
, unop(Iop_64to32
, mkexpr(t5
)), True
));
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
;
29418 goto decode_failure_dsp
;
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
);
29429 assign(t1
, getHI());
29430 assign(t2
, getLO());
29432 assign(t3
, binop(Iop_MullU32
, getIReg(rs
), getIReg(rt
)));
29434 assign(t4
, binop(Iop_Add32
, mkexpr(t2
), unop(Iop_64to32
,
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
)));
29440 putHI(binop(Iop_Add32
, mkexpr(t6
), unop(Iop_64HIto32
,
29449 case 0x04: { /* MSUB */
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
);
29459 assign(t1
, mkNarrowTo32(ty
, getHI()));
29460 assign(t2
, mkNarrowTo32(ty
, getLO()));
29462 assign(t3
, binop(Iop_MullS32
, mkNarrowTo32(ty
, getIReg(rs
)),
29463 mkNarrowTo32(ty
, getIReg(rt
))));
29465 assign(t4
, binop(Iop_32HLto64
, mkexpr(t1
), mkexpr(t2
)));
29466 assign(t5
, binop(Iop_Sub64
, mkexpr(t4
), mkexpr(t3
)));
29468 putHI(mkWidenFrom32(ty
, unop(Iop_64HIto32
, mkexpr(t5
)), True
));
29469 putLO(mkWidenFrom32(ty
, unop(Iop_64to32
, mkexpr(t5
)), True
));
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
;
29480 goto decode_failure_dsp
;
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
);
29491 assign(t1
, getHI());
29492 assign(t2
, getLO());
29494 assign(t3
, binop(Iop_MullS32
, getIReg(rs
), getIReg(rt
)));
29495 assign(t4
, unop(Iop_64to32
, mkexpr(t3
))); /* new lo */
29497 /* if lo<lo(mul) hi = hi - 1 */
29498 assign(t5
, binop(Iop_CmpLT32U
,
29502 assign(t6
, IRExpr_ITE(mkexpr(t5
),
29503 binop(Iop_Sub32
, mkexpr(t1
), mkU32(0x1)),
29506 putHI(binop(Iop_Sub32
, mkexpr(t6
), unop(Iop_64HIto32
,
29508 putLO(binop(Iop_Sub32
, mkexpr(t2
), mkexpr(t4
)));
29515 case 0x05: { /* MSUBU */
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
);
29525 assign(t1
, mkNarrowTo32(ty
, getHI()));
29526 assign(t2
, mkNarrowTo32(ty
, getLO()));
29528 assign(t3
, binop(Iop_MullU32
, mkNarrowTo32(ty
, getIReg(rs
)),
29529 mkNarrowTo32(ty
, getIReg(rt
))));
29531 assign(t4
, binop(Iop_32HLto64
, mkexpr(t1
), mkexpr(t2
)));
29532 assign(t5
, binop(Iop_Sub64
, mkexpr(t4
), mkexpr(t3
)));
29534 putHI(mkWidenFrom32(ty
, unop(Iop_64HIto32
, mkexpr(t5
)), True
));
29535 putLO(mkWidenFrom32(ty
, unop(Iop_64to32
, mkexpr(t5
)), True
));
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
;
29546 goto decode_failure_dsp
;
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
);
29557 assign(t1
, getHI());
29558 assign(t2
, getLO());
29560 assign(t3
, binop(Iop_MullU32
, getIReg(rs
), getIReg(rt
)));
29561 assign(t4
, unop(Iop_64to32
, mkexpr(t3
))); /* new lo */
29563 /* if lo<lo(mul) hi = hi - 1 */
29564 assign(t5
, binop(Iop_CmpLT32U
,
29568 assign(t6
, IRExpr_ITE(mkexpr(t5
),
29574 putHI(binop(Iop_Sub32
, mkexpr(t6
), unop(Iop_64HIto32
,
29576 putLO(binop(Iop_Sub32
, mkexpr(t2
), mkexpr(t4
)));
29583 case 0x6: /* dmul MIPS64 - Netlogic */
29584 DIP("dmul r%u, r%u, r%u", rd
, rs
, rt
);
29585 t0
= newTemp(Ity_I128
);
29587 assign(t0
, binop(Iop_MullU64
, getIReg(rs
), getIReg(rt
)));
29589 putIReg(rd
, unop(Iop_128to64
, mkexpr(t0
)));
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
);
29603 assign(t0
, mkNarrowTo32(ty
, getIReg(rt
)));
29605 /* GPR[rt] = memory[base]; */
29606 assign(t1
, load(Ity_I32
, getIReg(rs
)));
29607 putIReg(rt
, mkWidenFrom32(ty
, mkexpr(t1
), True
));
29609 /* memory[base] = memory[base] + v; */
29610 store(getIReg(rs
), binop(Iop_Add32
, mkexpr(t0
), mkexpr(t1
)));
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
);
29619 assign(t0
, getIReg(rt
));
29621 /* GPR[rt] = memory[base]; */
29622 assign(t1
, load(Ity_I64
, getIReg(rs
)));
29623 putIReg(rt
, mkexpr(t1
));
29625 /* memory[base] = memory[base] + v; */
29626 store(getIReg(rs
), binop(Iop_Add64
, mkexpr(t0
), mkexpr(t1
)));
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
));
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
));
29649 case 0x20: { /* CLZ */
29650 DIP("clz r%u, r%u", rd
, rs
);
29652 IRTemp tmpClz32
= newTemp(Ity_I32
);
29653 IRTemp tmpRs32
= newTemp(Ity_I32
);
29655 assign(tmpRs32
, mkNarrowTo32(ty
, getIReg(rs
)));
29656 assign(tmpClz32
, unop(Iop_Clz32
, mkexpr(tmpRs32
)));
29657 putIReg(rd
, mkWidenFrom32(ty
, mkexpr(tmpClz32
), True
));
29659 t1
= newTemp(Ity_I1
);
29660 assign(t1
, binop(Iop_CmpEQ32
, getIReg(rs
), mkU32(0)));
29661 putIReg(rd
, IRExpr_ITE(mkexpr(t1
),
29663 unop(Iop_Clz32
, getIReg(rs
))));
29668 case 0x21: { /* CLO */
29669 DIP("clo r%u, r%u", rd
, rs
);
29671 IRTemp tmpClo32
= newTemp(Ity_I32
);
29672 IRTemp tmpRs32
= newTemp(Ity_I32
);
29673 assign(tmpRs32
, mkNarrowTo32(ty
, getIReg(rs
)));
29675 t1
= newTemp(Ity_I1
);
29676 assign(t1
, binop(Iop_CmpEQ32
, mkexpr(tmpRs32
), mkU32(0xffffffff)));
29677 assign(tmpClo32
, IRExpr_ITE(mkexpr(t1
),
29679 unop(Iop_Clz32
, unop(Iop_Not32
, mkexpr(tmpRs32
)))));
29681 putIReg(rd
, mkWidenFrom32(ty
, mkexpr(tmpClo32
), True
));
29684 t1
= newTemp(Ity_I1
);
29685 assign(t1
, binop(Iop_CmpEQ32
, getIReg(rs
), mkU32(0xffffffff)));
29686 putIReg(rd
, IRExpr_ITE(mkexpr(t1
),
29689 unop(Iop_Not32
, getIReg(rs
)))));
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
),
29700 unop(Iop_Clz64
, getIReg(rs
))));
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
),
29710 unop(Iop_Clz64
, unop(Iop_Not64
,
29715 goto decode_failure
;
29719 case 0x1F: /* Special3 */
29720 switch (function
) {
29722 /* Doubleword Extract Bit Field - DEXTM; MIPS64r2 */
29723 msb
= get_msb(cins
);
29724 lsb
= get_lsb(cins
);
29727 UInt dstSz
= msb
+ 33;
29728 t1
= newTemp(Ity_I64
);
29729 DIP("dextm r%u, r%u, %u, %u", rt
, rs
, lsb
, msb
+ 1);
29731 UChar lsAmt
= 64 - (srcPos
+ dstSz
); /* left shift amount; */
29732 UChar rsAmt
= 64 - dstSz
; /* right shift amount; */
29734 assign(t1
, binop(Iop_Shl64
, getIReg(rs
), mkU8(lsAmt
)));
29735 putIReg(rt
, binop(Iop_Shr64
, mkexpr(t1
), mkU8(rsAmt
)));
29740 /* Doubleword Extract Bit Field Upper - DEXTU; MIPS64r2 */
29741 msb
= get_msb(cins
);
29742 lsb
= get_lsb(cins
);
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
);
29749 vassert(srcPos
>= 32 && srcPos
< 64);
29750 vassert(dstSz
> 0 && dstSz
<= 32);
29751 vassert((srcPos
+ dstSz
) > 32 && (srcPos
+ dstSz
) <= 64);
29753 UChar lsAmt
= 64 - (srcPos
+ dstSz
); /* left shift amount; */
29754 UChar rsAmt
= 64 - dstSz
; /* right shift amount; */
29756 assign(t1
, binop(Iop_Shl64
, getIReg(rs
), mkU8(lsAmt
)));
29757 putIReg(rt
, binop(Iop_Shr64
, mkexpr(t1
), mkU8(rsAmt
)));
29761 /* Doubleword Insert Bit Field Middle - DINSM; MIPS64r2 */
29762 msb
= get_msb(cins
);
29763 lsb
= get_lsb(cins
);
29766 UInt srcSz
= msb
- lsb
+ 33;
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
);
29782 assign(tmpRs
, getIReg(rs
));
29783 assign(tmpRt
, getIReg(rt
));
29784 DIP("dinsm r%u, r%u, %u, %u", rt
, rs
, lsb
, msb
);
29786 UChar lsAmt
= dstPos
+ srcSz
- 1; /* left shift amount; */
29787 UChar rsAmt
= dstPos
+ srcSz
- 1; /* right shift amount; */
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)));
29794 lsAmt
= 63 - dstPos
; /* left shift amount; */
29795 rsAmt
= 63 - dstPos
; /* right shift amount; */
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)));
29802 /* extract size from src register */
29803 lsAmt
= 64 - srcSz
; /* left shift amount; */
29804 rsAmt
= 64 - (lsb
+ srcSz
); /* right shift amount; */
29806 assign(tmpT5
, binop(Iop_Shl64
, mkexpr(tmpRs
), mkU8(lsAmt
)));
29807 assign(tmpT6
, binop(Iop_Shr64
, mkexpr(tmpT5
), mkU8(rsAmt
)));
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
));
29815 /* Doubleword Insert Bit Field Upper - DINSU; MIPS64r2 */
29816 msb
= get_msb(cins
);
29817 lsb
= get_lsb(cins
);
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
);
29834 assign(tmpRs
, getIReg(rs
));
29835 assign(tmpRt
, getIReg(rt
));
29836 DIP("dinsu r%u, r%u, %u, %u", rt
, rs
, lsb
, msb
);
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
)));
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
)));
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
)));
29853 assign(tmpT7
, binop(Iop_Shl64
, mkexpr(tmpT6
), mkU8(rsAmt
)));
29854 assign(tmpT8
, binop(Iop_Shl64
, mkexpr(tmpT7
), mkU8(lsAmt
)));
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
));
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
);
29878 assign(tmpRs
, getIReg(rs
));
29879 assign(tmpRt
, getIReg(rt
));
29881 msb
= get_msb(cins
);
29882 lsb
= get_lsb(cins
);
29884 DIP("dins r%u, r%u, %u, %u", rt
, rs
, lsb
,
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)));
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
)));
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
)));
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
));
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
));
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
));
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
));
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;
29965 putIReg(rd
, binop(Iop_Or64
,
29966 binop(Iop_Shl64
, getIReg(rt
), mkU8(bp
)),
29968 getIReg(rs
), mkU8(64 - bp
))));
29970 putIReg(rd
, getIReg(rt
));
29972 ILLEGAL_INSTRUCTON
;
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)));
29982 ILLEGAL_INSTRUCTON
;
29986 vex_printf("\nop6o10 = %u", lsb
);
29987 goto decode_failure
;;
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
)) {
29996 putIReg(rt
, getULR());
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
,
30005 "mips_dirtyhelper_rdhwr",
30006 &mips_dirtyhelper_rdhwr
,
30008 stmt(IRStmt_Dirty(d
));
30009 putIReg(rt
, mkexpr(val
));
30011 goto decode_failure
;
30013 ILLEGAL_INSTRUCTON
;
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
);
30022 vassert(lsb
+ size
<= 32);
30023 vassert(lsb
+ size
> 0);
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
30030 assign(t0
, binop(Iop_Shl32
, mkNarrowTo32(ty
, getIReg(rs
)),
30032 /* now set it at pos */
30033 t1
= newTemp(Ity_I32
);
30034 assign(t1
, binop(Iop_Shr32
, mkexpr(t0
), mkU8(32 - size
- lsb
)));
30037 t2
= newTemp(Ity_I32
);
30038 /* clear everything but lower pos bits from rt */
30039 assign(t2
, binop(Iop_Shl32
, mkNarrowTo32(ty
, getIReg(rt
)),
30041 assign(t3
, binop(Iop_Shr32
, mkexpr(t2
), mkU8(32 - lsb
)));
30043 assign(t3
, mkU32(0));
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
)),
30050 t5
= newTemp(Ity_I32
);
30051 assign(t5
, binop(Iop_Shl32
, mkexpr(t4
), mkU8(msb
+ 1)));
30053 /* now combine these registers */
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
));
30060 putIReg(rt
, mkWidenFrom32(ty
, binop(Iop_Or32
, mkexpr(t1
),
30061 mkexpr(t5
)), True
));
30064 putIReg(rt
, mkWidenFrom32(ty
, binop(Iop_Or32
, mkexpr(t1
),
30065 mkexpr(t3
)), True
));
30069 case 0x00: /* EXT */
30070 msb
= get_msb(cins
);
30071 lsb
= get_lsb(cins
);
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
)));
30082 putIReg(rt
, mkWidenFrom32(ty
, binop(Iop_Shr32
, mkexpr(t0
),
30083 mkU8(32 - size
)), True
));
30085 putIReg(rt
, mkWidenFrom32(ty
, binop(Iop_Shr32
,
30086 mkNarrowTo32(ty
, getIReg(rs
)),
30087 mkU8(32 - size
)), True
));
30091 case 0x03: /* Doubleword Extract Bit Field - DEXT; MIPS64r2 */
30092 msb
= get_msb(cins
);
30093 lsb
= get_lsb(cins
);
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);
30101 UChar lsAmt
= 63 - (lsb
+ msb
); /* left shift amount; */
30102 UChar rsAmt
= 63 - msb
; /* right shift amount; */
30104 assign(t1
, binop(Iop_Shl64
, getIReg(rs
), mkU8(lsAmt
)));
30105 putIReg(rt
, binop(Iop_Shr64
, mkexpr(t1
), mkU8(rsAmt
)));
30109 case 0x20: /* BSHFL */
30111 case 0x0: /* BITSWAP */
30112 if (VEX_MIPS_CPU_HAS_MIPSR6(archinfo
->hwcaps
)) {
30113 DIP("bitswap r%u, r%u", rd
, rt
);
30115 putIReg(rd
, unop(Iop_32Uto64
, qop(Iop_Rotx32
, unop(Iop_64to32
, getIReg(rt
)),
30116 mkU8(7), mkU8(8), mkU8(1))));
30118 putIReg(rd
, qop(Iop_Rotx32
, getIReg(rt
), mkU8(7),
30119 mkU8(8), mkU8(1)));
30122 ILLEGAL_INSTRUCTON
;
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)),
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
));
30147 case 0x10: /* SEB */
30148 DIP("seb r%u, r%u", rd
, rt
);
30150 putIReg(rd
, unop(Iop_8Sto64
, unop(Iop_64to8
, getIReg(rt
))));
30152 putIReg(rd
, unop(Iop_8Sto32
, unop(Iop_32to8
, getIReg(rt
))));
30155 case 0x18: /* SEH */
30156 DIP("seh r%u, r%u", rd
, rt
);
30158 putIReg(rd
, unop(Iop_16Sto64
, unop(Iop_64to16
, getIReg(rt
))));
30160 putIReg(rd
, unop(Iop_16Sto32
, unop(Iop_32to16
, getIReg(rt
))));
30163 case 0x08 ... 0x0b: /* ALIGN */
30164 if (VEX_MIPS_CPU_HAS_MIPSR6(archinfo
->hwcaps
)) {
30166 UInt bp
= (sa
& 0x3) << 3;
30168 putIReg(rd
, unop(Iop_32Sto64
,
30179 putIReg(rd
, getIReg(rt
));
30181 UInt bp
= (sa
& 0x3) << 3;
30183 putIReg(rd
, binop(Iop_Or32
,
30185 getIReg(rt
), mkU8(bp
)),
30187 getIReg(rs
), mkU8(32 - bp
))));
30189 putIReg(rd
, getIReg(rt
));
30192 ILLEGAL_INSTRUCTON
;
30197 goto decode_failure
;
30202 /* --- MIPS32(r2) DSP ASE(r2) / Cavium Specfic (LX) instructions --- */
30204 if (VEX_MIPS_COMP_ID(archinfo
->hwcaps
) == VEX_PRID_COMP_CAVIUM
) {
30205 if (dis_instr_CVM(cins
))
30207 goto decode_failure
;
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
;
30218 goto decode_failure_dsp
;
30222 case 0x10: { /* ADDU.QB */
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
;
30234 goto decode_failure_dsp
;
30239 if (VEX_MIPS_PROC_DSP(archinfo
->hwcaps
)) {
30240 UInt retVal
= disDSPInstr_MIPS_WRK ( cins
);
30241 if (0 != retVal
) {
30242 goto decode_failure_dsp
;
30246 goto decode_failure_dsp
;
30253 case 0x11: { /* CMPU.EQ.QB */
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
;
30268 goto decode_failure_dsp
;
30273 if (VEX_MIPS_PROC_DSP(archinfo
->hwcaps
)) {
30274 UInt retVal
= disDSPInstr_MIPS_WRK ( cins
);
30275 if (0 != retVal
) {
30276 goto decode_failure_dsp
;
30280 goto decode_failure_dsp
;
30287 case 0x12: { /* ABSQ_S.PH */
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
;
30297 goto decode_failure_dsp
;
30302 if (VEX_MIPS_PROC_DSP(archinfo
->hwcaps
)) {
30303 UInt retVal
= disDSPInstr_MIPS_WRK ( cins
);
30304 if (0 != retVal
) {
30305 goto decode_failure_dsp
;
30309 goto decode_failure_dsp
;
30316 case 0x13: { /* SHLL.QB */
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
;
30331 goto decode_failure_dsp
;
30336 if (VEX_MIPS_PROC_DSP(archinfo
->hwcaps
)) {
30337 UInt retVal
= disDSPInstr_MIPS_WRK ( cins
);
30338 if (0 != retVal
) {
30339 goto decode_failure_dsp
;
30343 goto decode_failure_dsp
;
30350 case 0x30: { /* DPAQ.W.PH */
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
;
30368 goto decode_failure_dsp
;
30373 if (VEX_MIPS_PROC_DSP(archinfo
->hwcaps
)) {
30374 UInt retVal
= disDSPInstr_MIPS_WRK ( cins
);
30375 if (0 != retVal
) {
30376 goto decode_failure_dsp
;
30380 goto decode_failure_dsp
;
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
;
30396 goto decode_failure_dsp
;
30399 case 0x35: { /* PREF r6*/
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
;
30408 assign(t2
, mkWidenFrom32(ty
, load(Ity_I32
, mkexpr(t1
)), True
));
30409 putLLaddr(mkexpr(t1
));
30410 putLLdata(mkexpr(t2
));
30411 putIReg(rt
, mkexpr(t2
));
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
;
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));
30427 mips_next_insn_if(mkexpr(t2
));
30429 t4
= newTemp(Ity_I32
);
30430 t5
= newTemp(Ity_I32
);
30432 assign(t5
, mkNarrowTo32(ty
, getLLdata()));
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 */)));
30439 putIReg(rt
, unop(mode64
? Iop_1Uto64
: Iop_1Uto32
,
30440 binop(Iop_CmpEQ32
, mkexpr(t4
), mkexpr(t5
))));
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
;
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
));
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
;
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));
30467 mips_next_insn_if(mkexpr(t2
));
30469 t4
= newTemp(Ity_I64
);
30470 t5
= newTemp(Ity_I64
);
30472 assign(t5
, getLLdata());
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 */)));
30479 putIReg(rt
, unop(Iop_1Uto64
,
30480 binop(Iop_CmpEQ64
, mkexpr(t4
), mkexpr(t5
))));
30484 goto decode_failure
;
30487 break; /* Special3 */
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
);
30494 putIReg(rs
, mkU64(guest_PC_curr_instr
+ (imm
<< 16)));
30496 putIReg(rs
, mkU32(guest_PC_curr_instr
+ (imm
<< 16)));
30499 ILLEGAL_INSTRUCTON
;
30502 } else if (rt
== 0x1F) { /* ALUIPC */
30503 if (VEX_MIPS_CPU_HAS_MIPSR6(archinfo
->hwcaps
)) {
30504 DIP("aluipc r%u, %u", rs
, imm
);
30506 putIReg(rs
, mkU64((~0x0FFFFULL
) &
30507 (guest_PC_curr_instr
+ extend_s_32to64(imm
<< 16))));
30509 putIReg(rs
, mkU32((~0x0FFFFULL
) &
30510 (guest_PC_curr_instr
+ (imm
<< 16))));
30513 ILLEGAL_INSTRUCTON
;
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);
30520 putIReg(rs
, mkU64(guest_PC_curr_instr
+
30521 (extend_s_19to64(instr_index
& 0x7FFFF) << 2)));
30523 putIReg(rs
, mkU32(guest_PC_curr_instr
+
30524 (extend_s_19to32(instr_index
& 0x7FFFF) << 2)));
30527 ILLEGAL_INSTRUCTON
;
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);
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
))));
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
)));
30545 ILLEGAL_INSTRUCTON
;
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);
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
))));
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
)));
30563 ILLEGAL_INSTRUCTON
;
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
)));
30574 ILLEGAL_INSTRUCTON
;
30578 goto decode_failure
;
30581 if (0x3B == function
&&
30582 (VEX_MIPS_COMP_ID(archinfo
->hwcaps
) == VEX_PRID_COMP_BROADCOM
)) {
30584 DIP("rdhwr r%u, r%u", rt
, rd
);
30586 putIReg(rt
, getULR());
30588 goto decode_failure
;
30591 goto decode_failure
;
30594 case 0x00: /* Special */
30596 switch (function
) {
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
);
30605 assign(t1
, binop(Iop_CmpEQ32
, mkU32(0), mkU32(mov_cc
)));
30606 assign(t2
, IRExpr_ITE(mkexpr(t1
),
30608 binop(Iop_Shr32
, getFCSR(),
30612 binop(Iop_Shr32
, getFCSR(),
30613 mkU8(24 + mov_cc
)),
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
);
30624 assign(t1
, binop(Iop_CmpEQ32
, mkU32(0), mkU32(mov_cc
)));
30625 assign(t2
, IRExpr_ITE(mkexpr(t1
),
30627 binop(Iop_Shr32
, getFCSR(),
30631 binop(Iop_Shr32
, getFCSR(),
30632 mkU8(24 + mov_cc
)),
30635 assign(t3
, binop(Iop_CmpEQ32
, mkU32(1), mkexpr(t2
)));
30636 putIReg(rd
, IRExpr_ITE(mkexpr(t3
), getIReg(rs
), getIReg(rd
)));
30640 case 0x0A: { /* MOVZ */
30641 DIP("movz r%u, r%u, r%u", rd
, rs
, rt
);
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
))));
30652 assign(t1
, unop(Iop_1Sto32
, binop(Iop_CmpEQ32
, getIReg(rt
),
30654 assign(t2
, unop(Iop_1Sto32
, binop(Iop_CmpNE32
, getIReg(rt
),
30656 putIReg(rd
, binop(Iop_Add32
, binop(Iop_And32
, getIReg(rs
),
30657 mkexpr(t1
)), binop(Iop_And32
, getIReg(rd
),
30663 case 0x0B: { /* MOVN */
30664 DIP("movn r%u, r%u, r%u", rd
, rs
, rt
);
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
),
30676 assign(t1
, unop(Iop_1Sto32
, binop(Iop_CmpEQ32
, getIReg(rt
),
30678 assign(t2
, unop(Iop_1Sto32
, binop(Iop_CmpNE32
, getIReg(rt
),
30680 putIReg(rd
, binop(Iop_Add32
, binop(Iop_And32
, getIReg(rs
),
30681 mkexpr(t2
)), binop(Iop_And32
, getIReg(rd
),
30687 case 0x18: { /* MULT */
30688 switch (sa
& 0x3) {
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
);
30695 goto decode_failure_dsp
;
30699 goto decode_failure_dsp
;
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
;
30707 t2
= newTemp(Ity_I64
);
30709 assign(t2
, binop(Iop_MullS32
, mkNarrowTo32(ty
, getIReg(rs
)),
30710 mkNarrowTo32(ty
, getIReg(rt
))));
30712 putHI(mkWidenFrom32(ty
, unop(Iop_64HIto32
, mkexpr(t2
)), True
));
30713 putLO(mkWidenFrom32(ty
, unop(Iop_64to32
, mkexpr(t2
)), True
));
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
);
30721 putIReg(rd
, unop(Iop_32Sto64
,
30724 unop(Iop_64to32
, getIReg(rs
)),
30725 unop(Iop_64to32
, getIReg(rt
))))));
30727 putIReg(rd
, unop(Iop_64to32
,
30729 getIReg(rs
), getIReg(rt
))));
30732 ILLEGAL_INSTRUCTON
;
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
);
30741 putIReg(rd
, unop(Iop_32Sto64
,
30744 unop(Iop_64to32
, getIReg(rs
)),
30745 unop(Iop_64to32
, getIReg(rt
))))));
30747 putIReg(rd
, unop(Iop_64HIto32
,
30749 getIReg(rs
), getIReg(rt
))));
30752 ILLEGAL_INSTRUCTON
;
30760 case 0x19: { /* MULTU */
30761 switch (sa
& 0x3) {
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
);
30768 goto decode_failure_dsp
;
30772 goto decode_failure_dsp
;
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
;
30780 t2
= newTemp(Ity_I64
);
30782 assign(t2
, binop(Iop_MullU32
, mkNarrowTo32(ty
, getIReg(rs
)),
30783 mkNarrowTo32(ty
, getIReg(rt
))));
30785 putHI(mkWidenFrom32(ty
, unop(Iop_64HIto32
, mkexpr(t2
)), True
));
30786 putLO(mkWidenFrom32(ty
, unop(Iop_64to32
, mkexpr(t2
)), True
));
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
);
30794 putIReg(rd
, unop(Iop_32Uto64
,
30797 unop(Iop_64to32
, getIReg(rs
)),
30798 unop(Iop_64to32
, getIReg(rt
))))));
30800 putIReg(rd
, unop(Iop_64to32
,
30802 getIReg(rs
), getIReg(rt
))));
30805 ILLEGAL_INSTRUCTON
;
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
);
30813 putIReg(rd
, unop(Iop_32Uto64
,
30816 unop(Iop_64to32
, getIReg(rs
)),
30817 unop(Iop_64to32
, getIReg(rt
))))));
30819 putIReg(rd
, unop(Iop_64HIto32
,
30821 getIReg(rs
), getIReg(rt
))));
30824 ILLEGAL_INSTRUCTON
;
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
);
30837 assign(tmpRs32
, mkNarrowTo32(ty
, getIReg(rs
)));
30838 assign(tmpRt32
, mkNarrowTo32(ty
, getIReg(rt
)));
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 ))
30848 if (sign(dst) == sign(src0 ))
30850 we have overflow! */
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
,
30856 binop(Iop_And32
, mkexpr(t1
), mkU32(0x80000000)),
30857 mkU32(0x80000000))));
30859 assign(t3
, binop(Iop_Xor32
, mkexpr(t0
), mkexpr(tmpRs32
)));
30860 assign(t4
, unop(Iop_1Uto32
,
30862 binop(Iop_And32
, mkexpr(t3
), mkU32(0x80000000)),
30863 mkU32(0x80000000))));
30865 stmt(IRStmt_Exit(binop(Iop_CmpEQ32
,
30866 binop(Iop_Or32
, mkexpr(t2
), mkexpr(t4
)),
30869 mode64
? IRConst_U64(guest_PC_curr_instr
+ 4) :
30870 IRConst_U32(guest_PC_curr_instr
+ 4),
30873 putIReg(rd
, mkWidenFrom32(ty
, mkexpr(t0
), True
));
30877 case 0x1A: /* DIV */
30878 switch (sa
& 0x3) {
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
;
30886 t2
= newTemp(Ity_I64
);
30888 assign(t2
, binop(Iop_DivModS32to32
,
30889 mkNarrowTo32(ty
, getIReg(rs
)),
30890 mkNarrowTo32(ty
, getIReg(rt
))));
30892 putHI(mkWidenFrom32(ty
, unop(Iop_64HIto32
, mkexpr(t2
)), True
));
30893 putLO(mkWidenFrom32(ty
, unop(Iop_64to32
, mkexpr(t2
)), True
));
30895 t1
= newTemp(Ity_I64
);
30897 assign(t1
, binop(Iop_DivModS32to32
, getIReg(rs
), getIReg(rt
)));
30899 putHI(unop(Iop_64HIto32
, mkexpr(t1
)));
30900 putLO(unop(Iop_64to32
, mkexpr(t1
)));
30904 if (VEX_MIPS_CPU_HAS_MIPSR6(archinfo
->hwcaps
)) {
30905 DIP("div r%u, r%u, r%u", rs
, rt
, rd
);
30907 putIReg(rd
, unop(Iop_32Sto64
,
30909 unop(Iop_64to32
, getIReg(rs
)),
30910 unop(Iop_64to32
, getIReg(rt
)))));
30912 putIReg(rd
, binop(Iop_DivS32
, getIReg(rs
), getIReg(rt
)));
30914 ILLEGAL_INSTRUCTON
;
30918 if (VEX_MIPS_CPU_HAS_MIPSR6(archinfo
->hwcaps
)) {
30919 DIP("mod r%u, r%u, r%u", rs
, rt
, rd
);
30921 putIReg(rd
, unop(Iop_32Sto64
,
30923 binop(Iop_DivModS32to32
,
30924 unop(Iop_64to32
, getIReg(rs
)),
30925 unop(Iop_64to32
, getIReg(rt
))))));
30927 t1
= newTemp(Ity_I64
);
30929 assign(t1
, binop(Iop_DivModS32to32
, getIReg(rs
), getIReg(rt
)));
30930 putIReg(rd
, unop(Iop_64HIto32
, mkexpr(t1
)));
30933 ILLEGAL_INSTRUCTON
;
30939 case 0x1B: /* DIVU */
30940 switch (sa
& 0x3) {
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
;
30948 t1
= newTemp(Ity_I64
);
30950 assign(t1
, binop(Iop_DivModU32to32
,
30951 mkNarrowTo32(ty
, getIReg(rs
)),
30952 mkNarrowTo32(ty
, getIReg(rt
))));
30954 putHI(mkWidenFrom32(ty
, unop(Iop_64HIto32
, mkexpr(t1
)), True
));
30955 putLO(mkWidenFrom32(ty
, unop(Iop_64to32
, mkexpr(t1
)), True
));
30957 t1
= newTemp(Ity_I64
);
30959 assign(t1
, binop(Iop_DivModU32to32
, getIReg(rs
), getIReg(rt
)));
30960 putHI(unop(Iop_64HIto32
, mkexpr(t1
)));
30961 putLO(unop(Iop_64to32
, mkexpr(t1
)));
30965 if (VEX_MIPS_CPU_HAS_MIPSR6(archinfo
->hwcaps
)) {
30966 DIP("divu r%u, r%u, r%u", rs
, rt
, rd
);
30968 putIReg(rd
, unop(Iop_32Sto64
,
30970 unop(Iop_64to32
, getIReg(rs
)),
30971 unop(Iop_64to32
, getIReg(rt
)))));
30973 putIReg(rd
, binop(Iop_DivU32
, getIReg(rs
), getIReg(rt
)));
30977 ILLEGAL_INSTRUCTON
;
30981 if (VEX_MIPS_CPU_HAS_MIPSR6(archinfo
->hwcaps
)) {
30982 DIP("modu r%u, r%u, r%u", rs
, rt
, rd
);
30984 putIReg(rd
, unop(Iop_32Uto64
,
30986 binop(Iop_DivModU32to32
,
30987 unop(Iop_64to32
, getIReg(rs
)),
30988 unop(Iop_64to32
, getIReg(rt
))))));
30990 t1
= newTemp(Ity_I64
);
30992 assign(t1
, binop(Iop_DivModU32to32
, getIReg(rs
), getIReg(rt
)));
30993 putIReg(rd
, unop(Iop_64HIto32
, mkexpr(t1
)));
30996 ILLEGAL_INSTRUCTON
;
31002 case 0x1C: /* Doubleword Multiply - DMULT; MIPS64 */
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
;
31010 t0
= newTemp(Ity_I128
);
31012 assign(t0
, binop(Iop_MullS64
, getIReg(rs
), getIReg(rt
)));
31014 putHI(unop(Iop_128HIto64
, mkexpr(t0
)));
31015 putLO(unop(Iop_128to64
, mkexpr(t0
)));
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
))));
31023 ILLEGAL_INSTRUCTON
;
31025 /* Value for function in documentation is 111000 */
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
))));
31033 ILLEGAL_INSTRUCTON
;
31039 case 0x1D: /* Doubleword Multiply Unsigned - DMULTU; MIPS64 */
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
;
31047 t0
= newTemp(Ity_I128
);
31049 assign(t0
, binop(Iop_MullU64
, getIReg(rs
), getIReg(rt
)));
31051 putHI(unop(Iop_128HIto64
, mkexpr(t0
)));
31052 putLO(unop(Iop_128to64
, mkexpr(t0
)));
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
))));
31060 ILLEGAL_INSTRUCTON
;
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
))));
31069 ILLEGAL_INSTRUCTON
;
31075 case 0x1E: /* Doubleword Divide DDIV; MIPS64 */
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
;
31083 t1
= newTemp(Ity_I128
);
31085 assign(t1
, binop(Iop_DivModS64to64
, getIReg(rs
), getIReg(rt
)));
31087 putHI(unop(Iop_128HIto64
, mkexpr(t1
)));
31088 putLO(unop(Iop_128to64
, mkexpr(t1
)));
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
))));
31097 ILLEGAL_INSTRUCTON
;
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
)));
31107 ILLEGAL_INSTRUCTON
;
31113 case 0x1F: /* Doubleword Divide Unsigned DDIVU; MIPS64 check this */
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
;
31121 t1
= newTemp(Ity_I128
);
31123 assign(t1
, binop(Iop_DivModU64to64
, getIReg(rs
), getIReg(rt
)));
31125 putHI(unop(Iop_128HIto64
, mkexpr(t1
)));
31126 putLO(unop(Iop_128to64
, mkexpr(t1
)));
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
))));
31134 ILLEGAL_INSTRUCTON
;
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
))));
31143 ILLEGAL_INSTRUCTON
;
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
);
31154 IRTemp tmpClz32
= newTemp(Ity_I32
);
31155 IRTemp tmpRs32
= newTemp(Ity_I32
);
31157 assign(tmpRs32
, mkNarrowTo32(ty
, getIReg(rs
)));
31158 assign(tmpClz32
, unop(Iop_Clz32
, mkexpr(tmpRs32
)));
31159 putIReg(rd
, mkWidenFrom32(ty
, mkexpr(tmpClz32
), True
));
31161 t1
= newTemp(Ity_I1
);
31162 assign(t1
, binop(Iop_CmpEQ32
, getIReg(rs
), mkU32(0)));
31163 putIReg(rd
, IRExpr_ITE(mkexpr(t1
),
31165 unop(Iop_Clz32
, getIReg(rs
))));
31168 ILLEGAL_INSTRUCTON
;
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
;
31179 DIP("mfhi r%u", rd
);
31180 putIReg(rd
, getHI());
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
);
31190 IRTemp tmpClo32
= newTemp(Ity_I32
);
31191 IRTemp tmpRs32
= newTemp(Ity_I32
);
31192 assign(tmpRs32
, mkNarrowTo32(ty
, getIReg(rs
)));
31194 t1
= newTemp(Ity_I1
);
31195 assign(t1
, binop(Iop_CmpEQ32
, mkexpr(tmpRs32
), mkU32(0xffffffff)));
31196 assign(tmpClo32
, IRExpr_ITE(mkexpr(t1
),
31198 unop(Iop_Clz32
, unop(Iop_Not32
, mkexpr(tmpRs32
)))));
31200 putIReg(rd
, mkWidenFrom32(ty
, mkexpr(tmpClo32
), True
));
31203 t1
= newTemp(Ity_I1
);
31204 assign(t1
, binop(Iop_CmpEQ32
, getIReg(rs
), mkU32(0xffffffff)));
31205 putIReg(rd
, IRExpr_ITE(mkexpr(t1
),
31208 unop(Iop_Not32
, getIReg(rs
)))));
31211 ILLEGAL_INSTRUCTON
;
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
;
31222 DIP("mthi r%u", rs
);
31223 putHI(getIReg(rs
));
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
;
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
;
31244 putIReg(rd
, getLO());
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
),
31252 unop(Iop_Clz64
, getIReg(rs
))));
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
;
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
;
31275 putLO(getIReg(rs
));
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
),
31284 unop(Iop_Clz64
, unop(Iop_Not64
,
31292 case 0x21: /* ADDU */
31293 DIP("addu r%u, r%u, r%u", rd
, rs
, rt
);
31295 ALU_PATTERN64(Iop_Add32
);
31297 ALU_PATTERN(Iop_Add32
);
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
);
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) ))
31317 if(sign(dst) == sign(src0 ))
31319 we have overflow! */
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))));
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))));
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),
31337 putIReg(rd
, mkWidenFrom32(ty
, mkexpr(t0
), True
));
31340 case 0x23: /* SUBU */
31341 DIP("subu r%u, r%u, r%u", rd
, rs
, rt
);
31343 ALU_PATTERN64(Iop_Sub32
);
31345 ALU_PATTERN(Iop_Sub32
);
31349 case 0x24: /* AND */
31350 DIP("and r%u, r%u, r%u", rd
, rs
, rt
);
31352 ALU_PATTERN(Iop_And64
);
31354 ALU_PATTERN(Iop_And32
);
31358 case 0x25: /* OR */
31359 DIP("or r%u, r%u, r%u", rd
, rs
, rt
);
31361 ALU_PATTERN(Iop_Or64
);
31363 ALU_PATTERN(Iop_Or32
);
31367 case 0x26: /* XOR */
31368 DIP("xor r%u, r%u, r%u", rd
, rs
, rt
);
31370 ALU_PATTERN(Iop_Xor64
);
31372 ALU_PATTERN(Iop_Xor32
);
31376 case 0x27: /* NOR */
31377 DIP("nor r%u, r%u, r%u", rd
, rs
, rt
);
31379 putIReg(rd
, unop(Iop_Not64
, binop(Iop_Or64
, getIReg(rs
),
31382 putIReg(rd
, unop(Iop_Not32
, binop(Iop_Or32
, getIReg(rs
),
31386 case 0x08: /* JR */
31389 assign(t0
, getIReg(rs
));
31390 lastn
= mkexpr(t0
);
31393 case 0x09: /* JALR */
31394 DIP("jalr r%u r%u", rd
, rs
);
31396 putIReg(rd
, mkU64(guest_PC_curr_instr
+ 8));
31397 t0
= newTemp(Ity_I64
);
31398 assign(t0
, getIReg(rs
));
31399 lastn
= mkexpr(t0
);
31401 putIReg(rd
, mkU32(guest_PC_curr_instr
+ 8));
31402 t0
= newTemp(Ity_I32
);
31403 assign(t0
, getIReg(rs
));
31404 lastn
= mkexpr(t0
);
31408 case 0x0C: /* SYSCALL */
31411 putPC(mkU64(guest_PC_curr_instr
+ 4));
31413 putPC(mkU32(guest_PC_curr_instr
+ 4));
31414 dres
.jk_StopHere
= Ijk_Sys_syscall
;
31415 dres
.whatNext
= Dis_StopHere
;
31418 case 0x2A: /* SLT */
31419 DIP("slt r%u, r%u, r%u", rd
, rs
, rt
);
31421 putIReg(rd
, unop(Iop_1Uto64
, binop(Iop_CmpLT64S
, getIReg(rs
),
31424 putIReg(rd
, unop(Iop_1Uto32
, binop(Iop_CmpLT32S
, getIReg(rs
),
31428 case 0x2B: /* SLTU */
31429 DIP("sltu r%u, r%u, r%u", rd
, rs
, rt
);
31431 putIReg(rd
, unop(Iop_1Uto64
, binop(Iop_CmpLT64U
, getIReg(rs
),
31434 putIReg(rd
, unop(Iop_1Uto32
, binop(Iop_CmpLT32U
, getIReg(rs
),
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
);
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
));
31449 SXX_PATTERN(Iop_Shl32
);
31453 case 0x04: { /* SLLV */
31454 DIP("sllv r%u, r%u, r%u", rd
, rt
, rs
);
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
),
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
));
31467 SXXV_PATTERN(Iop_Shl32
);
31472 case 0x03: /* SRA */
31473 DIP("sra r%u, r%u, %u", rd
, rt
, sa
);
31475 IRTemp tmpRt32
= newTemp(Ity_I32
);
31476 IRTemp tmpSh32
= newTemp(Ity_I32
);
31478 t1
= newTemp(Ity_I64
);
31479 t2
= newTemp(Ity_I64
);
31480 t3
= newTemp(Ity_I64
);
31482 assign(t1
, binop(Iop_And64
, getIReg(rt
), /* hi */
31483 mkU64(0xFFFFFFFF00000000ULL
)));
31485 assign(t2
, binop(Iop_Sar64
, mkexpr(t1
), mkU8(sa
)));
31487 assign(tmpRt32
, mkNarrowTo32(ty
, getIReg(rt
)));
31488 assign(tmpSh32
, binop(Iop_Sar32
, mkexpr(tmpRt32
), mkU8(sa
)));
31490 putIReg(rd
, mkWidenFrom32(ty
, mkexpr(tmpSh32
), True
));
31492 SXX_PATTERN(Iop_Sar32
);
31496 case 0x07: /* SRAV */
31497 DIP("srav r%u, r%u, r%u", rd
, rt
, rs
);
31499 IRTemp tmpRt32
= newTemp(Ity_I32
);
31500 IRTemp tmpSh32
= newTemp(Ity_I32
);
31502 t1
= newTemp(Ity_I64
);
31503 t2
= newTemp(Ity_I64
);
31504 t3
= newTemp(Ity_I64
);
31505 t4
= newTemp(Ity_I8
);
31507 assign(t4
, unop(Iop_32to8
, binop(Iop_And32
,
31508 mkNarrowTo32(ty
, getIReg(rs
)), mkU32(0x0000001F))));
31510 assign(t1
, binop(Iop_And64
, getIReg(rt
), /* hi */
31511 mkU64(0xFFFFFFFF00000000ULL
)));
31513 assign(t2
, binop(Iop_Sar64
, mkexpr(t1
), mkexpr(t4
)));
31515 assign(tmpRt32
, mkNarrowTo32(ty
, getIReg(rt
)));
31516 assign(tmpSh32
, binop(Iop_Sar32
, mkexpr(tmpRt32
), mkexpr(t4
)));
31518 putIReg(rd
, mkWidenFrom32(ty
, mkexpr(tmpSh32
), True
));
31520 SXXV_PATTERN(Iop_Sar32
);
31524 case 0x02: { /* SRL */
31525 rot
= get_rot(cins
);
31527 DIP("rotr r%u, r%u, %u", rd
, rt
, sa
);
31528 putIReg(rd
, mkWidenFrom32(ty
, genROR32(mkNarrowTo32(ty
,
31529 getIReg(rt
)), sa
), True
));
31531 DIP("srl r%u, r%u, %u", rd
, rt
, sa
);
31533 IRTemp tmpSh32
= newTemp(Ity_I32
);
31534 IRTemp tmpRt32
= newTemp(Ity_I32
);
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
));
31540 SXX_PATTERN(Iop_Shr32
);
31547 rot
= get_rotv(cins
);
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
));
31553 } else { /* SRLV */
31554 DIP("srlv r%u, r%u, r%u", rd
, rt
, rs
);
31556 SXXV_PATTERN64(Iop_Shr32
);
31558 SXXV_PATTERN(Iop_Shr32
);
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
);
31568 DIP("lsa r%u, r%u, r%u, imm: 0x%x", rd
, rs
, rt
, imm2
);
31569 putIReg(rd
, unop(Iop_32Sto64
,
31572 unop(Iop_64to32
, getIReg(rs
)),
31574 unop(Iop_64to32
, getIReg(rt
)))));
31577 DIP("lsa r%u, r%u, r%u, imm: 0x%x", rd
, rs
, rt
, imm2
);
31578 putIReg(rd
, binop(Iop_Add32
,
31580 getIReg(rs
), mkU8(imm2
+ 1)), getIReg(rt
)));
31584 ILLEGAL_INSTRUCTON
;
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)),
31596 ILLEGAL_INSTRUCTON
;
31601 case 0x0D: /* BREAK */
31602 DIP("break 0x%x", trap_code
);
31604 jmp_lit64(&dres
, Ijk_SigTRAP
, (guest_PC_curr_instr
+ 4));
31606 jmp_lit32(&dres
, Ijk_SigTRAP
, (guest_PC_curr_instr
+ 4));
31607 vassert(dres
.whatNext
== Dis_StopHere
);
31610 case 0x30: { /* TGE */
31611 DIP("tge r%u, r%u %u", rs
, rt
, trap_code
);
31613 if (trap_code
== 7)
31614 stmt (IRStmt_Exit (unop (Iop_Not1
,
31615 binop (Iop_CmpLT64S
,
31619 IRConst_U64(guest_PC_curr_instr
+ 4),
31621 else if (trap_code
== 6)
31622 stmt (IRStmt_Exit (unop (Iop_Not1
,
31623 binop (Iop_CmpLT64S
,
31627 IRConst_U64(guest_PC_curr_instr
+ 4),
31630 stmt (IRStmt_Exit (unop (Iop_Not1
,
31631 binop (Iop_CmpLT64S
,
31635 IRConst_U64(guest_PC_curr_instr
+ 4),
31638 if (trap_code
== 7)
31639 stmt (IRStmt_Exit (unop (Iop_Not1
,
31640 binop (Iop_CmpLT32S
,
31644 IRConst_U32(guest_PC_curr_instr
+ 4),
31646 else if (trap_code
== 6)
31647 stmt (IRStmt_Exit (unop (Iop_Not1
,
31648 binop (Iop_CmpLT32S
,
31652 IRConst_U32(guest_PC_curr_instr
+ 4),
31655 stmt (IRStmt_Exit (unop (Iop_Not1
,
31656 binop (Iop_CmpLT32S
,
31660 IRConst_U32(guest_PC_curr_instr
+ 4),
31665 case 0x31: { /* TGEU */
31666 DIP("tgeu r%u, r%u %u", rs
, rt
, trap_code
);
31668 if (trap_code
== 7)
31669 stmt (IRStmt_Exit (unop (Iop_Not1
,
31670 binop (Iop_CmpLT64U
,
31674 IRConst_U64(guest_PC_curr_instr
+ 4),
31676 else if (trap_code
== 6)
31677 stmt (IRStmt_Exit (unop (Iop_Not1
,
31678 binop (Iop_CmpLT64U
,
31682 IRConst_U64(guest_PC_curr_instr
+ 4),
31685 stmt (IRStmt_Exit (unop (Iop_Not1
,
31686 binop (Iop_CmpLT64U
,
31690 IRConst_U64(guest_PC_curr_instr
+ 4),
31693 if (trap_code
== 7)
31694 stmt (IRStmt_Exit (unop (Iop_Not1
,
31695 binop (Iop_CmpLT32U
,
31699 IRConst_U32(guest_PC_curr_instr
+ 4),
31701 else if (trap_code
== 6)
31702 stmt (IRStmt_Exit (unop (Iop_Not1
,
31703 binop (Iop_CmpLT32U
,
31707 IRConst_U32(guest_PC_curr_instr
+ 4),
31710 stmt (IRStmt_Exit (unop (Iop_Not1
,
31711 binop (Iop_CmpLT32U
,
31715 IRConst_U32(guest_PC_curr_instr
+ 4),
31720 case 0x32: { /* TLT */
31721 DIP("tlt r%u, r%u %u", rs
, rt
, trap_code
);
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),
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),
31734 stmt(IRStmt_Exit(binop(Iop_CmpLT64S
, getIReg(rs
),
31735 getIReg(rt
)), Ijk_SigTRAP
,
31736 IRConst_U64(guest_PC_curr_instr
+ 4),
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),
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),
31750 stmt(IRStmt_Exit(binop(Iop_CmpLT32S
, getIReg(rs
),
31751 getIReg(rt
)), Ijk_SigTRAP
,
31752 IRConst_U32(guest_PC_curr_instr
+ 4),
31757 case 0x33: { /* TLTU */
31758 DIP("tltu r%u, r%u %u", rs
, rt
, trap_code
);
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),
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),
31771 stmt(IRStmt_Exit(binop(Iop_CmpLT64U
, getIReg(rs
),
31772 getIReg(rt
)), Ijk_SigTRAP
,
31773 IRConst_U64(guest_PC_curr_instr
+ 4),
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),
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),
31787 stmt(IRStmt_Exit(binop(Iop_CmpLT32U
, getIReg(rs
),
31788 getIReg (rt
)), Ijk_SigTRAP
,
31789 IRConst_U32(guest_PC_curr_instr
+ 4),
31794 case 0x34: { /* TEQ */
31795 DIP("teq r%u, r%u, %u", rs
, rt
, trap_code
);
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),
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),
31808 stmt(IRStmt_Exit(binop(Iop_CmpEQ64
, getIReg(rs
),
31809 getIReg(rt
)), Ijk_SigTRAP
,
31810 IRConst_U64(guest_PC_curr_instr
+ 4),
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),
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),
31824 stmt(IRStmt_Exit(binop(Iop_CmpEQ32
, getIReg(rs
),
31825 getIReg(rt
)), Ijk_SigTRAP
,
31826 IRConst_U32(guest_PC_curr_instr
+ 4),
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
);
31835 putIReg(rd
, binop(Iop_And64
,
31837 unop(Iop_CmpwNEZ64
, getIReg(rt
))),
31840 putIReg(rd
, binop(Iop_And32
,
31842 unop(Iop_CmpwNEZ32
, getIReg(rt
))),
31846 ILLEGAL_INSTRUCTON
;
31851 case 0x36: { /* TNE */
31852 DIP("tne r%u, r%u %u", rs
, rt
, trap_code
);
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),
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),
31865 stmt(IRStmt_Exit(binop(Iop_CmpNE64
, getIReg(rs
),
31866 getIReg(rt
)), Ijk_SigTRAP
,
31867 IRConst_U64(guest_PC_curr_instr
+ 4),
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),
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),
31881 stmt(IRStmt_Exit(binop(Iop_CmpNE32
, getIReg(rs
),
31882 getIReg(rt
)), Ijk_SigTRAP
,
31883 IRConst_U32(guest_PC_curr_instr
+ 4),
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
);
31892 putIReg(rd
, binop(Iop_And64
,
31893 unop(Iop_CmpwNEZ64
, getIReg(rt
)), getIReg(rs
)));
31895 putIReg(rd
, binop(Iop_And32
,
31896 unop(Iop_CmpwNEZ32
, getIReg(rt
)), getIReg(rs
)));
31899 ILLEGAL_INSTRUCTON
;
31905 case 0x17: /* DSLLV, DROTRV:DSRLV, DSRAV */
31908 case 0x3B: /* DSLL, DROTL:DSRL, DSRA */
31911 case 0x3F: /* DSLL32, DROTR32:DSRL32, DSRA32 */
31912 if (dis_instr_shrt(cins
))
31914 goto decode_failure
;
31916 case 0x0F: /* SYNC */
31917 DIP("sync 0x%x", sel
);
31918 /* Just ignore it. */
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
);
31926 assign(tmpRs64
, getIReg(rs
));
31927 assign(tmpRt64
, getIReg(rt
));
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 ))
31937 if(sign(dst) == sign(src0 ))
31939 we have overflow! */
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
,
31945 binop(Iop_And64
, mkexpr(t1
),
31946 mkU64(0x8000000000000000ULL
)),
31947 mkU64(0x8000000000000000ULL
))));
31949 assign(t3
, binop(Iop_Xor64
, mkexpr(t0
), mkexpr(tmpRs64
)));
31950 assign(t4
, unop(Iop_1Uto64
,
31952 binop(Iop_And64
, mkexpr(t3
),
31953 mkU64(0x8000000000000000ULL
)),
31954 mkU64(0x8000000000000000ULL
))));
31956 stmt(IRStmt_Exit(binop(Iop_CmpEQ64
,
31957 binop(Iop_Or64
, mkexpr(t2
), mkexpr(t4
)),
31960 IRConst_U64(guest_PC_curr_instr
+ 4),
31963 putIReg(rd
, mkexpr(t0
));
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
);
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
);
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) ))
31988 if(sign(dst) == sign(src0 ))
31990 we have overflow! */
31992 assign(t5
, binop(Iop_Mul64
,
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
,
32001 mkU64(0x8000000000000000ULL
)),
32002 mkU64(0x8000000000000000ULL
))));
32004 assign(t3
, binop(Iop_Xor64
, mkexpr(t0
), mkexpr(tmpRs64
)));
32005 assign(t4
, unop(Iop_1Sto64
,
32009 mkU64(0x8000000000000000ULL
)),
32010 mkU64(0x8000000000000000ULL
))));
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),
32017 putIReg(rd
, binop(Iop_Sub64
, getIReg(rs
), getIReg(rt
)));
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
);
32027 goto decode_failure
;
32031 case 0x01: /* Regimm */
32034 case 0x00: /* BLTZ */
32035 DIP("bltz r%u, %u", rs
, imm
);
32037 if (!dis_instr_branch(cins
, &dres
, resteerOkFn
,
32038 callback_opaque
, &bstmt
))
32039 goto decode_failure
;
32041 dis_branch(False
, binop(Iop_CmpEQ32
, binop(Iop_And32
, getIReg(rs
),
32042 mkU32(0x80000000)), mkU32(0x80000000)), imm
, &bstmt
);
32045 case 0x01: /* BGEZ */
32046 DIP("bgez r%u, %u", rs
, imm
);
32048 if (!dis_instr_branch(cins
, &dres
, resteerOkFn
,
32049 callback_opaque
, &bstmt
))
32050 goto decode_failure
;
32052 dis_branch(False
, binop(Iop_CmpEQ32
, binop(Iop_And32
, getIReg(rs
),
32053 mkU32(0x80000000)), mkU32(0x0)), imm
, &bstmt
);
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)),
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
);
32073 case 0x10: /* BLTZAL */
32074 DIP("bltzal r%u, %u", rs
, imm
);
32076 if (!dis_instr_branch(cins
, &dres
, resteerOkFn
,
32077 callback_opaque
, &bstmt
))
32078 goto decode_failure
;
32080 dis_branch(True
, binop(Iop_CmpEQ32
, binop(Iop_And32
, getIReg(rs
),
32081 mkU32(0x80000000)), mkU32(0x80000000)), imm
, &bstmt
);
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)),
32095 case 0x11: /* BGEZAL */
32096 DIP("bgezal r%u, %u", rs
, imm
);
32098 if (!dis_instr_branch(cins
, &dres
, resteerOkFn
,
32099 callback_opaque
, &bstmt
))
32100 goto decode_failure
;
32102 dis_branch(True
, binop(Iop_CmpEQ32
, binop(Iop_And32
, getIReg(rs
),
32103 mkU32(0x80000000)), mkU32(0x0)), imm
, &bstmt
);
32106 case 0x13: /* BGEZALL */
32107 DIP("bgezall r%u, %u", rs
, imm
);
32109 putIReg(31, mkU64(guest_PC_curr_instr
+ 8));
32110 lastn
= dis_branch_likely(binop(Iop_CmpNE64
,
32113 mkU64(0x8000000000000000ULL
)),
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)),
32124 case 0x08: /* TGEI */
32125 DIP("tgei r%u, %u %u", rs
, imm
, trap_code
);
32127 stmt (IRStmt_Exit(unop(Iop_Not1
,
32128 binop(Iop_CmpLT64S
,
32130 mkU64(extend_s_16to64 (imm
)))),
32132 IRConst_U64(guest_PC_curr_instr
+ 4),
32135 stmt (IRStmt_Exit(unop(Iop_Not1
,
32136 binop(Iop_CmpLT32S
,
32138 mkU32(extend_s_16to32 (imm
)))),
32140 IRConst_U32(guest_PC_curr_instr
+ 4),
32145 case 0x09: { /* TGEIU */
32146 DIP("tgeiu r%u, %u %u", rs
, imm
, trap_code
);
32148 stmt (IRStmt_Exit (unop (Iop_Not1
,
32149 binop (Iop_CmpLT64U
,
32151 mkU64 (extend_s_16to64 (imm
)))),
32153 IRConst_U64(guest_PC_curr_instr
+ 4),
32156 stmt (IRStmt_Exit (unop (Iop_Not1
,
32157 binop (Iop_CmpLT32U
,
32159 mkU32 (extend_s_16to32 (imm
)))),
32161 IRConst_U32(guest_PC_curr_instr
+ 4),
32166 case 0x0A: { /* TLTI */
32167 DIP("tlti r%u, %u %u", rs
, imm
, trap_code
);
32169 stmt (IRStmt_Exit (binop (Iop_CmpLT64S
, getIReg (rs
),
32170 mkU64 (extend_s_16to64 (imm
))),
32172 IRConst_U64(guest_PC_curr_instr
+ 4),
32175 stmt (IRStmt_Exit (binop (Iop_CmpLT32S
, getIReg (rs
),
32176 mkU32 (extend_s_16to32 (imm
))),
32178 IRConst_U32(guest_PC_curr_instr
+ 4),
32183 case 0x0B: { /* TLTIU */
32184 DIP("tltiu r%u, %u %u", rs
, imm
, trap_code
);
32186 stmt (IRStmt_Exit (binop (Iop_CmpLT64U
, getIReg (rs
),
32187 mkU64 (extend_s_16to64 (imm
))),
32189 IRConst_U64(guest_PC_curr_instr
+ 4),
32192 stmt (IRStmt_Exit (binop (Iop_CmpLT32U
, getIReg (rs
),
32193 mkU32 (extend_s_16to32 (imm
))),
32195 IRConst_U32(guest_PC_curr_instr
+ 4),
32200 case 0x0C: { /* TEQI */
32201 DIP("teqi r%u, %u %u", rs
, imm
, trap_code
);
32203 stmt (IRStmt_Exit (binop (Iop_CmpEQ64
, getIReg (rs
),
32204 mkU64 (extend_s_16to64 (imm
))),
32206 IRConst_U64(guest_PC_curr_instr
+ 4),
32209 stmt (IRStmt_Exit (binop (Iop_CmpEQ32
, getIReg (rs
),
32210 mkU32 (extend_s_16to32 (imm
))),
32212 IRConst_U32(guest_PC_curr_instr
+ 4),
32217 case 0x0E: { /* TNEI */
32218 DIP("tnei r%u, %u %u", rs
, imm
, trap_code
);
32220 stmt (IRStmt_Exit (binop (Iop_CmpNE64
, getIReg (rs
),
32221 mkU64 (extend_s_16to64 (imm
))),
32223 IRConst_U64(guest_PC_curr_instr
+ 4),
32226 stmt (IRStmt_Exit (binop (Iop_CmpNE32
, getIReg (rs
),
32227 mkU32 (extend_s_16to32 (imm
))),
32229 IRConst_U32(guest_PC_curr_instr
+ 4),
32234 case 0x1C: { /* BPOSGE32 */
32235 DIP("bposge32 %u", imm
);
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
);
32245 /* Just ignore it */
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)));
32254 ILLEGAL_INSTRUCTON
;
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)));
32265 ILLEGAL_INSTRUCTON
;
32271 goto decode_failure
;
32276 DIP("beq r%u, r%u, %u", rs
, rt
, imm
);
32278 dis_branch(False
, binop(Iop_CmpEQ64
, getIReg(rs
), getIReg(rt
)),
32281 dis_branch(False
, binop(Iop_CmpEQ32
, getIReg(rs
), getIReg(rt
)),
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
);
32292 DIP("bne r%u, r%u, %u", rs
, rt
, imm
);
32294 dis_branch(False
, binop(Iop_CmpNE64
, getIReg(rs
), getIReg(rt
)),
32297 dis_branch(False
, binop(Iop_CmpNE32
, getIReg(rs
), getIReg(rt
)),
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
);
32307 case 0x07: /* BGTZ, BGTZALC, BLTZALC, BLTUC */
32308 if (rt
== 0) { /* BGTZ */
32309 DIP("bgtz r%u, %u", rs
, imm
);
32311 dis_branch(False
, unop(Iop_Not1
, binop(Iop_CmpLE64S
, getIReg(rs
),
32312 mkU64(0x00))), imm
, &bstmt
);
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
);
32320 dis_branch_compact(True
,
32322 binop(Iop_CmpLE64S
,
32323 getIReg(rt
), mkU64(0x0))),
32326 dis_branch_compact(True
,
32328 binop(Iop_CmpLE32S
,
32329 getIReg(rt
), mkU32(0x0))),
32332 } else if (rs
== rt
) { /* BLTZALC */
32333 DIP("bltzalc r%u, %u", rt
, imm
);
32335 dis_branch_compact(True
,
32337 binop(Iop_CmpLE64S
,
32338 mkU64(0x0), getIReg(rt
))),
32341 dis_branch_compact(True
,
32343 binop(Iop_CmpLE32S
,
32344 mkU32(0x0), getIReg(rt
))),
32347 } else { /* BLTUC */
32348 DIP("bltuc r%u, r%u, %u", rt
, rs
, imm
);
32350 dis_branch_compact(False
,
32351 binop(Iop_CmpLT64U
, getIReg(rs
), getIReg(rt
)),
32354 dis_branch_compact(False
,
32355 binop(Iop_CmpLT32U
, getIReg(rs
), getIReg(rt
)),
32360 ILLEGAL_INSTRUCTON
;
32364 case 0x17: /* BGTZL, BGTZC, BLTZC, BLTC */
32365 if (rt
== 0) { /* BGTZL */
32366 DIP("bgtzl r%u, %u", rs
, imm
);
32368 lastn
= dis_branch_likely(binop(Iop_CmpLE64S
, getIReg(rs
),
32369 mkU64(0x00)), imm
);
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
);
32377 dis_branch_compact(False
,
32379 binop(Iop_CmpLE64S
,
32380 getIReg(rt
), mkU64(0x0))),
32383 dis_branch_compact(False
,
32385 binop(Iop_CmpLE32S
,
32386 getIReg(rt
), mkU32(0x0))),
32389 } else if (rs
== rt
) { /* BLTZC */
32390 DIP("bltzc r%u, %u", rt
, imm
);
32392 dis_branch_compact(False
,
32394 binop(Iop_CmpLE64S
,
32395 mkU64(0x0), getIReg(rt
))),
32398 dis_branch_compact(False
,
32400 binop(Iop_CmpLE32S
,
32401 mkU32(0x0), getIReg(rt
))),
32404 } else { /* BLTC */
32405 DIP("bltc r%u, r%u, %u", rs
, rt
, imm
);
32407 dis_branch_compact(False
,
32409 binop(Iop_CmpLE64S
,
32410 getIReg(rt
), getIReg(rs
))),
32413 dis_branch_compact(False
,
32415 binop(Iop_CmpLE32S
,
32416 getIReg(rt
), getIReg(rs
))),
32421 ILLEGAL_INSTRUCTON
;
32425 case 0x06: /* BLEZ, BLEZALC, BGEZALC, BGEUC */
32426 if (rt
== 0) { /* BLEZ */
32427 DIP("blez r%u, %u", rs
, imm
);
32429 dis_branch(False
, binop(Iop_CmpLE64S
, getIReg(rs
), mkU64(0x0)),
32432 dis_branch(False
, binop(Iop_CmpLE32S
, getIReg(rs
), mkU32(0x0)), imm
,
32434 } else if (VEX_MIPS_CPU_HAS_MIPSR6(archinfo
->hwcaps
)) {
32435 if (rs
== 0) { /* BLEZALC */
32436 DIP("blezalc r%u, %u", rt
, imm
);
32438 dis_branch_compact(True
,
32439 binop(Iop_CmpLE64S
, getIReg(rt
), mkU64(0x0)),
32442 dis_branch_compact(True
,
32443 binop(Iop_CmpLE32S
, getIReg(rt
), mkU32(0x0)),
32445 } else if (rt
== rs
) {/* BGEZALC */
32446 DIP("bgezalc r%u, %u", rt
, imm
);
32448 dis_branch_compact(True
,
32449 binop(Iop_CmpLE64S
, mkU64(0x0), getIReg(rt
)),
32452 dis_branch_compact(True
,
32453 binop(Iop_CmpLE32S
, mkU32(0x0), getIReg(rt
)),
32455 } else { /* BGEUC */
32456 DIP("bgeuc r%u, r%u, %u", rt
, rs
, imm
);
32458 dis_branch_compact(False
,
32460 binop(Iop_CmpLT64U
,
32461 getIReg(rs
), getIReg(rt
))),
32464 dis_branch_compact(False
,
32466 binop(Iop_CmpLT32U
,
32467 getIReg(rs
), getIReg(rt
))),
32471 ILLEGAL_INSTRUCTON
;
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
);
32485 dis_branch_compact(False
,
32486 binop(Iop_CmpLE64S
, getIReg(rt
), mkU64(0x0)),
32489 dis_branch_compact(False
,
32490 binop(Iop_CmpLE32S
, getIReg(rt
), mkU32(0x0)),
32493 } else if (rt
== rs
) { /* BGEZC */
32494 DIP("bgezc r%u, %u", rt
, imm
);
32496 dis_branch_compact(False
,
32497 binop(Iop_CmpLE64S
, mkU64(0x0), getIReg(rt
)),
32500 dis_branch_compact(False
,
32501 binop(Iop_CmpLE32S
, mkU32(0x0), getIReg(rt
)),
32504 } else { /* BGEC */
32505 DIP("bgec r%u, r%u, %u", rs
, rt
, imm
);
32507 dis_branch_compact(False
,
32508 binop(Iop_CmpLE64S
, getIReg(rt
), getIReg(rs
)),
32511 dis_branch_compact(False
,
32512 binop(Iop_CmpLE32S
, getIReg(rt
), getIReg(rs
)),
32517 ILLEGAL_INSTRUCTON
;
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
)));
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 ))
32535 if(sign(dst) == sign(src0 ))
32537 we have overflow! */
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))));
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))));
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),
32556 putIReg(rt
, mkWidenFrom32(ty
, mkexpr(t0
), True
));
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
);
32564 dis_branch_compact(True
,
32565 binop(Iop_CmpEQ64
, getIReg(rt
), mkU64(0x0)),
32568 dis_branch_compact(True
,
32569 binop(Iop_CmpEQ32
, getIReg(rt
), mkU32(0x0)),
32572 } else if (rs
< rt
) { /* BEQC */
32573 DIP("beqc r%u, r%u, %u",rs
, rt
, imm
);
32575 dis_branch_compact(False
,
32576 binop(Iop_CmpEQ64
, getIReg(rt
), getIReg(rs
)),
32579 dis_branch_compact(False
,
32580 binop(Iop_CmpEQ32
, getIReg(rt
), getIReg(rs
)),
32583 } else { /* BOVC */
32584 DIP("bovc r%u, r%u, %u",rs
, rt
, imm
);
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
,
32592 mkU64(0xffffffff80000000ULL
)),
32594 IRExpr_ITE(binop(Iop_CmpLT64S
,
32596 mkU64(0x7FFFFFFFULL
)),
32597 mkU32(0),mkU32(1))));
32598 assign(t1
, IRExpr_ITE(binop(Iop_CmpLT64S
,
32600 mkU64(0xffffffff80000000ULL
)),
32602 IRExpr_ITE(binop(Iop_CmpLT64S
,
32604 mkU64(0x7FFFFFFFULL
)),
32605 mkU32(0), mkU32(1))));
32606 assign(t2
, IRExpr_ITE(binop(Iop_CmpLT64S
,
32608 getIReg(rt
), getIReg(rs
)),
32609 mkU64(0xffffffff80000000ULL
)),
32611 IRExpr_ITE(binop(Iop_CmpLT64S
,
32615 mkU64(0x7FFFFFFFULL
)),
32616 mkU32(0), mkU32(1))));
32617 assign(t3
, binop(Iop_Add32
,
32619 binop(Iop_Add32
, mkexpr(t1
), mkexpr(t2
))));
32620 dis_branch_compact(False
,
32621 binop(Iop_CmpNE32
, mkexpr(t3
), mkU32(0)),
32624 IRTemp tmpRs32
= newTemp(Ity_I32
);
32625 IRTemp tmpRt32
= newTemp(Ity_I32
);
32626 assign(tmpRs32
, getIReg(rs
));
32627 assign(tmpRt32
, getIReg(rt
));
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 ))
32637 if (sign(dst) == sign(src0 ))
32639 we have overflow! */
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
,
32645 binop(Iop_And32
, mkexpr(t1
), mkU32(0x80000000)),
32646 mkU32(0x80000000))));
32648 assign(t3
, binop(Iop_Xor32
, mkexpr(t0
), mkexpr(tmpRs32
)));
32649 assign(t4
, unop(Iop_1Uto32
,
32651 binop(Iop_And32
, mkexpr(t3
), mkU32(0x80000000)),
32652 mkU32(0x80000000))));
32654 dis_branch_compact(False
, binop(Iop_CmpEQ32
,
32655 binop(Iop_Or32
, mkexpr(t2
), mkexpr(t4
)),
32656 mkU32(0)), imm
, &dres
);
32660 /* In documentation for BEQC stands rs > rt and for BOVC stands rs >= rt! */
32664 case 0x09: /* ADDIU */
32665 DIP("addiu r%u, r%u, %u", rt
, rs
, imm
);
32667 putIReg(rt
, mkWidenFrom32(ty
, binop(Iop_Add32
,
32668 mkNarrowTo32(ty
, getIReg(rs
)),mkU32(extend_s_16to32(imm
))),
32671 putIReg(rt
, binop(Iop_Add32
, getIReg(rs
),mkU32(extend_s_16to32(imm
))));
32673 case 0x0C: /* ANDI */
32674 DIP("andi r%u, r%u, %u", rt
, rs
, imm
);
32676 ALUI_PATTERN64(Iop_And64
);
32678 ALUI_PATTERN(Iop_And32
);
32682 case 0x0E: /* XORI */
32683 DIP("xori r%u, r%u, %u", rt
, rs
, imm
);
32685 ALUI_PATTERN64(Iop_Xor64
);
32687 ALUI_PATTERN(Iop_Xor32
);
32691 case 0x0D: /* ORI */
32692 DIP("ori r%u, r%u, %u", rt
, rs
, imm
);
32694 ALUI_PATTERN64(Iop_Or64
);
32696 ALUI_PATTERN(Iop_Or32
);
32700 case 0x0A: /* SLTI */
32701 DIP("slti r%u, r%u, %u", rt
, rs
, imm
);
32703 putIReg(rt
, unop(Iop_1Uto64
, binop(Iop_CmpLT64S
, getIReg(rs
),
32704 mkU64(extend_s_16to64(imm
)))));
32706 putIReg(rt
, unop(Iop_1Uto32
, binop(Iop_CmpLT32S
, getIReg(rs
),
32707 mkU32(extend_s_16to32(imm
)))));
32710 case 0x0B: /* SLTIU */
32711 DIP("sltiu r%u, r%u, %u", rt
, rs
, imm
);
32713 putIReg(rt
, unop(Iop_1Uto64
, binop(Iop_CmpLT64U
, getIReg(rs
),
32714 mkU64(extend_s_16to64(imm
)))));
32716 putIReg(rt
, unop(Iop_1Uto32
, binop(Iop_CmpLT32U
, getIReg(rs
),
32717 mkU32(extend_s_16to32(imm
)))));
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
));
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 ))
32734 if(sign(dst) == sign(src0 ))
32736 we have overflow! */
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
))));
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
))));
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),
32756 putIReg(rt
, mkexpr(t0
));
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
);
32764 dis_branch_compact(True
,
32766 binop(Iop_CmpEQ64
, getIReg(rt
), mkU64(0x0))),
32769 dis_branch_compact(True
,
32771 binop(Iop_CmpEQ32
, getIReg(rt
), mkU32(0x0))),
32774 } else if (rs
< rt
) { /* BNEC */
32775 DIP("bnec r%u, %u", rt
, imm
);
32777 dis_branch_compact(False
,
32780 getIReg(rt
), getIReg(rs
))),
32783 dis_branch_compact(False
,
32786 getIReg(rt
), getIReg(rs
))),
32789 } else { /* BNVC */
32790 DIP("bnvc r%u, r%u, %u", rs
, rt
, imm
);
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
,
32798 mkU64(0xffffffff80000000ULL
)),
32800 IRExpr_ITE(binop(Iop_CmpLT64S
,
32802 mkU64(0x7FFFFFFFULL
)),
32803 mkU32(0),mkU32(1))));
32804 assign(t1
, IRExpr_ITE(binop(Iop_CmpLT64S
,
32806 mkU64(0xffffffff80000000ULL
)),
32808 IRExpr_ITE(binop(Iop_CmpLT64S
,
32810 mkU64(0x7FFFFFFFULL
)),
32811 mkU32(0),mkU32(1))));
32812 assign(t2
, IRExpr_ITE(binop(Iop_CmpLT64S
,
32814 getIReg(rt
), getIReg(rs
)),
32815 mkU64(0xffffffff80000000ULL
)),
32817 IRExpr_ITE(binop(Iop_CmpLT64S
,
32821 mkU64(0x7FFFFFFFULL
)),
32822 mkU32(0),mkU32(1))));
32823 assign(t3
, binop(Iop_Add32
,
32825 binop(Iop_Add32
, mkexpr(t1
), mkexpr(t2
))));
32826 dis_branch_compact(False
,
32827 binop(Iop_CmpEQ32
, mkexpr(t3
), mkU32(0)),
32830 IRTemp tmpRs32
= newTemp(Ity_I32
);
32831 IRTemp tmpRt32
= newTemp(Ity_I32
);
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 ))
32843 if (sign(dst) == sign(src0 ))
32845 we have overflow! */
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
,
32851 binop(Iop_And32
, mkexpr(t1
), mkU32(0x80000000)),
32852 mkU32(0x80000000))));
32854 assign(t3
, binop(Iop_Xor32
, mkexpr(t0
), mkexpr(tmpRs32
)));
32855 assign(t4
, unop(Iop_1Uto32
,
32857 binop(Iop_And32
, mkexpr(t3
), mkU32(0x80000000)),
32858 mkU32(0x80000000))));
32860 dis_branch_compact(False
, binop(Iop_CmpNE32
,
32861 binop(Iop_Or32
, mkexpr(t2
), mkexpr(t4
)),
32862 mkU32(0)), imm
, &dres
);
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
))));
32875 /* Load Doubleword Left - LDL; MIPS64 */
32877 DIP("ldl r%u, %u(r%u)", rt
, imm
, rs
);
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
)))));
32887 /* t2 = word addr */
32888 /* t4 = addr mod 8 */
32889 LWX_SWX_PATTERN64_1
;
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)))));
32897 /* rt content - adjusted */
32898 t5
= newTemp(Ity_I64
);
32899 t6
= newTemp(Ity_I64
);
32900 t7
= newTemp(Ity_I64
);
32902 assign(t5
, binop(Iop_Mul64
, mkexpr(t4
), mkU64(0x8)));
32904 assign(t6
, binop(Iop_Shr64
, mkU64(0x00FFFFFFFFFFFFFFULL
),
32905 narrowTo(Ity_I8
, mkexpr(t5
))));
32907 assign(t7
, binop(Iop_And64
, getIReg(rt
), mkexpr(t6
)));
32909 putIReg(rt
, binop(Iop_Or64
, mkexpr(t7
), mkexpr(t3
)));
32914 /* Load Doubleword Right - LDR; MIPS64 */
32916 DIP("ldr r%u,%u(r%u)", rt
, imm
, rs
);
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
)))));
32926 /* t2 = word addr */
32927 /* t4 = addr mod 8 */
32928 LWX_SWX_PATTERN64_1
;
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)))));
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)))))));
32941 putIReg(rt
, binop(Iop_Or64
, mkexpr(t5
), mkexpr(t3
)));
32945 case 0x27: /* Load Word unsigned - LWU; MIPS64 */
32946 DIP("lwu r%u,%u(r%u)", rt
, imm
, rs
);
32947 LOAD_STORE_PATTERN
;
32949 putIReg(rt
, mkWidenFrom32(ty
, load(Ity_I32
, mkexpr(t1
)), False
));
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
) {
32957 assign(t2
, mkWidenFrom32(ty
, load(Ity_I32
, mkexpr(t1
)), True
));
32958 putLLaddr(mkexpr(t1
));
32959 putLLdata(mkexpr(t2
));
32960 putIReg(rt
, mkexpr(t2
));
32962 t2
= newTemp(Ity_I32
);
32963 stmt(IRStmt_LLSC(MIPS_IEND
, t2
, mkexpr(t1
), NULL
));
32964 putIReg(rt
, mkWidenFrom32(ty
, mkexpr(t2
), True
));
32968 case 0x34: /* Load Linked Doubleword - LLD; MIPS64 */
32969 DIP("lld r%u, %u(r%u)", rt
, imm
, rs
);
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
));
32978 stmt(IRStmt_LLSC(MIPS_IEND
, t2
, mkexpr(t1
), NULL
));
32980 putIReg(rt
, mkexpr(t2
));
32982 ILLEGAL_INSTRUCTON
;
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));
32998 mips_next_insn_if(mkexpr(t2
));
33000 t4
= newTemp(Ity_I32
);
33001 t5
= newTemp(Ity_I32
);
33003 assign(t5
, mkNarrowTo32(ty
, getLLdata()));
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 */)));
33010 putIReg(rt
, unop(mode64
? Iop_1Uto64
: Iop_1Uto32
,
33011 binop(Iop_CmpEQ32
, mkexpr(t4
), mkexpr(t5
))));
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
)));
33019 case 0x3C: /* Store Conditional Doubleword - SCD; MIPS64 */
33020 DIP("scd r%u, %u(r%u)", rt
, imm
, rs
);
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));
33031 mips_next_insn_if(mkexpr(t2
));
33033 t4
= newTemp(Ity_I64
);
33034 t5
= newTemp(Ity_I64
);
33036 assign(t5
, getLLdata());
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 */)));
33043 putIReg(rt
, unop(Iop_1Uto64
,
33044 binop(Iop_CmpEQ64
, mkexpr(t4
), mkexpr(t5
))));
33046 stmt(IRStmt_LLSC(MIPS_IEND
, t2
, mkexpr(t1
), getIReg(rt
)));
33047 putIReg(rt
, unop(Iop_1Uto64
, mkexpr(t2
)));
33050 ILLEGAL_INSTRUCTON
;
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
)));
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
));
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
,
33077 mkNarrowTo32(ty
, getIReg(rs
))),
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);
33084 t0
= newTemp(Ity_I64
);
33085 assign(t0
, mkU64(guest_PC_curr_instr
+
33086 ((extend_s_26to64(instr_index
& 0x3FFFFFF) + 1 ) << 2)));
33088 t0
= newTemp(Ity_I32
);
33089 assign(t0
, mkU32(guest_PC_curr_instr
+
33090 ((extend_s_26to32(instr_index
& 0x3FFFFFF) + 1) << 2)));
33093 dres
.whatNext
= Dis_StopHere
;
33094 dres
.jk_StopHere
= Ijk_Boring
;
33096 ILLEGAL_INSTRUCTON
;
33099 goto decode_failure
;
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
,
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);
33122 t0
= newTemp(Ity_I64
);
33123 assign(t0
, binop(Iop_Add64
, getIReg(rt
),
33124 mkU64(extend_s_16to64((instr_index
& 0xFFFF)))));
33126 t0
= newTemp(Ity_I32
);
33127 assign(t0
, binop(Iop_Add32
, getIReg(rt
),
33128 mkU32(extend_s_16to32((instr_index
& 0xFFFF)))));
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
);
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
),
33145 putPC(mkU64(guest_PC_curr_instr
+ 4));
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));
33156 ILLEGAL_INSTRUCTON
;
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
,
33170 mkNarrowTo32(ty
, getIReg(rs
))),
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);
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));
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));
33186 dres
.whatNext
= Dis_StopHere
;
33187 dres
.jk_StopHere
= Ijk_Call
;
33189 ILLEGAL_INSTRUCTON
;
33192 goto decode_failure
;
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
,
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
;
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));
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));
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
);
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
),
33241 putPC(mkU64(guest_PC_curr_instr
+ 4));
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));
33252 goto decode_failure
;
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))));
33261 ILLEGAL_INSTRUCTON
;
33265 case 0x1E: /* MIPS MSA (SIMD) */
33267 Int retVal
= disMSAInstr_MIPS_WRK(cins
);
33270 } else if (retVal
== -2) {
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");
33280 goto decode_failure
;
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");
33287 /* All decode failures end up here. */
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));
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
33302 stmt(IRStmt_Put(offsetof(VexGuestMIPS64State
, guest_PC
),
33303 mkU64(guest_PC_curr_instr
)));
33304 jmp_lit64(&dres
, Ijk_NoDecode
, guest_PC_curr_instr
);
33306 stmt(IRStmt_Put(offsetof(VexGuestMIPS32State
, guest_PC
),
33307 mkU32(guest_PC_curr_instr
)));
33308 jmp_lit32(&dres
, Ijk_NoDecode
, guest_PC_curr_instr
);
33310 dres
.whatNext
= Dis_StopHere
;
33313 } /* switch (opc) for the main (primary) opcode switch. */
33315 /* All MIPS insn have 4 bytes */
33317 if (delay_slot_branch
) {
33318 delay_slot_branch
= False
;
33322 putPC(mkU64(guest_PC_curr_instr
+ 4));
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
;
33329 if (likely_delay_slot
) {
33330 dres
.jk_StopHere
= Ijk_Boring
;
33331 dres
.whatNext
= Dis_StopHere
;
33335 if (delay_slot_jump
) {
33338 dres
.jk_StopHere
= is_Branch_or_Jump_and_Link(guest_code
+ delta
- 4) ?
33339 Ijk_Call
: Ijk_Boring
;
33343 /* All decode successes end up here. */
33344 switch (dres
.whatNext
) {
33347 putPC(mkU64(guest_PC_curr_instr
+ 4));
33349 putPC(mkU32(guest_PC_curr_instr
+ 4));
33354 putPC(mkU64(dres
.continueAt
));
33356 putPC(mkU32(dres
.continueAt
));
33365 /* On MIPS we need to check if the last instruction in block is branch or
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
;
33373 putPC(mkU64(guest_PC_curr_instr
+ 4));
33375 putPC(mkU32(guest_PC_curr_instr
+ 4));
33385 /*------------------------------------------------------------*/
33386 /*--- Top-level fn ---*/
33387 /*------------------------------------------------------------*/
33389 /* Disassemble a single instruction into IR. The instruction
33390 is located in host memory at &guest_code[delta]. */
33391 DisResult
disInstr_MIPS( IRSB
* irsb_IN
,
33392 Bool (*resteerOkFn
) ( void *, Addr
),
33394 void* callback_opaque
,
33395 const UChar
* guest_code_IN
,
33398 VexArch guest_arch
,
33399 const VexArchInfo
* archinfo
,
33400 const VexAbiInfo
* abiinfo
,
33401 VexEndness host_endness_IN
,
33402 Bool sigill_diag_IN
)
33405 /* Set globals (see top of this file) */
33406 vassert(guest_arch
== VexArchMIPS32
|| guest_arch
== VexArchMIPS64
);
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
);
33413 vassert(VEX_MIPS_HOST_FP_MODE(archinfo
->hwcaps
) >= fp_mode64
);
33415 guest_code
= guest_code_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
;
33424 dres
= disInstr_MIPS_WRK(resteerOkFn
, resteerCisOk
, callback_opaque
,
33425 delta
, archinfo
, abiinfo
, sigill_diag_IN
);
33430 /*--------------------------------------------------------------------*/
33431 /*--- end guest_mips_toIR.c ---*/
33432 /*--------------------------------------------------------------------*/